netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH iproute2 v4] ip: Simplify executing ip cmd within network ns
@ 2014-12-12 22:15 Vadim Kochan
  2014-12-13  8:29 ` Jiri Pirko
  0 siblings, 1 reply; 7+ messages in thread
From: Vadim Kochan @ 2014-12-12 22:15 UTC (permalink / raw)
  To: netdev; +Cc: Vadim Kochan

From: Vadim Kochan <vadim4j@gmail.com>

Added new '-netns' option to simplify executing following cmd:

    ip netns exec NETNS ip OPTIONS COMMAND OBJECT

    to

    ip -n[etns] NETNS OPTIONS COMMAND OBJECT

e.g.:

    ip -net vnet0 link add br0 type bridge
    ip -n vnet0 link

Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
---
 include/namespace.h |  46 +++++++++++++++++++++++
 ip/ip.c             |   5 +++
 ip/ipnetns.c        | 106 ++--------------------------------------------------
 lib/Makefile        |   6 ++-
 lib/namespace.c     |  86 ++++++++++++++++++++++++++++++++++++++++++
 man/man8/ip.8       |  23 +++++++++++-
 6 files changed, 167 insertions(+), 105 deletions(-)
 create mode 100644 include/namespace.h
 create mode 100644 lib/namespace.c

diff --git a/include/namespace.h b/include/namespace.h
new file mode 100644
index 0000000..2f13e65
--- /dev/null
+++ b/include/namespace.h
@@ -0,0 +1,46 @@
+#ifndef __NAMESPACE_H__
+#define __NAMESPACE_H__ 1
+
+#include <sched.h>
+#include <sys/mount.h>
+#include <errno.h>
+
+#define NETNS_RUN_DIR "/var/run/netns"
+#define NETNS_ETC_DIR "/etc/netns"
+
+#ifndef CLONE_NEWNET
+#define CLONE_NEWNET 0x40000000	/* New network namespace (lo, device, names sockets, etc) */
+#endif
+
+#ifndef MNT_DETACH
+#define MNT_DETACH	0x00000002	/* Just detach from the tree */
+#endif /* MNT_DETACH */
+
+/* sys/mount.h may be out too old to have these */
+#ifndef MS_REC
+#define MS_REC		16384
+#endif
+
+#ifndef MS_SLAVE
+#define MS_SLAVE	(1 << 19)
+#endif
+
+#ifndef MS_SHARED
+#define MS_SHARED	(1 << 20)
+#endif
+
+#ifndef HAVE_SETNS
+static int setns(int fd, int nstype)
+{
+#ifdef __NR_setns
+	return syscall(__NR_setns, fd, nstype);
+#else
+	errno = ENOSYS;
+	return -1;
+#endif
+}
+#endif /* HAVE_SETNS */
+
+extern int netns_switch(char *netns);
+
+#endif /* __NAMESPACE_H__ */
diff --git a/ip/ip.c b/ip/ip.c
index 5f759d5..d6c9123 100644
--- a/ip/ip.c
+++ b/ip/ip.c
@@ -22,6 +22,7 @@
 #include "SNAPSHOT.h"
 #include "utils.h"
 #include "ip_common.h"
+#include "namespace.h"
 
 int preferred_family = AF_UNSPEC;
 int human_readable = 0;
@@ -262,6 +263,10 @@ int main(int argc, char **argv)
 			rcvbuf = size;
 		} else if (matches(opt, "-help") == 0) {
 			usage();
+		} else if (matches(opt, "-netns") == 0) {
+			NEXT_ARG();
+			if (netns_switch(argv[1]))
+				exit(-1);
 		} else {
 			fprintf(stderr, "Option \"%s\" is unknown, try \"ip -help\".\n", opt);
 			exit(-1);
diff --git a/ip/ipnetns.c b/ip/ipnetns.c
index 1c8aa02..519d518 100644
--- a/ip/ipnetns.c
+++ b/ip/ipnetns.c
@@ -17,42 +17,7 @@
 
 #include "utils.h"
 #include "ip_common.h"
-
-#define NETNS_RUN_DIR "/var/run/netns"
-#define NETNS_ETC_DIR "/etc/netns"
-
-#ifndef CLONE_NEWNET
-#define CLONE_NEWNET 0x40000000	/* New network namespace (lo, device, names sockets, etc) */
-#endif
-
-#ifndef MNT_DETACH
-#define MNT_DETACH	0x00000002	/* Just detach from the tree */
-#endif /* MNT_DETACH */
-
-/* sys/mount.h may be out too old to have these */
-#ifndef MS_REC
-#define MS_REC		16384
-#endif
-
-#ifndef MS_SLAVE
-#define MS_SLAVE	(1 << 19)
-#endif
-
-#ifndef MS_SHARED
-#define MS_SHARED	(1 << 20)
-#endif
-
-#ifndef HAVE_SETNS
-static int setns(int fd, int nstype)
-{
-#ifdef __NR_setns
-	return syscall(__NR_setns, fd, nstype);
-#else
-	errno = ENOSYS;
-	return -1;
-#endif
-}
-#endif /* HAVE_SETNS */
+#include "namespace.h"
 
 static int usage(void)
 {
@@ -101,42 +66,12 @@ static int netns_list(int argc, char **argv)
 	return 0;
 }
 
-static void bind_etc(const char *name)
-{
-	char etc_netns_path[MAXPATHLEN];
-	char netns_name[MAXPATHLEN];
-	char etc_name[MAXPATHLEN];
-	struct dirent *entry;
-	DIR *dir;
-
-	snprintf(etc_netns_path, sizeof(etc_netns_path), "%s/%s", NETNS_ETC_DIR, name);
-	dir = opendir(etc_netns_path);
-	if (!dir)
-		return;
-
-	while ((entry = readdir(dir)) != NULL) {
-		if (strcmp(entry->d_name, ".") == 0)
-			continue;
-		if (strcmp(entry->d_name, "..") == 0)
-			continue;
-		snprintf(netns_name, sizeof(netns_name), "%s/%s", etc_netns_path, entry->d_name);
-		snprintf(etc_name, sizeof(etc_name), "/etc/%s", entry->d_name);
-		if (mount(netns_name, etc_name, "none", MS_BIND, NULL) < 0) {
-			fprintf(stderr, "Bind %s -> %s failed: %s\n",
-				netns_name, etc_name, strerror(errno));
-		}
-	}
-	closedir(dir);
-}
-
 static int netns_exec(int argc, char **argv)
 {
 	/* Setup the proper environment for apps that are not netns
 	 * aware, and execute a program in that environment.
 	 */
-	const char *name, *cmd;
-	char net_path[MAXPATHLEN];
-	int netns;
+	const char *cmd;
 
 	if (argc < 1) {
 		fprintf(stderr, "No netns name specified\n");
@@ -146,45 +81,10 @@ static int netns_exec(int argc, char **argv)
 		fprintf(stderr, "No command specified\n");
 		return -1;
 	}
-
-	name = argv[0];
 	cmd = argv[1];
-	snprintf(net_path, sizeof(net_path), "%s/%s", NETNS_RUN_DIR, name);
-	netns = open(net_path, O_RDONLY | O_CLOEXEC);
-	if (netns < 0) {
-		fprintf(stderr, "Cannot open network namespace \"%s\": %s\n",
-			name, strerror(errno));
-		return -1;
-	}
-
-	if (setns(netns, CLONE_NEWNET) < 0) {
-		fprintf(stderr, "setting the network namespace \"%s\" failed: %s\n",
-			name, strerror(errno));
-		return -1;
-	}
 
-	if (unshare(CLONE_NEWNS) < 0) {
-		fprintf(stderr, "unshare failed: %s\n", strerror(errno));
-		return -1;
-	}
-	/* Don't let any mounts propagate back to the parent */
-	if (mount("", "/", "none", MS_SLAVE | MS_REC, NULL)) {
-		fprintf(stderr, "\"mount --make-rslave /\" failed: %s\n",
-			strerror(errno));
+	if (netns_switch(argv[0]))
 		return -1;
-	}
-	/* Mount a version of /sys that describes the network namespace */
-	if (umount2("/sys", MNT_DETACH) < 0) {
-		fprintf(stderr, "umount of /sys failed: %s\n", strerror(errno));
-		return -1;
-	}
-	if (mount(name, "/sys", "sysfs", 0, NULL) < 0) {
-		fprintf(stderr, "mount of /sys failed: %s\n",strerror(errno));
-		return -1;
-	}
-
-	/* Setup bind mounts for config files in /etc */
-	bind_etc(name);
 
 	fflush(stdout);
 
diff --git a/lib/Makefile b/lib/Makefile
index a42b885..66f89f1 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -1,8 +1,12 @@
 include ../Config
 
+ifeq ($(IP_CONFIG_SETNS),y)
+	CFLAGS += -DHAVE_SETNS
+endif
+
 CFLAGS += -fPIC
 
-UTILOBJ=utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o inet_proto.o
+UTILOBJ=utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o inet_proto.o namespace.o
 
 NLOBJ=libgenl.o ll_map.o libnetlink.o
 
diff --git a/lib/namespace.c b/lib/namespace.c
new file mode 100644
index 0000000..1554ce0
--- /dev/null
+++ b/lib/namespace.c
@@ -0,0 +1,86 @@
+/*
+ * namespace.c
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+
+#include <fcntl.h>
+#include <dirent.h>
+
+#include "utils.h"
+#include "namespace.h"
+
+static void bind_etc(const char *name)
+{
+	char etc_netns_path[MAXPATHLEN];
+	char netns_name[MAXPATHLEN];
+	char etc_name[MAXPATHLEN];
+	struct dirent *entry;
+	DIR *dir;
+
+	snprintf(etc_netns_path, sizeof(etc_netns_path), "%s/%s", NETNS_ETC_DIR, name);
+	dir = opendir(etc_netns_path);
+	if (!dir)
+		return;
+
+	while ((entry = readdir(dir)) != NULL) {
+		if (strcmp(entry->d_name, ".") == 0)
+			continue;
+		if (strcmp(entry->d_name, "..") == 0)
+			continue;
+		snprintf(netns_name, sizeof(netns_name), "%s/%s", etc_netns_path, entry->d_name);
+		snprintf(etc_name, sizeof(etc_name), "/etc/%s", entry->d_name);
+		if (mount(netns_name, etc_name, "none", MS_BIND, NULL) < 0) {
+			fprintf(stderr, "Bind %s -> %s failed: %s\n",
+				netns_name, etc_name, strerror(errno));
+		}
+	}
+	closedir(dir);
+}
+
+int netns_switch(char *name)
+{
+	char net_path[MAXPATHLEN];
+	int netns;
+
+	snprintf(net_path, sizeof(net_path), "%s/%s", NETNS_RUN_DIR, name);
+	netns = open(net_path, O_RDONLY | O_CLOEXEC);
+	if (netns < 0) {
+		fprintf(stderr, "Cannot open network namespace \"%s\": %s\n",
+			name, strerror(errno));
+		return -1;
+	}
+
+	if (setns(netns, CLONE_NEWNET) < 0) {
+		fprintf(stderr, "setting the network namespace \"%s\" failed: %s\n",
+			name, strerror(errno));
+		return -1;
+	}
+
+	if (unshare(CLONE_NEWNS) < 0) {
+		fprintf(stderr, "unshare failed: %s\n", strerror(errno));
+		return -1;
+	}
+	/* Don't let any mounts propagate back to the parent */
+	if (mount("", "/", "none", MS_SLAVE | MS_REC, NULL)) {
+		fprintf(stderr, "\"mount --make-rslave /\" failed: %s\n",
+			strerror(errno));
+		return -1;
+	}
+	/* Mount a version of /sys that describes the network namespace */
+	if (umount2("/sys", MNT_DETACH) < 0) {
+		fprintf(stderr, "umount of /sys failed: %s\n", strerror(errno));
+		return -1;
+	}
+	if (mount(name, "/sys", "sysfs", 0, NULL) < 0) {
+		fprintf(stderr, "mount of /sys failed: %s\n",strerror(errno));
+		return -1;
+	}
+
+	/* Setup bind mounts for config files in /etc */
+	bind_etc(name);
+	return 0;
+}
diff --git a/man/man8/ip.8 b/man/man8/ip.8
index 2d42e98..0fb759d 100644
--- a/man/man8/ip.8
+++ b/man/man8/ip.8
@@ -31,7 +31,8 @@ ip \- show / manipulate routing, devices, policy routing and tunnels
 \fB\-r\fR[\fIesolve\fR] |
 \fB\-f\fR[\fIamily\fR] {
 .BR inet " | " inet6 " | " ipx " | " dnet " | " link " } | "
-\fB\-o\fR[\fIneline\fR] }
+\fB\-o\fR[\fIneline\fR] |
+\fB\-n\fR[\fIetns\fR] }
 
 
 .SH OPTIONS
@@ -134,6 +135,26 @@ the output.
 use the system's name resolver to print DNS names instead of
 host addresses.
 
+.TP
+.BR "\-n" , " \-net" , " \-netns " <NETNS>
+switches
+.B ip
+to the specified network namespace
+.IR NETNS .
+Actually it just simplifies executing of:
+
+.B ip netns exec
+.IR NETNS
+.B ip
+.RI "[ " OPTIONS " ] " OBJECT " { " COMMAND " | "
+.BR help " }"
+
+to
+
+.B ip
+.RI "-n[etns] " NETNS " [ " OPTIONS " ] " OBJECT " { " COMMAND " | "
+.BR help " }"
+
 .SH IP - COMMAND SYNTAX
 
 .SS
-- 
2.1.3

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH iproute2 v4] ip: Simplify executing ip cmd within network ns
  2014-12-12 22:15 [PATCH iproute2 v4] ip: Simplify executing ip cmd within network ns Vadim Kochan
@ 2014-12-13  8:29 ` Jiri Pirko
  2014-12-13  8:42   ` vadim4j
  0 siblings, 1 reply; 7+ messages in thread
From: Jiri Pirko @ 2014-12-13  8:29 UTC (permalink / raw)
  To: Vadim Kochan; +Cc: netdev

Fri, Dec 12, 2014 at 11:15:07PM CET, vadim4j@gmail.com wrote:
>From: Vadim Kochan <vadim4j@gmail.com>
>
>Added new '-netns' option to simplify executing following cmd:
>
>    ip netns exec NETNS ip OPTIONS COMMAND OBJECT
>
>    to
>
>    ip -n[etns] NETNS OPTIONS COMMAND OBJECT
>
>e.g.:
>
>    ip -net vnet0 link add br0 type bridge
>    ip -n vnet0 link
>
>Signed-off-by: Vadim Kochan <vadim4j@gmail.com>


This looks good. I'm still missing support in tc, bridge, etc. I think
it would be great to do this in the same patch/patchset.


>---
> include/namespace.h |  46 +++++++++++++++++++++++
> ip/ip.c             |   5 +++
> ip/ipnetns.c        | 106 ++--------------------------------------------------
> lib/Makefile        |   6 ++-
> lib/namespace.c     |  86 ++++++++++++++++++++++++++++++++++++++++++
> man/man8/ip.8       |  23 +++++++++++-
> 6 files changed, 167 insertions(+), 105 deletions(-)
> create mode 100644 include/namespace.h
> create mode 100644 lib/namespace.c
>
>diff --git a/include/namespace.h b/include/namespace.h
>new file mode 100644
>index 0000000..2f13e65
>--- /dev/null
>+++ b/include/namespace.h
>@@ -0,0 +1,46 @@
>+#ifndef __NAMESPACE_H__
>+#define __NAMESPACE_H__ 1
>+
>+#include <sched.h>
>+#include <sys/mount.h>
>+#include <errno.h>
>+
>+#define NETNS_RUN_DIR "/var/run/netns"
>+#define NETNS_ETC_DIR "/etc/netns"
>+
>+#ifndef CLONE_NEWNET
>+#define CLONE_NEWNET 0x40000000	/* New network namespace (lo, device, names sockets, etc) */
>+#endif
>+
>+#ifndef MNT_DETACH
>+#define MNT_DETACH	0x00000002	/* Just detach from the tree */
>+#endif /* MNT_DETACH */
>+
>+/* sys/mount.h may be out too old to have these */
>+#ifndef MS_REC
>+#define MS_REC		16384
>+#endif
>+
>+#ifndef MS_SLAVE
>+#define MS_SLAVE	(1 << 19)
>+#endif
>+
>+#ifndef MS_SHARED
>+#define MS_SHARED	(1 << 20)
>+#endif
>+
>+#ifndef HAVE_SETNS
>+static int setns(int fd, int nstype)
>+{
>+#ifdef __NR_setns
>+	return syscall(__NR_setns, fd, nstype);
>+#else
>+	errno = ENOSYS;
>+	return -1;
>+#endif
>+}
>+#endif /* HAVE_SETNS */
>+
>+extern int netns_switch(char *netns);
>+
>+#endif /* __NAMESPACE_H__ */
>diff --git a/ip/ip.c b/ip/ip.c
>index 5f759d5..d6c9123 100644
>--- a/ip/ip.c
>+++ b/ip/ip.c
>@@ -22,6 +22,7 @@
> #include "SNAPSHOT.h"
> #include "utils.h"
> #include "ip_common.h"
>+#include "namespace.h"
> 
> int preferred_family = AF_UNSPEC;
> int human_readable = 0;
>@@ -262,6 +263,10 @@ int main(int argc, char **argv)
> 			rcvbuf = size;
> 		} else if (matches(opt, "-help") == 0) {
> 			usage();
>+		} else if (matches(opt, "-netns") == 0) {
>+			NEXT_ARG();
>+			if (netns_switch(argv[1]))
>+				exit(-1);
> 		} else {
> 			fprintf(stderr, "Option \"%s\" is unknown, try \"ip -help\".\n", opt);
> 			exit(-1);
>diff --git a/ip/ipnetns.c b/ip/ipnetns.c
>index 1c8aa02..519d518 100644
>--- a/ip/ipnetns.c
>+++ b/ip/ipnetns.c
>@@ -17,42 +17,7 @@
> 
> #include "utils.h"
> #include "ip_common.h"
>-
>-#define NETNS_RUN_DIR "/var/run/netns"
>-#define NETNS_ETC_DIR "/etc/netns"
>-
>-#ifndef CLONE_NEWNET
>-#define CLONE_NEWNET 0x40000000	/* New network namespace (lo, device, names sockets, etc) */
>-#endif
>-
>-#ifndef MNT_DETACH
>-#define MNT_DETACH	0x00000002	/* Just detach from the tree */
>-#endif /* MNT_DETACH */
>-
>-/* sys/mount.h may be out too old to have these */
>-#ifndef MS_REC
>-#define MS_REC		16384
>-#endif
>-
>-#ifndef MS_SLAVE
>-#define MS_SLAVE	(1 << 19)
>-#endif
>-
>-#ifndef MS_SHARED
>-#define MS_SHARED	(1 << 20)
>-#endif
>-
>-#ifndef HAVE_SETNS
>-static int setns(int fd, int nstype)
>-{
>-#ifdef __NR_setns
>-	return syscall(__NR_setns, fd, nstype);
>-#else
>-	errno = ENOSYS;
>-	return -1;
>-#endif
>-}
>-#endif /* HAVE_SETNS */
>+#include "namespace.h"
> 
> static int usage(void)
> {
>@@ -101,42 +66,12 @@ static int netns_list(int argc, char **argv)
> 	return 0;
> }
> 
>-static void bind_etc(const char *name)
>-{
>-	char etc_netns_path[MAXPATHLEN];
>-	char netns_name[MAXPATHLEN];
>-	char etc_name[MAXPATHLEN];
>-	struct dirent *entry;
>-	DIR *dir;
>-
>-	snprintf(etc_netns_path, sizeof(etc_netns_path), "%s/%s", NETNS_ETC_DIR, name);
>-	dir = opendir(etc_netns_path);
>-	if (!dir)
>-		return;
>-
>-	while ((entry = readdir(dir)) != NULL) {
>-		if (strcmp(entry->d_name, ".") == 0)
>-			continue;
>-		if (strcmp(entry->d_name, "..") == 0)
>-			continue;
>-		snprintf(netns_name, sizeof(netns_name), "%s/%s", etc_netns_path, entry->d_name);
>-		snprintf(etc_name, sizeof(etc_name), "/etc/%s", entry->d_name);
>-		if (mount(netns_name, etc_name, "none", MS_BIND, NULL) < 0) {
>-			fprintf(stderr, "Bind %s -> %s failed: %s\n",
>-				netns_name, etc_name, strerror(errno));
>-		}
>-	}
>-	closedir(dir);
>-}
>-
> static int netns_exec(int argc, char **argv)
> {
> 	/* Setup the proper environment for apps that are not netns
> 	 * aware, and execute a program in that environment.
> 	 */
>-	const char *name, *cmd;
>-	char net_path[MAXPATHLEN];
>-	int netns;
>+	const char *cmd;
> 
> 	if (argc < 1) {
> 		fprintf(stderr, "No netns name specified\n");
>@@ -146,45 +81,10 @@ static int netns_exec(int argc, char **argv)
> 		fprintf(stderr, "No command specified\n");
> 		return -1;
> 	}
>-
>-	name = argv[0];
> 	cmd = argv[1];
>-	snprintf(net_path, sizeof(net_path), "%s/%s", NETNS_RUN_DIR, name);
>-	netns = open(net_path, O_RDONLY | O_CLOEXEC);
>-	if (netns < 0) {
>-		fprintf(stderr, "Cannot open network namespace \"%s\": %s\n",
>-			name, strerror(errno));
>-		return -1;
>-	}
>-
>-	if (setns(netns, CLONE_NEWNET) < 0) {
>-		fprintf(stderr, "setting the network namespace \"%s\" failed: %s\n",
>-			name, strerror(errno));
>-		return -1;
>-	}
> 
>-	if (unshare(CLONE_NEWNS) < 0) {
>-		fprintf(stderr, "unshare failed: %s\n", strerror(errno));
>-		return -1;
>-	}
>-	/* Don't let any mounts propagate back to the parent */
>-	if (mount("", "/", "none", MS_SLAVE | MS_REC, NULL)) {
>-		fprintf(stderr, "\"mount --make-rslave /\" failed: %s\n",
>-			strerror(errno));
>+	if (netns_switch(argv[0]))
> 		return -1;
>-	}
>-	/* Mount a version of /sys that describes the network namespace */
>-	if (umount2("/sys", MNT_DETACH) < 0) {
>-		fprintf(stderr, "umount of /sys failed: %s\n", strerror(errno));
>-		return -1;
>-	}
>-	if (mount(name, "/sys", "sysfs", 0, NULL) < 0) {
>-		fprintf(stderr, "mount of /sys failed: %s\n",strerror(errno));
>-		return -1;
>-	}
>-
>-	/* Setup bind mounts for config files in /etc */
>-	bind_etc(name);
> 
> 	fflush(stdout);
> 
>diff --git a/lib/Makefile b/lib/Makefile
>index a42b885..66f89f1 100644
>--- a/lib/Makefile
>+++ b/lib/Makefile
>@@ -1,8 +1,12 @@
> include ../Config
> 
>+ifeq ($(IP_CONFIG_SETNS),y)
>+	CFLAGS += -DHAVE_SETNS
>+endif
>+
> CFLAGS += -fPIC
> 
>-UTILOBJ=utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o inet_proto.o
>+UTILOBJ=utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o inet_proto.o namespace.o
> 
> NLOBJ=libgenl.o ll_map.o libnetlink.o
> 
>diff --git a/lib/namespace.c b/lib/namespace.c
>new file mode 100644
>index 0000000..1554ce0
>--- /dev/null
>+++ b/lib/namespace.c
>@@ -0,0 +1,86 @@
>+/*
>+ * namespace.c
>+ *
>+ *		This program is free software; you can redistribute it and/or
>+ *		modify it under the terms of the GNU General Public License
>+ *		as published by the Free Software Foundation; either version
>+ *		2 of the License, or (at your option) any later version.
>+ */
>+
>+#include <fcntl.h>
>+#include <dirent.h>
>+
>+#include "utils.h"
>+#include "namespace.h"
>+
>+static void bind_etc(const char *name)
>+{
>+	char etc_netns_path[MAXPATHLEN];
>+	char netns_name[MAXPATHLEN];
>+	char etc_name[MAXPATHLEN];
>+	struct dirent *entry;
>+	DIR *dir;
>+
>+	snprintf(etc_netns_path, sizeof(etc_netns_path), "%s/%s", NETNS_ETC_DIR, name);
>+	dir = opendir(etc_netns_path);
>+	if (!dir)
>+		return;
>+
>+	while ((entry = readdir(dir)) != NULL) {
>+		if (strcmp(entry->d_name, ".") == 0)
>+			continue;
>+		if (strcmp(entry->d_name, "..") == 0)
>+			continue;
>+		snprintf(netns_name, sizeof(netns_name), "%s/%s", etc_netns_path, entry->d_name);
>+		snprintf(etc_name, sizeof(etc_name), "/etc/%s", entry->d_name);
>+		if (mount(netns_name, etc_name, "none", MS_BIND, NULL) < 0) {
>+			fprintf(stderr, "Bind %s -> %s failed: %s\n",
>+				netns_name, etc_name, strerror(errno));
>+		}
>+	}
>+	closedir(dir);
>+}
>+
>+int netns_switch(char *name)
>+{
>+	char net_path[MAXPATHLEN];
>+	int netns;
>+
>+	snprintf(net_path, sizeof(net_path), "%s/%s", NETNS_RUN_DIR, name);
>+	netns = open(net_path, O_RDONLY | O_CLOEXEC);
>+	if (netns < 0) {
>+		fprintf(stderr, "Cannot open network namespace \"%s\": %s\n",
>+			name, strerror(errno));
>+		return -1;
>+	}
>+
>+	if (setns(netns, CLONE_NEWNET) < 0) {
>+		fprintf(stderr, "setting the network namespace \"%s\" failed: %s\n",
>+			name, strerror(errno));
>+		return -1;
>+	}
>+
>+	if (unshare(CLONE_NEWNS) < 0) {
>+		fprintf(stderr, "unshare failed: %s\n", strerror(errno));
>+		return -1;
>+	}
>+	/* Don't let any mounts propagate back to the parent */
>+	if (mount("", "/", "none", MS_SLAVE | MS_REC, NULL)) {
>+		fprintf(stderr, "\"mount --make-rslave /\" failed: %s\n",
>+			strerror(errno));
>+		return -1;
>+	}
>+	/* Mount a version of /sys that describes the network namespace */
>+	if (umount2("/sys", MNT_DETACH) < 0) {
>+		fprintf(stderr, "umount of /sys failed: %s\n", strerror(errno));
>+		return -1;
>+	}
>+	if (mount(name, "/sys", "sysfs", 0, NULL) < 0) {
>+		fprintf(stderr, "mount of /sys failed: %s\n",strerror(errno));
>+		return -1;
>+	}
>+
>+	/* Setup bind mounts for config files in /etc */
>+	bind_etc(name);
>+	return 0;
>+}
>diff --git a/man/man8/ip.8 b/man/man8/ip.8
>index 2d42e98..0fb759d 100644
>--- a/man/man8/ip.8
>+++ b/man/man8/ip.8
>@@ -31,7 +31,8 @@ ip \- show / manipulate routing, devices, policy routing and tunnels
> \fB\-r\fR[\fIesolve\fR] |
> \fB\-f\fR[\fIamily\fR] {
> .BR inet " | " inet6 " | " ipx " | " dnet " | " link " } | "
>-\fB\-o\fR[\fIneline\fR] }
>+\fB\-o\fR[\fIneline\fR] |
>+\fB\-n\fR[\fIetns\fR] }
> 
> 
> .SH OPTIONS
>@@ -134,6 +135,26 @@ the output.
> use the system's name resolver to print DNS names instead of
> host addresses.
> 
>+.TP
>+.BR "\-n" , " \-net" , " \-netns " <NETNS>
>+switches
>+.B ip
>+to the specified network namespace
>+.IR NETNS .
>+Actually it just simplifies executing of:
>+
>+.B ip netns exec
>+.IR NETNS
>+.B ip
>+.RI "[ " OPTIONS " ] " OBJECT " { " COMMAND " | "
>+.BR help " }"
>+
>+to
>+
>+.B ip
>+.RI "-n[etns] " NETNS " [ " OPTIONS " ] " OBJECT " { " COMMAND " | "
>+.BR help " }"
>+
> .SH IP - COMMAND SYNTAX
> 
> .SS
>-- 
>2.1.3
>
>--
>To unsubscribe from this list: send the line "unsubscribe netdev" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH iproute2 v4] ip: Simplify executing ip cmd within network ns
  2014-12-13  8:29 ` Jiri Pirko
