[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1428913385-4331-3-git-send-email-nicolas.dichtel@6wind.com>
Date: Mon, 13 Apr 2015 10:23:05 +0200
From: Nicolas Dichtel <nicolas.dichtel@...nd.com>
To: shemminger@...tta.com
Cc: netdev@...r.kernel.org, vadim4j@...il.com, jbenc@...hat.com,
Nicolas Dichtel <nicolas.dichtel@...nd.com>
Subject: [PATCH iproute2 3/3] 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@...nd.com>
---
ip/ipnetns.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 53 insertions(+), 3 deletions(-)
diff --git a/ip/ipnetns.c b/ip/ipnetns.c
index 5a213dcf46cd..12f6b90de89a 100644
--- a/ip/ipnetns.c
+++ b/ip/ipnetns.c
@@ -34,6 +34,54 @@ 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)
+ return fd;
+
+ 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 +143,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);
--
2.2.2
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists