{ LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RW, "sysfs", "%r/sys", "sysfs", 0, NULL },
{ LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RO, "sysfs", "%r/sys", "sysfs", MS_RDONLY, NULL },
{ LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED, "sysfs", "%r/sys", "sysfs", MS_NODEV|MS_NOEXEC|MS_NOSUID, NULL },
- { LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED, "%r/sys", "%r/sys", NULL, MS_BIND, NULL },
{ LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED, NULL, "%r/sys", NULL, MS_REMOUNT|MS_BIND|MS_RDONLY, NULL },
{ LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED, "sysfs", "%r/sys/devices/virtual/net", "sysfs", 0, NULL },
{ LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED, "%r/sys/devices/virtual/net/devices/virtual/net", "%r/sys/devices/virtual/net", NULL, MS_BIND, NULL },
int len = RTA_LENGTH(alen);
struct rtattr *rta;
+ errno = EMSGSIZE;
if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen)
return -1;
int lxc_netns_set_nsid(int fd)
{
- ssize_t ret;
+ int ret;
char buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
NLMSG_ALIGN(sizeof(struct rtgenmsg)) +
NLMSG_ALIGN(1024)];
struct nlmsghdr *hdr;
struct rtgenmsg *msg;
int saved_errno;
- __s32 ns_id = -1;
- __u32 netns_fd = fd;
+ const __s32 ns_id = -1;
+ const __u32 netns_fd = fd;
ret = netlink_open(&nlh, NETLINK_ROUTE);
if (ret < 0)
- return ret;
+ return -1;
memset(buf, 0, sizeof(buf));
hdr = (struct nlmsghdr *)buf;
hdr->nlmsg_seq = RTM_NEWNSID;
msg->rtgen_family = AF_UNSPEC;
- addattr(hdr, 1024, __LXC_NETNSA_FD, &netns_fd, sizeof(netns_fd));
- addattr(hdr, 1024, __LXC_NETNSA_NSID, &ns_id, sizeof(ns_id));
+ ret = addattr(hdr, 1024, __LXC_NETNSA_FD, &netns_fd, sizeof(netns_fd));
+ 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);
+
+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;
netlink_close(&nlh);
errno = saved_errno;
if (ret < 0)
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;
}