@ 2014-12-13  8:42   ` vadim4j
  2014-12-13  8:58     ` vadim4j
  0 siblings, 1 reply; 7+ messages in thread
From: vadim4j @ 2014-12-13  8:42 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: Vadim Kochan, netdev

On Sat, Dec 13, 2014 at 09:29:36AM +0100, Jiri Pirko wrote:
> Fri, Dec 12, 2014 at 11:15:07PM CET, vadim4j@gmail.com wrote:
> >From: Vadim Kochan <vadim4j@gmail.com>
> >
> >Added new '-netns' option to simplify executing following cmd:
> >
> >    ip netns exec NETNS ip OPTIONS COMMAND OBJECT
> >
> >    to
> >
> >    ip -n[etns] NETNS OPTIONS COMMAND OBJECT
> >
> >e.g.:
> >
> >    ip -net vnet0 link add br0 type bridge
> >    ip -n vnet0 link
> >
> >Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
> 
> 
> This looks good. I'm still missing support in tc, bridge, etc. I think
> it would be great to do this in the same patch/patchset.
> 
 I planned to do this in the future patches after this main
 changes will be accepted. Actually adding this option to other
 tools is trivial.

 Anyway may be I will re-send v5 with supporting of these tools if I will have time.

 Regards,

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH iproute2 v4] ip: Simplify executing ip cmd within network ns
  2014-12-13  8:42   ` vadim4j
@ 2014-12-13  8:58     ` vadim4j
  2014-12-13 13:32       ` vadim4j
  0 siblings, 1 reply; 7+ messages in thread
From: vadim4j @ 2014-12-13  8:58 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: Vadim Kochan, netdev

On Sat, Dec 13, 2014 at 10:42:43AM +0200, vadim4j@gmail.com wrote:
> On Sat, Dec 13, 2014 at 09:29:36AM +0100, Jiri Pirko wrote:
> > Fri, Dec 12, 2014 at 11:15:07PM CET, vadim4j@gmail.com wrote:
> > >From: Vadim Kochan <vadim4j@gmail.com>
> > >
> > >Added new '-netns' option to simplify executing following cmd:
> > >
> > >    ip netns exec NETNS ip OPTIONS COMMAND OBJECT
> > >
> > >    to
> > >
> > >    ip -n[etns] NETNS OPTIONS COMMAND OBJECT
> > >
> > >e.g.:
> > >
> > >    ip -net vnet0 link add br0 type bridge
> > >    ip -n vnet0 link
> > >
> > >Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
> > 
> > 
> > This looks good. I'm still missing support in tc, bridge, etc. I think
> > it would be great to do this in the same patch/patchset.
> > 
>  I planned to do this in the future patches after this main
>  changes will be accepted. Actually adding this option to other
>  tools is trivial.
> 
>  Anyway may be I will re-send v5 with supporting of these tools if I will have time.
> 
>  Regards,

BTW, some tools already have '-n' option, so I think only '-net' can be
used in such cases.

Regards,

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH iproute2 v4] ip: Simplify executing ip cmd within network ns
  2014-12-13  8:58     ` vadim4j
