now "net -n pid|task" should show list of network devices in specifed network
namespace
Signed-off-by: Vasily Averin <vvs(a)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