Merge branch 'master' into net-next
diff --git a/configure b/configure
index 8f528af..f1325df 100755
--- a/configure
+++ b/configure
@@ -218,23 +218,6 @@
rm -f $TMPDIR/setnstest.c $TMPDIR/setnstest
}
-check_netnsid()
-{
- cat >$TMPDIR/netnsid.c <<EOF
-#include <linux/rtnetlink.h>
-int test_def = RTM_GETNSID;
-EOF
- $CC -I$INCLUDE -c $TMPDIR/netnsid.c >/dev/null 2>&1
- if [ $? -eq 0 ]
- then
- echo "IP_CONFIG_NETNSID:=y" >> Config
- echo "yes"
- else
- echo "no"
- fi
- rm -f $TMPDIR/netnsid.c $TMPDIR/netnsid.o
-}
-
check_ipset()
{
cat >$TMPDIR/ipsettest.c <<EOF
@@ -323,8 +306,6 @@
echo -n "libc has setns: "
check_setns
-echo -n "netns has peer id suport: "
-check_netnsid
echo -n "SELinux support: "
check_selinux
diff --git a/include/SNAPSHOT.h b/include/SNAPSHOT.h
index 35bda66..8bd0c56 100644
--- a/include/SNAPSHOT.h
+++ b/include/SNAPSHOT.h
@@ -1 +1 @@
-static const char SNAPSHOT[] = "150210";
+static const char SNAPSHOT[] = "150413";
diff --git a/ip/Makefile b/ip/Makefile
index 5637bcf..2c742f3 100644
--- a/ip/Makefile
+++ b/ip/Makefile
@@ -16,10 +16,6 @@
CFLAGS += -DHAVE_SETNS
endif
-ifeq ($(IP_CONFIG_NETNSID),y)
- CFLAGS += -DHAVE_NETNSID
-endif
-
ALLOBJ=$(IPOBJ) $(RTMONOBJ)
SCRIPTS=ifcfg rtpr routel routef
TARGETS=ip rtmon
diff --git a/ip/ipnetns.c b/ip/ipnetns.c
index 45e234a..24df167 100644
--- a/ip/ipnetns.c
+++ b/ip/ipnetns.c
@@ -34,7 +34,56 @@
exit(-1);
}
-#ifdef HAVE_NETNSID
+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 {
@@ -79,12 +128,6 @@
return -1;
}
-#else
-static int get_netnsid_from_name(const char *name)
-{
- return -1;
-}
-#endif /* HAVE_NETNSID */
static int netns_list(int argc, char **argv)
{
@@ -102,9 +145,11 @@
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);