@ 2014-12-13 13:32       ` vadim4j
  2014-12-13 15:20         ` Jiri Pirko
  0 siblings, 1 reply; 7+ messages in thread
From: vadim4j @ 2014-12-13 13:32 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: Vadim Kochan, netdev

On Sat, Dec 13, 2014 at 10:58:03AM +0200, vadim4j@gmail.com wrote:
> On Sat, Dec 13, 2014 at 10:42:43AM +0200, vadim4j@gmail.com wrote:
> > On Sat, Dec 13, 2014 at 09:29:36AM +0100, Jiri Pirko wrote:
> > > Fri, Dec 12, 2014 at 11:15:07PM CET, vadim4j@gmail.com wrote:
> > > >From: Vadim Kochan <vadim4j@gmail.com>
> > > >
> > > >Added new '-netns' option to simplify executing following cmd:
> > > >
> > > >    ip netns exec NETNS ip OPTIONS COMMAND OBJECT
> > > >
> > > >    to
> > > >
> > > >    ip -n[etns] NETNS OPTIONS COMMAND OBJECT
> > > >
> > > >e.g.:
> > > >
> > > >    ip -net vnet0 link add br0 type bridge
> > > >    ip -n vnet0 link
> > > >
> > > >Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
> > > 
> > > 
> > > This looks good. I'm still missing support in tc, bridge, etc. I think
> > > it would be great to do this in the same patch/patchset.
> > > 
> >  I planned to do this in the future patches after this main
> >  changes will be accepted. Actually adding this option to other
> >  tools is trivial.
> > 
> >  Anyway may be I will re-send v5 with supporting of these tools if I will have time.
> > 
> >  Regards,
> 
> BTW, some tools already have '-n' option, so I think only '-net' can be
> used in such cases.
> 
> Regards,

