summaryrefslogtreecommitdiff
path: root/ip/ipnetns.c
diff options
context:
space:
mode:
authorNicolas Dichtel <nicolas.dichtel@6wind.com>2015-04-13 10:34:26 +0200
committerStephen Hemminger <shemming@brocade.com>2015-04-13 08:50:10 -0700
commit4c7d9a588896c56e3b484a160850b14b389856c0 (patch)
tree024baa64d8d7b0e21d88a6c3e3236e679537d047 /ip/ipnetns.c
parent5a2ce868235cb337a88d2711005eb5972a06e1ac (diff)
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: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Diffstat (limited to 'ip/ipnetns.c')
-rw-r--r--ip/ipnetns.c58
1 files changed, 55 insertions, 3 deletions
diff --git a/ip/ipnetns.c b/ip/ipnetns.c
index 5a213dcf..24df167e 100644
--- a/ip/ipnetns.c
+++ b/ip/ipnetns.c
@@ -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);