aboutsummaryrefslogtreecommitdiffstats
path: root/main/musl/1002-reimplement-if_nameindex-and-getifaddrs-using-netlin.patch
diff options
context:
space:
mode:
Diffstat (limited to 'main/musl/1002-reimplement-if_nameindex-and-getifaddrs-using-netlin.patch')
-rw-r--r--main/musl/1002-reimplement-if_nameindex-and-getifaddrs-using-netlin.patch247
1 files changed, 89 insertions, 158 deletions
diff --git a/main/musl/1002-reimplement-if_nameindex-and-getifaddrs-using-netlin.patch b/main/musl/1002-reimplement-if_nameindex-and-getifaddrs-using-netlin.patch
index f740e20672..f8df5dc399 100644
--- a/main/musl/1002-reimplement-if_nameindex-and-getifaddrs-using-netlin.patch
+++ b/main/musl/1002-reimplement-if_nameindex-and-getifaddrs-using-netlin.patch
@@ -1,85 +1,55 @@
-From 274b49ab1c7296fc13076b3ed8ca30050487a343 Mon Sep 17 00:00:00 2001
+From c3d5cce5c550896fd8e9cf856f66f5f264b49ef7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
Date: Tue, 8 Apr 2014 14:03:16 +0000
Subject: [PATCH] reimplement if_nameindex and getifaddrs using netlink
---
- src/network/__netlink.c | 68 ++++++++++
- src/network/__netlink.h | 143 ++++++++++++++++++++
- src/network/getifaddrs.c | 322 ++++++++++++++++++++++++---------------------
- src/network/if_nameindex.c | 105 +++++++++------
- 4 files changed, 451 insertions(+), 187 deletions(-)
+ src/network/__netlink.c | 38 ++++++
+ src/network/__netlink.h | 99 ++++++++++++++
+ src/network/getifaddrs.c | 325 +++++++++++++++++++++++++--------------------
+ src/network/if_nameindex.c | 107 +++++++++------
+ 4 files changed, 382 insertions(+), 187 deletions(-)
create mode 100644 src/network/__netlink.c
create mode 100644 src/network/__netlink.h
diff --git a/src/network/__netlink.c b/src/network/__netlink.c
new file mode 100644
-index 0000000..d0c9fab
+index 0000000..e75f374
--- /dev/null
+++ b/src/network/__netlink.c
-@@ -0,0 +1,68 @@
-+#define _GNU_SOURCE
+@@ -0,0 +1,38 @@
+#include <errno.h>
+#include <string.h>
-+#include <stdlib.h>
-+#include <unistd.h>
+#include <sys/socket.h>
-+#include <sys/param.h>
+#include "__netlink.h"
+
-+struct __netlink_handle {
-+ int fd;
-+ unsigned int seq;
-+ size_t bufsize;
-+};
-+
-+struct __netlink_handle *__netlink_open(int type)
-+{
-+ struct __netlink_handle *nh;
-+ int bufsize = getpagesize();
-+ /* required buffer size is MIN(8192,pagesize)-sizeof(struct skb_shared_info)
-+ * the estimate for skb_shared_info size is conservative, but gives enough
-+ * space to fit struct __netlink_handle including malloc overhead in one page . */
-+ if (bufsize > 8192) bufsize = 8192;
-+ bufsize -= 128;
-+ nh = malloc(sizeof(struct __netlink_handle) + bufsize);
-+ if (!nh) return 0;
-+ nh->fd = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, type);
-+ if (nh->fd < 0) { free(nh); return 0; }
-+ nh->seq = 1;
-+ nh->bufsize = bufsize;
-+ return nh;
-+}
-+
-+void __netlink_close(struct __netlink_handle *nh)
-+{
-+ close(nh->fd);
-+ free(nh);
-+}
-+
-+int __netlink_enumerate(struct __netlink_handle *nh, int type, int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx)
++int __netlink_enumerate(int fd, unsigned int seq, int type, int af,
++ int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx)
+{
+ struct nlmsghdr *h;
-+ void *buf = (void*)(nh+1);
-+ struct {
-+ struct nlmsghdr nlh;
-+ struct rtgenmsg g;
-+ } *req = buf;
++ union {
++ uint8_t buf[8192];
++ struct {
++ struct nlmsghdr nlh;
++ struct rtgenmsg g;
++ } req;
++ struct nlmsghdr reply;
++ } u;
+ int r, ret = 0;
+
-+ memset(req, 0, NETLINK_ALIGN(sizeof(*req)));
-+ req->nlh.nlmsg_len = sizeof(*req);
-+ req->nlh.nlmsg_type = type;
-+ req->nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
-+ req->nlh.nlmsg_seq = nh->seq++;
-+ req->g.rtgen_family = AF_UNSPEC;
-+ r = send(nh->fd, req, sizeof(*req), 0);
++ memset(&u.req, 0, sizeof(u.req));
++ u.req.nlh.nlmsg_len = sizeof(u.req);
++ u.req.nlh.nlmsg_type = type;
++ u.req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
++ u.req.nlh.nlmsg_seq = seq;
++ u.req.g.rtgen_family = af;
++ r = send(fd, &u.req, sizeof(u.req), 0);
+ if (r < 0) return r;
+
+ while (1) {
-+ r = recv(nh->fd, buf, nh->bufsize, MSG_DONTWAIT);
++ r = recv(fd, u.buf, sizeof(u.buf), MSG_DONTWAIT);
+ if (r <= 0) return -1;
-+ for (h = (struct nlmsghdr*) buf; NLMSG_OK(h, (void*)((uint8_t*)buf+r)); h = NLMSG_NEXT(h)) {
++ for (h = &u.reply; NLMSG_OK(h, (void*)&u.buf[r]); h = NLMSG_NEXT(h)) {
+ if (h->nlmsg_type == NLMSG_DONE) return ret;
+ if (h->nlmsg_type == NLMSG_ERROR) return -1;
+ if (!ret) ret = cb(ctx, h);
@@ -88,10 +58,10 @@ index 0000000..d0c9fab
+}
diff --git a/src/network/__netlink.h b/src/network/__netlink.h
new file mode 100644
-index 0000000..94728f3
+index 0000000..40b12a2
--- /dev/null
+++ b/src/network/__netlink.h
-@@ -0,0 +1,143 @@
+@@ -0,0 +1,99 @@
+#include <stdint.h>
+
+/* linux/netlink.h */
@@ -147,44 +117,10 @@ index 0000000..94728f3
+
+/* linux/if_link.h */
+
-+enum {
-+ IFLA_UNSPEC,
-+ IFLA_ADDRESS,
-+ IFLA_BROADCAST,
-+ IFLA_IFNAME,
-+ IFLA_MTU,
-+ IFLA_LINK,
-+ IFLA_QDISC,
-+ IFLA_STATS,
-+ IFLA_COST,
-+ IFLA_PRIORITY,
-+ IFLA_MASTER,
-+ IFLA_WIRELESS,
-+ IFLA_PROTINFO,
-+ IFLA_TXQLEN,
-+ IFLA_MAP,
-+ IFLA_WEIGHT,
-+ IFLA_OPERSTATE,
-+ IFLA_LINKMODE,
-+ IFLA_LINKINFO,
-+ IFLA_NET_NS_PID,
-+ IFLA_IFALIAS,
-+ IFLA_NUM_VF,
-+ IFLA_VFINFO_LIST,
-+ IFLA_STATS64,
-+ IFLA_VF_PORTS,
-+ IFLA_PORT_SELF,
-+ IFLA_AF_SPEC,
-+ IFLA_GROUP,
-+ IFLA_NET_NS_FD,
-+ IFLA_EXT_MASK,
-+ IFLA_PROMISCUITY,
-+ IFLA_NUM_TX_QUEUES,
-+ IFLA_NUM_RX_QUEUES,
-+ IFLA_CARRIER,
-+ IFLA_PHYS_PORT_ID,
-+ __IFLA_MAX
-+};
++#define IFLA_ADDRESS 1
++#define IFLA_BROADCAST 2
++#define IFLA_IFNAME 3
++#define IFLA_STATS 7
+
+/* linux/if_addr.h */
+
@@ -196,50 +132,40 @@ index 0000000..94728f3
+ uint32_t ifa_index;
+};
+
-+enum {
-+ IFA_UNSPEC,
-+ IFA_ADDRESS,
-+ IFA_LOCAL,
-+ IFA_LABEL,
-+ IFA_BROADCAST,
-+ IFA_ANYCAST,
-+ IFA_CACHEINFO,
-+ IFA_MULTICAST,
-+ __IFA_MAX
-+};
++#define IFA_ADDRESS 1
++#define IFA_LOCAL 2
++#define IFA_LABEL 3
++#define IFA_BROADCAST 4
+
+/* musl */
+
+#define NETLINK_ALIGN(len) (((len)+3) & ~3)
-+#define NLMSG_DATA(nlh) ((void*)((char*)(nlh)+NETLINK_ALIGN(sizeof(struct nlmsghdr))))
-+#define NLMSG_DATALEN(nlh) ((nlh)->nlmsg_len-NETLINK_ALIGN(sizeof(struct nlmsghdr)))
++#define NLMSG_DATA(nlh) ((void*)((char*)(nlh)+sizeof(struct nlmsghdr)))
++#define NLMSG_DATALEN(nlh) ((nlh)->nlmsg_len-sizeof(struct nlmsghdr))
+#define NLMSG_DATAEND(nlh) ((char*)(nlh)+(nlh)->nlmsg_len)
+#define NLMSG_NEXT(nlh) (struct nlmsghdr*)((char*)(nlh)+NETLINK_ALIGN((nlh)->nlmsg_len))
+#define NLMSG_OK(nlh,end) (NLMSG_DATA(nlh) <= (end) && \
+ (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \
+ (void*)NLMSG_NEXT(nlh) <= (end))
+
-+#define RTA_DATA(rta) ((void*)((char*)(rta)+NETLINK_ALIGN(sizeof(struct rtattr))))
-+#define RTA_DATALEN(rta) ((rta)->rta_len-NETLINK_ALIGN(sizeof(struct rtattr)))
++#define RTA_DATA(rta) ((void*)((char*)(rta)+sizeof(struct rtattr)))
++#define RTA_DATALEN(rta) ((rta)->rta_len-sizeof(struct rtattr))
+#define RTA_DATAEND(rta) ((char*)(rta)+(rta)->rta_len)
+#define RTA_NEXT(rta) (struct rtattr*)((char*)(rta)+NETLINK_ALIGN((rta)->rta_len))
+#define RTA_OK(rta,end) (RTA_DATA(rta) <= (void*)(end) && \
+ (rta)->rta_len >= sizeof(struct rtattr) && \
+ (void*)RTA_NEXT(rta) <= (void*)(end))
+
-+#define NLMSG_RTA(nlh,len) ((void*)((char*)(nlh)+NETLINK_ALIGN(sizeof(struct nlmsghdr))+NETLINK_ALIGN(len)))
++#define NLMSG_RTA(nlh,len) ((void*)((char*)(nlh)+sizeof(struct nlmsghdr)+NETLINK_ALIGN(len)))
+#define NLMSG_RTAOK(rta,nlh) RTA_OK(rta,NLMSG_DATAEND(nlh))
+
-+struct __netlink_handle;
-+
-+struct __netlink_handle *__netlink_open(int type);
-+void __netlink_close(struct __netlink_handle *h);
-+int __netlink_enumerate(struct __netlink_handle *h, int type, int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx);
++int __netlink_enumerate(int fd, unsigned int seq, int type, int af,
++ int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx);
diff --git a/src/network/getifaddrs.c b/src/network/getifaddrs.c
-index 5a94cc7..5b1ebe7 100644
+index 5a94cc7..9d4bd5b 100644
--- a/src/network/getifaddrs.c
+++ b/src/network/getifaddrs.c
-@@ -1,181 +1,209 @@
+@@ -1,181 +1,212 @@
-/* (C) 2013 John Spencer. released under musl's standard MIT license. */
-#undef _GNU_SOURCE
#define _GNU_SOURCE
@@ -257,14 +183,16 @@ index 5a94cc7..5b1ebe7 100644
-#include <sys/ioctl.h>
-#include <sys/socket.h>
+#include <ifaddrs.h>
++#include <syscall.h>
+#include <net/if.h>
+#include "__netlink.h"
-typedef union {
- struct sockaddr_in6 v6;
-+/* getifaddrs() uses PF_PACKET to relay hardware addresses.
-+ * But Infiniband socket address length is longer, so use this hack
-+ * (like glibc) to return it anyway. */
++/* getifaddrs() reports hardware addresses with PF_PACKET that implies
++ * struct sockaddr_ll. But e.g. Infiniband socket address length is
++ * longer than sockaddr_ll.ssl_addr[8] can hold. Use this hack struct
++ * to extend ssl_addr - callers should be able to still use it. */
+struct sockaddr_ll_hack {
+ unsigned short sll_family, sll_protocol;
+ int sll_ifindex;
@@ -336,10 +264,21 @@ index 5a94cc7..5b1ebe7 100644
+ if (!ctx->first) ctx->first = add;
+ if (ctx->last) ctx->last->ifa.ifa_next = &add->ifa;
+ ctx->last = add;
++}
++
++static struct sockaddr* copy_lladdr(union sockany *sa, struct rtattr *rta, struct ifinfomsg *ifi)
++{
++ if (RTA_DATALEN(rta) > sizeof(sa->ll.sll_addr)) return 0;
++ sa->ll.sll_family = AF_PACKET;
++ sa->ll.sll_ifindex = ifi->ifi_index;
++ sa->ll.sll_hatype = ifi->ifi_type;
++ sa->ll.sll_halen = RTA_DATALEN(rta);
++ memcpy(sa->ll.sll_addr, RTA_DATA(rta), RTA_DATALEN(rta));
++ return &sa->sa;
}
-static void ipv6netmask(unsigned prefix_length, struct sockaddr_in6 *sa)
-+static struct sockaddr* copy_lladdr(union sockany *sa, struct rtattr *rta, struct ifinfomsg *ifi)
++static uint8_t *sockany_addr(int af, union sockany *sa, int *len)
{
- unsigned char* hb = sa->sin6_addr.s6_addr;
- unsigned onebytes = prefix_length / 8;
@@ -351,17 +290,6 @@ index 5a94cc7..5b1ebe7 100644
- unsigned char x = -1;
- x <<= 8 - bits;
- hb[onebytes] = x;
-+ if (RTA_DATALEN(rta) > sizeof(sa->ll.sll_addr)) return 0;
-+ sa->ll.sll_family = AF_PACKET;
-+ sa->ll.sll_ifindex = ifi->ifi_index;
-+ sa->ll.sll_hatype = ifi->ifi_type;
-+ sa->ll.sll_halen = RTA_DATALEN(rta);
-+ memcpy(sa->ll.sll_addr, RTA_DATA(rta), RTA_DATALEN(rta));
-+ return &sa->sa;
-+}
-+
-+static uint8_t *sockany_addr(int af, union sockany *sa, int *len)
-+{
+ switch (af) {
+ case AF_INET: *len = 4; return (uint8_t*) &sa->v4.sin_addr;
+ case AF_INET6: *len = 16; return (uint8_t*) &sa->v6.sin6_addr;
@@ -583,24 +511,25 @@ index 5a94cc7..5b1ebe7 100644
+int getifaddrs(struct ifaddrs **ifap)
+{
+ struct ifaddrs_ctx _ctx, *ctx = &_ctx;
-+ struct __netlink_handle *nh;
-+ int r = 0;
++ int r = 0, fd;
++
++ fd = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE);
++ if (fd < 0) return -1;
+
-+ nh = __netlink_open(NETLINK_ROUTE);
-+ if (!nh) return -1;
+ memset(ctx, 0, sizeof(*ctx));
-+ if (__netlink_enumerate(nh, RTM_GETLINK, __handle_link, ctx)) r = -1;
-+ if (__netlink_enumerate(nh, RTM_GETADDR, __handle_addr, ctx)) r = -1;
-+ __netlink_close(nh);
++ if (__netlink_enumerate(fd, 1, RTM_GETLINK, AF_UNSPEC, __handle_link, ctx)) r = -1;
++ if (__netlink_enumerate(fd, 1, RTM_GETADDR, AF_UNSPEC, __handle_addr, ctx)) r = -1;
++ __syscall(SYS_close,fd);
++
+ if (r == 0) *ifap = &ctx->first->ifa;
+ else freeifaddrs(&ctx->first->ifa);
+ return r;
+}
diff --git a/src/network/if_nameindex.c b/src/network/if_nameindex.c
-index 53b80b2..d4e8b2d 100644
+index 53b80b2..cb5587c 100644
--- a/src/network/if_nameindex.c
+++ b/src/network/if_nameindex.c
-@@ -1,55 +1,80 @@
+@@ -1,55 +1,82 @@
#define _GNU_SOURCE
#include <net/if.h>
-#include <stdlib.h>
@@ -611,6 +540,7 @@ index 53b80b2..d4e8b2d 100644
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
++#include <syscall.h>
+#include "__netlink.h"
+
+struct ifnamemap {
@@ -618,14 +548,14 @@ index 53b80b2..d4e8b2d 100644
+ unsigned char namelen;
+ char name[IFNAMSIZ];
+};
-
--static void *do_nameindex(int s, size_t n)
++
+struct ifnameindexctx {
+ unsigned int num;
+ unsigned int str_bytes;
+ struct ifnamemap *list;
+};
-+
+
+-static void *do_nameindex(int s, size_t n)
+static int __handle_link(void *pctx, struct nlmsghdr *h)
{
- size_t i, len, k;
@@ -649,6 +579,10 @@ index 53b80b2..d4e8b2d 100644
+ struct ifinfomsg *ifim = NLMSG_DATA(h);
+ struct rtattr *rta;
+ struct ifnamemap *e;
++
++ for (rta = NLMSG_RTA(h, sizeof(*ifim)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
++ if (rta->rta_type != IFLA_IFNAME) continue;
++ if (RTA_DATALEN(rta) > IFNAMSIZ) return -ENOBUFS;
- n = conf.ifc_len / sizeof(struct ifreq);
- for (i=k=0; i<n; i++) {
@@ -658,10 +592,6 @@ index 53b80b2..d4e8b2d 100644
- }
- idx[i-k].if_index = conf.ifc_req[i].ifr_ifindex;
- idx[i-k].if_name = conf.ifc_req[i].ifr_name;
-+ for (rta = NLMSG_RTA(h, sizeof(*ifim)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
-+ if (rta->rta_type != IFLA_IFNAME) continue;
-+ if (RTA_DATALEN(rta) > IFNAMSIZ) return -ENOBUFS;
-+
+ ctx->num++;
+ ctx->str_bytes += RTA_DATALEN(rta) + 1;
+ e = realloc(ctx->list, sizeof(struct ifnamemap[ctx->num]));
@@ -690,15 +620,16 @@ index 53b80b2..d4e8b2d 100644
- __syscall(SYS_close, s);
+ struct ifnameindexctx _ctx, *ctx = &_ctx;
+ struct if_nameindex *ifs = NULL;
-+ struct __netlink_handle *nh;
-+ int r, i;
++ int fd, r, i;
+ char *p;
+
-+ nh = __netlink_open(NETLINK_ROUTE);
-+ if (!nh) goto err;
++ fd = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE);
++ if (fd < 0) goto err;
++
+ memset(ctx, 0, sizeof(*ctx));
-+ r = __netlink_enumerate(nh, RTM_GETLINK, __handle_link, ctx);
-+ __netlink_close(nh);
++ r = __netlink_enumerate(fd, 1, RTM_GETLINK, AF_UNSPEC, __handle_link, ctx);
++ __syscall(SYS_close,fd);
++
+ if (r < 0) goto err;
+
+ ifs = malloc(sizeof(struct if_nameindex[ctx->num+1]) + ctx->str_bytes);
@@ -722,5 +653,5 @@ index 53b80b2..d4e8b2d 100644
+ return ifs;
}
--
-1.9.1
+1.9.2