[Devel] [patch crash v2 2/2] namespace support for net command

Vasily Averin vvs at parallels.com
Thu Dec 4 05:08:18 PST 2014


net without arguments shows network devices in init_net
net -n  --  in network namespace of current task
net -n pid|taskp -- in network namespace of specified task

Signed-off-by: Vasily Averin <vvs at openvz.org>
---
 defs.h    |  1 +
 help.c    | 10 +++++++++-
 net.c     | 56 +++++++++++++++++++++++++++++++++++++++++---------------
 symbols.c |  2 ++
 4 files changed, 53 insertions(+), 16 deletions(-)

diff --git a/defs.h b/defs.h
index dc2d65a..d51936f 100644
--- a/defs.h
+++ b/defs.h
@@ -1923,6 +1923,7 @@ struct offset_table {                    /* stash of commonly-used offsets */
 	long kernfs_node_parent;
 	long kmem_cache_cpu_partial;
 	long kmem_cache_cpu_cache;
+	long nsproxy_net_ns;
 };
 
 struct size_table {         /* stash of commonly-used sizes */
diff --git a/help.c b/help.c
index 780966b..4f98aa5 100644
--- a/help.c
+++ b/help.c
@@ -6452,7 +6452,7 @@ NULL
 char *help_net[] = {
 "net",
 "network command",
-"[-a] [[-s | -S [-xd]] [-R ref] [pid | taskp]] [-N addr]",
+"[-a] [[-s | -S [-xd]] [-R ref] [-n] [pid | taskp]] [-N addr]",
 "  Display various network related data:\n",
 "      -a  display the ARP cache.",
 "      -s  display open network socket/sock addresses, their family and type,",
@@ -6465,6 +6465,9 @@ char *help_net[] = {
 "  -N addr translates an IPv4 address expressed as a decimal or hexadecimal",
 "          value into a standard numbers-and-dots notation.",
 "  -R ref  socket or sock address, or file descriptor.",
+"  For kernels supporting namespaces, the -n option may be used to",
+"  display the network devices with respect to the network namespace"
+"  of a current task or a task specified by pid or taskp:\n",
 "     pid  a process PID.",
 "   taskp  a hexadecimal task_struct pointer.\n",
 "  If no arguments are entered, the list of network devices, names and IP",
@@ -6479,6 +6482,11 @@ char *help_net[] = {
 "    c0249f20  lo     127.0.0.1",
 "    c7fe6d80  eth0   10.1.8.20", 
 " ",
+"\n    %s> net -n 2618",
+"   NET_DEVICE     NAME   IP ADDRESS(ES)",
+"   ffff880456ee7020  lo     127.0.0.1",
+"   ffff8804516a1020  eth0   10.1.9.223",
+" ",
 "  Dump the ARP cache:\n",
 "    %s> net -a",
 "    NEIGHBOUR      IP ADDRESS     HW TYPE   HW ADDRESS         DEVICE  STATE",
diff --git a/net.c b/net.c
index cdd424c..dd1c7c2 100644
--- a/net.c
+++ b/net.c
@@ -64,9 +64,9 @@ struct devinfo {
 /* bytes needed for <ip address>:<port> notation */
 #define BYTES_IP_TUPLE	(BYTES_IP_ADDR + BYTES_PORT_NUM + 1)
 
-static void show_net_devices(void);
-static void show_net_devices_v2(void);
-static void show_net_devices_v3(void);
+static void show_net_devices(ulong);
+static void show_net_devices_v2(ulong);
+static void show_net_devices_v3(ulong);
 static void print_neighbour_q(ulong, int);
 static void get_netdev_info(ulong, struct devinfo *);
 static void get_device_name(ulong, char *);
@@ -137,6 +137,8 @@ net_init(void)
 			error(WARNING, 
 				"net_init: unknown device type for net device");
 	}
+	if (VALID_MEMBER(task_struct_nsproxy))
+		MEMBER_OFFSET_INIT(nsproxy_net_ns, "nsproxy", "net_ns");
 
 	if (net->flags & NETDEV_INIT) {
 		MK_TYPE_T(net->dev_name_t, net->netdevice, "name");
@@ -304,7 +306,7 @@ net_init(void)
  * The net command...
  */
 
-#define NETOPTS	  "N:asSR:xd"
+#define NETOPTS	  "N:asSR:xdn"
 #define s_FLAG FOREACH_s_FLAG
 #define S_FLAG FOREACH_S_FLAG
 #define x_FLAG FOREACH_x_FLAG
@@ -324,8 +326,10 @@ void
 cmd_net(void)
 {
 	int c;
-	ulong sflag;
+	ulong sflag, nflag;
 	ulong value;
+	ulong task;
+	struct task_context *tc = NULL;
 	struct in_addr in_addr;
 	struct reference reference, *ref;
 
@@ -333,7 +337,8 @@ cmd_net(void)
 		error(FATAL, "net subsystem not initialized!");
 
 	ref = NULL;
-	sflag = 0;
+	sflag = nflag = 0;
+	task = pid_to_task(0);
 
 	while ((c = getopt(argcnt, args, NETOPTS)) != EOF) {
 		switch (c) {
@@ -387,6 +392,19 @@ cmd_net(void)
 			sflag |= d_FLAG;
 			break;
 
+		case 'n':
+			nflag = 1;
+			task = CURRENT_TASK();
+			if (args[optind]) {
+				switch (str_to_context(args[optind],
+					 &value, &tc)) {
+				case STR_PID:
+				case STR_TASK:
+					task = tc->task;
+				}
+			}
+			break;
+
 		default:
 			argerrs++;
 			break;
@@ -399,8 +417,8 @@ cmd_net(void)
 	if (sflag)
 		dump_sockets(sflag, ref);
 
-	if (argcnt == 1)
-		show_net_devices();
+	if ((argcnt == 1) || nflag)
+		show_net_devices(task);
 }
 
 /*
@@ -408,17 +426,17 @@ cmd_net(void)
  */
 
 static void
-show_net_devices(void)
+show_net_devices(ulong task)
 {
 	ulong next;
 	long flen;
 	char buf[BUFSIZE];
 
 	if (symbol_exists("dev_base_head")) {
-		show_net_devices_v2();
+		show_net_devices_v2(task);
 		return;
 	} else if (symbol_exists("init_net")) {
-		show_net_devices_v3();
+		show_net_devices_v3(task);
 		return;
 	}
 
@@ -452,7 +470,7 @@ show_net_devices(void)
 }
 
 static void
-show_net_devices_v2(void)
+show_net_devices_v2(ulong task)
 {
 	struct list_data list_data, *ld;
 	char *net_device_buf;
@@ -501,8 +519,9 @@ show_net_devices_v2(void)
 }
 
 static void
-show_net_devices_v3(void)
+show_net_devices_v3(ulong task)
 {
+	ulong nsproxy_p, net_ns_p;
 	struct list_data list_data, *ld;
 	char *net_device_buf;
 	char buf[BUFSIZE];
@@ -523,8 +542,15 @@ show_net_devices_v3(void)
 	ld =  &list_data;
 	BZERO(ld, sizeof(struct list_data));
 	ld->flags |= LIST_ALLOCATE;
-	ld->start = ld->end =
-		 symbol_value("init_net") + OFFSET(net_dev_base_head);
+	if (VALID_MEMBER(task_struct_nsproxy)) {
+		readmem(task + OFFSET(task_struct_nsproxy), KVADDR, &nsproxy_p,
+			sizeof(ulong), "task_struct.nsproxy", FAULT_ON_ERROR);
+		if (!readmem(nsproxy_p + OFFSET(nsproxy_net_ns), KVADDR, &net_ns_p,
+			sizeof(ulong), "nsproxy.net_ns", RETURN_ON_ERROR|QUIET))
+			error(FATAL, "cannot determine net_namespace location!\n");
+	} else
+		net_ns_p = symbol_value("init_net");
+	ld->start = ld->end = net_ns_p + OFFSET(net_dev_base_head);
 	ld->list_head_offset = OFFSET(net_device_dev_list);
 
 	ndevcnt = do_list(ld);
diff --git a/symbols.c b/symbols.c
index cebff52..cb642f6 100644
--- a/symbols.c
+++ b/symbols.c
@@ -9295,6 +9295,8 @@ dump_offset_table(char *spec, ulong makestruct)
 		OFFSET(kern_ipc_perm_seq));
 	fprintf(fp, "                nsproxy_ipc_ns: %ld\n",
 		OFFSET(nsproxy_ipc_ns));
+	fprintf(fp, "                nsproxy_net_ns: %ld\n",
+		OFFSET(nsproxy_net_ns));
 	fprintf(fp, "      shmem_inode_info_swapped: %ld\n",
 		OFFSET(shmem_inode_info_swapped));
 	fprintf(fp, "    shmem_inode_info_vfs_inode: %ld\n",
-- 
1.9.1




More information about the Devel mailing list