]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
network: add lxc_netns_get_nsid()
authorChristian Brauner <christian.brauner@ubuntu.com>
Tue, 11 Sep 2018 12:02:23 +0000 (14:02 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Wed, 12 Sep 2018 02:38:49 +0000 (04:38 +0200)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/macro.h
src/lxc/network.c
src/lxc/network.h

index c0a50371d728005ea644feaa56ca54d4f645e624..3ff40648ac3d805014468f9ee55d963348b054a4 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/loop.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
+#include <linux/types.h>
 #include <stdint.h>
 #include <string.h>
 #include <sys/mount.h>
@@ -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
index 9fcd3b07cd24fbdc73aea86a291b3e8c72cde10f..8a7613f4d69d5bee12de29a0a496e89d15d3a739 100644 (file)
@@ -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;
+}
index 50e6b2c567cee49c5340cf6f1976511337ef73d1..38f7c8d5f56951b55076bc4e6691468ffcf08d49 100644 (file)
@@ -27,6 +27,7 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <arpa/inet.h>
+#include <linux/types.h>
 #include <sys/socket.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_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 */