From: Christian Brauner Date: Tue, 11 Sep 2018 12:02:23 +0000 (+0200) Subject: network: add lxc_netns_get_nsid() X-Git-Tag: lxc-3.1.0~104^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=938980bac36ecff940df7374f73c7815234c9e1b;p=thirdparty%2Flxc.git network: add lxc_netns_get_nsid() Signed-off-by: Christian Brauner --- diff --git a/src/lxc/macro.h b/src/lxc/macro.h index c0a50371d..3ff40648a 100644 --- a/src/lxc/macro.h +++ b/src/lxc/macro.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -279,6 +280,10 @@ extern int __build_bug_on_failed; #define RTM_NEWNSID 88 #endif +#ifndef RTM_GETNSID +#define RTM_GETNSID 90 +#endif + #ifndef NLMSG_ERROR #define NLMSG_ERROR 0x2 #endif diff --git a/src/lxc/network.c b/src/lxc/network.c index 9fcd3b07c..8a7613f4d 100644 --- a/src/lxc/network.c +++ b/src/lxc/network.c @@ -3234,3 +3234,79 @@ int lxc_netns_set_nsid(int fd) return 0; } + +static int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) +{ + + memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); + + while (RTA_OK(rta, len)) { + unsigned short type = rta->rta_type; + + if ((type <= max) && (!tb[type])) + tb[type] = rta; + + rta = RTA_NEXT(rta, len); + } + + return 0; +} + +static inline __s32 rta_getattr_s32(const struct rtattr *rta) +{ + return *(__s32 *)RTA_DATA(rta); +} + +#ifndef NETNS_RTA +#define NETNS_RTA(r) \ + ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct rtgenmsg)))) +#endif + +int lxc_netns_get_nsid(int fd) +{ + int ret; + ssize_t len; + char buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + + NLMSG_ALIGN(sizeof(struct rtgenmsg)) + NLMSG_ALIGN(1024)]; + struct rtattr *tb[__LXC_NETNSA_MAX + 1]; + struct nl_handler nlh; + struct nlmsghdr *hdr; + struct rtgenmsg *msg; + int saved_errno; + __u32 netns_fd = fd; + + ret = netlink_open(&nlh, NETLINK_ROUTE); + if (ret < 0) + return -1; + + memset(buf, 0, sizeof(buf)); + hdr = (struct nlmsghdr *)buf; + msg = (struct rtgenmsg *)NLMSG_DATA(hdr); + + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*msg)); + hdr->nlmsg_type = RTM_GETNSID; + hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + hdr->nlmsg_pid = 0; + hdr->nlmsg_seq = RTM_GETNSID; + msg->rtgen_family = AF_UNSPEC; + + addattr(hdr, 1024, __LXC_NETNSA_FD, &netns_fd, sizeof(netns_fd)); + + ret = __netlink_transaction(&nlh, hdr, hdr); + saved_errno = errno; + netlink_close(&nlh); + errno = saved_errno; + if (ret < 0) + return -1; + + msg = NLMSG_DATA(hdr); + len = hdr->nlmsg_len - NLMSG_SPACE(sizeof(*msg)); + if (len < 0) + return -1; + + parse_rtattr(tb, __LXC_NETNSA_MAX, NETNS_RTA(msg), len); + if (tb[__LXC_NETNSA_NSID]) + return rta_getattr_s32(tb[__LXC_NETNSA_NSID]); + + return -1; +} diff --git a/src/lxc/network.h b/src/lxc/network.h index 50e6b2c56..38f7c8d5f 100644 --- a/src/lxc/network.h +++ b/src/lxc/network.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "list.h" @@ -273,5 +274,6 @@ 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); +extern int lxc_netns_get_nsid(__s32 fd); #endif /* __LXC_NETWORK_H */