network: add lxc_netns_get_nsid()

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
Christian Brauner 2018-09-11 14:02:23 +02:00
parent 41a3300dbb
commit 938980bac3
No known key found for this signature in database
GPG Key ID: 8EB056D53EECB12D
3 changed files with 83 additions and 0 deletions

View File

@ -27,6 +27,7 @@
#include <linux/loop.h> #include <linux/loop.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <linux/types.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <sys/mount.h> #include <sys/mount.h>
@ -279,6 +280,10 @@ extern int __build_bug_on_failed;
#define RTM_NEWNSID 88 #define RTM_NEWNSID 88
#endif #endif
#ifndef RTM_GETNSID
#define RTM_GETNSID 90
#endif
#ifndef NLMSG_ERROR #ifndef NLMSG_ERROR
#define NLMSG_ERROR 0x2 #define NLMSG_ERROR 0x2
#endif #endif

View File

@ -3234,3 +3234,79 @@ int lxc_netns_set_nsid(int fd)
return 0; 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;
}

View File

@ -27,6 +27,7 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <linux/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include "list.h" #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_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); extern int lxc_netns_set_nsid(int netns_fd);
extern int lxc_netns_get_nsid(__s32 fd);
#endif /* __LXC_NETWORK_H */ #endif /* __LXC_NETWORK_H */