]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
netns: allocate network namespace id
authorChristian Brauner <christian.brauner@ubuntu.com>
Tue, 6 Feb 2018 19:16:40 +0000 (20:16 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Wed, 8 Aug 2018 11:11:05 +0000 (13:11 +0200)
Start to allocate a new network namespace id for each container.

Relates to https://github.com/lxc/lxd/issues/4831.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/network.c
src/lxc/network.h
src/lxc/start.c

index d1e4e28bda38b8f060fe007ba47569d94d406620..96d1da34bf1bebc873eec0a589c039c0c52a964f 100644 (file)
@@ -31,6 +31,7 @@
 #include <time.h>
 #include <unistd.h>
 #include <arpa/inet.h>
+#include <linux/net_namespace.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
 #include <linux/sockios.h>
 #define IFLA_MACVLAN_MODE 1
 #endif
 
+#ifndef IFLA_NEW_NETNSID
+#define IFLA_NEW_NETNSID 45
+#endif
+
+#ifndef IFLA_IF_NETNSID
+#define IFLA_IF_NETNSID 46
+#endif
+
 lxc_log_define(network, lxc);
 
 typedef int (*instantiate_cb)(struct lxc_handler *, struct lxc_netdev *);
@@ -3195,3 +3204,63 @@ void lxc_delete_network(struct lxc_handler *handler)
        else
                DEBUG("Deleted network devices");
 }
+
+int addattr(struct nlmsghdr *n, int maxlen, int type, const void *data, int alen)
+{
+       int len = RTA_LENGTH(alen);
+       struct rtattr *rta;
+
+       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;
+}
+
+int lxc_netns_set_nsid(int fd)
+{
+       ssize_t ret;
+       char l_buffer[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
+                     NLMSG_ALIGN(sizeof(struct rtgenmsg)) +
+                     NLMSG_ALIGN(1024)];
+       struct nl_handler nlh;
+       struct nlmsghdr *l_hdr;
+       struct rtgenmsg *l_msg;
+       struct sockaddr_nl l_addr;
+       int nsid = -1;
+
+       ret = netlink_open(&nlh, NETLINK_ROUTE);
+       if (ret < 0)
+               return ret;
+
+       memset(l_buffer, 0, sizeof(l_buffer));
+       l_hdr = (struct nlmsghdr *)l_buffer;
+       l_msg = (struct rtgenmsg *)NLMSG_DATA(l_hdr);
+
+       l_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*l_msg));
+       l_hdr->nlmsg_type = RTM_NEWNSID;
+       l_hdr->nlmsg_flags = NLM_F_REQUEST;
+       l_hdr->nlmsg_pid = 0;
+       l_hdr->nlmsg_seq = RTM_NEWNSID;
+       l_msg->rtgen_family = AF_UNSPEC;
+
+       addattr(l_hdr, 1024, NETNSA_FD, &fd, sizeof(__u32));
+       addattr(l_hdr, 1024, NETNSA_NSID, &nsid, sizeof(__u32));
+
+       memset(&l_addr, 0, sizeof(l_addr));
+       l_addr.nl_family = AF_NETLINK;
+
+       ret = sendto(nlh.fd, l_hdr, l_hdr->nlmsg_len, 0,
+                    (struct sockaddr *)&l_addr, sizeof(l_addr));
+       netlink_close(&nlh);
+       if (ret < 0)
+               return -1;
+
+       return 0;
+}
index 415d13502bd5b6593d61365624ac759e4b357af9..50e6b2c567cee49c5340cf6f1976511337ef73d1 100644 (file)
@@ -272,5 +272,6 @@ extern int lxc_network_send_veth_names_to_child(struct lxc_handler *handler);
 extern int lxc_network_recv_veth_names_from_parent(struct lxc_handler *handler);
 extern int lxc_network_send_name_and_ifindex_to_parent(struct lxc_handler *handler);
 extern int lxc_network_recv_name_and_ifindex_from_child(struct lxc_handler *handler);
+extern int lxc_netns_set_nsid(int netns_fd);
 
 #endif /* __LXC_NETWORK_H */
index 3616527eb04f09286f1b277604aa66054a01f3e3..2485472e257de670e64a0ac08c59d70766adbc4a 100644 (file)
@@ -1818,6 +1818,13 @@ static int lxc_spawn(struct lxc_handler *handler)
        } else {
                handler->nsfd[LXC_NS_NET] = ret;
                DEBUG("Preserved net namespace via fd %d", ret);
+
+               ret = lxc_netns_set_nsid(handler->nsfd[LXC_NS_NET]);
+               if (ret < 0) {
+                       ERROR("Failed to allocate new network namespace id: %d", ret);
+                       goto out_delete_net;
+               }
+               TRACE("Allocated new network namespace id");
        }
 
        /* Create the network configuration. */