aboutsummaryrefslogtreecommitdiffstats
path: root/main/musl/0015-properly-handle-point-to-point-interfaces-in-getifad.patch
diff options
context:
space:
mode:
Diffstat (limited to 'main/musl/0015-properly-handle-point-to-point-interfaces-in-getifad.patch')
-rw-r--r--main/musl/0015-properly-handle-point-to-point-interfaces-in-getifad.patch59
1 files changed, 59 insertions, 0 deletions
diff --git a/main/musl/0015-properly-handle-point-to-point-interfaces-in-getifad.patch b/main/musl/0015-properly-handle-point-to-point-interfaces-in-getifad.patch
new file mode 100644
index 0000000000..88279d07f9
--- /dev/null
+++ b/main/musl/0015-properly-handle-point-to-point-interfaces-in-getifad.patch
@@ -0,0 +1,59 @@
+From 7b712844e38bdfc1ef728e257fb8616c16ec4cc8 Mon Sep 17 00:00:00 2001
+From: Jo-Philipp Wich <jow@openwrt.org>
+Date: Thu, 19 Nov 2015 21:43:10 +0100
+Subject: [PATCH] properly handle point-to-point interfaces in getifaddrs()
+
+With point-to-point interfaces, the IFA_ADDRESS netlink attribute
+contains the peer address while an extra attribute IFA_LOCAL carries
+the actual local interface address.
+
+Both the glibc and uclibc implementations of getifaddrs() handle this
+case by moving the ifa_addr contents to the broadcast/remote address
+union and overwriting ifa_addr upon receipt of an IFA_LOCAL attribute.
+
+This patch adds the same special treatment logic of IFA_LOCAL to
+musl's implementation of getifaddrs() in order to align its behaviour
+with that of uclibc and glibc.
+
+Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
+---
+ src/network/getifaddrs.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/src/network/getifaddrs.c b/src/network/getifaddrs.c
+index 89a8f72..fed75bd 100644
+--- a/src/network/getifaddrs.c
++++ b/src/network/getifaddrs.c
+@@ -162,13 +162,26 @@ static int netlink_msg_to_ifaddr(void *pctx, struct nlmsghdr *h)
+ for (rta = NLMSG_RTA(h, sizeof(*ifa)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
+ switch (rta->rta_type) {
+ case IFA_ADDRESS:
+- copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
++ /* If ifa_addr is already set we, received an IFA_LOCAL before
++ * so treat this as destination address */
++ if (ifs->ifa.ifa_addr)
++ copy_addr(&ifs->ifa.ifa_dstaddr, ifa->ifa_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
++ else
++ copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
+ break;
+ case IFA_BROADCAST:
+- /* For point-to-point links this is peer, but ifa_broadaddr
+- * and ifa_dstaddr are union, so this works for both. */
+ copy_addr(&ifs->ifa.ifa_broadaddr, ifa->ifa_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
+ break;
++ case IFA_LOCAL:
++ /* If ifa_addr is set and we get IFA_LOCAL, assume we have
++ * a point-to-point network. Move address to correct field. */
++ if (ifs->ifa.ifa_addr) {
++ ifs->ifu = ifs->addr;
++ ifs->ifa.ifa_dstaddr = &ifs->ifu.sa;
++ memset(&ifs->addr, 0, sizeof(ifs->addr));
++ }
++ copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
++ break;
+ case IFA_LABEL:
+ if (RTA_DATALEN(rta) < sizeof(ifs->name)) {
+ memcpy(ifs->name, RTA_DATA(rta), RTA_DATALEN(rta));
+--
+2.7.0
+