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: 's avatarChristian Brauner <christian.brauner@ubuntu.com>
parent 12c3adb4
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <linux/net_namespace.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <linux/sockios.h> #include <linux/sockios.h>
...@@ -95,6 +96,14 @@ ...@@ -95,6 +96,14 @@
#define IFLA_MACVLAN_MODE 1 #define IFLA_MACVLAN_MODE 1
#endif #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); lxc_log_define(network, lxc);
typedef int (*instantiate_cb)(struct lxc_handler *, struct lxc_netdev *); typedef int (*instantiate_cb)(struct lxc_handler *, struct lxc_netdev *);
...@@ -3195,3 +3204,63 @@ void lxc_delete_network(struct lxc_handler *handler) ...@@ -3195,3 +3204,63 @@ void lxc_delete_network(struct lxc_handler *handler)
else else
DEBUG("Deleted network devices"); 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;
}
...@@ -272,5 +272,6 @@ extern int lxc_network_send_veth_names_to_child(struct lxc_handler *handler); ...@@ -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_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_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_network_recv_name_and_ifindex_from_child(struct lxc_handler *handler);
extern int lxc_netns_set_nsid(int netns_fd);
#endif /* __LXC_NETWORK_H */ #endif /* __LXC_NETWORK_H */
...@@ -1709,6 +1709,13 @@ static int lxc_spawn(struct lxc_handler *handler) ...@@ -1709,6 +1709,13 @@ static int lxc_spawn(struct lxc_handler *handler)
} else { } else {
handler->nsfd[LXC_NS_NET] = ret; handler->nsfd[LXC_NS_NET] = ret;
DEBUG("Preserved net namespace via fd %d", 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. */ /* Create the network configuration. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment