pid->real_pid to fetch netns across vserver contexts
[linux-2.6.git] / linux-2.6-594-new_ns_pid.patch
1 diff -Nurb linux-2.6.22-592/net/core/net-sysfs.c linux-2.6.22-594/net/core/net-sysfs.c
2 --- linux-2.6.22-592/net/core/net-sysfs.c       2008-02-29 08:45:15.000000000 -0500
3 +++ linux-2.6.22-594/net/core/net-sysfs.c       2008-02-29 08:55:47.000000000 -0500
4 @@ -190,6 +190,40 @@
5         return netdev_store(device, attr, buf, len, change_mtu);
6  }
7  
8 +static ssize_t show_new_ns_pid(struct class_device *cd, char *buf)
9 +{
10 +       return -EPERM;
11 +}
12 +static int change_new_ns_pid(struct net_device *dev, unsigned long new_ns_pid)
13 +{
14 +       struct task_struct *tsk;
15 +       int err;
16 +       struct net *net;
17 +       /* Look up the network namespace */
18 +       err = -ESRCH;
19 +       rcu_read_lock();
20 +       tsk = find_task_by_real_pid(new_ns_pid);
21 +       if (tsk) {
22 +               task_lock(tsk);
23 +               if (tsk->nsproxy) {
24 +                       err = 0;
25 +                       net = get_net(tsk->nsproxy->net_ns);
26 +               }
27 +               task_unlock(tsk);
28 +       }
29 +       rcu_read_unlock();
30 +       /* If I found a network namespace move the device */
31 +       if (!err) {
32 +               err = dev_change_net_namespace(dev, net, NULL);
33 +               put_net(net);
34 +       }
35 +       return err;
36 +}
37 +static ssize_t store_new_ns_pid(struct class_device *cd, const char *buf, size_t len)
38 +{
39 +       return netdev_store(cd, buf, len, change_new_ns_pid);
40 +}
41 +
42  NETDEVICE_SHOW(flags, fmt_hex);
43  
44  static int change_flags(struct net_device *dev, unsigned long new_flags)
45 @@ -249,6 +283,7 @@
46         __ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len,
47                store_tx_queue_len),
48         __ATTR(weight, S_IRUGO | S_IWUSR, show_weight, store_weight),
49 +       __ATTR(new_ns_pid, S_IWUSR, show_new_ns_pid, store_new_ns_pid),
50         {}
51  };
52