OK, I am going to split changes into series of patches and bring new
option to : ip, tc, and bridge tools.
Regarding other misc tools - will do it later as I am  not very familiar with them.
Are you OK with this Jiri ?

Regards,

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH iproute2 v4] ip: Simplify executing ip cmd within network ns
  2014-12-13 13:32       ` vadim4j
@ 2014-12-13 15:20         ` Jiri Pirko
  2014-12-15 17:30           ` Nicolas Dichtel
  0 siblings, 1 reply; 7+ messages in thread
From: Jiri Pirko @ 2014-12-13 15:20 UTC (permalink / raw)
  To: vadim4j; +Cc: netdev

Sat, Dec 13, 2014 at 02:32:10PM CET, vadim4j@gmail.com wrote:
>On Sat, Dec 13, 2014 at 10:58:03AM +0200, vadim4j@gmail.com wrote:
>> On Sat, Dec 13, 2014 at 10:42:43AM +0200, vadim4j@gmail.com wrote:
>> > On Sat, Dec 13, 2014 at 09:29:36AM +0100, Jiri Pirko wrote:
>> > > Fri, Dec 12, 2014 at 11:15:07PM CET, vadim4j@gmail.com wrote:
>> > > >From: Vadim Kochan <vadim4j@gmail.com>
>> > > >
>> > > >Added new '-netns' option to simplify executing following cmd:
>> > > >
>> > > >    ip netns exec NETNS ip OPTIONS COMMAND OBJECT
>> > > >
>> > > >    to
>> > > >
>> > > >    ip -n[etns] NETNS OPTIONS COMMAND OBJECT
>> > > >
>> > > >e.g.:
>> > > >
>> > > >    ip -net vnet0 link add br0 type bridge
>> > > >    ip -n vnet0 link
>> > > >
>> > > >Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
>> > > 
>> > > 
>> > > This looks good. I'm still missing support in tc, bridge, etc. I think
>> > > it would be great to do this in the same patch/patchset.
>> > > 
>> >  I planned to do this in the future patches after this main
>> >  changes will be accepted. Actually adding this option to other
>> >  tools is trivial.
>> > 
>> >  Anyway may be I will re-send v5 with supporting of these tools if I will have time.
>> > 
>> >  Regards,
>> 
>> BTW, some tools already have '-n' option, so I think only '-net' can be
>> used in such cases.


Yep, that is my point. I would like to have the same option for all.

>> 
>> Regards,
>
>OK, I am going to split changes into series of patches and bring new
>option to : ip, tc, and bridge tools.
>Regarding other misc tools - will do it later as I am  not very familiar with them.
>Are you OK with this Jiri ?

Yep. Thank you!

>
>Regards,

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH iproute2 v4] ip: Simplify executing ip cmd within network ns
  2014-12-13 15:20         ` Jiri Pirko
