Unverified Commit e430137c by Stéphane Graber Committed by GitHub

Merge pull request #2608 from brauner/2018-09-11/netns_get_nsid

network: add lxc_netns_get_nsid()
parents 2339fce5 9d036caa
...@@ -27,6 +27,7 @@ ...@@ -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; ...@@ -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
......
...@@ -3171,6 +3171,7 @@ int addattr(struct nlmsghdr *n, size_t maxlen, int type, const void *data, size_ ...@@ -3171,6 +3171,7 @@ int addattr(struct nlmsghdr *n, size_t maxlen, int type, const void *data, size_
int len = RTA_LENGTH(alen); int len = RTA_LENGTH(alen);
struct rtattr *rta; struct rtattr *rta;
errno = EMSGSIZE;
if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen)
return -1; return -1;
...@@ -3196,7 +3197,7 @@ enum { ...@@ -3196,7 +3197,7 @@ enum {
int lxc_netns_set_nsid(int fd) int lxc_netns_set_nsid(int fd)
{ {
ssize_t ret; int ret;
char buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + char buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
NLMSG_ALIGN(sizeof(struct rtgenmsg)) + NLMSG_ALIGN(sizeof(struct rtgenmsg)) +
NLMSG_ALIGN(1024)]; NLMSG_ALIGN(1024)];
...@@ -3204,12 +3205,12 @@ int lxc_netns_set_nsid(int fd) ...@@ -3204,12 +3205,12 @@ int lxc_netns_set_nsid(int fd)
struct nlmsghdr *hdr; struct nlmsghdr *hdr;
struct rtgenmsg *msg; struct rtgenmsg *msg;
int saved_errno; int saved_errno;
__s32 ns_id = -1; const __s32 ns_id = -1;
__u32 netns_fd = fd; const __u32 netns_fd = fd;
ret = netlink_open(&nlh, NETLINK_ROUTE); ret = netlink_open(&nlh, NETLINK_ROUTE);
if (ret < 0) if (ret < 0)
return ret; return -1;
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
hdr = (struct nlmsghdr *)buf; hdr = (struct nlmsghdr *)buf;
...@@ -3222,15 +3223,99 @@ int lxc_netns_set_nsid(int fd) ...@@ -3222,15 +3223,99 @@ int lxc_netns_set_nsid(int fd)
hdr->nlmsg_seq = RTM_NEWNSID; hdr->nlmsg_seq = RTM_NEWNSID;
msg->rtgen_family = AF_UNSPEC; msg->rtgen_family = AF_UNSPEC;
addattr(hdr, 1024, __LXC_NETNSA_FD, &netns_fd, sizeof(netns_fd)); ret = addattr(hdr, 1024, __LXC_NETNSA_FD, &netns_fd, sizeof(netns_fd));
addattr(hdr, 1024, __LXC_NETNSA_NSID, &ns_id, sizeof(ns_id)); if (ret < 0)
goto on_error;
ret = addattr(hdr, 1024, __LXC_NETNSA_NSID, &ns_id, sizeof(ns_id));
if (ret < 0)
goto on_error;
ret = __netlink_transaction(&nlh, hdr, hdr); ret = __netlink_transaction(&nlh, hdr, hdr);
on_error:
saved_errno = errno;
netlink_close(&nlh);
errno = saved_errno;
return ret;
}
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;
ret = addattr(hdr, 1024, __LXC_NETNSA_FD, &netns_fd, sizeof(netns_fd));
if (ret == 0)
ret = __netlink_transaction(&nlh, hdr, hdr);
saved_errno = errno; saved_errno = errno;
netlink_close(&nlh); netlink_close(&nlh);
errno = saved_errno; errno = saved_errno;
if (ret < 0) if (ret < 0)
return -1; return -1;
return 0; errno = EINVAL;
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;
} }
...@@ -27,6 +27,7 @@ ...@@ -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); ...@@ -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 */
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