From cc6119a0334a0debf43c4d2dffc9f549a67e315d Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Sun, 23 Sep 2018 15:29:22 +0200 Subject: [PATCH] network: add netns_getifaddrs() implementation This commit introduces my concept of a network namespace aware getifaddrs(), i.e. netns_getifaddrs(). This presupposes a kernel that carries my IF{L}A_TARGET_NETNSID patches: struct netns_ifaddrs { struct netns_ifaddrs *ifa_next; /* Can - but shouldn't be - NULL. */ char *ifa_name; /* This field is not present struct ifaddrs. */ int ifa_ifindex; unsigned ifa_flags; /* This field is not present struct ifaddrs. */ int ifa_mtu; /* This field is not present struct ifaddrs. */ int ifa_prefixlen; struct sockaddr *ifa_addr; struct sockaddr *ifa_netmask; union { struct sockaddr *ifu_broadaddr; struct sockaddr *ifu_dstaddr; } ifa_ifu; /* If you don't know what this is for don't touch it. */ void *ifa_data; }; which is a superset of struct ifaddrs. It contains additional information such as the mtu, ifindex of the interface and the prefix length of the address. Note that the field ordering is different. So don't get any ideas of using memcpy() to copy from an old struct ifaddrs into a struct netns_ifaddrs. int netns_getifaddrs(struct netns_ifaddrs **ifap, __s32 netns_id, bool *netnsid_aware) takes a network namespace identifier as argument which identifies the target network namespace. If successfull, i.e. netns_getifaddrs() returns 0, callers should check the bool *netnsid_aware return argument. If it is true then RTM_GET{ADDR,LINK} requests are fully netnsid aware. If it is false then they are not and the information returned in struct netns_ifaddrs does *not* contain correct information about the target network namespace identified by netnsid. Signed-off-by: Christian Brauner --- src/include/ifaddrs.h | 34 --- src/include/{ifaddrs.c => netns_ifaddrs.c} | 261 ++++++++++++++++----- src/include/netns_ifaddrs.h | 53 +++++ src/lxc/Makefile.am | 10 +- src/lxc/macro.h | 22 +- src/lxc/network.c | 29 --- src/lxc/nl.c | 19 ++ src/lxc/nl.h | 4 + 8 files changed, 301 insertions(+), 131 deletions(-) delete mode 100644 src/include/ifaddrs.h rename src/include/{ifaddrs.c => netns_ifaddrs.c} (57%) create mode 100644 src/include/netns_ifaddrs.h diff --git a/src/include/ifaddrs.h b/src/include/ifaddrs.h deleted file mode 100644 index 4f1352d05..000000000 --- a/src/include/ifaddrs.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef _IFADDRS_H -#define _IFADDRS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include - -struct ifaddrs { - struct ifaddrs *ifa_next; - char *ifa_name; - unsigned ifa_flags; - struct sockaddr *ifa_addr; - struct sockaddr *ifa_netmask; - union { - struct sockaddr *ifu_broadaddr; - struct sockaddr *ifu_dstaddr; - } ifa_ifu; - void *ifa_data; -}; -#define ifa_broadaddr ifa_ifu.ifu_broadaddr -#define ifa_dstaddr ifa_ifu.ifu_dstaddr - -void freeifaddrs(struct ifaddrs *); -int getifaddrs(struct ifaddrs **); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/include/ifaddrs.c b/src/include/netns_ifaddrs.c similarity index 57% rename from src/include/ifaddrs.c rename to src/include/netns_ifaddrs.c index ee52bf397..3fbb10520 100644 --- a/src/include/ifaddrs.c +++ b/src/include/netns_ifaddrs.c @@ -1,15 +1,30 @@ #define _GNU_SOURCE +#include #include +#include +#include +#include +#include #include #include -#include +#include +#include #include +#include +#include #include #include #include #include -#include "ifaddrs.h" +#include "nl.h" +#include "macro.h" +#include "netns_ifaddrs.h" + +#ifndef NETNS_RTA +#define NETNS_RTA(r) \ + ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct rtgenmsg)))) +#endif #define IFADDRS_HASH_SIZE 64 @@ -47,10 +62,11 @@ #define __RTA_DATA(rta) ((void *)((char *)(rta) + sizeof(struct rtattr))) -/* 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. */ +/* 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; @@ -67,7 +83,7 @@ union sockany { }; struct ifaddrs_storage { - struct ifaddrs ifa; + struct netns_ifaddrs ifa; struct ifaddrs_storage *hash_next; union sockany addr, netmask, ifu; unsigned int index; @@ -80,17 +96,6 @@ struct ifaddrs_ctx { struct ifaddrs_storage *hash[IFADDRS_HASH_SIZE]; }; -void freeifaddrs(struct ifaddrs *ifp) -{ - struct ifaddrs *n; - - while (ifp) { - n = ifp->ifa_next; - free(ifp); - ifp = n; - } -} - static void copy_addr(struct sockaddr **r, int af, union sockany *sa, void *addr, size_t addrlen, int ifindex) { @@ -105,7 +110,8 @@ static void copy_addr(struct sockaddr **r, int af, union sockany *sa, case AF_INET6: dst = (uint8_t *)&sa->v6.sin6_addr; len = 16; - if (__IN6_IS_ADDR_LINKLOCAL(addr) || __IN6_IS_ADDR_MC_LINKLOCAL(addr)) + if (__IN6_IS_ADDR_LINKLOCAL(addr) || + __IN6_IS_ADDR_MC_LINKLOCAL(addr)) sa->v6.sin6_scope_id = ifindex; break; default: @@ -157,7 +163,7 @@ static void copy_lladdr(struct sockaddr **r, union sockany *sa, void *addr, *r = &sa->sa; } -static int nl_msg_to_ifaddr(void *pctx, struct nlmsghdr *h) +static int nl_msg_to_ifaddr(void *pctx, bool *netnsid_aware, struct nlmsghdr *h) { struct ifaddrs_storage *ifs, *ifs0; struct rtattr *rta; @@ -169,7 +175,6 @@ static int nl_msg_to_ifaddr(void *pctx, struct nlmsghdr *h) if (h->nlmsg_type == RTM_NEWLINK) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" - for (rta = __NLMSG_RTA(h, sizeof(*ifi)); __NLMSG_RTAOK(rta, h); rta = __RTA_NEXT(rta)) { if (rta->rta_type != IFLA_STATS) @@ -178,7 +183,6 @@ static int nl_msg_to_ifaddr(void *pctx, struct nlmsghdr *h) stats_len = __RTA_DATALEN(rta); break; } - #pragma GCC diagnostic pop } else { for (ifs0 = ctx->hash[ifa->ifa_index % IFADDRS_HASH_SIZE]; ifs0; @@ -197,9 +201,9 @@ static int nl_msg_to_ifaddr(void *pctx, struct nlmsghdr *h) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" - if (h->nlmsg_type == RTM_NEWLINK) { ifs->index = ifi->ifi_index; + ifs->ifa.ifa_ifindex = ifi->ifi_index; ifs->ifa.ifa_flags = ifi->ifi_flags; for (rta = __NLMSG_RTA(h, sizeof(*ifi)); __NLMSG_RTAOK(rta, h); @@ -218,7 +222,7 @@ static int nl_msg_to_ifaddr(void *pctx, struct nlmsghdr *h) ifi->ifi_index, ifi->ifi_type); break; case IFLA_BROADCAST: - copy_lladdr(&ifs->ifa.ifa_broadaddr, &ifs->ifu, + copy_lladdr(&ifs->ifa.__ifa_broadaddr, &ifs->ifu, __RTA_DATA(rta), __RTA_DATALEN(rta), ifi->ifi_index, ifi->ifi_type); break; @@ -227,6 +231,13 @@ static int nl_msg_to_ifaddr(void *pctx, struct nlmsghdr *h) memcpy(ifs->ifa.ifa_data, __RTA_DATA(rta), __RTA_DATALEN(rta)); break; + case IFLA_MTU: + memcpy(&ifs->ifa.ifa_mtu, __RTA_DATA(rta), + sizeof(int)); + break; + case IFLA_TARGET_NETNSID: + *netnsid_aware = true; + break; } } @@ -237,6 +248,8 @@ static int nl_msg_to_ifaddr(void *pctx, struct nlmsghdr *h) } } else { ifs->ifa.ifa_name = ifs0->ifa.ifa_name; + ifs->ifa.ifa_mtu = ifs0->ifa.ifa_mtu; + ifs->ifa.ifa_ifindex = ifs0->ifa.ifa_ifindex; ifs->ifa.ifa_flags = ifs0->ifa.ifa_flags; for (rta = __NLMSG_RTA(h, sizeof(*ifa)); __NLMSG_RTAOK(rta, h); @@ -244,11 +257,11 @@ static int nl_msg_to_ifaddr(void *pctx, struct nlmsghdr *h) switch (rta->rta_type) { case IFA_ADDRESS: /* If ifa_addr is already set we, received an - * IFA_LOCAL before so treat this as destination - * address. + * IFA_LOCAL before so treat this as + * destination address. */ if (ifs->ifa.ifa_addr) - copy_addr(&ifs->ifa.ifa_dstaddr, + copy_addr(&ifs->ifa.__ifa_dstaddr, ifa->ifa_family, &ifs->ifu, __RTA_DATA(rta), __RTA_DATALEN(rta), @@ -261,19 +274,19 @@ static int nl_msg_to_ifaddr(void *pctx, struct nlmsghdr *h) ifa->ifa_index); break; case IFA_BROADCAST: - copy_addr(&ifs->ifa.ifa_broadaddr, + 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. + * 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; + ifs->ifa.__ifa_dstaddr = &ifs->ifu.sa; memset(&ifs->addr, 0, sizeof(ifs->addr)); } @@ -289,14 +302,18 @@ static int nl_msg_to_ifaddr(void *pctx, struct nlmsghdr *h) ifs->ifa.ifa_name = ifs->name; } break; + case IFA_TARGET_NETNSID: + *netnsid_aware = true; + break; } } - if (ifs->ifa.ifa_addr) + if (ifs->ifa.ifa_addr) { gen_netmask(&ifs->ifa.ifa_netmask, ifa->ifa_family, &ifs->netmask, ifa->ifa_prefixlen); + ifs->ifa.ifa_prefixlen = ifa->ifa_prefixlen; + } } - #pragma GCC diagnostic pop if (ifs->ifa.ifa_name) { @@ -314,11 +331,49 @@ static int nl_msg_to_ifaddr(void *pctx, struct nlmsghdr *h) return 0; } -static int __nl_recv(int fd, unsigned int seq, int type, int af, - int (*cb)(void *ctx, struct nlmsghdr *h), - void *ctx) +static int __ifaddrs_netlink_send(int fd, struct nlmsghdr *nlmsghdr) +{ + int ret; + struct sockaddr_nl nladdr; + struct iovec iov = { + .iov_base = nlmsghdr, + .iov_len = nlmsghdr->nlmsg_len, + }; + struct msghdr msg = { + .msg_name = &nladdr, + .msg_namelen = sizeof(nladdr), + .msg_iov = &iov, + .msg_iovlen = 1, + }; + + memset(&nladdr, 0, sizeof(nladdr)); + nladdr.nl_family = AF_NETLINK; + nladdr.nl_pid = 0; + nladdr.nl_groups = 0; + + ret = sendmsg(fd, &msg, MSG_NOSIGNAL); + if (ret < 0) + return -1; + + return ret; +} + +static int __ifaddrs_netlink_recv(int fd, unsigned int seq, int type, int af, + __s32 netns_id, bool *netnsid_aware, + int (*cb)(void *ctx, bool *netnsid_aware, + struct nlmsghdr *h), + void *ctx) { - struct nlmsghdr *h; + char getlink_buf[__NETLINK_ALIGN(sizeof(struct nlmsghdr)) + + __NETLINK_ALIGN(sizeof(struct ifinfomsg)) + + __NETLINK_ALIGN(1024)]; + char getaddr_buf[__NETLINK_ALIGN(sizeof(struct nlmsghdr)) + + __NETLINK_ALIGN(sizeof(struct ifaddrmsg)) + + __NETLINK_ALIGN(1024)]; + char *buf; + struct nlmsghdr *hdr; + struct ifinfomsg *ifi_msg; + struct ifaddrmsg *ifa_msg; union { uint8_t buf[8192]; struct { @@ -327,17 +382,50 @@ static int __nl_recv(int fd, unsigned int seq, int type, int af, } req; struct nlmsghdr reply; } u; - int r, ret; - - 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_DUMP | NLM_F_REQUEST; - u.req.nlh.nlmsg_seq = seq; - u.req.g.rtgen_family = af; - r = send(fd, &u.req, sizeof(u.req), 0); + int r, property, ret; + + if (type == RTM_GETLINK) + buf = getlink_buf; + else if (type == RTM_GETADDR) + buf = getaddr_buf; + else + return -1; + + memset(buf, 0, sizeof(*buf)); + hdr = (struct nlmsghdr *)buf; + if (type == RTM_GETLINK) + ifi_msg = (struct ifinfomsg *)__NLMSG_DATA(hdr); + else + ifa_msg = (struct ifaddrmsg *)__NLMSG_DATA(hdr); + + if (type == RTM_GETLINK) + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*ifi_msg)); + else + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*ifa_msg)); + + hdr->nlmsg_type = type; + hdr->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; + hdr->nlmsg_pid = 0; + hdr->nlmsg_seq = seq; + if (type == RTM_GETLINK) + ifi_msg->ifi_family = af; + else + ifa_msg->ifa_family = af; + + errno = EINVAL; + if (type == RTM_GETLINK) + property = IFLA_TARGET_NETNSID; + else if (type == RTM_GETADDR) + property = IFA_TARGET_NETNSID; + else + return -1; + + if (netns_id >= 0) + addattr(hdr, 1024, property, &netns_id, sizeof(netns_id)); + + r = __ifaddrs_netlink_send(fd, hdr); if (r < 0) - return r; + return -1; for (;;) { r = recv(fd, u.buf, sizeof(u.buf), MSG_DONTWAIT); @@ -346,17 +434,17 @@ static int __nl_recv(int fd, unsigned int seq, int type, int af, #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" - for (h = &u.reply; __NLMSG_OK(h, (void *)&u.buf[r]); - h = __NLMSG_NEXT(h)) { - if (h->nlmsg_type == NLMSG_DONE) + for (hdr = &u.reply; __NLMSG_OK(hdr, (void *)&u.buf[r]); + hdr = __NLMSG_NEXT(hdr)) { + if (hdr->nlmsg_type == NLMSG_DONE) return 0; - if (h->nlmsg_type == NLMSG_ERROR) { + if (hdr->nlmsg_type == NLMSG_ERROR) { errno = EINVAL; return -1; } - ret = cb(ctx, h); + ret = cb(ctx, netnsid_aware, hdr); if (ret) return ret; } @@ -364,27 +452,81 @@ static int __nl_recv(int fd, unsigned int seq, int type, int af, } } -static int __rtnl_enumerate(int link_af, int addr_af, - int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx) +static int __rtnl_enumerate(int link_af, int addr_af, __s32 netns_id, + bool *netnsid_aware, + int (*cb)(void *ctx, bool *netnsid_aware, struct nlmsghdr *h), + void *ctx) { int fd, r, saved_errno; + bool getaddr_netnsid_aware = false, getlink_netnsid_aware = false; fd = socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE); if (fd < 0) return -1; - r = __nl_recv(fd, 1, RTM_GETLINK, link_af, cb, ctx); + r = __ifaddrs_netlink_recv(fd, 1, RTM_GETLINK, link_af, netns_id, + &getlink_netnsid_aware, cb, ctx); if (!r) - r = __nl_recv(fd, 2, RTM_GETADDR, addr_af, cb, ctx); + r = __ifaddrs_netlink_recv(fd, 2, RTM_GETADDR, addr_af, netns_id, + &getaddr_netnsid_aware, cb, ctx); saved_errno = errno; close(fd); errno = saved_errno; + if (getaddr_netnsid_aware && getlink_netnsid_aware) + *netnsid_aware = true; + else + *netnsid_aware = false; + return r; } -int getifaddrs(struct ifaddrs **ifap) +/* Get a pointer to the address structure from a sockaddr. */ +static void *get_addr_ptr(struct sockaddr *sockaddr_ptr) +{ + if (sockaddr_ptr->sa_family == AF_INET) + return &((struct sockaddr_in *)sockaddr_ptr)->sin_addr; + + if (sockaddr_ptr->sa_family == AF_INET6) + return &((struct sockaddr_in6 *)sockaddr_ptr)->sin6_addr; + + return NULL; +} + +static char *get_packet_address(struct sockaddr *sockaddr_ptr, char *buf, size_t buflen) +{ + char *slider = buf; + unsigned char *m = ((struct sockaddr_ll *)sockaddr_ptr)->sll_addr; + unsigned char n = ((struct sockaddr_ll *)sockaddr_ptr)->sll_halen; + + for (unsigned char i = 0; i < n; i++) { + int ret; + + ret = snprintf(slider, buflen, "%02x%s", m[i], (i + 1) < n ? ":" : ""); + if (ret < 0 || (size_t)ret >= buflen) + return NULL; + + buflen -= ret; + slider = (slider + ret); + } + + return buf; +} + +void netns_freeifaddrs(struct netns_ifaddrs *ifp) +{ + struct netns_ifaddrs *n; + + while (ifp) { + n = ifp->ifa_next; + free(ifp); + ifp = n; + } +} + +int netns_getifaddrs(struct netns_ifaddrs **ifap, __s32 netns_id, + bool *netnsid_aware) { int r, saved_errno; struct ifaddrs_ctx _ctx; @@ -392,10 +534,11 @@ int getifaddrs(struct ifaddrs **ifap) memset(ctx, 0, sizeof *ctx); - r = __rtnl_enumerate(AF_UNSPEC, AF_UNSPEC, nl_msg_to_ifaddr, ctx); + r = __rtnl_enumerate(AF_UNSPEC, AF_UNSPEC, netns_id, netnsid_aware, + nl_msg_to_ifaddr, ctx); saved_errno = errno; if (r < 0) - freeifaddrs(&ctx->first->ifa); + netns_freeifaddrs(&ctx->first->ifa); else *ifap = &ctx->first->ifa; errno = saved_errno; diff --git a/src/include/netns_ifaddrs.h b/src/include/netns_ifaddrs.h new file mode 100644 index 000000000..ee9236ed9 --- /dev/null +++ b/src/include/netns_ifaddrs.h @@ -0,0 +1,53 @@ +#ifndef _LXC_NETNS_IFADDRS_H +#define _LXC_NETNS_IFADDRS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + +struct netns_ifaddrs { + struct netns_ifaddrs *ifa_next; + + /* Can - but shouldn't be - NULL. */ + char *ifa_name; + + /* This field is not present struct ifaddrs. */ + int ifa_ifindex; + + unsigned ifa_flags; + + /* This field is not present struct ifaddrs. */ + int ifa_mtu; + + /* This field is not present struct ifaddrs. */ + int ifa_prefixlen; + + struct sockaddr *ifa_addr; + struct sockaddr *ifa_netmask; + union { + struct sockaddr *ifu_broadaddr; + struct sockaddr *ifu_dstaddr; + } ifa_ifu; + + /* If you don't know what this is for don't touch it. */ + void *ifa_data; +}; + +#define __ifa_broadaddr ifa_ifu.ifu_broadaddr +#define __ifa_dstaddr ifa_ifu.ifu_dstaddr + +extern void netns_freeifaddrs(struct netns_ifaddrs *); +extern int netns_getifaddrs(struct netns_ifaddrs **ifap, __s32 netns_id, + bool *netnsid_aware); + +#ifdef __cplusplus +} +#endif + +#endif /* _LXC_NETNS_IFADDRS_H */ diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am index 51c871eb6..690486d34 100644 --- a/src/lxc/Makefile.am +++ b/src/lxc/Makefile.am @@ -14,6 +14,7 @@ noinst_HEADERS = api_extensions.h \ criu.h \ error.h \ file_utils.h \ + ../include/netns_ifaddrs.h \ initutils.h \ list.h \ log.h \ @@ -41,10 +42,6 @@ noinst_HEADERS = api_extensions.h \ tools/arguments.h \ utils.h -if !HAVE_IFADDRS_H -noinst_HEADERS += ../include/ifaddrs.h -endif - if IS_BIONIC noinst_HEADERS += ../include/lxcmntent.h \ ../include/openpty.h @@ -103,6 +100,7 @@ liblxc_la_SOURCES = af_unix.c af_unix.h \ execute.c \ freezer.c \ file_utils.c file_utils.h \ + ../include/netns_ifaddrs.c ../include/netns_ifaddrs.h \ initutils.c initutils.h \ list.h \ log.c log.h \ @@ -139,10 +137,6 @@ liblxc_la_SOURCES = af_unix.c af_unix.h \ version.h \ $(LSM_SOURCES) -if !HAVE_IFADDRS_H -liblxc_la_SOURCES += ../include/ifaddrs.c ../include/ifaddrs.h -endif - if IS_BIONIC liblxc_la_SOURCES += ../include/lxcmntent.c ../include/lxcmntent.h \ ../include/openpty.c ../include/openpty.h diff --git a/src/lxc/macro.h b/src/lxc/macro.h index 52acfee80..c9b46bd21 100644 --- a/src/lxc/macro.h +++ b/src/lxc/macro.h @@ -272,10 +272,20 @@ extern int __build_bug_on_failed; #define IFLA_NEW_NETNSID 45 #endif -#ifndef IFLA_IF_NETNSID +#ifdef IFLA_IF_NETNSID +#ifndef IFLA_TARGET_NETNSID +#define IFLA_TARGET_NETNSID = IFLA_IF_NETNSID +#endif +#else #define IFLA_IF_NETNSID 46 +#define IFLA_TARGET_NETNSID 46 +#endif + +#ifndef IFA_TARGET_NETNSID +#define IFA_TARGET_NETNSID 10 #endif + #ifndef RTM_NEWNSID #define RTM_NEWNSID 88 #endif @@ -304,6 +314,16 @@ extern int __build_bug_on_failed; #define MACVLAN_MODE_PASSTHRU 8 #endif +/* Attributes of RTM_NEWNSID/RTM_GETNSID messages */ +enum { + __LXC_NETNSA_NONE, +#define __LXC_NETNSA_NSID_NOT_ASSIGNED -1 + __LXC_NETNSA_NSID, + __LXC_NETNSA_PID, + __LXC_NETNSA_FD, + __LXC_NETNSA_MAX, +}; + /* Length of abstract unix domain socket socket address. */ #define LXC_AUDS_ADDR_LEN sizeof(((struct sockaddr_un *)0)->sun_path) diff --git a/src/lxc/network.c b/src/lxc/network.c index 789d2a929..8bfe6a1a2 100644 --- a/src/lxc/network.c +++ b/src/lxc/network.c @@ -3181,35 +3181,6 @@ void lxc_delete_network(struct lxc_handler *handler) DEBUG("Deleted network devices"); } -int addattr(struct nlmsghdr *n, size_t maxlen, int type, const void *data, size_t alen) -{ - int len = RTA_LENGTH(alen); - struct rtattr *rta; - - errno = EMSGSIZE; - if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) - return -1; - - rta = NLMSG_TAIL(n); - rta->rta_type = type; - rta->rta_len = len; - if (alen) - memcpy(RTA_DATA(rta), data, alen); - n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len); - - return 0; -} - -/* Attributes of RTM_NEWNSID/RTM_GETNSID messages */ -enum { - __LXC_NETNSA_NONE, -#define __LXC_NETNSA_NSID_NOT_ASSIGNED -1 - __LXC_NETNSA_NSID, - __LXC_NETNSA_PID, - __LXC_NETNSA_FD, - __LXC_NETNSA_MAX, -}; - int lxc_netns_set_nsid(int fd) { int ret; diff --git a/src/lxc/nl.c b/src/lxc/nl.c index bf2452f0e..06a72fb88 100644 --- a/src/lxc/nl.c +++ b/src/lxc/nl.c @@ -345,3 +345,22 @@ extern int netlink_close(struct nl_handler *handler) return 0; } +int addattr(struct nlmsghdr *n, size_t maxlen, int type, const void *data, + size_t alen) +{ + int len = RTA_LENGTH(alen); + struct rtattr *rta; + + errno = EMSGSIZE; + if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) + return -1; + + rta = NLMSG_TAIL(n); + rta->rta_type = type; + rta->rta_len = len; + if (alen) + memcpy(RTA_DATA(rta), data, alen); + n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len); + + return 0; +} diff --git a/src/lxc/nl.h b/src/lxc/nl.h index a00fc16df..2afda5f0f 100644 --- a/src/lxc/nl.h +++ b/src/lxc/nl.h @@ -23,6 +23,8 @@ #ifndef __LXC_NL_H #define __LXC_NL_H +#include + /* * Use this as a good size to allocate generic netlink messages */ @@ -259,5 +261,7 @@ void nlmsg_free(struct nlmsg *nlmsg); */ void *nlmsg_data(struct nlmsg *nlmsg); +extern int addattr(struct nlmsghdr *n, size_t maxlen, int type, + const void *data, size_t alen); #endif -- 2.47.2