]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
network: add netns_getifaddrs() implementation
authorChristian Brauner <christian.brauner@ubuntu.com>
Sun, 23 Sep 2018 13:29:22 +0000 (15:29 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Sun, 23 Sep 2018 19:19:35 +0000 (21:19 +0200)
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 <christian.brauner@ubuntu.com>
src/include/ifaddrs.h [deleted file]
src/include/netns_ifaddrs.c [moved from src/include/ifaddrs.c with 57% similarity]
src/include/netns_ifaddrs.h [new file with mode: 0644]
src/lxc/Makefile.am
src/lxc/macro.h
src/lxc/network.c
src/lxc/nl.c
src/lxc/nl.h

diff --git a/src/include/ifaddrs.h b/src/include/ifaddrs.h
deleted file mode 100644 (file)
index 4f1352d..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef _IFADDRS_H
-#define _IFADDRS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <features.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-
-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
similarity index 57%
rename from src/include/ifaddrs.c
rename to src/include/netns_ifaddrs.c
index ee52bf397c4ede02c8b2c19b8acbffb75865832d..3fbb10520fd0d71f90427b3cbc2515761104718b 100644 (file)
@@ -1,15 +1,30 @@
 #define _GNU_SOURCE
+#include <arpa/inet.h>
 #include <errno.h>
+#include <linux/if.h>
+#include <linux/if_addr.h>
+#include <linux/if_link.h>
+#include <linux/if_packet.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
-#include <net/if.h>
+#include <linux/types.h>
+#include <net/ethernet.h>
 #include <netinet/in.h>
+#include <stdbool.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/socket.h>
 #include <unistd.h>
 
-#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
 
 
 #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 (file)
index 0000000..ee9236e
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef _LXC_NETNS_IFADDRS_H
+#define _LXC_NETNS_IFADDRS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <linux/types.h>
+#include <netinet/in.h>
+#include <stdbool.h>
+#include <sys/socket.h>
+
+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 */
index 51c871eb6ed6b78c7513f4b5922099bd14c1ed6f..690486d34dbd7836e9d1d3506c68ae373e735554 100644 (file)
@@ -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
index 52acfee807a221b1cbfba6c558cd10b97ce3eeb6..c9b46bd2131569b5b74e70fc6c54d1a070a8daca 100644 (file)
@@ -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)
 
index 789d2a92968b068f0a6e3192ee5c1f381ead8927..8bfe6a1a2f4c223acd572fe2a1b008f02bf8fc7f 100644 (file)
@@ -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;
index bf2452f0e3218709ee3a8c759ec2fb3b6240ac0f..06a72fb88b3969bb03a30d4ca34f008a1e9bda43 100644 (file)
@@ -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;
+}
index a00fc16df3626d27e105ed2373f4aeaf2eb698e2..2afda5f0f0761eed658cb6dc576c0703e0cb9c9f 100644 (file)
@@ -23,6 +23,8 @@
 #ifndef __LXC_NL_H
 #define __LXC_NL_H
 
+#include <stdio.h>
+
 /*
  * 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