now "net -n pid|task" should show list of network devices in specifed network namespace Signed-off-by: Vasily Averin <vvs@xxxxxxxxxx> --- 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 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility