diff --git a/.travis.yml b/.travis.yml index 2baaabaef..2c8a1c7cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ before_install: - echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- - sudo add-apt-repository ppa:ubuntu-lxc/daily -y - sudo apt-get update -qq - - sudo apt-get install -qq libapparmor-dev libcap-dev libseccomp-dev python3-dev python3-setuptools docbook2x libgnutls-dev libselinux1-dev + - sudo apt-get install -qq libapparmor-dev libcap-dev libseccomp-dev python3-dev python3-setuptools docbook2x libgnutls-dev libselinux1-dev linux-libc-dev script: - ./autogen.sh - rm -Rf build diff --git a/src/lxc/macro.h b/src/lxc/macro.h index 0a9698e49..83c40cef0 100644 --- a/src/lxc/macro.h +++ b/src/lxc/macro.h @@ -142,4 +142,49 @@ extern int __build_bug_on_failed; #define prctl_arg(x) ((unsigned long)x) +/* networking */ +#ifndef IFLA_LINKMODE +#define IFLA_LINKMODE 17 +#endif + +#ifndef IFLA_LINKINFO +#define IFLA_LINKINFO 18 +#endif + +#ifndef IFLA_NET_NS_PID +#define IFLA_NET_NS_PID 19 +#endif + +#ifndef IFLA_INFO_KIND +#define IFLA_INFO_KIND 1 +#endif + +#ifndef IFLA_VLAN_ID +#define IFLA_VLAN_ID 1 +#endif + +#ifndef IFLA_INFO_DATA +#define IFLA_INFO_DATA 2 +#endif + +#ifndef VETH_INFO_PEER +#define VETH_INFO_PEER 1 +#endif + +#ifndef IFLA_MACVLAN_MODE +#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 + +#ifndef RTM_NEWNSID +#define RTM_NEWNSID 88 +#endif + #endif /* __LXC_MACRO_H */ diff --git a/src/lxc/network.c b/src/lxc/network.c index d1e4e28bd..277133513 100644 --- a/src/lxc/network.c +++ b/src/lxc/network.c @@ -63,38 +63,6 @@ #include "include/strlcpy.h" #endif -#ifndef IFLA_LINKMODE -#define IFLA_LINKMODE 17 -#endif - -#ifndef IFLA_LINKINFO -#define IFLA_LINKINFO 18 -#endif - -#ifndef IFLA_NET_NS_PID -#define IFLA_NET_NS_PID 19 -#endif - -#ifndef IFLA_INFO_KIND -#define IFLA_INFO_KIND 1 -#endif - -#ifndef IFLA_VLAN_ID -#define IFLA_VLAN_ID 1 -#endif - -#ifndef IFLA_INFO_DATA -#define IFLA_INFO_DATA 2 -#endif - -#ifndef VETH_INFO_PEER -#define VETH_INFO_PEER 1 -#endif - -#ifndef IFLA_MACVLAN_MODE -#define IFLA_MACVLAN_MODE 1 -#endif - lxc_log_define(network, lxc); typedef int (*instantiate_cb)(struct lxc_handler *, struct lxc_netdev *); @@ -3195,3 +3163,73 @@ 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; +} + +/* 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) +{ + 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, LXC_NETNSA_FD, &fd, sizeof(__u32)); + addattr(l_hdr, 1024, LXC_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. */