From: Christian Brauner Date: Tue, 6 Feb 2018 19:16:40 +0000 (+0100) Subject: netns: allocate network namespace id X-Git-Tag: lxc-3.1.0~172^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1cd952141702a33b1083ab0dadb1ea383882add5;p=thirdparty%2Flxc.git netns: allocate network namespace id 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 --- diff --git a/src/lxc/network.c b/src/lxc/network.c index d1e4e28bd..96d1da34b 100644 --- a/src/lxc/network.c +++ b/src/lxc/network.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -95,6 +96,14 @@ #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; +} diff --git a/src/lxc/network.h b/src/lxc/network.h index 415d13502..50e6b2c56 100644 --- a/src/lxc/network.h +++ b/src/lxc/network.h @@ -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 */ diff --git a/src/lxc/start.c b/src/lxc/start.c index 3616527eb..2485472e2 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -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. */