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

Vasily Averin vvs at parallels.com
Wed Dec 3 06:16:15 PST 2014


now "net -n pid|task" should show list of network devices in specifed network namespace

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

diff --git a/defs.h b/defs.h
index dc2d65a..350dcf5 100644
--- a/defs.h
+++ b/defs.h
@@ -1824,6 +1824,7 @@ struct offset_table {                    /* stash of commonly-used offsets */
 	long kern_ipc_perm_id;
 	long kern_ipc_perm_seq;
 	long nsproxy_ipc_ns;
+	long nsproxy_net_ns;
 	long shmem_inode_info_swapped;
 	long shmem_inode_info_vfs_inode;
 	long shm_file_data_file;
diff --git a/help.c b/help.c
index 780966b..0ba666b 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 namespace of a",
+"  specified task:\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",
diff --git a/net.c b/net.c
index cdd424c..642ac20 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 *);
@@ -304,7 +304,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
@@ -326,6 +326,8 @@ cmd_net(void)
 	int c;
 	ulong sflag;
 	ulong value;
+	ulong task;
+	struct task_context *tc = NULL;
 	struct in_addr in_addr;
 	struct reference reference, *ref;
 
@@ -387,6 +389,18 @@ cmd_net(void)
 			sflag |= d_FLAG;
 			break;
 
+		case 'n':
+			switch (str_to_context(optarg, &value, &tc)) {
+			case STR_PID:
+			case STR_TASK:
+				break;
+			case STR_INVALID:
+				error(FATAL, "invalid task or pid value: %s\n",
+					optarg);
+				break;
+			}
+			break;
+
 		default:
 			argerrs++;
 			break;
@@ -399,8 +413,9 @@ cmd_net(void)
 	if (sflag)
 		dump_sockets(sflag, ref);
 
-	if (argcnt == 1)
-		show_net_devices();
+	task = tc ? tc->task : pid_to_task(0);
+	if ((argcnt == 1) || tc )
+		show_net_devices(task);
 }
 
 /*
@@ -408,17 +423,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 +467,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,7 +516,7 @@ show_net_devices_v2(void)
 }
 
 static void
-show_net_devices_v3(void)
+show_net_devices_v3(ulong task)
 {
 	struct list_data list_data, *ld;
 	char *net_device_buf;
@@ -523,8 +538,13 @@ 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);
+	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");
+
+	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