@ 2014-12-15 17:30           ` Nicolas Dichtel
  0 siblings, 0 replies; 7+ messages in thread
From: Nicolas Dichtel @ 2014-12-15 17:30 UTC (permalink / raw)
  To: Jiri Pirko, vadim4j; +Cc: netdev

Le 13/12/2014 16:20, Jiri Pirko a écrit :
> Sat, Dec 13, 2014 at 02:32:10PM CET, vadim4j@gmail.com wrote:
>> On Sat, Dec 13, 2014 at 10:58:03AM +0200, vadim4j@gmail.com wrote:
>>> On Sat, Dec 13, 2014 at 10:42:43AM +0200, vadim4j@gmail.com wrote:
>>>> On Sat, Dec 13, 2014 at 09:29:36AM +0100, Jiri Pirko wrote:
>>>>> Fri, Dec 12, 2014 at 11:15:07PM CET, vadim4j@gmail.com wrote:
>>>>>> From: Vadim Kochan <vadim4j@gmail.com>
>>>>>>
>>>>>> Added new '-netns' option to simplify executing following cmd:
>>>>>>
>>>>>>     ip netns exec NETNS ip OPTIONS COMMAND OBJECT
>>>>>>
>>>>>>     to
>>>>>>
>>>>>>     ip -n[etns] NETNS OPTIONS COMMAND OBJECT
>>>>>>
>>>>>> e.g.:
>>>>>>
>>>>>>     ip -net vnet0 link add br0 type bridge
>>>>>>     ip -n vnet0 link
>>>>>>
>>>>>> Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
>>>>>
>>>>>
>>>>> This looks good. I'm still missing support in tc, bridge, etc. I think
>>>>> it would be great to do this in the same patch/patchset.
>>>>>
>>>>   I planned to do this in the future patches after this main
>>>>   changes will be accepted. Actually adding this option to other
>>>>   tools is trivial.
>>>>
>>>>   Anyway may be I will re-send v5 with supporting of these tools if I will have time.
>>>>
>>>>   Regards,
>>>
>>> BTW, some tools already have '-n' option, so I think only '-net' can be
>>> used in such cases.
>
>
> Yep, that is my point. I would like to have the same option for all.
Agreed. The real option name is '-netns'. The fact that '-n' will work comes
from how 'ip' is implemented. This kind of shortcut will depend on each tool
implementation. But again, the *real* option name is '-netns' ;-)


Regards,
Nicolas

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-12-15 17:30 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-12 22:15 [PATCH iproute2 v4] ip: Simplify executing ip cmd within network ns Vadim Kochan
2014-12-13  8:29 ` Jiri Pirko
2014-12-13  8:42   ` vadim4j
2014-12-13  8:58     ` vadim4j
2014-12-13 13:32       ` vadim4j
2014-12-13 15:20         ` Jiri Pirko
2014-12-15 17:30           ` Nicolas Dichtel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).