Commit 4c7d9a58 authored by Nicolas Dichtel's avatar Nicolas Dichtel Committed by Stephen Hemminger

ipnetns: add a runtime check for RTM_GETNSID support

The goal of this patch is to test during the runtime if the command RTM_GETNSID
is supported by the kernel.
Signed-off-by: default avatarNicolas Dichtel <nicolas.dichtel@6wind.com>
parent 5a2ce868
......@@ -34,6 +34,56 @@ static int usage(void)
exit(-1);
}
static int have_rtnl_getnsid = -1;
static int ipnetns_accept_msg(const struct sockaddr_nl *who,
struct nlmsghdr *n, void *arg)
{
struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(n);
if (n->nlmsg_type == NLMSG_ERROR &&
(err->error == -EOPNOTSUPP || err->error == -EINVAL))
have_rtnl_getnsid = 0;
else
have_rtnl_getnsid = 1;
return -1;
}
static int ipnetns_have_nsid(void)
{
struct {
struct nlmsghdr n;
struct rtgenmsg g;
char buf[1024];
} req;
int fd;
if (have_rtnl_getnsid < 0) {
memset(&req, 0, sizeof(req));
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
req.n.nlmsg_flags = NLM_F_REQUEST;
req.n.nlmsg_type = RTM_GETNSID;
req.g.rtgen_family = AF_UNSPEC;
fd = open("/proc/self/ns/net", O_RDONLY);
if (fd < 0) {
perror("open(\"/proc/self/ns/net\")");
exit(1);
}
addattr32(&req.n, 1024, NETNSA_FD, fd);
if (rtnl_send(&rth, &req.n, req.n.nlmsg_len) < 0) {
perror("request send failed");
exit(1);
}
rtnl_listen(&rth, ipnetns_accept_msg, NULL);
close(fd);
}
return have_rtnl_getnsid;
}
static int get_netnsid_from_name(const char *name)
{
struct {
......@@ -95,9 +145,11 @@ static int netns_list(int argc, char **argv)
if (strcmp(entry->d_name, "..") == 0)
continue;
printf("%s", entry->d_name);
id = get_netnsid_from_name(entry->d_name);
if (id >= 0)
printf(" (id: %d)", id);
if (ipnetns_have_nsid()) {
id = get_netnsid_from_name(entry->d_name);
if (id >= 0)
printf(" (id: %d)", id);
}
printf("\n");
}
closedir(dir);
......
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