5e852a0e21dfc5990d379f93b05b71cbafad8c56
[linux-2.6.git] / trellis-netns.patch
1 diff -Nurb linux-2.6.22-try2/arch/ia64/hp/sim/simeth.c linux-2.6.22-try2-netns/arch/ia64/hp/sim/simeth.c
2 --- linux-2.6.22-try2/arch/ia64/hp/sim/simeth.c 2007-12-19 13:37:12.000000000 -0500
3 +++ linux-2.6.22-try2-netns/arch/ia64/hp/sim/simeth.c   2007-12-19 22:49:13.000000000 -0500
4 @@ -300,6 +300,9 @@
5                 return NOTIFY_DONE;
6         }
7  
8 +       if (dev->nd_net != &init_net)
9 +               return NOTIFY_DONE;
10 +
11         if ( event != NETDEV_UP && event != NETDEV_DOWN ) return NOTIFY_DONE;
12  
13         /*
14 diff -Nurb linux-2.6.22-try2/arch/s390/appldata/appldata_net_sum.c linux-2.6.22-try2-netns/arch/s390/appldata/appldata_net_sum.c
15 --- linux-2.6.22-try2/arch/s390/appldata/appldata_net_sum.c     2007-12-19 13:37:20.000000000 -0500
16 +++ linux-2.6.22-try2-netns/arch/s390/appldata/appldata_net_sum.c       2007-12-19 22:49:13.000000000 -0500
17 @@ -16,6 +16,7 @@
18  #include <linux/errno.h>
19  #include <linux/kernel_stat.h>
20  #include <linux/netdevice.h>
21 +#include <net/net_namespace.h>
22  
23  #include "appldata.h"
24  
25 @@ -107,7 +108,7 @@
26         tx_dropped = 0;
27         collisions = 0;
28         read_lock(&dev_base_lock);
29 -       for_each_netdev(dev) {
30 +       for_each_netdev(&init_net, dev) {
31                 stats = dev->get_stats(dev);
32                 rx_packets += stats->rx_packets;
33                 tx_packets += stats->tx_packets;
34 diff -Nurb linux-2.6.22-try2/arch/sparc64/solaris/ioctl.c linux-2.6.22-try2-netns/arch/sparc64/solaris/ioctl.c
35 --- linux-2.6.22-try2/arch/sparc64/solaris/ioctl.c      2007-12-19 13:37:22.000000000 -0500
36 +++ linux-2.6.22-try2-netns/arch/sparc64/solaris/ioctl.c        2007-12-19 22:49:13.000000000 -0500
37 @@ -28,6 +28,7 @@
38  #include <linux/compat.h>
39  
40  #include <net/sock.h>
41 +#include <net/net_namespace.h>
42  
43  #include <asm/uaccess.h>
44  #include <asm/termios.h>
45 @@ -686,7 +687,7 @@
46                         int i = 0;
47                         
48                         read_lock_bh(&dev_base_lock);
49 -                       for_each_netdev(d)
50 +                       for_each_netdev(&init_net, d)
51                                 i++;
52                         read_unlock_bh(&dev_base_lock);
53  
54 diff -Nurb linux-2.6.22-try2/drivers/atm/idt77252.c linux-2.6.22-try2-netns/drivers/atm/idt77252.c
55 --- linux-2.6.22-try2/drivers/atm/idt77252.c    2007-12-19 13:37:27.000000000 -0500
56 +++ linux-2.6.22-try2-netns/drivers/atm/idt77252.c      2007-12-19 22:49:13.000000000 -0500
57 @@ -3576,7 +3576,7 @@
58          * XXX: <hack>
59          */
60         sprintf(tname, "eth%d", card->index);
61 -       tmp = dev_get_by_name(tname);   /* jhs: was "tmp = dev_get(tname);" */
62 +       tmp = dev_get_by_name(&init_net, tname);        /* jhs: was "tmp = dev_get(tname);" */
63         if (tmp) {
64                 memcpy(card->atmdev->esi, tmp->dev_addr, 6);
65  
66 diff -Nurb linux-2.6.22-try2/drivers/base/class.c linux-2.6.22-try2-netns/drivers/base/class.c
67 --- linux-2.6.22-try2/drivers/base/class.c      2007-12-19 15:29:22.000000000 -0500
68 +++ linux-2.6.22-try2-netns/drivers/base/class.c        2007-12-19 22:49:13.000000000 -0500
69 @@ -134,6 +134,17 @@
70         }
71  }
72  
73 +static int class_setup_shadowing(struct class *cls)
74 +{
75 +       const struct shadow_dir_operations *shadow_ops;
76 +
77 +       shadow_ops = cls->shadow_ops;
78 +       if (!shadow_ops)
79 +               return 0;
80 +
81 +       return sysfs_enable_shadowing(&cls->subsys.kobj, shadow_ops);
82 +}
83 +
84  int class_register(struct class * cls)
85  {
86         int error;
87 @@ -152,11 +163,22 @@
88         subsys_set_kset(cls, class_subsys);
89  
90         error = subsystem_register(&cls->subsys);
91 -       if (!error) {
92 -               error = add_class_attrs(class_get(cls));
93 -               class_put(cls);
94 -       }
95 +       if (error)
96 +               goto out;
97 +
98 +       error = class_setup_shadowing(cls);
99 +       if (error)
100 +               goto out_unregister;
101 +
102 +       error = add_class_attrs(cls);
103 +       if (error)
104 +               goto out_unregister;
105 +
106 +out:
107         return error;
108 +out_unregister:
109 +       subsystem_unregister(&cls->subsys);
110 +       goto out;
111  }
112  
113  void class_unregister(struct class * cls)
114 diff -Nurb linux-2.6.22-try2/drivers/base/core.c linux-2.6.22-try2-netns/drivers/base/core.c
115 --- linux-2.6.22-try2/drivers/base/core.c       2007-12-19 15:29:23.000000000 -0500
116 +++ linux-2.6.22-try2-netns/drivers/base/core.c 2007-12-19 22:49:13.000000000 -0500
117 @@ -622,8 +622,14 @@
118                         return kobj;
119  
120                 /* or create a new class-directory at the parent device */
121 -               return kobject_kset_add_dir(&dev->class->class_dirs,
122 +               kobj = kobject_kset_add_dir(&dev->class->class_dirs,
123                                             parent_kobj, dev->class->name);
124 +
125 +               /* If we created a new class-directory setup shadowing */
126 +               if (kobj && dev->class->shadow_ops)
127 +                       sysfs_enable_shadowing(kobj, dev->class->shadow_ops);
128 +
129 +               return kobj;
130         }
131  
132         if (parent)
133 @@ -913,8 +919,8 @@
134                 /* If this is not a "fake" compatible device, remove the
135                  * symlink from the class to the device. */
136                 if (dev->kobj.parent != &dev->class->subsys.kobj)
137 -                       sysfs_remove_link(&dev->class->subsys.kobj,
138 -                                         dev->bus_id);
139 +                       sysfs_delete_link(&dev->class->subsys.kobj,
140 +                                         &dev->kobj, dev->bus_id);
141                 if (parent) {
142  #ifdef CONFIG_SYSFS_DEPRECATED
143                         char *class_name = make_class_name(dev->class->name,
144 @@ -1212,6 +1218,13 @@
145         strlcpy(old_device_name, dev->bus_id, BUS_ID_SIZE);
146         strlcpy(dev->bus_id, new_name, BUS_ID_SIZE);
147  
148 +       if (dev->class && (dev->kobj.parent != &dev->class->subsys.kobj)) {
149 +               error = sysfs_rename_link(&dev->class->subsys.kobj,
150 +                       &dev->kobj, old_device_name, new_name);
151 +               if (error)
152 +                       goto out;
153 +       }
154 +
155         error = kobject_rename(&dev->kobj, new_name);
156         if (error) {
157                 strlcpy(dev->bus_id, old_device_name, BUS_ID_SIZE);
158 @@ -1220,27 +1233,17 @@
159  
160  #ifdef CONFIG_SYSFS_DEPRECATED
161         if (old_class_name) {
162 +               error = -ENOMEM;
163                 new_class_name = make_class_name(dev->class->name, &dev->kobj);
164 -               if (new_class_name) {
165 -                       error = sysfs_create_link(&dev->parent->kobj,
166 -                                                 &dev->kobj, new_class_name);
167 +               if (!new_class_name)
168 +                       goto out;
169 +
170 +               error = sysfs_rename_link(&dev->parent->kobj, &dev->kobj,
171 +                                         old_class_name, new_class_name);
172                         if (error)
173                                 goto out;
174 -                       sysfs_remove_link(&dev->parent->kobj, old_class_name);
175 -               }
176         }
177  #endif
178 -
179 -       if (dev->class) {
180 -               sysfs_remove_link(&dev->class->subsys.kobj, old_device_name);
181 -               error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
182 -                                         dev->bus_id);
183 -               if (error) {
184 -                       /* Uh... how to unravel this if restoring can fail? */
185 -                       dev_err(dev, "%s: sysfs_create_symlink failed (%d)\n",
186 -                               __FUNCTION__, error);
187 -               }
188 -       }
189  out:
190         put_device(dev);
191  
192 diff -Nurb linux-2.6.22-try2/drivers/block/aoe/aoecmd.c linux-2.6.22-try2-netns/drivers/block/aoe/aoecmd.c
193 --- linux-2.6.22-try2/drivers/block/aoe/aoecmd.c        2007-12-19 13:37:27.000000000 -0500
194 +++ linux-2.6.22-try2-netns/drivers/block/aoe/aoecmd.c  2007-12-19 22:49:13.000000000 -0500
195 @@ -9,6 +9,7 @@
196  #include <linux/skbuff.h>
197  #include <linux/netdevice.h>
198  #include <linux/genhd.h>
199 +#include <net/net_namespace.h>
200  #include <asm/unaligned.h>
201  #include "aoe.h"
202  
203 @@ -194,7 +195,7 @@
204         sl = sl_tail = NULL;
205  
206         read_lock(&dev_base_lock);
207 -       for_each_netdev(ifp) {
208 +       for_each_netdev(&init_net, ifp) {
209                 dev_hold(ifp);
210                 if (!is_aoe_netif(ifp))
211                         goto cont;
212 diff -Nurb linux-2.6.22-try2/drivers/block/aoe/aoenet.c linux-2.6.22-try2-netns/drivers/block/aoe/aoenet.c
213 --- linux-2.6.22-try2/drivers/block/aoe/aoenet.c        2007-12-19 13:37:27.000000000 -0500
214 +++ linux-2.6.22-try2-netns/drivers/block/aoe/aoenet.c  2007-12-19 22:49:13.000000000 -0500
215 @@ -8,6 +8,7 @@
216  #include <linux/blkdev.h>
217  #include <linux/netdevice.h>
218  #include <linux/moduleparam.h>
219 +#include <net/net_namespace.h>
220  #include <asm/unaligned.h>
221  #include "aoe.h"
222  
223 @@ -114,6 +115,9 @@
224         struct aoe_hdr *h;
225         u32 n;
226  
227 +       if (ifp->nd_net != &init_net)
228 +               goto exit;
229 +
230         skb = skb_share_check(skb, GFP_ATOMIC);
231         if (skb == NULL)
232                 return 0;
233 diff -Nurb linux-2.6.22-try2/drivers/connector/connector.c linux-2.6.22-try2-netns/drivers/connector/connector.c
234 --- linux-2.6.22-try2/drivers/connector/connector.c     2007-12-19 13:37:28.000000000 -0500
235 +++ linux-2.6.22-try2-netns/drivers/connector/connector.c       2007-12-19 22:49:13.000000000 -0500
236 @@ -446,7 +446,7 @@
237         dev->id.idx = cn_idx;
238         dev->id.val = cn_val;
239  
240 -       dev->nls = netlink_kernel_create(NETLINK_CONNECTOR,
241 +       dev->nls = netlink_kernel_create(&init_net, NETLINK_CONNECTOR,
242                                          CN_NETLINK_USERS + 0xf,
243                                          dev->input, NULL, THIS_MODULE);
244         if (!dev->nls)
245 diff -Nurb linux-2.6.22-try2/drivers/infiniband/core/addr.c linux-2.6.22-try2-netns/drivers/infiniband/core/addr.c
246 --- linux-2.6.22-try2/drivers/infiniband/core/addr.c    2007-12-19 13:37:29.000000000 -0500
247 +++ linux-2.6.22-try2-netns/drivers/infiniband/core/addr.c      2007-12-19 22:49:13.000000000 -0500
248 @@ -110,7 +110,7 @@
249         __be32 ip = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
250         int ret;
251  
252 -       dev = ip_dev_find(ip);
253 +       dev = ip_dev_find(&init_net, ip);
254         if (!dev)
255                 return -EADDRNOTAVAIL;
256  
257 @@ -157,6 +157,7 @@
258         u32 dst_ip = dst_in->sin_addr.s_addr;
259  
260         memset(&fl, 0, sizeof fl);
261 +       fl.fl_net = &init_net;
262         fl.nl_u.ip4_u.daddr = dst_ip;
263         if (ip_route_output_key(&rt, &fl))
264                 return;
265 @@ -178,6 +179,7 @@
266         int ret;
267  
268         memset(&fl, 0, sizeof fl);
269 +       fl.fl_net = &init_net;
270         fl.nl_u.ip4_u.daddr = dst_ip;
271         fl.nl_u.ip4_u.saddr = src_ip;
272         ret = ip_route_output_key(&rt, &fl);
273 @@ -262,7 +264,7 @@
274         __be32 dst_ip = dst_in->sin_addr.s_addr;
275         int ret;
276  
277 -       dev = ip_dev_find(dst_ip);
278 +       dev = ip_dev_find(&init_net, dst_ip);
279         if (!dev)
280                 return -EADDRNOTAVAIL;
281  
282 diff -Nurb linux-2.6.22-try2/drivers/infiniband/core/cma.c linux-2.6.22-try2-netns/drivers/infiniband/core/cma.c
283 --- linux-2.6.22-try2/drivers/infiniband/core/cma.c     2007-12-19 13:37:29.000000000 -0500
284 +++ linux-2.6.22-try2-netns/drivers/infiniband/core/cma.c       2007-12-19 22:49:13.000000000 -0500
285 @@ -1267,7 +1267,7 @@
286         atomic_inc(&conn_id->dev_remove);
287         conn_id->state = CMA_CONNECT;
288  
289 -       dev = ip_dev_find(iw_event->local_addr.sin_addr.s_addr);
290 +       dev = ip_dev_find(&init_net, iw_event->local_addr.sin_addr.s_addr);
291         if (!dev) {
292                 ret = -EADDRNOTAVAIL;
293                 cma_enable_remove(conn_id);
294 @@ -1880,18 +1880,18 @@
295         if (ret)
296                 goto err1;
297  
298 -       if (port > sysctl_local_port_range[1]) {
299 -               if (next_port != sysctl_local_port_range[0]) {
300 +       if (port > init_net.sysctl_local_port_range[1]) {
301 +               if (next_port != init_net.sysctl_local_port_range[0]) {
302                         idr_remove(ps, port);
303 -                       next_port = sysctl_local_port_range[0];
304 +                       next_port = init_net.sysctl_local_port_range[0];
305                         goto retry;
306                 }
307                 ret = -EADDRNOTAVAIL;
308                 goto err2;
309         }
310  
311 -       if (port == sysctl_local_port_range[1])
312 -               next_port = sysctl_local_port_range[0];
313 +       if (port == init_net.sysctl_local_port_range[1])
314 +               next_port = init_net.sysctl_local_port_range[0];
315         else
316                 next_port = port + 1;
317  
318 @@ -2774,8 +2774,9 @@
319  
320         get_random_bytes(&next_port, sizeof next_port);
321         next_port = ((unsigned int) next_port %
322 -                   (sysctl_local_port_range[1] - sysctl_local_port_range[0])) +
323 -                   sysctl_local_port_range[0];
324 +                    (init_net.sysctl_local_port_range[1] - 
325 +                     init_net.sysctl_local_port_range[0])) +
326 +                   init_net.sysctl_local_port_range[0];
327         cma_wq = create_singlethread_workqueue("rdma_cm");
328         if (!cma_wq)
329                 return -ENOMEM;
330 diff -Nurb linux-2.6.22-try2/drivers/isdn/divert/divert_procfs.c linux-2.6.22-try2-netns/drivers/isdn/divert/divert_procfs.c
331 --- linux-2.6.22-try2/drivers/isdn/divert/divert_procfs.c       2007-12-19 13:37:29.000000000 -0500
332 +++ linux-2.6.22-try2-netns/drivers/isdn/divert/divert_procfs.c 2007-12-19 22:49:13.000000000 -0500
333 @@ -17,6 +17,7 @@
334  #include <linux/fs.h>
335  #endif
336  #include <linux/isdnif.h>
337 +#include <net/net_namespace.h>
338  #include "isdn_divert.h"
339  
340  
341 @@ -284,12 +285,12 @@
342         init_waitqueue_head(&rd_queue);
343  
344  #ifdef CONFIG_PROC_FS
345 -       isdn_proc_entry = proc_mkdir("net/isdn", NULL);
346 +       isdn_proc_entry = proc_mkdir("isdn", init_net.proc_net);
347         if (!isdn_proc_entry)
348                 return (-1);
349         isdn_divert_entry = create_proc_entry("divert", S_IFREG | S_IRUGO, isdn_proc_entry);
350         if (!isdn_divert_entry) {
351 -               remove_proc_entry("net/isdn", NULL);
352 +               remove_proc_entry("isdn", init_net.proc_net);
353                 return (-1);
354         }
355         isdn_divert_entry->proc_fops = &isdn_fops; 
356 @@ -309,7 +310,7 @@
357  
358  #ifdef CONFIG_PROC_FS
359         remove_proc_entry("divert", isdn_proc_entry);
360 -       remove_proc_entry("net/isdn", NULL);
361 +       remove_proc_entry("isdn", init_net.proc_net);
362  #endif /* CONFIG_PROC_FS */
363  
364         return (0);
365 diff -Nurb linux-2.6.22-try2/drivers/isdn/hardware/eicon/diva_didd.c linux-2.6.22-try2-netns/drivers/isdn/hardware/eicon/diva_didd.c
366 --- linux-2.6.22-try2/drivers/isdn/hardware/eicon/diva_didd.c   2007-12-19 13:37:29.000000000 -0500
367 +++ linux-2.6.22-try2-netns/drivers/isdn/hardware/eicon/diva_didd.c     2007-12-19 22:49:13.000000000 -0500
368 @@ -15,6 +15,7 @@
369  #include <linux/init.h>
370  #include <linux/kernel.h>
371  #include <linux/proc_fs.h>
372 +#include <net/net_namespace.h>
373  
374  #include "platform.h"
375  #include "di_defs.h"
376 @@ -86,7 +87,7 @@
377  
378  static int DIVA_INIT_FUNCTION create_proc(void)
379  {
380 -       proc_net_eicon = proc_mkdir("net/eicon", NULL);
381 +       proc_net_eicon = proc_mkdir("eicon", init_net.proc_net);
382  
383         if (proc_net_eicon) {
384                 if ((proc_didd =
385 @@ -102,7 +103,7 @@
386  static void remove_proc(void)
387  {
388         remove_proc_entry(DRIVERLNAME, proc_net_eicon);
389 -       remove_proc_entry("net/eicon", NULL);
390 +       remove_proc_entry("eicon", init_net.proc_net);
391  }
392  
393  static int DIVA_INIT_FUNCTION divadidd_init(void)
394 diff -Nurb linux-2.6.22-try2/drivers/isdn/hysdn/hysdn_procconf.c linux-2.6.22-try2-netns/drivers/isdn/hysdn/hysdn_procconf.c
395 --- linux-2.6.22-try2/drivers/isdn/hysdn/hysdn_procconf.c       2007-12-19 13:37:29.000000000 -0500
396 +++ linux-2.6.22-try2-netns/drivers/isdn/hysdn/hysdn_procconf.c 2007-12-19 22:49:13.000000000 -0500
397 @@ -392,7 +392,7 @@
398         hysdn_card *card;
399         unsigned char conf_name[20];
400  
401 -       hysdn_proc_entry = proc_mkdir(PROC_SUBDIR_NAME, proc_net);
402 +       hysdn_proc_entry = proc_mkdir(PROC_SUBDIR_NAME, init_net.proc_net);
403         if (!hysdn_proc_entry) {
404                 printk(KERN_ERR "HYSDN: unable to create hysdn subdir\n");
405                 return (-1);
406 @@ -437,5 +437,5 @@
407                 card = card->next;      /* point to next card */
408         }
409  
410 -       remove_proc_entry(PROC_SUBDIR_NAME, proc_net);
411 +       remove_proc_entry(PROC_SUBDIR_NAME, init_net.proc_net);
412  }
413 diff -Nurb linux-2.6.22-try2/drivers/net/Kconfig linux-2.6.22-try2-netns/drivers/net/Kconfig
414 --- linux-2.6.22-try2/drivers/net/Kconfig       2007-12-19 15:29:23.000000000 -0500
415 +++ linux-2.6.22-try2-netns/drivers/net/Kconfig 2007-12-19 22:49:13.000000000 -0500
416 @@ -119,6 +119,20 @@
417  
418           If you don't know what to use this for, you don't need it.
419  
420 +config ETUN
421 +       tristate "Ethernet tunnel device driver support"
422 +       depends on SYSFS
423 +       ---help---
424 +         ETUN provices a pair of network devices that can be used for
425 +         configuring interesting topolgies.  What one devices transmits
426 +         the other receives and vice versa.  The link level framing
427 +         is ethernet for wide compatibility with network stacks.
428 +
429 +         To compile this driver as a module, choose M here: the module
430 +         will be called etun.
431 +
432 +         If you don't know what to use this for, you don't need it.
433 +
434  config NET_SB1000
435         tristate "General Instruments Surfboard 1000"
436         depends on PNP
437 diff -Nurb linux-2.6.22-try2/drivers/net/Makefile linux-2.6.22-try2-netns/drivers/net/Makefile
438 --- linux-2.6.22-try2/drivers/net/Makefile      2007-12-19 15:29:24.000000000 -0500
439 +++ linux-2.6.22-try2-netns/drivers/net/Makefile        2007-12-19 22:49:13.000000000 -0500
440 @@ -186,6 +186,7 @@
441  obj-$(CONFIG_MACMACE) += macmace.o
442  obj-$(CONFIG_MAC89x0) += mac89x0.o
443  obj-$(CONFIG_TUN) += tun.o
444 +obj-$(CONFIG_ETUN) += etun.o
445  obj-$(CONFIG_NET_NETX) += netx-eth.o
446  obj-$(CONFIG_DL2K) += dl2k.o
447  obj-$(CONFIG_R8169) += r8169.o
448 diff -Nurb linux-2.6.22-try2/drivers/net/bonding/bond_3ad.c linux-2.6.22-try2-netns/drivers/net/bonding/bond_3ad.c
449 --- linux-2.6.22-try2/drivers/net/bonding/bond_3ad.c    2007-12-19 13:37:30.000000000 -0500
450 +++ linux-2.6.22-try2-netns/drivers/net/bonding/bond_3ad.c      2007-12-19 22:49:13.000000000 -0500
451 @@ -29,6 +29,7 @@
452  #include <linux/ethtool.h>
453  #include <linux/if_bonding.h>
454  #include <linux/pkt_sched.h>
455 +#include <net/net_namespace.h>
456  #include "bonding.h"
457  #include "bond_3ad.h"
458  
459 @@ -2448,6 +2449,9 @@
460         struct slave *slave = NULL;
461         int ret = NET_RX_DROP;
462  
463 +       if (dev->nd_net != &init_net)
464 +               goto out;
465 +
466         if (!(dev->flags & IFF_MASTER))
467                 goto out;
468  
469 diff -Nurb linux-2.6.22-try2/drivers/net/bonding/bond_alb.c linux-2.6.22-try2-netns/drivers/net/bonding/bond_alb.c
470 --- linux-2.6.22-try2/drivers/net/bonding/bond_alb.c    2007-12-19 13:37:30.000000000 -0500
471 +++ linux-2.6.22-try2-netns/drivers/net/bonding/bond_alb.c      2007-12-19 22:49:13.000000000 -0500
472 @@ -345,6 +345,9 @@
473         struct arp_pkt *arp = (struct arp_pkt *)skb->data;
474         int res = NET_RX_DROP;
475  
476 +       if (bond_dev->nd_net != &init_net)
477 +               goto out;
478 +
479         if (!(bond_dev->flags & IFF_MASTER))
480                 goto out;
481  
482 diff -Nurb linux-2.6.22-try2/drivers/net/bonding/bond_main.c linux-2.6.22-try2-netns/drivers/net/bonding/bond_main.c
483 --- linux-2.6.22-try2/drivers/net/bonding/bond_main.c   2007-12-19 13:37:30.000000000 -0500
484 +++ linux-2.6.22-try2-netns/drivers/net/bonding/bond_main.c     2007-12-19 22:49:13.000000000 -0500
485 @@ -75,6 +75,7 @@
486  #include <linux/if_vlan.h>
487  #include <linux/if_bonding.h>
488  #include <net/route.h>
489 +#include <net/net_namespace.h>
490  #include "bonding.h"
491  #include "bond_3ad.h"
492  #include "bond_alb.h"
493 @@ -2376,6 +2377,7 @@
494                  * can tag the ARP with the proper VLAN tag.
495                  */
496                 memset(&fl, 0, sizeof(fl));
497 +               fl.fl_net = &init_net;
498                 fl.fl4_dst = targets[i];
499                 fl.fl4_tos = RTO_ONLINK;
500  
501 @@ -2485,6 +2487,9 @@
502         unsigned char *arp_ptr;
503         u32 sip, tip;
504  
505 +       if (dev->nd_net != &init_net)
506 +               goto out;
507 +
508         if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER))
509                 goto out;
510  
511 @@ -3172,7 +3177,7 @@
512  {
513         int len = strlen(DRV_NAME);
514  
515 -       for (bond_proc_dir = proc_net->subdir; bond_proc_dir;
516 +       for (bond_proc_dir = init_net.proc_net->subdir; bond_proc_dir;
517              bond_proc_dir = bond_proc_dir->next) {
518                 if ((bond_proc_dir->namelen == len) &&
519                     !memcmp(bond_proc_dir->name, DRV_NAME, len)) {
520 @@ -3181,7 +3186,7 @@
521         }
522  
523         if (!bond_proc_dir) {
524 -               bond_proc_dir = proc_mkdir(DRV_NAME, proc_net);
525 +               bond_proc_dir = proc_mkdir(DRV_NAME, init_net.proc_net);
526                 if (bond_proc_dir) {
527                         bond_proc_dir->owner = THIS_MODULE;
528                 } else {
529 @@ -3216,7 +3221,7 @@
530                         bond_proc_dir->owner = NULL;
531                 }
532         } else {
533 -               remove_proc_entry(DRV_NAME, proc_net);
534 +               remove_proc_entry(DRV_NAME, init_net.proc_net);
535                 bond_proc_dir = NULL;
536         }
537  }
538 @@ -3323,6 +3328,9 @@
539  {
540         struct net_device *event_dev = (struct net_device *)ptr;
541  
542 +       if (event_dev->nd_net != &init_net)
543 +               return NOTIFY_DONE;
544 +
545         dprintk("event_dev: %s, event: %lx\n",
546                 (event_dev ? event_dev->name : "None"),
547                 event);
548 @@ -3740,7 +3748,7 @@
549         }
550  
551         down_write(&(bonding_rwsem));
552 -       slave_dev = dev_get_by_name(ifr->ifr_slave);
553 +       slave_dev = dev_get_by_name(&init_net, ifr->ifr_slave);
554  
555         dprintk("slave_dev=%p: \n", slave_dev);
556  
557 diff -Nurb linux-2.6.22-try2/drivers/net/bonding/bond_sysfs.c linux-2.6.22-try2-netns/drivers/net/bonding/bond_sysfs.c
558 --- linux-2.6.22-try2/drivers/net/bonding/bond_sysfs.c  2007-12-19 13:37:31.000000000 -0500
559 +++ linux-2.6.22-try2-netns/drivers/net/bonding/bond_sysfs.c    2007-12-19 22:49:13.000000000 -0500
560 @@ -35,6 +35,7 @@
561  #include <linux/ctype.h>
562  #include <linux/inet.h>
563  #include <linux/rtnetlink.h>
564 +#include <net/net_namespace.h>
565  
566  /* #define BONDING_DEBUG 1 */
567  #include "bonding.h"
568 @@ -299,7 +300,7 @@
569                 read_unlock_bh(&bond->lock);
570                 printk(KERN_INFO DRV_NAME ": %s: Adding slave %s.\n",
571                        bond->dev->name, ifname);
572 -               dev = dev_get_by_name(ifname);
573 +               dev = dev_get_by_name(&init_net, ifname);
574                 if (!dev) {
575                         printk(KERN_INFO DRV_NAME
576                                ": %s: Interface %s does not exist!\n",
577 diff -Nurb linux-2.6.22-try2/drivers/net/eql.c linux-2.6.22-try2-netns/drivers/net/eql.c
578 --- linux-2.6.22-try2/drivers/net/eql.c 2007-12-19 13:37:31.000000000 -0500
579 +++ linux-2.6.22-try2-netns/drivers/net/eql.c   2007-12-19 22:49:13.000000000 -0500
580 @@ -116,6 +116,7 @@
581  #include <linux/init.h>
582  #include <linux/timer.h>
583  #include <linux/netdevice.h>
584 +#include <net/net_namespace.h>
585  
586  #include <linux/if.h>
587  #include <linux/if_arp.h>
588 @@ -412,7 +413,7 @@
589         if (copy_from_user(&srq, srqp, sizeof (slaving_request_t)))
590                 return -EFAULT;
591  
592 -       slave_dev  = dev_get_by_name(srq.slave_name);
593 +       slave_dev  = dev_get_by_name(&init_net, srq.slave_name);
594         if (slave_dev) {
595                 if ((master_dev->flags & IFF_UP) == IFF_UP) {
596                         /* slave is not a master & not already a slave: */
597 @@ -460,7 +461,7 @@
598         if (copy_from_user(&srq, srqp, sizeof (slaving_request_t)))
599                 return -EFAULT;
600  
601 -       slave_dev = dev_get_by_name(srq.slave_name);
602 +       slave_dev = dev_get_by_name(&init_net, srq.slave_name);
603         ret = -EINVAL;
604         if (slave_dev) {
605                 spin_lock_bh(&eql->queue.lock);
606 @@ -493,7 +494,7 @@
607         if (copy_from_user(&sc, scp, sizeof (slave_config_t)))
608                 return -EFAULT;
609  
610 -       slave_dev = dev_get_by_name(sc.slave_name);
611 +       slave_dev = dev_get_by_name(&init_net, sc.slave_name);
612         if (!slave_dev)
613                 return -ENODEV;
614  
615 @@ -528,7 +529,7 @@
616         if (copy_from_user(&sc, scp, sizeof (slave_config_t)))
617                 return -EFAULT;
618  
619 -       slave_dev = dev_get_by_name(sc.slave_name);
620 +       slave_dev = dev_get_by_name(&init_net, sc.slave_name);
621         if (!slave_dev)
622                 return -ENODEV;
623  
624 diff -Nurb linux-2.6.22-try2/drivers/net/etun.c linux-2.6.22-try2-netns/drivers/net/etun.c
625 --- linux-2.6.22-try2/drivers/net/etun.c        1969-12-31 19:00:00.000000000 -0500
626 +++ linux-2.6.22-try2-netns/drivers/net/etun.c  2007-12-19 22:49:13.000000000 -0500
627 @@ -0,0 +1,489 @@
628 +/*
629 + *  ETUN - Universal ETUN device driver.
630 + *  Copyright (C) 2006 Linux Networx
631 + *
632 + */
633 +
634 +#define DRV_NAME       "etun"
635 +#define DRV_VERSION    "1.0"
636 +#define DRV_DESCRIPTION        "Ethernet pseudo tunnel device driver"
637 +#define DRV_COPYRIGHT  "(C) 2007 Linux Networx"
638 +
639 +#include <linux/module.h>
640 +#include <linux/kernel.h>
641 +#include <linux/list.h>
642 +#include <linux/spinlock.h>
643 +#include <linux/skbuff.h>
644 +#include <linux/netdevice.h>
645 +#include <linux/etherdevice.h>
646 +#include <linux/ethtool.h>
647 +#include <linux/rtnetlink.h>
648 +#include <linux/if.h>
649 +#include <linux/if_ether.h>
650 +#include <linux/ctype.h>
651 +#include <linux/nsproxy.h>
652 +#include <net/net_namespace.h>
653 +#include <net/dst.h>
654 +
655 +
656 +/* Device cheksum strategy.
657 + *
658 + * etun is designed to a be a pair of virutal devices
659 + * connecting two network stack instances.
660 + *
661 + * Typically it will either be used with ethernet bridging or
662 + * it will be used to route packets between the two stacks.
663 + *
664 + * The only checksum offloading I can do is to completely
665 + * skip the checksumming step all together.
666 + *
667 + * When used for ethernet bridging I don't believe any
668 + * checksum off loading is safe.
669 + * - If my source is an external interface the checksum may be
670 + *   invalid so I don't want to report I have already checked it.
671 + * - If my destination is an external interface I don't want to put
672 + *   a packet on the wire with someone computing the checksum.
673 + *
674 + * When used for routing between two stacks checksums should
675 + * be as unnecessary as they are on the loopback device.
676 + *
677 + * So by default I am safe and disable checksumming and
678 + * other advanced features like SG and TSO.
679 + *
680 + * However because I think these features could be useful
681 + * I provide the ethtool functions to and enable/disable
682 + * them at runtime.
683 + *
684 + * If you think you can correctly enable these go ahead.
685 + * For checksums both the transmitter and the receiver must
686 + * agree before the are actually disabled.
687 + */
688 +
689 +#define ETUN_NUM_STATS 1
690 +static struct {
691 +       const char string[ETH_GSTRING_LEN];
692 +} ethtool_stats_keys[ETUN_NUM_STATS] = {
693 +       { "partner_ifindex" },
694 +};
695 +
696 +struct etun_info {
697 +       struct net_device       *rx_dev;
698 +       unsigned                ip_summed;
699 +       struct net_device_stats stats;
700 +       struct list_head        list;
701 +       struct net_device       *dev;
702 +};
703 +
704 +/*
705 + * I have to hold the rtnl_lock during device delete.
706 + * So I use the rtnl_lock to protect my list manipulations
707 + * as well.  Crude but simple.
708 + */
709 +static LIST_HEAD(etun_list);
710 +
711 +/*
712 + * The higher levels take care of making this non-reentrant (it's
713 + * called with bh's disabled).
714 + */
715 +static int etun_xmit(struct sk_buff *skb, struct net_device *tx_dev)
716 +{
717 +       struct etun_info *tx_info = tx_dev->priv;
718 +       struct net_device *rx_dev = tx_info->rx_dev;
719 +       struct etun_info *rx_info = rx_dev->priv;
720 +
721 +       tx_info->stats.tx_packets++;
722 +       tx_info->stats.tx_bytes += skb->len;
723 +
724 +       /* Drop the skb state that was needed to get here */
725 +       skb_orphan(skb);
726 +       if (skb->dst)
727 +               skb->dst = dst_pop(skb->dst);   /* Allow for smart routing */
728 +
729 +       /* Switch to the receiving device */
730 +       skb->pkt_type = PACKET_HOST;
731 +       skb->protocol = eth_type_trans(skb, rx_dev);
732 +       skb->dev = rx_dev;
733 +       skb->ip_summed = CHECKSUM_NONE;
734 +
735 +       /* If both halves agree no checksum is needed */
736 +       if (tx_dev->features & NETIF_F_NO_CSUM)
737 +               skb->ip_summed = rx_info->ip_summed;
738 +
739 +       rx_dev->last_rx = jiffies;
740 +       rx_info->stats.rx_packets++;
741 +       rx_info->stats.rx_bytes += skb->len;
742 +       netif_rx(skb);
743 +
744 +       return 0;
745 +}
746 +
747 +static struct net_device_stats *etun_get_stats(struct net_device *dev)
748 +{
749 +       struct etun_info *info = dev->priv;
750 +       return &info->stats;
751 +}
752 +
753 +/* ethtool interface */
754 +static int etun_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
755 +{
756 +       cmd->supported          = 0;
757 +       cmd->advertising        = 0;
758 +       cmd->speed              = SPEED_10000; /* Memory is fast! */
759 +       cmd->duplex             = DUPLEX_FULL;
760 +       cmd->port               = PORT_TP;
761 +       cmd->phy_address        = 0;
762 +       cmd->transceiver        = XCVR_INTERNAL;
763 +       cmd->autoneg            = AUTONEG_DISABLE;
764 +       cmd->maxtxpkt           = 0;
765 +       cmd->maxrxpkt           = 0;
766 +       return 0;
767 +}
768 +
769 +static void etun_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
770 +{
771 +       strcpy(info->driver, DRV_NAME);
772 +       strcpy(info->version, DRV_VERSION);
773 +       strcpy(info->fw_version, "N/A");
774 +}
775 +
776 +static void etun_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
777 +{
778 +       switch(stringset) {
779 +       case ETH_SS_STATS:
780 +               memcpy(buf, &ethtool_stats_keys, sizeof(ethtool_stats_keys));
781 +               break;
782 +       case ETH_SS_TEST:
783 +       default:
784 +               break;
785 +       }
786 +}
787 +
788 +static int etun_get_stats_count(struct net_device *dev)
789 +{
790 +       return ETUN_NUM_STATS;
791 +}
792 +
793 +static void etun_get_ethtool_stats(struct net_device *dev,
794 +       struct ethtool_stats *stats, u64 *data)
795 +{
796 +       struct etun_info *info = dev->priv;
797 +
798 +       data[0] = info->rx_dev->ifindex;
799 +}
800 +
801 +static u32 etun_get_rx_csum(struct net_device *dev)
802 +{
803 +       struct etun_info *info = dev->priv;
804 +       return info->ip_summed == CHECKSUM_UNNECESSARY;
805 +}
806 +
807 +static int etun_set_rx_csum(struct net_device *dev, u32 data)
808 +{
809 +       struct etun_info *info = dev->priv;
810 +
811 +       info->ip_summed = data ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
812 +
813 +       return 0;
814 +}
815 +
816 +static u32 etun_get_tx_csum(struct net_device *dev)
817 +{
818 +       return (dev->features & NETIF_F_NO_CSUM) != 0;
819 +}
820 +
821 +static int etun_set_tx_csum(struct net_device *dev, u32 data)
822 +{
823 +       dev->features &= ~NETIF_F_NO_CSUM;
824 +       if (data)
825 +               dev->features |= NETIF_F_NO_CSUM;
826 +
827 +       return 0;
828 +}
829 +
830 +static struct ethtool_ops etun_ethtool_ops = {
831 +       .get_settings           = etun_get_settings,
832 +       .get_drvinfo            = etun_get_drvinfo,
833 +       .get_link               = ethtool_op_get_link,
834 +       .get_rx_csum            = etun_get_rx_csum,
835 +       .set_rx_csum            = etun_set_rx_csum,
836 +       .get_tx_csum            = etun_get_tx_csum,
837 +       .set_tx_csum            = etun_set_tx_csum,
838 +       .get_sg                 = ethtool_op_get_sg,
839 +       .set_sg                 = ethtool_op_set_sg,
840 +#if 0 /* Does just setting the bit successfuly emulate tso? */
841 +       .get_tso                = ethtool_op_get_tso,
842 +       .set_tso                = ethtool_op_set_tso,
843 +#endif
844 +       .get_strings            = etun_get_strings,
845 +       .get_stats_count        = etun_get_stats_count,
846 +       .get_ethtool_stats      = etun_get_ethtool_stats,
847 +       .get_perm_addr          = ethtool_op_get_perm_addr,
848 +};
849 +
850 +static int etun_open(struct net_device *tx_dev)
851 +{
852 +       struct etun_info *tx_info = tx_dev->priv;
853 +       struct net_device *rx_dev = tx_info->rx_dev;
854 +       /* If we attempt to bring up etun in the small window before
855 +        * it is connected to it's partner error.
856 +        */
857 +       if (!rx_dev)
858 +               return -ENOTCONN;
859 +       if (rx_dev->flags & IFF_UP) {
860 +               netif_carrier_on(tx_dev);
861 +               netif_carrier_on(rx_dev);
862 +       }
863 +       netif_start_queue(tx_dev);
864 +       return 0;
865 +}
866 +
867 +static int etun_stop(struct net_device *tx_dev)
868 +{
869 +       struct etun_info *tx_info = tx_dev->priv;
870 +       struct net_device *rx_dev = tx_info->rx_dev;
871 +       netif_stop_queue(tx_dev);
872 +       if (netif_carrier_ok(tx_dev)) {
873 +               netif_carrier_off(tx_dev);
874 +               netif_carrier_off(rx_dev);
875 +       }
876 +       return 0;
877 +}
878 +
879 +static int etun_change_mtu(struct net_device *dev, int new_mtu)
880 +{
881 +       /* Don't allow ridiculously small mtus */
882 +       if (new_mtu < (ETH_ZLEN - ETH_HLEN))
883 +               return -EINVAL;
884 +       dev->mtu = new_mtu;
885 +       return 0;
886 +}
887 +
888 +static void etun_set_multicast_list(struct net_device *dev)
889 +{
890 +       /* Nothing sane I can do here */
891 +       return;
892 +}
893 +
894 +static int etun_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
895 +{
896 +       return -EOPNOTSUPP;
897 +}
898 +
899 +/* Only allow letters and numbers in an etun device name */
900 +static int is_valid_name(const char *name)
901 +{
902 +       const char *ptr;
903 +       for (ptr = name; *ptr; ptr++) {
904 +               if (!isalnum(*ptr))
905 +                       return 0;
906 +       }
907 +       return 1;
908 +}
909 +
910 +static struct net_device *etun_alloc(struct net *net, const char *name)
911 +{
912 +       struct net_device *dev;
913 +       struct etun_info *info;
914 +       int err;
915 +
916 +       if (!name || !is_valid_name(name))
917 +               return ERR_PTR(-EINVAL);
918 +
919 +       dev = alloc_netdev(sizeof(struct etun_info), name, ether_setup);
920 +       if (!dev)
921 +               return ERR_PTR(-ENOMEM);
922 +
923 +       info = dev->priv;
924 +       info->dev = dev;
925 +       dev->nd_net = net;
926 +
927 +       random_ether_addr(dev->dev_addr);
928 +       dev->tx_queue_len       = 0; /* A queue is silly for a loopback device */
929 +       dev->hard_start_xmit    = etun_xmit;
930 +       dev->get_stats          = etun_get_stats;
931 +       dev->open               = etun_open;
932 +       dev->stop               = etun_stop;
933 +       dev->set_multicast_list = etun_set_multicast_list;
934 +       dev->do_ioctl           = etun_ioctl;
935 +       dev->features           = NETIF_F_FRAGLIST
936 +                                 | NETIF_F_HIGHDMA
937 +                                 | NETIF_F_LLTX;
938 +       dev->flags              = IFF_BROADCAST | IFF_MULTICAST |IFF_PROMISC;
939 +       dev->ethtool_ops        = &etun_ethtool_ops;
940 +       dev->destructor         = free_netdev;
941 +       dev->change_mtu         = etun_change_mtu;
942 +       err = register_netdev(dev);
943 +       if (err) {
944 +               free_netdev(dev);
945 +               dev = ERR_PTR(err);
946 +               goto out;
947 +       }
948 +       netif_carrier_off(dev);
949 +out:
950 +       return dev;
951 +}
952 +
953 +static int etun_alloc_pair(struct net *net, const char *name0, const char *name1)
954 +{
955 +       struct net_device *dev0, *dev1;
956 +       struct etun_info *info0, *info1;
957 +
958 +       dev0 = etun_alloc(net, name0);
959 +       if (IS_ERR(dev0)) {
960 +               return PTR_ERR(dev0);
961 +       }
962 +       info0 = dev0->priv;
963 +
964 +       dev1 = etun_alloc(net, name1);
965 +       if (IS_ERR(dev1)) {
966 +               unregister_netdev(dev0);
967 +               return PTR_ERR(dev1);
968 +       }
969 +       info1 = dev1->priv;
970 +
971 +       dev_hold(dev0);
972 +       dev_hold(dev1);
973 +       info0->rx_dev = dev1;
974 +       info1->rx_dev = dev0;
975 +
976 +       /* Only place one member of the pair on the list
977 +        * so I don't confuse list_for_each_entry_safe,
978 +        * by deleting two list entries at once.
979 +        */
980 +       rtnl_lock();
981 +       list_add(&info0->list, &etun_list);
982 +       INIT_LIST_HEAD(&info1->list);
983 +       rtnl_unlock();
984 +
985 +       return 0;
986 +}
987 +
988 +static int etun_unregister_pair(struct net_device *dev0)
989 +{
990 +       struct etun_info *info0, *info1;
991 +       struct net_device *dev1;
992 +
993 +       ASSERT_RTNL();
994 +
995 +       if (!dev0)
996 +               return -ENODEV;
997 +
998 +       /* Ensure my network devices are not passing packets */
999 +       dev_close(dev0);
1000 +       info0 = dev0->priv;
1001 +       dev1  = info0->rx_dev;
1002 +       info1 = dev1->priv;
1003 +       dev_close(dev1);
1004 +
1005 +       /* Drop the cross device references */
1006 +       dev_put(dev0);
1007 +       dev_put(dev1);
1008 +
1009 +       /* Remove from the etun list */
1010 +       if (!list_empty(&info0->list))
1011 +               list_del_init(&info0->list);
1012 +       if (!list_empty(&info1->list))
1013 +               list_del_init(&info1->list);
1014 +
1015 +       unregister_netdevice(dev0);
1016 +       unregister_netdevice(dev1);
1017 +       return 0;
1018 +}
1019 +
1020 +static int etun_noget(char *buffer, struct kernel_param *kp)
1021 +{
1022 +       return 0;
1023 +}
1024 +
1025 +static int etun_newif(const char *val, struct kernel_param *kp)
1026 +{
1027 +       char name0[IFNAMSIZ], name1[IFNAMSIZ];
1028 +       const char *mid;
1029 +       int len, len0, len1;
1030 +       if (!capable(CAP_NET_ADMIN))
1031 +               return -EPERM;
1032 +
1033 +       /* Avoid frustration by removing trailing whitespace */
1034 +       len = strlen(val);
1035 +       while (isspace(val[len - 1]))
1036 +               len--;
1037 +
1038 +       /* Split the string into 2 names */
1039 +       mid = memchr(val, ',', len);
1040 +       if (!mid)
1041 +               return -EINVAL;
1042 +
1043 +       /* Get the first device name */
1044 +       len0 = mid - val;
1045 +       if (len0 > sizeof(name0) - 1)
1046 +               len = sizeof(name0) - 1;
1047 +       strncpy(name0, val, len0);
1048 +       name0[len0] = '\0';
1049 +
1050 +       /* And the second device name */
1051 +       len1 = len - (len0 + 1);
1052 +       if (len1 > sizeof(name1) - 1)
1053 +               len1 = sizeof(name1) - 1;
1054 +       strncpy(name1, mid + 1, len1);
1055 +       name1[len1] = '\0';
1056 +
1057 +       return etun_alloc_pair(current->nsproxy->net_ns, name0, name1);
1058 +}
1059 +
1060 +static int etun_delif(const char *val, struct kernel_param *kp)
1061 +{
1062 +       char name[IFNAMSIZ];
1063 +       int len;
1064 +       struct net_device *dev;
1065 +       int err;
1066 +       if (!capable(CAP_NET_ADMIN))
1067 +               return -EPERM;
1068 +
1069 +       /* Avoid frustration by removing trailing whitespace */
1070 +       len = strlen(val);
1071 +       while (isspace(val[len - 1]))
1072 +               len--;
1073 +
1074 +       /* Get the device name */
1075 +       if (len > sizeof(name) - 1)
1076 +               return -EINVAL;
1077 +       strncpy(name, val, len);
1078 +       name[len] = '\0';
1079 +
1080 +       /* Double check I don't have strange characters in my device name */
1081 +       if (!is_valid_name(name))
1082 +               return -EINVAL;
1083 +
1084 +       rtnl_lock();
1085 +       err = -ENODEV;
1086 +       dev = __dev_get_by_name(current->nsproxy->net_ns, name);
1087 +       err = etun_unregister_pair(dev);
1088 +       rtnl_unlock();
1089 +       return err;
1090 +}
1091 +
1092 +static int __init etun_init(void)
1093 +{
1094 +       printk(KERN_INFO "etun: %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
1095 +       printk(KERN_INFO "etun: %s\n", DRV_COPYRIGHT);
1096 +
1097 +       return 0;
1098 +}
1099 +
1100 +static void etun_cleanup(void)
1101 +{
1102 +       struct etun_info *info, *tmp;
1103 +       rtnl_lock();
1104 +       list_for_each_entry_safe(info, tmp, &etun_list, list) {
1105 +               etun_unregister_pair(info->dev);
1106 +       }
1107 +       rtnl_unlock();
1108 +}
1109 +
1110 +module_param_call(newif, etun_newif, etun_noget, NULL, S_IWUSR);
1111 +module_param_call(delif, etun_delif, etun_noget, NULL, S_IWUSR);
1112 +module_init(etun_init);
1113 +module_exit(etun_cleanup);
1114 +MODULE_DESCRIPTION(DRV_DESCRIPTION);
1115 +MODULE_AUTHOR("Eric Biederman <ebiederm@xmission.com>");
1116 +MODULE_LICENSE("GPL");
1117 diff -Nurb linux-2.6.22-try2/drivers/net/hamradio/bpqether.c linux-2.6.22-try2-netns/drivers/net/hamradio/bpqether.c
1118 --- linux-2.6.22-try2/drivers/net/hamradio/bpqether.c   2007-12-19 13:37:31.000000000 -0500
1119 +++ linux-2.6.22-try2-netns/drivers/net/hamradio/bpqether.c     2007-12-19 22:49:13.000000000 -0500
1120 @@ -83,6 +83,7 @@
1121  
1122  #include <net/ip.h>
1123  #include <net/arp.h>
1124 +#include <net/net_namespace.h>
1125  
1126  #include <linux/bpqether.h>
1127  
1128 @@ -172,6 +173,9 @@
1129         struct ethhdr *eth;
1130         struct bpqdev *bpq;
1131  
1132 +       if (dev->nd_net != &init_net)
1133 +               goto drop;
1134 +
1135         if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
1136                 return NET_RX_DROP;
1137  
1138 @@ -559,6 +563,9 @@
1139  {
1140         struct net_device *dev = (struct net_device *)ptr;
1141  
1142 +       if (dev->nd_net != &init_net)
1143 +               return NOTIFY_DONE;
1144 +
1145         if (!dev_is_ethdev(dev))
1146                 return NOTIFY_DONE;
1147  
1148 @@ -594,7 +601,7 @@
1149  static int __init bpq_init_driver(void)
1150  {
1151  #ifdef CONFIG_PROC_FS
1152 -       if (!proc_net_fops_create("bpqether", S_IRUGO, &bpq_info_fops)) {
1153 +       if (!proc_net_fops_create(&init_net, "bpqether", S_IRUGO, &bpq_info_fops)) {
1154                 printk(KERN_ERR
1155                         "bpq: cannot create /proc/net/bpqether entry.\n");
1156                 return -ENOENT;
1157 @@ -618,7 +625,7 @@
1158  
1159         unregister_netdevice_notifier(&bpq_dev_notifier);
1160  
1161 -       proc_net_remove("bpqether");
1162 +       proc_net_remove(&init_net, "bpqether");
1163  
1164         rtnl_lock();
1165         while (!list_empty(&bpq_devices)) {
1166 diff -Nurb linux-2.6.22-try2/drivers/net/hamradio/scc.c linux-2.6.22-try2-netns/drivers/net/hamradio/scc.c
1167 --- linux-2.6.22-try2/drivers/net/hamradio/scc.c        2007-12-19 13:37:31.000000000 -0500
1168 +++ linux-2.6.22-try2-netns/drivers/net/hamradio/scc.c  2007-12-19 22:49:13.000000000 -0500
1169 @@ -174,6 +174,7 @@
1170  #include <linux/seq_file.h>
1171  #include <linux/bitops.h>
1172  
1173 +#include <net/net_namespace.h>
1174  #include <net/ax25.h>
1175  
1176  #include <asm/irq.h>
1177 @@ -2114,7 +2115,7 @@
1178         }
1179         rtnl_unlock();
1180  
1181 -       proc_net_fops_create("z8530drv", 0, &scc_net_seq_fops);
1182 +       proc_net_fops_create(&init_net, "z8530drv", 0, &scc_net_seq_fops);
1183  
1184         return 0;
1185  }
1186 @@ -2169,7 +2170,7 @@
1187         if (Vector_Latch)
1188                 release_region(Vector_Latch, 1);
1189  
1190 -       proc_net_remove("z8530drv");
1191 +       proc_net_remove(&init_net, "z8530drv");
1192  }
1193  
1194  MODULE_AUTHOR("Joerg Reuter <jreuter@yaina.de>");
1195 diff -Nurb linux-2.6.22-try2/drivers/net/hamradio/yam.c linux-2.6.22-try2-netns/drivers/net/hamradio/yam.c
1196 --- linux-2.6.22-try2/drivers/net/hamradio/yam.c        2007-12-19 13:37:31.000000000 -0500
1197 +++ linux-2.6.22-try2-netns/drivers/net/hamradio/yam.c  2007-12-19 22:49:13.000000000 -0500
1198 @@ -61,6 +61,7 @@
1199  #include <linux/etherdevice.h>
1200  #include <linux/skbuff.h>
1201  #include <net/ax25.h>
1202 +#include <net/net_namespace.h>
1203  
1204  #include <linux/kernel.h>
1205  #include <linux/proc_fs.h>
1206 @@ -1142,7 +1143,7 @@
1207         yam_timer.expires = jiffies + HZ / 100;
1208         add_timer(&yam_timer);
1209  
1210 -       proc_net_fops_create("yam", S_IRUGO, &yam_info_fops);
1211 +       proc_net_fops_create(&init_net, "yam", S_IRUGO, &yam_info_fops);
1212         return 0;
1213   error:
1214         while (--i >= 0) {
1215 @@ -1174,7 +1175,7 @@
1216                 kfree(p);
1217         }
1218  
1219 -       proc_net_remove("yam");
1220 +       proc_net_remove(&init_net, "yam");
1221  }
1222  
1223  /* --------------------------------------------------------------------- */
1224 diff -Nurb linux-2.6.22-try2/drivers/net/ibmveth.c linux-2.6.22-try2-netns/drivers/net/ibmveth.c
1225 --- linux-2.6.22-try2/drivers/net/ibmveth.c     2007-12-19 15:29:22.000000000 -0500
1226 +++ linux-2.6.22-try2-netns/drivers/net/ibmveth.c       2007-12-19 22:49:13.000000000 -0500
1227 @@ -47,6 +47,7 @@
1228  #include <linux/mm.h>
1229  #include <linux/ethtool.h>
1230  #include <linux/proc_fs.h>
1231 +#include <net/net_namespace.h>
1232  #include <asm/semaphore.h>
1233  #include <asm/hvcall.h>
1234  #include <asm/atomic.h>
1235 @@ -97,7 +98,7 @@
1236  static struct kobj_type ktype_veth_pool;
1237  
1238  #ifdef CONFIG_PROC_FS
1239 -#define IBMVETH_PROC_DIR "net/ibmveth"
1240 +#define IBMVETH_PROC_DIR "ibmveth"
1241  static struct proc_dir_entry *ibmveth_proc_dir;
1242  #endif
1243  
1244 @@ -1093,7 +1094,7 @@
1245  #ifdef CONFIG_PROC_FS
1246  static void ibmveth_proc_register_driver(void)
1247  {
1248 -       ibmveth_proc_dir = proc_mkdir(IBMVETH_PROC_DIR, NULL);
1249 +       ibmveth_proc_dir = proc_mkdir(IBMVETH_PROC_DIR, init_net.proc_net);
1250         if (ibmveth_proc_dir) {
1251                 SET_MODULE_OWNER(ibmveth_proc_dir);
1252         }
1253 @@ -1101,7 +1102,7 @@
1254  
1255  static void ibmveth_proc_unregister_driver(void)
1256  {
1257 -       remove_proc_entry(IBMVETH_PROC_DIR, NULL);
1258 +       remove_proc_entry(IBMVETH_PROC_DIR, init_net.proc_net);
1259  }
1260  
1261  static void *ibmveth_seq_start(struct seq_file *seq, loff_t *pos)
1262 diff -Nurb linux-2.6.22-try2/drivers/net/loopback.c linux-2.6.22-try2-netns/drivers/net/loopback.c
1263 --- linux-2.6.22-try2/drivers/net/loopback.c    2007-12-19 13:37:32.000000000 -0500
1264 +++ linux-2.6.22-try2-netns/drivers/net/loopback.c      2007-12-19 22:49:13.000000000 -0500
1265 @@ -57,6 +57,7 @@
1266  #include <linux/ip.h>
1267  #include <linux/tcp.h>
1268  #include <linux/percpu.h>
1269 +#include <net/net_namespace.h>
1270  
1271  struct pcpu_lstats {
1272         unsigned long packets;
1273 @@ -199,39 +200,52 @@
1274         .get_rx_csum            = always_on,
1275  };
1276  
1277 +static int loopback_net_init(struct net *net)
1278 +{
1279 +       struct net_device *lo = &net->loopback_dev;
1280  /*
1281   * The loopback device is special. There is only one instance and
1282   * it is statically allocated. Don't do this for other devices.
1283   */
1284 -struct net_device loopback_dev = {
1285 -       .name                   = "lo",
1286 -       .get_stats              = &get_stats,
1287 -       .mtu                    = (16 * 1024) + 20 + 20 + 12,
1288 -       .hard_start_xmit        = loopback_xmit,
1289 -       .hard_header            = eth_header,
1290 -       .hard_header_cache      = eth_header_cache,
1291 -       .header_cache_update    = eth_header_cache_update,
1292 -       .hard_header_len        = ETH_HLEN,     /* 14   */
1293 -       .addr_len               = ETH_ALEN,     /* 6    */
1294 -       .tx_queue_len           = 0,
1295 -       .type                   = ARPHRD_LOOPBACK,      /* 0x0001*/
1296 -       .rebuild_header         = eth_rebuild_header,
1297 -       .flags                  = IFF_LOOPBACK,
1298 -       .features               = NETIF_F_SG | NETIF_F_FRAGLIST
1299 +       strcpy(lo->name, "lo");
1300 +       lo->get_stats           = &get_stats,
1301 +       lo->mtu                 = (16 * 1024) + 20 + 20 + 12,
1302 +       lo->hard_start_xmit     = loopback_xmit,
1303 +       lo->hard_header         = eth_header,
1304 +       lo->hard_header_cache   = eth_header_cache,
1305 +       lo->header_cache_update = eth_header_cache_update,
1306 +       lo->hard_header_len     = ETH_HLEN,     /* 14   */
1307 +       lo->addr_len            = ETH_ALEN,     /* 6    */
1308 +       lo->tx_queue_len        = 0,
1309 +       lo->type                = ARPHRD_LOOPBACK,      /* 0x0001*/
1310 +       lo->rebuild_header      = eth_rebuild_header,
1311 +       lo->flags               = IFF_LOOPBACK,
1312 +       lo->features            = NETIF_F_SG | NETIF_F_FRAGLIST
1313  #ifdef LOOPBACK_TSO
1314                                   | NETIF_F_TSO
1315  #endif
1316                                   | NETIF_F_NO_CSUM | NETIF_F_HIGHDMA
1317 -                                 | NETIF_F_LLTX,
1318 -       .ethtool_ops            = &loopback_ethtool_ops,
1319 +                                 | NETIF_F_LLTX
1320 +                                 | NETIF_F_NETNS_LOCAL,
1321 +       lo->ethtool_ops         = &loopback_ethtool_ops,
1322 +       lo->nd_net = net;
1323 +       return register_netdev(lo);
1324 +}
1325 +
1326 +static void loopback_net_exit(struct net *net)
1327 +{
1328 +       unregister_netdev(&net->loopback_dev);
1329 +}
1330 +
1331 +static struct pernet_operations loopback_net_ops = {
1332 +       .init = loopback_net_init,
1333 +       .exit = loopback_net_exit,
1334  };
1335  
1336  /* Setup and register the loopback device. */
1337  static int __init loopback_init(void)
1338  {
1339 -       return register_netdev(&loopback_dev);
1340 +       return register_pernet_device(&loopback_net_ops);
1341  };
1342  
1343  module_init(loopback_init);
1344 -
1345 -EXPORT_SYMBOL(loopback_dev);
1346 diff -Nurb linux-2.6.22-try2/drivers/net/pppoe.c linux-2.6.22-try2-netns/drivers/net/pppoe.c
1347 --- linux-2.6.22-try2/drivers/net/pppoe.c       2007-12-19 13:37:34.000000000 -0500
1348 +++ linux-2.6.22-try2-netns/drivers/net/pppoe.c 2007-12-19 22:49:13.000000000 -0500
1349 @@ -78,6 +78,7 @@
1350  #include <linux/proc_fs.h>
1351  #include <linux/seq_file.h>
1352  
1353 +#include <net/net_namespace.h>
1354  #include <net/sock.h>
1355  
1356  #include <asm/uaccess.h>
1357 @@ -210,7 +211,7 @@
1358         struct net_device *dev;
1359         int ifindex;
1360  
1361 -       dev = dev_get_by_name(sp->sa_addr.pppoe.dev);
1362 +       dev = dev_get_by_name(&init_net, sp->sa_addr.pppoe.dev);
1363         if(!dev)
1364                 return NULL;
1365         ifindex = dev->ifindex;
1366 @@ -295,6 +296,9 @@
1367  {
1368         struct net_device *dev = (struct net_device *) ptr;
1369  
1370 +       if (dev->nd_net != &init_net)
1371 +               return NOTIFY_DONE;
1372 +
1373         /* Only look at sockets that are using this specific device. */
1374         switch (event) {
1375         case NETDEV_CHANGEMTU:
1376 @@ -380,6 +384,9 @@
1377         struct pppoe_hdr *ph;
1378         struct pppox_sock *po;
1379  
1380 +       if (dev->nd_net != &init_net)
1381 +               goto drop;
1382 +
1383         if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
1384                 goto drop;
1385  
1386 @@ -412,6 +419,9 @@
1387         struct pppoe_hdr *ph;
1388         struct pppox_sock *po;
1389  
1390 +       if (dev->nd_net != &init_net)
1391 +               goto abort;
1392 +
1393         if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
1394                 goto abort;
1395  
1396 @@ -471,12 +481,12 @@
1397   * Initialize a new struct sock.
1398   *
1399   **********************************************************************/
1400 -static int pppoe_create(struct socket *sock)
1401 +static int pppoe_create(struct net *net, struct socket *sock)
1402  {
1403         int error = -ENOMEM;
1404         struct sock *sk;
1405  
1406 -       sk = sk_alloc(PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto, 1);
1407 +       sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto, 1);
1408         if (!sk)
1409                 goto out;
1410  
1411 @@ -588,7 +598,7 @@
1412  
1413         /* Don't re-bind if sid==0 */
1414         if (sp->sa_addr.pppoe.sid != 0) {
1415 -               dev = dev_get_by_name(sp->sa_addr.pppoe.dev);
1416 +               dev = dev_get_by_name(&init_net, sp->sa_addr.pppoe.dev);
1417  
1418                 error = -ENODEV;
1419                 if (!dev)
1420 @@ -1064,7 +1074,7 @@
1421  {
1422         struct proc_dir_entry *p;
1423  
1424 -       p = create_proc_entry("net/pppoe", S_IRUGO, NULL);
1425 +       p = create_proc_entry("pppoe", S_IRUGO, init_net.proc_net);
1426         if (!p)
1427                 return -ENOMEM;
1428  
1429 @@ -1135,7 +1145,7 @@
1430         dev_remove_pack(&pppoes_ptype);
1431         dev_remove_pack(&pppoed_ptype);
1432         unregister_netdevice_notifier(&pppoe_notifier);
1433 -       remove_proc_entry("net/pppoe", NULL);
1434 +       remove_proc_entry("pppoe", init_net.proc_net);
1435         proto_unregister(&pppoe_sk_proto);
1436  }
1437  
1438 diff -Nurb linux-2.6.22-try2/drivers/net/pppox.c linux-2.6.22-try2-netns/drivers/net/pppox.c
1439 --- linux-2.6.22-try2/drivers/net/pppox.c       2007-12-19 13:37:34.000000000 -0500
1440 +++ linux-2.6.22-try2-netns/drivers/net/pppox.c 2007-12-19 22:49:13.000000000 -0500
1441 @@ -107,10 +107,13 @@
1442  
1443  EXPORT_SYMBOL(pppox_ioctl);
1444  
1445 -static int pppox_create(struct socket *sock, int protocol)
1446 +static int pppox_create(struct net *net, struct socket *sock, int protocol)
1447  {
1448         int rc = -EPROTOTYPE;
1449  
1450 +       if (net != &init_net)
1451 +               return -EAFNOSUPPORT;
1452 +
1453         if (protocol < 0 || protocol > PX_MAX_PROTO)
1454                 goto out;
1455  
1456 @@ -126,7 +129,7 @@
1457             !try_module_get(pppox_protos[protocol]->owner))
1458                 goto out;
1459  
1460 -       rc = pppox_protos[protocol]->create(sock);
1461 +       rc = pppox_protos[protocol]->create(net, sock);
1462  
1463         module_put(pppox_protos[protocol]->owner);
1464  out:
1465 diff -Nurb linux-2.6.22-try2/drivers/net/shaper.c linux-2.6.22-try2-netns/drivers/net/shaper.c
1466 --- linux-2.6.22-try2/drivers/net/shaper.c      2007-12-19 13:37:34.000000000 -0500
1467 +++ linux-2.6.22-try2-netns/drivers/net/shaper.c        2007-12-19 22:49:13.000000000 -0500
1468 @@ -86,6 +86,7 @@
1469  
1470  #include <net/dst.h>
1471  #include <net/arp.h>
1472 +#include <net/net_namespace.h>
1473  
1474  struct shaper_cb {
1475         unsigned long   shapeclock;             /* Time it should go out */
1476 @@ -488,7 +489,7 @@
1477         {
1478                 case SHAPER_SET_DEV:
1479                 {
1480 -                       struct net_device *them=__dev_get_by_name(ss->ss_name);
1481 +                       struct net_device *them=__dev_get_by_name(&init_net, ss->ss_name);
1482                         if(them==NULL)
1483                                 return -ENODEV;
1484                         if(sh->dev)
1485 diff -Nurb linux-2.6.22-try2/drivers/net/tokenring/lanstreamer.c linux-2.6.22-try2-netns/drivers/net/tokenring/lanstreamer.c
1486 --- linux-2.6.22-try2/drivers/net/tokenring/lanstreamer.c       2007-12-19 13:37:37.000000000 -0500
1487 +++ linux-2.6.22-try2-netns/drivers/net/tokenring/lanstreamer.c 2007-12-19 22:49:13.000000000 -0500
1488 @@ -250,7 +250,7 @@
1489  #if STREAMER_NETWORK_MONITOR
1490  #ifdef CONFIG_PROC_FS
1491         if (!dev_streamer)
1492 -               create_proc_read_entry("net/streamer_tr", 0, 0,
1493 +               create_proc_read_entry("streamer_tr", 0, init_net.proc_net,
1494                                         streamer_proc_info, NULL); 
1495         streamer_priv->next = dev_streamer;
1496         dev_streamer = streamer_priv;
1497 @@ -423,7 +423,7 @@
1498                         }
1499                 }
1500                 if (!dev_streamer)
1501 -                       remove_proc_entry("net/streamer_tr", NULL);
1502 +                       remove_proc_entry("streamer_tr", init_net.proc_net);
1503         }
1504  #endif
1505  #endif
1506 diff -Nurb linux-2.6.22-try2/drivers/net/tokenring/olympic.c linux-2.6.22-try2-netns/drivers/net/tokenring/olympic.c
1507 --- linux-2.6.22-try2/drivers/net/tokenring/olympic.c   2007-12-19 13:37:37.000000000 -0500
1508 +++ linux-2.6.22-try2-netns/drivers/net/tokenring/olympic.c     2007-12-19 22:49:13.000000000 -0500
1509 @@ -101,6 +101,7 @@
1510  #include <linux/bitops.h>
1511  #include <linux/jiffies.h>
1512  
1513 +#include <net/net_namespace.h>
1514  #include <net/checksum.h>
1515  
1516  #include <asm/io.h>
1517 @@ -268,9 +269,9 @@
1518         printk("Olympic: %s registered as: %s\n",olympic_priv->olympic_card_name,dev->name);
1519         if (olympic_priv->olympic_network_monitor) { /* Must go after register_netdev as we need the device name */ 
1520                 char proc_name[20] ; 
1521 -               strcpy(proc_name,"net/olympic_") ; 
1522 +               strcpy(proc_name,"olympic_") ; 
1523                 strcat(proc_name,dev->name) ; 
1524 -               create_proc_read_entry(proc_name,0,NULL,olympic_proc_info,(void *)dev) ; 
1525 +               create_proc_read_entry(proc_name,0,init_net.proc_net,olympic_proc_info,(void *)dev) ; 
1526                 printk("Olympic: Network Monitor information: /proc/%s\n",proc_name); 
1527         }
1528         return  0 ;
1529 @@ -1752,9 +1753,9 @@
1530  
1531         if (olympic_priv->olympic_network_monitor) { 
1532                 char proc_name[20] ; 
1533 -               strcpy(proc_name,"net/olympic_") ; 
1534 +               strcpy(proc_name,"olympic_") ; 
1535                 strcat(proc_name,dev->name) ;
1536 -               remove_proc_entry(proc_name,NULL); 
1537 +               remove_proc_entry(proc_name,init_net.proc_net);
1538         }
1539         unregister_netdev(dev) ; 
1540         iounmap(olympic_priv->olympic_mmio) ; 
1541 diff -Nurb linux-2.6.22-try2/drivers/net/tun.c linux-2.6.22-try2-netns/drivers/net/tun.c
1542 --- linux-2.6.22-try2/drivers/net/tun.c 2007-12-19 15:29:23.000000000 -0500
1543 +++ linux-2.6.22-try2-netns/drivers/net/tun.c   2007-12-19 22:49:13.000000000 -0500
1544 @@ -62,6 +62,7 @@
1545  #include <linux/if_ether.h>
1546  #include <linux/if_tun.h>
1547  #include <linux/crc32.h>
1548 +#include <net/net_namespace.h>
1549  
1550  #include <asm/system.h>
1551  #include <asm/uaccess.h>
1552 @@ -475,7 +476,7 @@
1553                      !capable(CAP_NET_ADMIN))
1554                         return -EPERM;
1555         }
1556 -       else if (__dev_get_by_name(ifr->ifr_name))
1557 +       else if (__dev_get_by_name(&init_net, ifr->ifr_name))
1558                 return -EINVAL;
1559         else {
1560                 char *name;
1561 diff -Nurb linux-2.6.22-try2/drivers/net/wan/dlci.c linux-2.6.22-try2-netns/drivers/net/wan/dlci.c
1562 --- linux-2.6.22-try2/drivers/net/wan/dlci.c    2007-12-19 13:37:38.000000000 -0500
1563 +++ linux-2.6.22-try2-netns/drivers/net/wan/dlci.c      2007-12-19 22:49:13.000000000 -0500
1564 @@ -361,7 +361,7 @@
1565  
1566  
1567         /* validate slave device */
1568 -       slave = dev_get_by_name(dlci->devname);
1569 +       slave = dev_get_by_name(&init_net, dlci->devname);
1570         if (!slave)
1571                 return -ENODEV;
1572  
1573 @@ -427,7 +427,7 @@
1574         int                     err;
1575  
1576         /* validate slave device */
1577 -       master = __dev_get_by_name(dlci->devname);
1578 +       master = __dev_get_by_name(&init_net, dlci->devname);
1579         if (!master)
1580                 return(-ENODEV);
1581  
1582 @@ -513,6 +513,9 @@
1583  {
1584         struct net_device *dev = (struct net_device *) ptr;
1585  
1586 +       if (dev->nd_net != &init_net)
1587 +               return NOTIFY_DONE;
1588 +
1589         if (event == NETDEV_UNREGISTER) {
1590                 struct dlci_local *dlp;
1591  
1592 diff -Nurb linux-2.6.22-try2/drivers/net/wan/hdlc.c linux-2.6.22-try2-netns/drivers/net/wan/hdlc.c
1593 --- linux-2.6.22-try2/drivers/net/wan/hdlc.c    2007-12-19 13:37:38.000000000 -0500
1594 +++ linux-2.6.22-try2-netns/drivers/net/wan/hdlc.c      2007-12-19 22:49:13.000000000 -0500
1595 @@ -36,6 +36,7 @@
1596  #include <linux/rtnetlink.h>
1597  #include <linux/notifier.h>
1598  #include <linux/hdlc.h>
1599 +#include <net/net_namespace.h>
1600  
1601  
1602  static const char* version = "HDLC support module revision 1.21";
1603 @@ -66,6 +67,12 @@
1604                     struct packet_type *p, struct net_device *orig_dev)
1605  {
1606         struct hdlc_device_desc *desc = dev_to_desc(dev);
1607 +
1608 +       if (dev->nd_net != &init_net) {
1609 +               kfree_skb(skb);
1610 +               return 0;
1611 +       }
1612 +
1613         if (desc->netif_rx)
1614                 return desc->netif_rx(skb);
1615  
1616 @@ -102,6 +109,9 @@
1617         unsigned long flags;
1618         int on;
1619   
1620 +       if (dev->nd_net != &init_net)
1621 +               return NOTIFY_DONE;
1622 +
1623         if (dev->get_stats != hdlc_get_stats)
1624                 return NOTIFY_DONE; /* not an HDLC device */
1625   
1626 diff -Nurb linux-2.6.22-try2/drivers/net/wan/lapbether.c linux-2.6.22-try2-netns/drivers/net/wan/lapbether.c
1627 --- linux-2.6.22-try2/drivers/net/wan/lapbether.c       2007-12-19 13:37:38.000000000 -0500
1628 +++ linux-2.6.22-try2-netns/drivers/net/wan/lapbether.c 2007-12-19 22:49:13.000000000 -0500
1629 @@ -91,6 +91,9 @@
1630         int len, err;
1631         struct lapbethdev *lapbeth;
1632  
1633 +       if (dev->nd_net != &init_net)
1634 +               goto drop;
1635 +
1636         if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
1637                 return NET_RX_DROP;
1638  
1639 @@ -391,6 +394,9 @@
1640         struct lapbethdev *lapbeth;
1641         struct net_device *dev = ptr;
1642  
1643 +       if (dev->nd_net != &init_net)
1644 +               return NOTIFY_DONE;
1645 +
1646         if (!dev_is_ethdev(dev))
1647                 return NOTIFY_DONE;
1648  
1649 diff -Nurb linux-2.6.22-try2/drivers/net/wan/sbni.c linux-2.6.22-try2-netns/drivers/net/wan/sbni.c
1650 --- linux-2.6.22-try2/drivers/net/wan/sbni.c    2007-12-19 13:37:38.000000000 -0500
1651 +++ linux-2.6.22-try2-netns/drivers/net/wan/sbni.c      2007-12-19 22:49:13.000000000 -0500
1652 @@ -54,6 +54,7 @@
1653  #include <linux/init.h>
1654  #include <linux/delay.h>
1655  
1656 +#include <net/net_namespace.h>
1657  #include <net/arp.h>
1658  
1659  #include <asm/io.h>
1660 @@ -1362,7 +1363,7 @@
1661  
1662                 if (copy_from_user( slave_name, ifr->ifr_data, sizeof slave_name ))
1663                         return -EFAULT;
1664 -               slave_dev = dev_get_by_name( slave_name );
1665 +               slave_dev = dev_get_by_name(&init_net, slave_name );
1666                 if( !slave_dev  ||  !(slave_dev->flags & IFF_UP) ) {
1667                         printk( KERN_ERR "%s: trying to enslave non-active "
1668                                 "device %s\n", dev->name, slave_name );
1669 diff -Nurb linux-2.6.22-try2/drivers/net/wan/syncppp.c linux-2.6.22-try2-netns/drivers/net/wan/syncppp.c
1670 --- linux-2.6.22-try2/drivers/net/wan/syncppp.c 2007-12-19 13:37:38.000000000 -0500
1671 +++ linux-2.6.22-try2-netns/drivers/net/wan/syncppp.c   2007-12-19 22:49:13.000000000 -0500
1672 @@ -51,6 +51,7 @@
1673  #include <linux/spinlock.h>
1674  #include <linux/rcupdate.h>
1675  
1676 +#include <net/net_namespace.h>
1677  #include <net/syncppp.h>
1678  
1679  #include <asm/byteorder.h>
1680 @@ -1445,6 +1446,11 @@
1681  
1682  static int sppp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *p, struct net_device *orig_dev)
1683  {
1684 +       if (dev->nd_net != &init_net) {
1685 +               kfree_skb(skb);
1686 +               return 0;
1687 +       }
1688 +
1689         if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
1690                 return NET_RX_DROP;
1691         sppp_input(dev,skb);
1692 diff -Nurb linux-2.6.22-try2/drivers/net/wireless/hostap/hostap_main.c linux-2.6.22-try2-netns/drivers/net/wireless/hostap/hostap_main.c
1693 --- linux-2.6.22-try2/drivers/net/wireless/hostap/hostap_main.c 2007-12-19 13:37:38.000000000 -0500
1694 +++ linux-2.6.22-try2-netns/drivers/net/wireless/hostap/hostap_main.c   2007-12-19 22:49:13.000000000 -0500
1695 @@ -24,6 +24,7 @@
1696  #include <linux/rtnetlink.h>
1697  #include <linux/wireless.h>
1698  #include <linux/etherdevice.h>
1699 +#include <net/net_namespace.h>
1700  #include <net/iw_handler.h>
1701  #include <net/ieee80211.h>
1702  #include <net/ieee80211_crypt.h>
1703 @@ -1094,8 +1095,8 @@
1704  
1705  static int __init hostap_init(void)
1706  {
1707 -       if (proc_net != NULL) {
1708 -               hostap_proc = proc_mkdir("hostap", proc_net);
1709 +       if (init_net.proc_net != NULL) {
1710 +               hostap_proc = proc_mkdir("hostap", init_net.proc_net);
1711                 if (!hostap_proc)
1712                         printk(KERN_WARNING "Failed to mkdir "
1713                                "/proc/net/hostap\n");
1714 @@ -1110,7 +1111,7 @@
1715  {
1716         if (hostap_proc != NULL) {
1717                 hostap_proc = NULL;
1718 -               remove_proc_entry("hostap", proc_net);
1719 +               remove_proc_entry("hostap", init_net.proc_net);
1720         }
1721  }
1722  
1723 diff -Nurb linux-2.6.22-try2/drivers/net/wireless/strip.c linux-2.6.22-try2-netns/drivers/net/wireless/strip.c
1724 --- linux-2.6.22-try2/drivers/net/wireless/strip.c      2007-12-19 13:37:38.000000000 -0500
1725 +++ linux-2.6.22-try2-netns/drivers/net/wireless/strip.c        2007-12-19 22:49:13.000000000 -0500
1726 @@ -107,6 +107,7 @@
1727  #include <linux/serialP.h>
1728  #include <linux/rcupdate.h>
1729  #include <net/arp.h>
1730 +#include <net/net_namespace.h>
1731  
1732  #include <linux/ip.h>
1733  #include <linux/tcp.h>
1734 @@ -1971,7 +1972,7 @@
1735                       sizeof(zero_address))) {
1736                 struct net_device *dev;
1737                 read_lock_bh(&dev_base_lock);
1738 -               for_each_netdev(dev) {
1739 +               for_each_netdev(&init_net, dev) {
1740                         if (dev->type == strip_info->dev->type &&
1741                             !memcmp(dev->dev_addr,
1742                                     &strip_info->true_dev_addr,
1743 @@ -2787,7 +2788,7 @@
1744         /*
1745          * Register the status file with /proc
1746          */
1747 -       proc_net_fops_create("strip", S_IFREG | S_IRUGO, &strip_seq_fops);
1748 +       proc_net_fops_create(&init_net, "strip", S_IFREG | S_IRUGO, &strip_seq_fops);
1749  
1750         return status;
1751  }
1752 @@ -2809,7 +2810,7 @@
1753         }
1754  
1755         /* Unregister with the /proc/net file here. */
1756 -       proc_net_remove("strip");
1757 +       proc_net_remove(&init_net, "strip");
1758  
1759         if ((i = tty_unregister_ldisc(N_STRIP)))
1760                 printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i);
1761 diff -Nurb linux-2.6.22-try2/drivers/parisc/led.c linux-2.6.22-try2-netns/drivers/parisc/led.c
1762 --- linux-2.6.22-try2/drivers/parisc/led.c      2007-12-19 13:37:38.000000000 -0500
1763 +++ linux-2.6.22-try2-netns/drivers/parisc/led.c        2007-12-19 22:49:13.000000000 -0500
1764 @@ -359,7 +359,7 @@
1765          * for reading should be OK */
1766         read_lock(&dev_base_lock);
1767         rcu_read_lock();
1768 -       for_each_netdev(dev) {
1769 +       for_each_netdev(&init_net, dev) {
1770             struct net_device_stats *stats;
1771             struct in_device *in_dev = __in_dev_get_rcu(dev);
1772             if (!in_dev || !in_dev->ifa_list)
1773 diff -Nurb linux-2.6.22-try2/drivers/s390/net/qeth_main.c linux-2.6.22-try2-netns/drivers/s390/net/qeth_main.c
1774 --- linux-2.6.22-try2/drivers/s390/net/qeth_main.c      2007-12-19 13:37:38.000000000 -0500
1775 +++ linux-2.6.22-try2-netns/drivers/s390/net/qeth_main.c        2007-12-19 22:49:13.000000000 -0500
1776 @@ -8127,7 +8127,7 @@
1777         neigh->parms = neigh_parms_clone(parms);
1778         rcu_read_unlock();
1779  
1780 -       neigh->type = inet_addr_type(*(__be32 *) neigh->primary_key);
1781 +       neigh->type = inet_addr_type(&init_net, *(__be32 *) neigh->primary_key);
1782         neigh->nud_state = NUD_NOARP;
1783         neigh->ops = arp_direct_ops;
1784         neigh->output = neigh->ops->queue_xmit;
1785 diff -Nurb linux-2.6.22-try2/drivers/scsi/scsi_netlink.c linux-2.6.22-try2-netns/drivers/scsi/scsi_netlink.c
1786 --- linux-2.6.22-try2/drivers/scsi/scsi_netlink.c       2007-12-19 13:37:39.000000000 -0500
1787 +++ linux-2.6.22-try2-netns/drivers/scsi/scsi_netlink.c 2007-12-19 22:49:13.000000000 -0500
1788 @@ -167,7 +167,7 @@
1789                 return;
1790         }
1791  
1792 -       scsi_nl_sock = netlink_kernel_create(NETLINK_SCSITRANSPORT,
1793 +       scsi_nl_sock = netlink_kernel_create(&init_net, NETLINK_SCSITRANSPORT,
1794                                 SCSI_NL_GRP_CNT, scsi_nl_rcv, NULL,
1795                                 THIS_MODULE);
1796         if (!scsi_nl_sock) {
1797 diff -Nurb linux-2.6.22-try2/drivers/scsi/scsi_transport_iscsi.c linux-2.6.22-try2-netns/drivers/scsi/scsi_transport_iscsi.c
1798 --- linux-2.6.22-try2/drivers/scsi/scsi_transport_iscsi.c       2007-12-19 15:29:23.000000000 -0500
1799 +++ linux-2.6.22-try2-netns/drivers/scsi/scsi_transport_iscsi.c 2007-12-19 22:49:13.000000000 -0500
1800 @@ -1523,7 +1523,7 @@
1801         if (err)
1802                 goto unregister_conn_class;
1803  
1804 -       nls = netlink_kernel_create(NETLINK_ISCSI, 1, iscsi_if_rx, NULL,
1805 +       nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, 1, iscsi_if_rx, NULL,
1806                         THIS_MODULE);
1807         if (!nls) {
1808                 err = -ENOBUFS;
1809 diff -Nurb linux-2.6.22-try2/edit linux-2.6.22-try2-netns/edit
1810 --- linux-2.6.22-try2/edit      1969-12-31 19:00:00.000000000 -0500
1811 +++ linux-2.6.22-try2-netns/edit        2007-12-19 22:57:06.000000000 -0500
1812 @@ -0,0 +1,19 @@
1813 +vi -o ./fs/proc/root.c ./fs/proc/root.c.rej
1814 +vi -o ./include/linux/nsproxy.h ./include/linux/nsproxy.h.rej
1815 +vi -o ./include/linux/sched.h ./include/linux/sched.h.rej
1816 +vi -o ./include/net/inet_timewait_sock.h ./include/net/inet_timewait_sock.h.rej
1817 +vi -o ./include/net/route.h ./include/net/route.h.rej
1818 +vi -o ./include/net/sock.h ./include/net/sock.h.rej
1819 +vi -o ./kernel/nsproxy.c ./kernel/nsproxy.c.rej
1820 +vi -o ./lib/Makefile ./lib/Makefile.rej
1821 +vi -o ./net/core/dev.c ./net/core/dev.c.rej
1822 +vi -o ./net/core/rtnetlink.c ./net/core/rtnetlink.c.rej
1823 +vi -o ./net/core/sock.c ./net/core/sock.c.rej
1824 +vi -o ./net/ipv4/af_inet.c ./net/ipv4/af_inet.c.rej
1825 +vi -o ./net/ipv4/inet_connection_sock.c ./net/ipv4/inet_connection_sock.c.rej
1826 +vi -o ./net/ipv4/inet_hashtables.c ./net/ipv4/inet_hashtables.c.rej
1827 +vi -o ./net/ipv4/raw.c ./net/ipv4/raw.c.rej
1828 +vi -o ./net/ipv4/tcp_ipv4.c ./net/ipv4/tcp_ipv4.c.rej
1829 +vi -o ./net/ipv4/udp.c ./net/ipv4/udp.c.rej
1830 +vi -o ./net/ipv6/addrconf.c ./net/ipv6/addrconf.c.rej
1831 +vi -o ./net/unix/af_unix.c ./net/unix/af_unix.c.rej
1832 diff -Nurb linux-2.6.22-try2/fs/afs/netdevices.c linux-2.6.22-try2-netns/fs/afs/netdevices.c
1833 --- linux-2.6.22-try2/fs/afs/netdevices.c       2007-12-19 13:37:40.000000000 -0500
1834 +++ linux-2.6.22-try2-netns/fs/afs/netdevices.c 2007-12-19 22:49:13.000000000 -0500
1835 @@ -8,6 +8,7 @@
1836  #include <linux/inetdevice.h>
1837  #include <linux/netdevice.h>
1838  #include <linux/if_arp.h>
1839 +#include <net/net_namespace.h>
1840  #include "internal.h"
1841  
1842  /*
1843 @@ -23,7 +24,7 @@
1844                 BUG();
1845  
1846         rtnl_lock();
1847 -       dev = __dev_getfirstbyhwtype(ARPHRD_ETHER);
1848 +       dev = __dev_getfirstbyhwtype(&init_net, ARPHRD_ETHER);
1849         if (dev) {
1850                 memcpy(mac, dev->dev_addr, maclen);
1851                 ret = 0;
1852 @@ -47,7 +48,7 @@
1853         ASSERT(maxbufs > 0);
1854  
1855         rtnl_lock();
1856 -       for_each_netdev(dev) {
1857 +       for_each_netdev(&init_net, dev) {
1858                 if (dev->type == ARPHRD_LOOPBACK && !wantloopback)
1859                         continue;
1860                 idev = __in_dev_get_rtnl(dev);
1861 diff -Nurb linux-2.6.22-try2/fs/compat_ioctl.c linux-2.6.22-try2-netns/fs/compat_ioctl.c
1862 --- linux-2.6.22-try2/fs/compat_ioctl.c 2007-12-19 13:37:40.000000000 -0500
1863 +++ linux-2.6.22-try2-netns/fs/compat_ioctl.c   2007-12-19 22:49:13.000000000 -0500
1864 @@ -319,22 +319,21 @@
1865  
1866  static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
1867  {
1868 -       struct net_device *dev;
1869 -       struct ifreq32 ifr32;
1870 +       struct ifreq __user *uifr;
1871         int err;
1872  
1873 -       if (copy_from_user(&ifr32, compat_ptr(arg), sizeof(ifr32)))
1874 +       uifr = compat_alloc_user_space(sizeof(struct ifreq));
1875 +       if (copy_in_user(uifr, compat_ptr(arg), sizeof(struct ifreq32)));
1876                 return -EFAULT;
1877  
1878 -       dev = dev_get_by_index(ifr32.ifr_ifindex);
1879 -       if (!dev)
1880 -               return -ENODEV;
1881 +       err = sys_ioctl(fd, SIOCGIFNAME, (unsigned long)uifr);
1882 +       if (err)
1883 +               return err;
1884  
1885 -       strlcpy(ifr32.ifr_name, dev->name, sizeof(ifr32.ifr_name));
1886 -       dev_put(dev);
1887 +       if (copy_in_user(compat_ptr(arg), uifr, sizeof(struct ifreq32)))
1888 +               return -EFAULT;
1889         
1890 -       err = copy_to_user(compat_ptr(arg), &ifr32, sizeof(ifr32));
1891 -       return (err ? -EFAULT : 0);
1892 +       return 0;
1893  }
1894  
1895  static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
1896 diff -Nurb linux-2.6.22-try2/fs/proc/Makefile linux-2.6.22-try2-netns/fs/proc/Makefile
1897 --- linux-2.6.22-try2/fs/proc/Makefile  2007-12-19 13:37:46.000000000 -0500
1898 +++ linux-2.6.22-try2-netns/fs/proc/Makefile    2007-12-19 22:49:13.000000000 -0500
1899 @@ -11,6 +11,7 @@
1900                 proc_tty.o proc_misc.o
1901  
1902  proc-$(CONFIG_PROC_SYSCTL)     += proc_sysctl.o
1903 +proc-$(CONFIG_NET)             += proc_net.o
1904  proc-$(CONFIG_PROC_KCORE)      += kcore.o
1905  proc-$(CONFIG_PROC_VMCORE)     += vmcore.o
1906  proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o
1907 diff -Nurb linux-2.6.22-try2/fs/proc/internal.h linux-2.6.22-try2-netns/fs/proc/internal.h
1908 --- linux-2.6.22-try2/fs/proc/internal.h        2007-12-19 15:29:24.000000000 -0500
1909 +++ linux-2.6.22-try2-netns/fs/proc/internal.h  2007-12-19 22:49:13.000000000 -0500
1910 @@ -17,6 +17,11 @@
1911  #else
1912  static inline void proc_sys_init(void) { }
1913  #endif
1914 +#ifdef CONFIG_NET
1915 +extern int proc_net_init(void);
1916 +#else
1917 +static inline int proc_net_init(void) { return 0; }
1918 +#endif
1919  
1920  struct vmalloc_info {
1921         unsigned long   used;
1922 diff -Nurb linux-2.6.22-try2/fs/proc/proc_net.c linux-2.6.22-try2-netns/fs/proc/proc_net.c
1923 --- linux-2.6.22-try2/fs/proc/proc_net.c        1969-12-31 19:00:00.000000000 -0500
1924 +++ linux-2.6.22-try2-netns/fs/proc/proc_net.c  2007-12-19 22:49:13.000000000 -0500
1925 @@ -0,0 +1,154 @@
1926 +/*
1927 + *  linux/fs/proc/net.c
1928 + *
1929 + *  Copyright (C) 2007
1930 + *
1931 + *  Author: Eric Biederman <ebiederm@xmission.com>
1932 + *
1933 + *  proc net directory handling functions
1934 + */
1935 +
1936 +#include <asm/uaccess.h>
1937 +
1938 +#include <linux/errno.h>
1939 +#include <linux/time.h>
1940 +#include <linux/proc_fs.h>
1941 +#include <linux/stat.h>
1942 +#include <linux/init.h>
1943 +#include <linux/sched.h>
1944 +#include <linux/module.h>
1945 +#include <linux/bitops.h>
1946 +#include <linux/smp_lock.h>
1947 +#include <linux/mount.h>
1948 +#include <linux/nsproxy.h>
1949 +#include <net/net_namespace.h>
1950 +
1951 +#include "internal.h"
1952 +
1953 +static struct proc_dir_entry *proc_net_shadow;
1954 +
1955 +static struct dentry *proc_net_shadow_dentry(struct dentry *parent,
1956 +                                               struct proc_dir_entry *de)
1957 +{
1958 +       struct dentry *shadow = NULL;
1959 +       struct inode *inode;
1960 +       if (!de)
1961 +               goto out;
1962 +       de_get(de);
1963 +       inode = proc_get_inode(parent->d_inode->i_sb, de->low_ino, de);
1964 +       if (!inode)
1965 +               goto out_de_put;
1966 +       shadow = d_alloc_name(parent, de->name);
1967 +       if (!shadow)
1968 +               goto out_iput;
1969 +       shadow->d_op = parent->d_op; /* proc_dentry_operations */
1970 +       d_instantiate(shadow, inode);
1971 +out:
1972 +       return shadow;
1973 +out_iput:
1974 +       iput(inode);
1975 +out_de_put:
1976 +       de_put(de);
1977 +       goto out;
1978 +}
1979 +
1980 +static void *proc_net_follow_link(struct dentry *parent, struct nameidata *nd)
1981 +{
1982 +       struct net *net = current->nsproxy->net_ns;
1983 +       struct dentry *shadow;
1984 +       shadow = proc_net_shadow_dentry(parent, net->proc_net);
1985 +       if (!shadow)
1986 +               return ERR_PTR(-ENOENT);
1987 +
1988 +       dput(nd->dentry);
1989 +       /* My dentry count is 1 and that should be enough as the 
1990 +        * shadow dentry is thrown away immediately.
1991 +        */
1992 +       nd->dentry = shadow;
1993 +       return NULL;
1994 +}
1995 +
1996 +static struct dentry *proc_net_lookup(struct inode *dir, struct dentry *dentry,
1997 +                                     struct nameidata *nd)
1998 +{
1999 +       struct net *net = current->nsproxy->net_ns;
2000 +       struct dentry *shadow;
2001 +       
2002 +       shadow = proc_net_shadow_dentry(nd->dentry, net->proc_net);
2003 +       if (!shadow)
2004 +               return ERR_PTR(-ENOENT);
2005 +
2006 +       dput(nd->dentry);
2007 +       nd->dentry = shadow;
2008 +       
2009 +       return shadow->d_inode->i_op->lookup(shadow->d_inode, dentry, nd);
2010 +}
2011 +
2012 +static int proc_net_setattr(struct dentry *dentry, struct iattr *iattr)
2013 +{
2014 +       struct net *net = current->nsproxy->net_ns;
2015 +       struct dentry *shadow;
2016 +       int ret;
2017 +
2018 +       shadow = proc_net_shadow_dentry(dentry->d_parent, net->proc_net);
2019 +       if (!shadow)
2020 +               return -ENOENT;
2021 +       ret = shadow->d_inode->i_op->setattr(shadow, iattr);
2022 +       dput(shadow);
2023 +       return ret;
2024 +}
2025 +
2026 +static const struct file_operations proc_net_dir_operations = {
2027 +       .read                   = generic_read_dir,
2028 +};
2029 +
2030 +static struct inode_operations proc_net_dir_inode_operations = {
2031 +       .follow_link    = proc_net_follow_link,
2032 +       .lookup         = proc_net_lookup,
2033 +       .setattr        = proc_net_setattr,
2034 +};
2035 +
2036 +
2037 +static int proc_net_ns_init(struct net *net)
2038 +{
2039 +       struct proc_dir_entry *netd, *net_statd;
2040 +
2041 +       netd = proc_mkdir("net", &net->proc_net_root);
2042 +       if (!netd)
2043 +               return -EEXIST;
2044 +
2045 +       net_statd = proc_mkdir("stat", netd);
2046 +       if (!net_statd) {
2047 +               remove_proc_entry("net", &net->proc_net_root);
2048 +               return -EEXIST;
2049 +       }
2050 +
2051 +       netd->data = net;
2052 +       net_statd->data = net;
2053 +       net->proc_net_root.data = net;
2054 +       net->proc_net = netd;
2055 +       net->proc_net_stat = net_statd;
2056 +
2057 +       return 0;
2058 +}
2059 +
2060 +static void proc_net_ns_exit(struct net *net)
2061 +{
2062 +       remove_proc_entry("stat", net->proc_net);
2063 +       remove_proc_entry("net", &net->proc_net_root);
2064 +
2065 +}
2066 +
2067 +struct pernet_operations proc_net_ns_ops = {
2068 +       .init = proc_net_ns_init,
2069 +       .exit = proc_net_ns_exit,
2070 +};
2071 +
2072 +int proc_net_init(void)
2073 +{
2074 +       proc_net_shadow = proc_mkdir("net", NULL);
2075 +       proc_net_shadow->proc_iops = &proc_net_dir_inode_operations;
2076 +       proc_net_shadow->proc_fops = &proc_net_dir_operations;
2077 +
2078 +       return register_pernet_subsys(&proc_net_ns_ops);
2079 +}
2080 diff -Nurb linux-2.6.22-try2/fs/proc/root.c linux-2.6.22-try2-netns/fs/proc/root.c
2081 --- linux-2.6.22-try2/fs/proc/root.c    2007-12-19 13:37:46.000000000 -0500
2082 +++ linux-2.6.22-try2-netns/fs/proc/root.c      2007-12-19 22:57:39.000000000 -0500
2083 @@ -21,11 +21,11 @@
2084  
2085  #include "internal.h"
2086  
2087 -struct proc_dir_entry *proc_net, *proc_net_stat, *proc_bus, *proc_root_fs, *proc_root_driver;
2088  struct proc_dir_entry *proc_virtual;
2089  
2090  extern void proc_vx_init(void);
2091  
2092 +struct proc_dir_entry *proc_bus, *proc_root_fs, *proc_root_driver;
2093  static int proc_get_sb(struct file_system_type *fs_type,
2094         int flags, const char *dev_name, void *data, struct vfsmount *mnt)
2095  {
2096 @@ -64,8 +64,8 @@
2097                 return;
2098         }
2099         proc_misc_init();
2100 -       proc_net = proc_mkdir("net", NULL);
2101 -       proc_net_stat = proc_mkdir("net/stat", NULL);
2102 +
2103 +       proc_net_init();
2104  
2105  #ifdef CONFIG_SYSVIPC
2106         proc_mkdir("sysvipc", NULL);
2107 @@ -163,7 +163,5 @@
2108  EXPORT_SYMBOL(remove_proc_entry);
2109  EXPORT_SYMBOL(proc_root);
2110  EXPORT_SYMBOL(proc_root_fs);
2111 -EXPORT_SYMBOL(proc_net);
2112 -EXPORT_SYMBOL(proc_net_stat);
2113  EXPORT_SYMBOL(proc_bus);
2114  EXPORT_SYMBOL(proc_root_driver);
2115 diff -Nurb linux-2.6.22-try2/fs/sysfs/bin.c linux-2.6.22-try2-netns/fs/sysfs/bin.c
2116 --- linux-2.6.22-try2/fs/sysfs/bin.c    2007-12-19 15:29:23.000000000 -0500
2117 +++ linux-2.6.22-try2-netns/fs/sysfs/bin.c      2007-12-19 22:49:13.000000000 -0500
2118 @@ -248,7 +248,7 @@
2119  
2120  void sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr)
2121  {
2122 -       if (sysfs_hash_and_remove(kobj->sd, attr->attr.name) < 0) {
2123 +       if (sysfs_hash_and_remove(kobj, kobj->sd, attr->attr.name) < 0) {
2124                 printk(KERN_ERR "%s: "
2125                         "bad dentry or inode or no such file: \"%s\"\n",
2126                         __FUNCTION__, attr->attr.name);
2127 diff -Nurb linux-2.6.22-try2/fs/sysfs/dir.c linux-2.6.22-try2-netns/fs/sysfs/dir.c
2128 --- linux-2.6.22-try2/fs/sysfs/dir.c    2007-12-19 15:29:23.000000000 -0500
2129 +++ linux-2.6.22-try2-netns/fs/sysfs/dir.c      2007-12-19 22:49:13.000000000 -0500
2130 @@ -14,12 +14,33 @@
2131  #include <asm/semaphore.h>
2132  #include "sysfs.h"
2133  
2134 +static void sysfs_prune_shadow_sd(struct sysfs_dirent *sd);
2135 +
2136  DEFINE_MUTEX(sysfs_mutex);
2137  spinlock_t sysfs_assoc_lock = SPIN_LOCK_UNLOCKED;
2138  
2139  static spinlock_t sysfs_ino_lock = SPIN_LOCK_UNLOCKED;
2140  static DEFINE_IDA(sysfs_ino_ida);
2141  
2142 +static struct sysfs_dirent *find_shadow_sd(struct sysfs_dirent *parent_sd, const void *target)
2143 +{
2144 +       /* Find the shadow directory for the specified tag */
2145 +       struct sysfs_dirent *sd;
2146 +
2147 +       for (sd = parent_sd->s_children; sd; sd = sd->s_sibling) {
2148 +               if (sd->s_name != target)
2149 +                       continue;
2150 +               break;
2151 +       }
2152 +       return sd;
2153 +}
2154 +
2155 +static const void *find_shadow_tag(struct kobject *kobj)
2156 +{
2157 +       /* Find the tag the current kobj is cached with */
2158 +       return kobj->sd->s_parent->s_name;
2159 +}
2160 +
2161  /**
2162   *     sysfs_link_sibling - link sysfs_dirent into sibling list
2163   *     @sd: sysfs_dirent of interest
2164 @@ -323,6 +344,7 @@
2165         if (sysfs_type(sd) & SYSFS_COPY_NAME)
2166                 kfree(sd->s_name);
2167         kfree(sd->s_iattr);
2168 +       if (sysfs_type(sd) != SYSFS_SHADOW_DIR)
2169         sysfs_free_ino(sd->s_ino);
2170         kmem_cache_free(sysfs_dir_cachep, sd);
2171  
2172 @@ -413,6 +435,7 @@
2173         sd->s_dentry = dentry;
2174         spin_unlock(&sysfs_assoc_lock);
2175  
2176 +       if (dentry->d_flags & DCACHE_UNHASHED)
2177         d_rehash(dentry);
2178  }
2179  
2180 @@ -568,8 +591,9 @@
2181         spin_unlock(&dcache_lock);
2182         spin_unlock(&sysfs_assoc_lock);
2183  
2184 -       /* dentries for shadowed inodes are pinned, unpin */
2185 -       if (dentry && sysfs_is_shadowed_inode(dentry->d_inode))
2186 +       /* dentries for shadowed directories are pinned, unpin */
2187 +       if ((sysfs_type(sd) == SYSFS_SHADOW_DIR) ||
2188 +           (sd->s_flags & SYSFS_FLAG_SHADOWED))
2189                 dput(dentry);
2190         dput(dentry);
2191  
2192 @@ -624,6 +648,7 @@
2193                 acxt->removed = sd->s_sibling;
2194                 sd->s_sibling = NULL;
2195  
2196 +               sysfs_prune_shadow_sd(sd->s_parent);
2197                 sysfs_drop_dentry(sd);
2198                 sysfs_deactivate(sd);
2199                 sysfs_put(sd);
2200 @@ -689,6 +714,7 @@
2201         umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
2202         struct sysfs_addrm_cxt acxt;
2203         struct sysfs_dirent *sd;
2204 +       int err;
2205  
2206         /* allocate */
2207         sd = sysfs_new_dirent(name, mode, SYSFS_DIR);
2208 @@ -698,17 +724,24 @@
2209  
2210         /* link in */
2211         sysfs_addrm_start(&acxt, parent_sd);
2212 -       if (!sysfs_find_dirent(parent_sd, name)) {
2213 +       err = -ENOENT;
2214 +       if (!sysfs_resolve_for_create(kobj, &acxt.parent_sd))
2215 +               goto addrm_finish;
2216 +
2217 +       err = -EEXIST;
2218 +       if (!sysfs_find_dirent(acxt.parent_sd, name)) {
2219                 sysfs_add_one(&acxt, sd);
2220                 sysfs_link_sibling(sd);
2221 +               err = 0;
2222         }
2223 +addrm_finish:
2224         if (sysfs_addrm_finish(&acxt)) {
2225                 *p_sd = sd;
2226                 return 0;
2227         }
2228  
2229         sysfs_put(sd);
2230 -       return -EEXIST;
2231 +       return err;
2232  }
2233  
2234  int sysfs_create_subdir(struct kobject *kobj, const char *name,
2235 @@ -720,19 +753,15 @@
2236  /**
2237   *     sysfs_create_dir - create a directory for an object.
2238   *     @kobj:          object we're creating directory for. 
2239 - *     @shadow_parent: parent object.
2240   */
2241 -int sysfs_create_dir(struct kobject *kobj,
2242 -                    struct sysfs_dirent *shadow_parent_sd)
2243 +int sysfs_create_dir(struct kobject * kobj)
2244  {
2245         struct sysfs_dirent *parent_sd, *sd;
2246         int error = 0;
2247  
2248         BUG_ON(!kobj);
2249  
2250 -       if (shadow_parent_sd)
2251 -               parent_sd = shadow_parent_sd;
2252 -       else if (kobj->parent)
2253 +       if (kobj->parent)
2254                 parent_sd = kobj->parent->sd;
2255         else if (sysfs_mount && sysfs_mount->mnt_sb)
2256                 parent_sd = sysfs_mount->mnt_sb->s_root->d_fsdata;
2257 @@ -817,18 +846,56 @@
2258         return NULL;
2259  }
2260  
2261 +static void *sysfs_shadow_follow_link(struct dentry *dentry, struct nameidata *nd)
2262 +{
2263 +       struct sysfs_dirent *sd;
2264 +       struct dentry *dest;
2265 +
2266 +       sd = dentry->d_fsdata;
2267 +       dest = NULL;
2268 +       if (sd->s_flags & SYSFS_FLAG_SHADOWED) {
2269 +               const struct shadow_dir_operations *shadow_ops;
2270 +               const void *tag;
2271 +
2272 +               mutex_lock(&sysfs_mutex);
2273 +
2274 +               shadow_ops = dentry->d_inode->i_private;
2275 +               tag = shadow_ops->current_tag();
2276 +
2277 +               sd = find_shadow_sd(sd, tag);
2278 +               if (sd)
2279 +                       dest = sd->s_dentry;
2280 +               dget(dest);
2281 +
2282 +               mutex_unlock(&sysfs_mutex);
2283 +       }
2284 +       if (!dest)
2285 +               dest = dget(dentry);
2286 +       dput(nd->dentry);
2287 +       nd->dentry = dest;
2288 +
2289 +       return NULL;
2290 +}
2291 +
2292 +
2293  const struct inode_operations sysfs_dir_inode_operations = {
2294         .lookup         = sysfs_lookup,
2295         .setattr        = sysfs_setattr,
2296 +       .follow_link    = sysfs_shadow_follow_link,
2297  };
2298  
2299 +static void __remove_dir(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
2300 +{
2301 +       sysfs_unlink_sibling(sd);
2302 +       sysfs_remove_one(acxt, sd);
2303 +}
2304 +
2305  static void remove_dir(struct sysfs_dirent *sd)
2306  {
2307         struct sysfs_addrm_cxt acxt;
2308  
2309         sysfs_addrm_start(&acxt, sd->s_parent);
2310 -       sysfs_unlink_sibling(sd);
2311 -       sysfs_remove_one(&acxt, sd);
2312 +       __remove_dir(&acxt, sd);
2313         sysfs_addrm_finish(&acxt);
2314  }
2315  
2316 @@ -837,17 +904,11 @@
2317         remove_dir(sd);
2318  }
2319  
2320 -
2321 -static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd)
2322 +static void sysfs_empty_dir(struct sysfs_addrm_cxt *acxt,
2323 +                           struct sysfs_dirent *dir_sd)
2324  {
2325 -       struct sysfs_addrm_cxt acxt;
2326         struct sysfs_dirent **pos;
2327  
2328 -       if (!dir_sd)
2329 -               return;
2330 -
2331 -       pr_debug("sysfs %s: removing dir\n", dir_sd->s_name);
2332 -       sysfs_addrm_start(&acxt, dir_sd);
2333         pos = &dir_sd->s_children;
2334         while (*pos) {
2335                 struct sysfs_dirent *sd = *pos;
2336 @@ -855,10 +916,39 @@
2337                 if (sysfs_type(sd) && sysfs_type(sd) != SYSFS_DIR) {
2338                         *pos = sd->s_sibling;
2339                         sd->s_sibling = NULL;
2340 -                       sysfs_remove_one(&acxt, sd);
2341 +                       sysfs_remove_one(acxt, sd);
2342                 } else
2343                         pos = &(*pos)->s_sibling;
2344         }
2345 +}
2346 +
2347 +static void sysfs_remove_shadows(struct sysfs_addrm_cxt * acxt,
2348 +                                       struct sysfs_dirent *dir_sd)
2349 +{
2350 +       struct sysfs_dirent **pos;
2351 +
2352 +       pos = &dir_sd->s_children;
2353 +       while (*pos) {
2354 +               struct sysfs_dirent *sd = *pos;
2355 +
2356 +               sysfs_empty_dir(acxt, sd);
2357 +               __remove_dir(acxt, sd);
2358 +       }
2359 +}
2360 +
2361 +static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd)
2362 +{
2363 +       struct sysfs_addrm_cxt acxt;
2364 +
2365 +       if (!dir_sd)
2366 +               return;
2367 +
2368 +       pr_debug("sysfs %s: removing dir\n", dir_sd->s_name);
2369 +       sysfs_addrm_start(&acxt, dir_sd);
2370 +       if (sysfs_type(dir_sd) == SYSFS_DIR)
2371 +               sysfs_empty_dir(&acxt, dir_sd);
2372 +       else
2373 +               sysfs_remove_shadows(&acxt, dir_sd);
2374         sysfs_addrm_finish(&acxt);
2375  
2376         remove_dir(dir_sd);
2377 @@ -884,89 +974,77 @@
2378         __sysfs_remove_dir(sd);
2379  }
2380  
2381 -int sysfs_rename_dir(struct kobject *kobj, struct sysfs_dirent *new_parent_sd,
2382 -                    const char *new_name)
2383 +int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
2384  {
2385 -       struct sysfs_dirent *sd = kobj->sd;
2386 -       struct dentry *new_parent = NULL;
2387 -       struct dentry *old_dentry = NULL, *new_dentry = NULL;
2388 -       const char *dup_name = NULL;
2389 +       struct dentry *old_dentry, *new_dentry, *parent;
2390 +       struct sysfs_addrm_cxt acxt;
2391 +       struct sysfs_dirent *sd;
2392 +       const char *dup_name;
2393         int error;
2394  
2395 -       /* get dentries */
2396 -       old_dentry = sysfs_get_dentry(sd);
2397 -       if (IS_ERR(old_dentry)) {
2398 -               error = PTR_ERR(old_dentry);
2399 -               goto out_dput;
2400 -       }
2401 +       dup_name = NULL;
2402 +       new_dentry = NULL;
2403  
2404 -       new_parent = sysfs_get_dentry(new_parent_sd);
2405 -       if (IS_ERR(new_parent)) {
2406 -               error = PTR_ERR(new_parent);
2407 -               goto out_dput;
2408 -       }
2409 +       sd = kobj->sd;
2410 +       sysfs_addrm_start(&acxt, sd->s_parent);
2411 +       error = -ENOENT;
2412 +       if (!sysfs_resolve_for_create(kobj, &acxt.parent_sd))
2413 +               goto addrm_finish;
2414  
2415 -       /* lock new_parent and get dentry for new name */
2416 -       mutex_lock(&new_parent->d_inode->i_mutex);
2417 +       error = -EEXIST;
2418 +       if (sysfs_find_dirent(acxt.parent_sd, new_name))
2419 +               goto addrm_finish;
2420  
2421 -       new_dentry = lookup_one_len(new_name, new_parent, strlen(new_name));
2422 +       error = -EINVAL;
2423 +       if ((sd->s_parent == acxt.parent_sd) &&
2424 +           (strcmp(new_name, sd->s_name) == 0))
2425 +               goto addrm_finish;
2426 +
2427 +       old_dentry = sd->s_dentry;
2428 +       parent = acxt.parent_sd->s_dentry;
2429 +       if (old_dentry) {
2430 +               old_dentry = sd->s_dentry;
2431 +               parent = acxt.parent_sd->s_dentry;
2432 +               new_dentry = lookup_one_len(new_name, parent, strlen(new_name));
2433         if (IS_ERR(new_dentry)) {
2434                 error = PTR_ERR(new_dentry);
2435 -               goto out_unlock;
2436 +                       goto addrm_finish;
2437         }
2438  
2439 -       /* By allowing two different directories with the same
2440 -        * d_parent we allow this routine to move between different
2441 -        * shadows of the same directory
2442 -        */
2443         error = -EINVAL;
2444 -       if (old_dentry->d_parent->d_inode != new_parent->d_inode ||
2445 -           new_dentry->d_parent->d_inode != new_parent->d_inode ||
2446 -           old_dentry == new_dentry)
2447 -               goto out_unlock;
2448 -
2449 -       error = -EEXIST;
2450 -       if (new_dentry->d_inode)
2451 -               goto out_unlock;
2452 +               if (old_dentry == new_dentry)
2453 +                       goto addrm_finish;
2454 +       }
2455  
2456         /* rename kobject and sysfs_dirent */
2457         error = -ENOMEM;
2458         new_name = dup_name = kstrdup(new_name, GFP_KERNEL);
2459         if (!new_name)
2460 -               goto out_drop;
2461 +               goto addrm_finish;
2462  
2463         error = kobject_set_name(kobj, "%s", new_name);
2464         if (error)
2465 -               goto out_drop;
2466 +               goto addrm_finish;
2467  
2468         dup_name = sd->s_name;
2469         sd->s_name = new_name;
2470  
2471         /* move under the new parent */
2472 -       d_add(new_dentry, NULL);
2473 -       d_move(sd->s_dentry, new_dentry);
2474 -
2475 -       mutex_lock(&sysfs_mutex);
2476 -
2477         sysfs_unlink_sibling(sd);
2478 -       sysfs_get(new_parent_sd);
2479 +       sysfs_get(acxt.parent_sd);
2480         sysfs_put(sd->s_parent);
2481 -       sd->s_parent = new_parent_sd;
2482 +       sd->s_parent = acxt.parent_sd;
2483         sysfs_link_sibling(sd);
2484  
2485 -       mutex_unlock(&sysfs_mutex);
2486 -
2487 +       if (new_dentry) {
2488 +               d_add(new_dentry, NULL);
2489 +               d_move(old_dentry, new_dentry);
2490 +       }
2491         error = 0;
2492 -       goto out_unlock;
2493 +addrm_finish:
2494 +       sysfs_addrm_finish(&acxt);
2495  
2496 - out_drop:
2497 -       d_drop(new_dentry);
2498 - out_unlock:
2499 -       mutex_unlock(&new_parent->d_inode->i_mutex);
2500 - out_dput:
2501         kfree(dup_name);
2502 -       dput(new_parent);
2503 -       dput(old_dentry);
2504         dput(new_dentry);
2505         return error;
2506  }
2507 @@ -1103,8 +1181,11 @@
2508                         i++;
2509                         /* fallthrough */
2510                 default:
2511 -                       mutex_lock(&sysfs_mutex);
2512 +                       /* If I am the shadow master return nothing. */
2513 +                       if (parent_sd->s_flags & SYSFS_FLAG_SHADOWED)
2514 +                               return 0;
2515  
2516 +                       mutex_lock(&sysfs_mutex);
2517                         pos = &parent_sd->s_children;
2518                         while (*pos != cursor)
2519                                 pos = &(*pos)->s_sibling;
2520 @@ -1186,125 +1267,192 @@
2521         return offset;
2522  }
2523  
2524 +const struct file_operations sysfs_dir_operations = {
2525 +       .open           = sysfs_dir_open,
2526 +       .release        = sysfs_dir_close,
2527 +       .llseek         = sysfs_dir_lseek,
2528 +       .read           = generic_read_dir,
2529 +       .readdir        = sysfs_readdir,
2530 +};
2531  
2532 -/**
2533 - *     sysfs_make_shadowed_dir - Setup so a directory can be shadowed
2534 - *     @kobj:  object we're creating shadow of.
2535 - */
2536  
2537 -int sysfs_make_shadowed_dir(struct kobject *kobj,
2538 -       void * (*follow_link)(struct dentry *, struct nameidata *))
2539 +static void sysfs_prune_shadow_sd(struct sysfs_dirent *sd)
2540  {
2541 -       struct dentry *dentry;
2542 -       struct inode *inode;
2543 -       struct inode_operations *i_op;
2544 +       struct sysfs_addrm_cxt acxt;
2545  
2546 -       /* get dentry for @kobj->sd, dentry of a shadowed dir is pinned */
2547 -       dentry = sysfs_get_dentry(kobj->sd);
2548 -       if (IS_ERR(dentry))
2549 -               return PTR_ERR(dentry);
2550 +       /* If a shadow directory goes empty remove it. */
2551 +       if (sysfs_type(sd) != SYSFS_SHADOW_DIR)
2552 +               return;
2553  
2554 -       inode = dentry->d_inode;
2555 -       if (inode->i_op != &sysfs_dir_inode_operations) {
2556 -               dput(dentry);
2557 -               return -EINVAL;
2558 -       }
2559 +       if (sd->s_children)
2560 +               return;
2561  
2562 -       i_op = kmalloc(sizeof(*i_op), GFP_KERNEL);
2563 -       if (!i_op)
2564 -               return -ENOMEM;
2565 +       sysfs_addrm_start(&acxt, sd->s_parent);
2566  
2567 -       memcpy(i_op, &sysfs_dir_inode_operations, sizeof(*i_op));
2568 -       i_op->follow_link = follow_link;
2569 +       if (sd->s_flags & SYSFS_FLAG_REMOVED)
2570 +               goto addrm_finish;
2571  
2572 -       /* Locking of inode->i_op?
2573 -        * Since setting i_op is a single word write and they
2574 -        * are atomic we should be ok here.
2575 -        */
2576 -       inode->i_op = i_op;
2577 -       return 0;
2578 -}
2579 +       if (sd->s_children)
2580 +               goto addrm_finish;
2581  
2582 -/**
2583 - *     sysfs_create_shadow_dir - create a shadow directory for an object.
2584 - *     @kobj:  object we're creating directory for.
2585 - *
2586 - *     sysfs_make_shadowed_dir must already have been called on this
2587 - *     directory.
2588 - */
2589 +       __remove_dir(&acxt, sd);
2590 +addrm_finish:
2591 +       sysfs_addrm_finish(&acxt);
2592 +}
2593  
2594 -struct sysfs_dirent *sysfs_create_shadow_dir(struct kobject *kobj)
2595 +static struct sysfs_dirent *add_shadow_sd(struct sysfs_dirent *parent_sd, const void *tag)
2596  {
2597 -       struct sysfs_dirent *parent_sd = kobj->sd->s_parent;
2598 -       struct dentry *dir, *parent, *shadow;
2599 +       struct sysfs_dirent *sd = NULL;
2600 +       struct dentry *dir, *shadow;
2601         struct inode *inode;
2602 -       struct sysfs_dirent *sd;
2603 -       struct sysfs_addrm_cxt acxt;
2604 -
2605 -       dir = sysfs_get_dentry(kobj->sd);
2606 -       if (IS_ERR(dir)) {
2607 -               sd = (void *)dir;
2608 -               goto out;
2609 -       }
2610 -       parent = dir->d_parent;
2611  
2612 +       dir = parent_sd->s_dentry;
2613         inode = dir->d_inode;
2614 -       sd = ERR_PTR(-EINVAL);
2615 -       if (!sysfs_is_shadowed_inode(inode))
2616 -               goto out_dput;
2617  
2618 -       shadow = d_alloc(parent, &dir->d_name);
2619 +       shadow = d_alloc(dir->d_parent, &dir->d_name);
2620         if (!shadow)
2621 -               goto nomem;
2622 +               goto out;
2623  
2624 -       sd = sysfs_new_dirent("_SHADOW_", inode->i_mode, SYSFS_DIR);
2625 +       /* Since the shadow directory is reachable make it look
2626 +        * like it is actually hashed.
2627 +        */
2628 +       shadow->d_hash.pprev = &shadow->d_hash.next;
2629 +       shadow->d_hash.next = NULL;
2630 +       shadow->d_flags &= ~DCACHE_UNHASHED;
2631 +
2632 +       sd = sysfs_new_dirent(tag, parent_sd->s_mode, SYSFS_SHADOW_DIR);
2633         if (!sd)
2634 -               goto nomem;
2635 -       sd->s_elem.dir.kobj = kobj;
2636 +               goto error;
2637  
2638 -       sysfs_addrm_start(&acxt, parent_sd);
2639 +       sd->s_elem.dir.kobj = parent_sd->s_elem.dir.kobj;
2640 +       sd->s_parent = sysfs_get(parent_sd);
2641  
2642 -       /* add but don't link into children list */
2643 -       sysfs_add_one(&acxt, sd);
2644 +       /* Use the inode number of the parent we are shadowing */
2645 +       sysfs_free_ino(sd->s_ino);
2646 +       sd->s_ino = parent_sd->s_ino;
2647 +
2648 +       inc_nlink(inode);
2649 +       inc_nlink(dir->d_parent->d_inode);
2650  
2651 -       /* attach and instantiate dentry */
2652 +       sysfs_link_sibling(sd);
2653 +       __iget(inode);
2654 +       sysfs_instantiate(shadow, inode);
2655         sysfs_attach_dentry(sd, shadow);
2656 -       d_instantiate(shadow, igrab(inode));
2657 -       inc_nlink(inode);       /* tj: synchronization? */
2658 +out:
2659 +       return sd;
2660 +error:
2661 +       dput(shadow);
2662 +       goto out;
2663 +}
2664  
2665 -       sysfs_addrm_finish(&acxt);
2666 +int sysfs_resolve_for_create(struct kobject *kobj,
2667 +                               struct sysfs_dirent **parent_sd)
2668 +{
2669 +       const struct shadow_dir_operations *shadow_ops;
2670 +       struct sysfs_dirent *sd, *shadow_sd;
2671 +
2672 +       sd = *parent_sd;
2673 +       if (sysfs_type(sd) == SYSFS_SHADOW_DIR)
2674 +               sd = sd->s_parent;
2675 +
2676 +       if (sd->s_flags & SYSFS_FLAG_SHADOWED) {
2677 +               const void *tag;
2678 +
2679 +               shadow_ops = sd->s_dentry->d_inode->i_private;
2680 +               tag = shadow_ops->kobject_tag(kobj);
2681 +
2682 +               shadow_sd = find_shadow_sd(sd, tag);
2683 +               if (!shadow_sd)
2684 +                       shadow_sd = add_shadow_sd(sd, tag);
2685 +               sd = shadow_sd;
2686 +       }
2687 +       if (sd) {
2688 +               *parent_sd = sd;
2689 +               return 1;
2690 +       }
2691 +       return 0;
2692 +}
2693  
2694 -       dget(shadow);           /* Extra count - pin the dentry in core */
2695 +int sysfs_resolve_for_remove(struct kobject *kobj,
2696 +                               struct sysfs_dirent **parent_sd)
2697 +{
2698 +       struct sysfs_dirent *sd;
2699 +       /* If dentry is a shadow directory find the shadow that is
2700 +        * stored under the same tag as kobj.  This allows removal
2701 +        * of dirents to function properly even if the value of
2702 +        * kobject_tag() has changed since we initially created
2703 +        * the dirents assoctated with kobj.
2704 +        */
2705  
2706 -       goto out_dput;
2707 +       sd = *parent_sd;
2708 +       if (sysfs_type(sd) == SYSFS_SHADOW_DIR)
2709 +               sd = sd->s_parent;
2710 +       if (sd->s_flags & SYSFS_FLAG_SHADOWED) {
2711 +               const void *tag;
2712  
2713 - nomem:
2714 -       dput(shadow);
2715 -       sd = ERR_PTR(-ENOMEM);
2716 - out_dput:
2717 -       dput(dir);
2718 - out:
2719 -       return sd;
2720 +               tag = find_shadow_tag(kobj);
2721 +               sd = find_shadow_sd(sd, tag);
2722 +       }
2723 +       if (sd) {
2724 +               *parent_sd = sd;
2725 +               return 1;
2726 +       }
2727 +       return 0;
2728  }
2729  
2730  /**
2731 - *     sysfs_remove_shadow_dir - remove an object's directory.
2732 - *     @shadow_sd: sysfs_dirent of shadow directory
2733 + *     sysfs_enable_shadowing - Automatically create shadows of a directory
2734 + *     @kobj:  object to automatically shadow
2735   *
2736 - *     The only thing special about this is that we remove any files in
2737 - *     the directory before we remove the directory, and we've inlined
2738 - *     what used to be sysfs_rmdir() below, instead of calling separately.
2739 + *     Once shadowing has been enabled on a directory the contents
2740 + *     of the directory become dependent upon context.
2741 + *
2742 + *     shadow_ops->current_tag() returns the context for the current
2743 + *     process.
2744 + *
2745 + *     shadow_ops->kobject_tag() returns the context that a given kobj
2746 + *     resides in.
2747 + *
2748 + *     Using those methods the sysfs code on shadowed directories
2749 + *     carefully stores the files so that when we lookup files
2750 + *     we get the proper answer for our context.
2751 + *
2752 + *     If the context of a kobject is changed it is expected that
2753 + *     the kobject will be renamed so the appopriate sysfs data structures
2754 + *     can be updated.
2755   */
2756 -
2757 -void sysfs_remove_shadow_dir(struct sysfs_dirent *shadow_sd)
2758 +int sysfs_enable_shadowing(struct kobject *kobj,
2759 +       const struct shadow_dir_operations *shadow_ops)
2760  {
2761 -       __sysfs_remove_dir(shadow_sd);
2762 +       struct sysfs_dirent *sd;
2763 +       struct dentry *dentry;
2764 +       int err;
2765 +
2766 +       /* Find the dentry for the shadowed directory and
2767 +        * increase it's count.
2768 +        */
2769 +       err = -ENOENT;
2770 +       sd = kobj->sd;
2771 +       dentry = sysfs_get_dentry(sd);
2772 +       if (!dentry)
2773 +               goto out;
2774 +
2775 +       mutex_lock(&sysfs_mutex);
2776 +       err = -EINVAL;
2777 +       /* We can only enable shadowing on empty directories
2778 +        * where shadowing is not already enabled.
2779 +        */
2780 +       if (!sd->s_children && (sysfs_type(sd) == SYSFS_DIR) &&
2781 +           !(sd->s_flags & SYSFS_FLAG_REMOVED) &&
2782 +           !(sd->s_flags & SYSFS_FLAG_SHADOWED)) {
2783 +               sd->s_flags |= SYSFS_FLAG_SHADOWED;
2784 +               dentry->d_inode->i_private = (void *)shadow_ops;
2785 +               err = 0;
2786 +       }
2787 +       mutex_unlock(&sysfs_mutex);
2788 +out:
2789 +       if (err)
2790 +               dput(dentry);
2791 +       return err;
2792  }
2793  
2794 -const struct file_operations sysfs_dir_operations = {
2795 -       .open           = sysfs_dir_open,
2796 -       .release        = sysfs_dir_close,
2797 -       .llseek         = sysfs_dir_lseek,
2798 -       .read           = generic_read_dir,
2799 -       .readdir        = sysfs_readdir,
2800 -};
2801 diff -Nurb linux-2.6.22-try2/fs/sysfs/file.c linux-2.6.22-try2-netns/fs/sysfs/file.c
2802 --- linux-2.6.22-try2/fs/sysfs/file.c   2007-12-19 15:46:06.000000000 -0500
2803 +++ linux-2.6.22-try2-netns/fs/sysfs/file.c     2007-12-19 22:49:13.000000000 -0500
2804 @@ -556,7 +556,7 @@
2805  
2806  void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
2807  {
2808 -       sysfs_hash_and_remove(kobj->sd, attr->name);
2809 +       sysfs_hash_and_remove(kobj, kobj->sd, attr->name);
2810  }
2811  
2812  
2813 @@ -573,7 +573,7 @@
2814  
2815         dir_sd = sysfs_get_dirent(kobj->sd, group);
2816         if (dir_sd) {
2817 -               sysfs_hash_and_remove(dir_sd, attr->name);
2818 +               sysfs_hash_and_remove(kobj, dir_sd, attr->name);
2819                 sysfs_put(dir_sd);
2820         }
2821  }
2822 diff -Nurb linux-2.6.22-try2/fs/sysfs/group.c linux-2.6.22-try2-netns/fs/sysfs/group.c
2823 --- linux-2.6.22-try2/fs/sysfs/group.c  2007-12-19 15:29:23.000000000 -0500
2824 +++ linux-2.6.22-try2-netns/fs/sysfs/group.c    2007-12-19 22:49:13.000000000 -0500
2825 @@ -13,21 +13,20 @@
2826  #include <linux/dcache.h>
2827  #include <linux/namei.h>
2828  #include <linux/err.h>
2829 -#include <linux/fs.h>
2830  #include <asm/semaphore.h>
2831  #include "sysfs.h"
2832  
2833  
2834 -static void remove_files(struct sysfs_dirent *dir_sd,
2835 +static void remove_files(struct kobject *kobj, struct sysfs_dirent *dir_sd,
2836                          const struct attribute_group *grp)
2837  {
2838         struct attribute *const* attr;
2839  
2840         for (attr = grp->attrs; *attr; attr++)
2841 -               sysfs_hash_and_remove(dir_sd, (*attr)->name);
2842 +               sysfs_hash_and_remove(kobj, dir_sd, (*attr)->name);
2843  }
2844  
2845 -static int create_files(struct sysfs_dirent *dir_sd,
2846 +static int create_files(struct kobject *kobj, struct sysfs_dirent *dir_sd,
2847                         const struct attribute_group *grp)
2848  {
2849         struct attribute *const* attr;
2850 @@ -36,7 +35,7 @@
2851         for (attr = grp->attrs; *attr && !error; attr++)
2852                 error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR);
2853         if (error)
2854 -               remove_files(dir_sd, grp);
2855 +               remove_files(kobj, dir_sd, grp);
2856         return error;
2857  }
2858  
2859 @@ -56,7 +55,7 @@
2860         } else
2861                 sd = kobj->sd;
2862         sysfs_get(sd);
2863 -       error = create_files(sd, grp);
2864 +       error = create_files(kobj, sd, grp);
2865         if (error) {
2866                 if (grp->name)
2867                         sysfs_remove_subdir(sd);
2868 @@ -77,7 +76,7 @@
2869         } else
2870                 sd = sysfs_get(dir_sd);
2871  
2872 -       remove_files(sd, grp);
2873 +       remove_files(kobj, sd, grp);
2874         if (grp->name)
2875                 sysfs_remove_subdir(sd);
2876  
2877 diff -Nurb linux-2.6.22-try2/fs/sysfs/inode.c linux-2.6.22-try2-netns/fs/sysfs/inode.c
2878 --- linux-2.6.22-try2/fs/sysfs/inode.c  2007-12-19 15:29:23.000000000 -0500
2879 +++ linux-2.6.22-try2-netns/fs/sysfs/inode.c    2007-12-19 22:49:13.000000000 -0500
2880 @@ -34,16 +34,6 @@
2881         .setattr        = sysfs_setattr,
2882  };
2883  
2884 -void sysfs_delete_inode(struct inode *inode)
2885 -{
2886 -       /* Free the shadowed directory inode operations */
2887 -       if (sysfs_is_shadowed_inode(inode)) {
2888 -               kfree(inode->i_op);
2889 -               inode->i_op = NULL;
2890 -       }
2891 -       return generic_delete_inode(inode);
2892 -}
2893 -
2894  int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
2895  {
2896         struct inode * inode = dentry->d_inode;
2897 @@ -197,17 +187,16 @@
2898         d_instantiate(dentry, inode);
2899  }
2900  
2901 -int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name)
2902 +int sysfs_hash_and_remove(struct kobject *kobj, struct sysfs_dirent *dir_sd, const char *name)
2903  {
2904         struct sysfs_addrm_cxt acxt;
2905         struct sysfs_dirent **pos, *sd;
2906  
2907 -       if (!dir_sd)
2908 -               return -ENOENT;
2909 -
2910         sysfs_addrm_start(&acxt, dir_sd);
2911 +       if (!sysfs_resolve_for_remove(kobj, &acxt.parent_sd))
2912 +               goto addrm_finish;
2913  
2914 -       for (pos = &dir_sd->s_children; *pos; pos = &(*pos)->s_sibling) {
2915 +       for (pos = &acxt.parent_sd->s_children; *pos; pos = &(*pos)->s_sibling) {
2916                 sd = *pos;
2917  
2918                 if (!sysfs_type(sd))
2919 @@ -219,7 +208,7 @@
2920                         break;
2921                 }
2922         }
2923 -
2924 +addrm_finish:
2925         if (sysfs_addrm_finish(&acxt))
2926                 return 0;
2927         return -ENOENT;
2928 diff -Nurb linux-2.6.22-try2/fs/sysfs/mount.c linux-2.6.22-try2-netns/fs/sysfs/mount.c
2929 --- linux-2.6.22-try2/fs/sysfs/mount.c  2007-12-19 15:29:23.000000000 -0500
2930 +++ linux-2.6.22-try2-netns/fs/sysfs/mount.c    2007-12-19 22:49:13.000000000 -0500
2931 @@ -19,7 +19,7 @@
2932  
2933  static const struct super_operations sysfs_ops = {
2934         .statfs         = simple_statfs,
2935 -       .drop_inode     = sysfs_delete_inode,
2936 +       .drop_inode     = generic_delete_inode,
2937  };
2938  
2939  struct sysfs_dirent sysfs_root = {
2940 diff -Nurb linux-2.6.22-try2/fs/sysfs/symlink.c linux-2.6.22-try2-netns/fs/sysfs/symlink.c
2941 --- linux-2.6.22-try2/fs/sysfs/symlink.c        2007-12-19 15:29:23.000000000 -0500
2942 +++ linux-2.6.22-try2-netns/fs/sysfs/symlink.c  2007-12-19 22:49:13.000000000 -0500
2943 @@ -15,8 +15,11 @@
2944  {
2945         int depth = 0;
2946  
2947 -       for (; sd->s_parent; sd = sd->s_parent)
2948 +       for (; sd->s_parent; sd = sd->s_parent) {
2949 +               if (sysfs_type(sd) == SYSFS_SHADOW_DIR)
2950 +                       continue;
2951                 depth++;
2952 +       }
2953  
2954         return depth;
2955  }
2956 @@ -25,17 +28,24 @@
2957  {
2958         int length = 1;
2959  
2960 -       for (; sd->s_parent; sd = sd->s_parent)
2961 +       for (; sd->s_parent; sd = sd->s_parent) {
2962 +               if (sysfs_type(sd) == SYSFS_SHADOW_DIR)
2963 +                       continue;
2964                 length += strlen(sd->s_name) + 1;
2965 +       }
2966  
2967         return length;
2968  }
2969  
2970  static void fill_object_path(struct sysfs_dirent *sd, char *buffer, int length)
2971  {
2972 +       int cur;
2973         --length;
2974         for (; sd->s_parent; sd = sd->s_parent) {
2975 -               int cur = strlen(sd->s_name);
2976 +               if (sysfs_type(sd) == SYSFS_SHADOW_DIR)
2977 +                       continue;
2978 +
2979 +               cur = strlen(sd->s_name);
2980  
2981                 /* back up enough to print this bus id with '/' */
2982                 length -= cur;
2983 @@ -89,12 +99,15 @@
2984         sd->s_elem.symlink.target_sd = target_sd;
2985  
2986         sysfs_addrm_start(&acxt, parent_sd);
2987 +       if (!sysfs_resolve_for_create(target, &acxt.parent_sd))
2988 +               goto addrm_finish;
2989  
2990 -       if (!sysfs_find_dirent(parent_sd, name)) {
2991 +       if (!sysfs_find_dirent(acxt.parent_sd, name)) {
2992                 sysfs_add_one(&acxt, sd);
2993                 sysfs_link_sibling(sd);
2994         }
2995  
2996 +addrm_finish:
2997         if (sysfs_addrm_finish(&acxt))
2998                 return 0;
2999  
3000 @@ -108,6 +121,21 @@
3001  
3002  
3003  /**
3004 + *     sysfs_delete_link - remove symlink in object's directory.
3005 + *     @kobj:  object we're acting for.
3006 + *     @targ:  object we're pointing to.
3007 + *     @name:  name of the symlink to remove.
3008 + *
3009 + *     Unlike sysfs_remove_link sysfs_delete_link has enough information
3010 + *     to successfully delete symlinks in shadow directories.
3011 + */
3012 +void sysfs_delete_link(struct kobject *kobj, struct kobject *targ,
3013 +                       const char *name)
3014 +{
3015 +       sysfs_hash_and_remove(targ, kobj->sd, name);
3016 +}
3017 +
3018 +/**
3019   *     sysfs_remove_link - remove symlink in object's directory.
3020   *     @kobj:  object we're acting for.
3021   *     @name:  name of the symlink to remove.
3022 @@ -115,7 +143,23 @@
3023  
3024  void sysfs_remove_link(struct kobject * kobj, const char * name)
3025  {
3026 -       sysfs_hash_and_remove(kobj->sd, name);
3027 +       sysfs_hash_and_remove(kobj, kobj->sd, name);
3028 +}
3029 +
3030 +/**
3031 + *     sysfs_rename_link - rename symlink in object's directory.
3032 + *     @kobj:  object we're acting for.
3033 + *     @targ:  object we're pointing to.
3034 + *     @old:   previous name of the symlink.
3035 + *     @new:   new name of the symlink.
3036 + *
3037 + *     A helper function for the common rename symlink idiom.
3038 + */
3039 +int sysfs_rename_link(struct kobject *kobj, struct kobject *targ,
3040 +                       const char *old, const char *new)
3041 +{
3042 +       sysfs_delete_link(kobj, targ, old);
3043 +       return sysfs_create_link(kobj, targ, new);
3044  }
3045  
3046  static int sysfs_get_target_path(struct sysfs_dirent * parent_sd,
3047 diff -Nurb linux-2.6.22-try2/fs/sysfs/sysfs.h linux-2.6.22-try2-netns/fs/sysfs/sysfs.h
3048 --- linux-2.6.22-try2/fs/sysfs/sysfs.h  2007-12-19 15:29:23.000000000 -0500
3049 +++ linux-2.6.22-try2-netns/fs/sysfs/sysfs.h    2007-12-19 22:49:13.000000000 -0500
3050 @@ -58,6 +58,12 @@
3051  extern struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd);
3052  extern void sysfs_link_sibling(struct sysfs_dirent *sd);
3053  extern void sysfs_unlink_sibling(struct sysfs_dirent *sd);
3054 +
3055 +extern int sysfs_resolve_for_create(struct kobject *kobj,
3056 +                                   struct sysfs_dirent **parent_sd);
3057 +extern int sysfs_resolve_for_remove(struct kobject *kobj,
3058 +                                   struct sysfs_dirent **parent_sd);
3059 +
3060  extern struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd);
3061  extern void sysfs_put_active(struct sysfs_dirent *sd);
3062  extern struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd);
3063 @@ -70,7 +76,6 @@
3064                              struct sysfs_dirent *sd);
3065  extern int sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt);
3066  
3067 -extern void sysfs_delete_inode(struct inode *inode);
3068  extern void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode);
3069  extern struct inode * sysfs_get_inode(struct sysfs_dirent *sd);
3070  extern void sysfs_instantiate(struct dentry *dentry, struct inode *inode);
3071 @@ -85,7 +90,8 @@
3072  
3073  extern int sysfs_add_file(struct sysfs_dirent *dir_sd,
3074                           const struct attribute *attr, int type);
3075 -extern int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name);
3076 +extern int sysfs_hash_and_remove(struct kobject *kobj,
3077 +                                struct sysfs_dirent *dir_sd, const char *name);
3078  extern struct sysfs_dirent *sysfs_find(struct sysfs_dirent *dir, const char * name);
3079  
3080  extern int sysfs_create_subdir(struct kobject *kobj, const char *name,
3081 @@ -122,8 +128,3 @@
3082         if (sd && atomic_dec_and_test(&sd->s_count))
3083                 release_sysfs_dirent(sd);
3084  }
3085 -
3086 -static inline int sysfs_is_shadowed_inode(struct inode *inode)
3087 -{
3088 -       return S_ISDIR(inode->i_mode) && inode->i_op->follow_link;
3089 -}
3090 diff -Nurb linux-2.6.22-try2/include/linux/device.h linux-2.6.22-try2-netns/include/linux/device.h
3091 --- linux-2.6.22-try2/include/linux/device.h    2007-12-19 15:29:22.000000000 -0500
3092 +++ linux-2.6.22-try2-netns/include/linux/device.h      2007-12-19 22:49:13.000000000 -0500
3093 @@ -200,6 +200,8 @@
3094  
3095         int     (*suspend)(struct device *, pm_message_t state);
3096         int     (*resume)(struct device *);
3097 +
3098 +       const struct shadow_dir_operations *shadow_ops;
3099  };
3100  
3101  extern int __must_check class_register(struct class *);
3102 diff -Nurb linux-2.6.22-try2/include/linux/if_bridge.h linux-2.6.22-try2-netns/include/linux/if_bridge.h
3103 --- linux-2.6.22-try2/include/linux/if_bridge.h 2007-12-19 13:37:51.000000000 -0500
3104 +++ linux-2.6.22-try2-netns/include/linux/if_bridge.h   2007-12-19 22:49:13.000000000 -0500
3105 @@ -104,7 +104,7 @@
3106  
3107  #include <linux/netdevice.h>
3108  
3109 -extern void brioctl_set(int (*ioctl_hook)(unsigned int, void __user *));
3110 +extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
3111  extern struct sk_buff *(*br_handle_frame_hook)(struct net_bridge_port *p,
3112                                                struct sk_buff *skb);
3113  extern int (*br_should_route_hook)(struct sk_buff **pskb);
3114 diff -Nurb linux-2.6.22-try2/include/linux/if_pppox.h linux-2.6.22-try2-netns/include/linux/if_pppox.h
3115 --- linux-2.6.22-try2/include/linux/if_pppox.h  2007-12-19 13:37:51.000000000 -0500
3116 +++ linux-2.6.22-try2-netns/include/linux/if_pppox.h    2007-12-19 22:49:13.000000000 -0500
3117 @@ -160,7 +160,7 @@
3118  struct module;
3119  
3120  struct pppox_proto {
3121 -       int             (*create)(struct socket *sock);
3122 +       int             (*create)(struct net *net, struct socket *sock);
3123         int             (*ioctl)(struct socket *sock, unsigned int cmd,
3124                                  unsigned long arg);
3125         struct module   *owner;
3126 diff -Nurb linux-2.6.22-try2/include/linux/if_vlan.h linux-2.6.22-try2-netns/include/linux/if_vlan.h
3127 --- linux-2.6.22-try2/include/linux/if_vlan.h   2007-12-19 15:29:23.000000000 -0500
3128 +++ linux-2.6.22-try2-netns/include/linux/if_vlan.h     2007-12-19 22:49:13.000000000 -0500
3129 @@ -62,7 +62,7 @@
3130  #define VLAN_VID_MASK  0xfff
3131  
3132  /* found in socket.c */
3133 -extern void vlan_ioctl_set(int (*hook)(void __user *));
3134 +extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *));
3135  
3136  #define VLAN_NAME "vlan"
3137  
3138 diff -Nurb linux-2.6.22-try2/include/linux/inetdevice.h linux-2.6.22-try2-netns/include/linux/inetdevice.h
3139 --- linux-2.6.22-try2/include/linux/inetdevice.h        2007-12-19 13:37:51.000000000 -0500
3140 +++ linux-2.6.22-try2-netns/include/linux/inetdevice.h  2007-12-19 22:49:13.000000000 -0500
3141 @@ -17,8 +17,6 @@
3142         DECLARE_BITMAP(state, __NET_IPV4_CONF_MAX - 1);
3143  };
3144  
3145 -extern struct ipv4_devconf ipv4_devconf;
3146 -
3147  struct in_device
3148  {
3149         struct net_device       *dev;
3150 @@ -44,7 +42,7 @@
3151  };
3152  
3153  #define IPV4_DEVCONF(cnf, attr) ((cnf).data[NET_IPV4_CONF_ ## attr - 1])
3154 -#define IPV4_DEVCONF_ALL(attr) IPV4_DEVCONF(ipv4_devconf, attr)
3155 +#define IPV4_DEVCONF_ALL(net, attr) IPV4_DEVCONF(*((net)->ipv4_devconf), attr)
3156  
3157  static inline int ipv4_devconf_get(struct in_device *in_dev, int index)
3158  {
3159 @@ -71,14 +69,14 @@
3160         ipv4_devconf_set((in_dev), NET_IPV4_CONF_ ## attr, (val))
3161  
3162  #define IN_DEV_ANDCONF(in_dev, attr) \
3163 -       (IPV4_DEVCONF_ALL(attr) && IN_DEV_CONF_GET((in_dev), attr))
3164 +       (IPV4_DEVCONF_ALL((in_dev)->dev->nd_net, attr) && IN_DEV_CONF_GET((in_dev), attr))
3165  #define IN_DEV_ORCONF(in_dev, attr) \
3166 -       (IPV4_DEVCONF_ALL(attr) || IN_DEV_CONF_GET((in_dev), attr))
3167 +       (IPV4_DEVCONF_ALL((in_dev)->dev->nd_net, attr) || IN_DEV_CONF_GET((in_dev), attr))
3168  #define IN_DEV_MAXCONF(in_dev, attr) \
3169 -       (max(IPV4_DEVCONF_ALL(attr), IN_DEV_CONF_GET((in_dev), attr)))
3170 +       (max(IPV4_DEVCONF_ALL((in_dev)->dev->nd_net, attr), IN_DEV_CONF_GET((in_dev), attr)))
3171  
3172  #define IN_DEV_FORWARD(in_dev)         IN_DEV_CONF_GET((in_dev), FORWARDING)
3173 -#define IN_DEV_MFORWARD(in_dev)                (IPV4_DEVCONF_ALL(MC_FORWARDING) && \
3174 +#define IN_DEV_MFORWARD(in_dev)                (IPV4_DEVCONF_ALL((in_dev)->dev->nd_net, MC_FORWARDING) && \
3175                                          IPV4_DEVCONF((in_dev)->cnf, \
3176                                                       MC_FORWARDING))
3177  #define IN_DEV_RPFILTER(in_dev)                IN_DEV_ANDCONF((in_dev), RP_FILTER)
3178 @@ -127,15 +125,15 @@
3179  extern int register_inetaddr_notifier(struct notifier_block *nb);
3180  extern int unregister_inetaddr_notifier(struct notifier_block *nb);
3181  
3182 -extern struct net_device       *ip_dev_find(__be32 addr);
3183 +extern struct net_device       *ip_dev_find(struct net *net, __be32 addr);
3184  extern int             inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b);
3185 -extern int             devinet_ioctl(unsigned int cmd, void __user *);
3186 +extern int             devinet_ioctl(struct net *net, unsigned int cmd, void __user *);
3187  extern void            devinet_init(void);
3188 -extern struct in_device        *inetdev_by_index(int);
3189 +extern struct in_device        *inetdev_by_index(struct net *, int);
3190  extern __be32          inet_select_addr(const struct net_device *dev, __be32 dst, int scope);
3191 -extern __be32          inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope);
3192 +extern __be32          inet_confirm_addr(struct net *net, const struct net_device *dev, __be32 dst, __be32 local, int scope);
3193  extern struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix, __be32 mask);
3194 -extern void            inet_forward_change(void);
3195 +extern void            inet_forward_change(struct net *net);
3196  
3197  static __inline__ int inet_ifa_match(__be32 addr, struct in_ifaddr *ifa)
3198  {
3199 diff -Nurb linux-2.6.22-try2/include/linux/init_task.h linux-2.6.22-try2-netns/include/linux/init_task.h
3200 --- linux-2.6.22-try2/include/linux/init_task.h 2007-12-19 15:29:24.000000000 -0500
3201 +++ linux-2.6.22-try2-netns/include/linux/init_task.h   2007-12-19 22:49:13.000000000 -0500
3202 @@ -9,6 +9,7 @@
3203  #include <linux/ipc.h>
3204  #include <linux/pid_namespace.h>
3205  #include <linux/user_namespace.h>
3206 +#include <net/net_namespace.h>
3207  
3208  #define INIT_FDTABLE \
3209  {                                                      \
3210 @@ -78,6 +79,7 @@
3211         .nslock         = __SPIN_LOCK_UNLOCKED(nsproxy.nslock),         \
3212         .uts_ns         = &init_uts_ns,                                 \
3213         .mnt_ns         = NULL,                                         \
3214 +       .net_ns         = &init_net,                                    \
3215         INIT_IPC_NS(ipc_ns)                                             \
3216         .user_ns        = &init_user_ns,                                \
3217  }
3218 diff -Nurb linux-2.6.22-try2/include/linux/kobject.h linux-2.6.22-try2-netns/include/linux/kobject.h
3219 --- linux-2.6.22-try2/include/linux/kobject.h   2007-12-19 15:29:23.000000000 -0500
3220 +++ linux-2.6.22-try2-netns/include/linux/kobject.h     2007-12-19 22:49:13.000000000 -0500
3221 @@ -71,14 +71,9 @@
3222  extern void kobject_cleanup(struct kobject *);
3223  
3224  extern int __must_check kobject_add(struct kobject *);
3225 -extern int __must_check kobject_shadow_add(struct kobject *kobj,
3226 -                                          struct sysfs_dirent *shadow_parent);
3227  extern void kobject_del(struct kobject *);
3228  
3229  extern int __must_check kobject_rename(struct kobject *, const char *new_name);
3230 -extern int __must_check kobject_shadow_rename(struct kobject *kobj,
3231 -                                             struct sysfs_dirent *new_parent,
3232 -                                             const char *new_name);
3233  extern int __must_check kobject_move(struct kobject *, struct kobject *);
3234  
3235  extern int __must_check kobject_register(struct kobject *);
3236 diff -Nurb linux-2.6.22-try2/include/linux/net.h linux-2.6.22-try2-netns/include/linux/net.h
3237 --- linux-2.6.22-try2/include/linux/net.h       2007-12-19 13:37:51.000000000 -0500
3238 +++ linux-2.6.22-try2-netns/include/linux/net.h 2007-12-19 22:49:13.000000000 -0500
3239 @@ -23,6 +23,7 @@
3240  
3241  struct poll_table_struct;
3242  struct inode;
3243 +struct net;
3244  
3245  #define NPROTO         34              /* should be enough for now..   */
3246  
3247 @@ -170,7 +171,7 @@
3248  
3249  struct net_proto_family {
3250         int             family;
3251 -       int             (*create)(struct socket *sock, int protocol);
3252 +       int             (*create)(struct net *net, struct socket *sock, int protocol);
3253         struct module   *owner;
3254  };
3255  
3256 diff -Nurb linux-2.6.22-try2/include/linux/netdevice.h linux-2.6.22-try2-netns/include/linux/netdevice.h
3257 --- linux-2.6.22-try2/include/linux/netdevice.h 2007-12-19 15:29:23.000000000 -0500
3258 +++ linux-2.6.22-try2-netns/include/linux/netdevice.h   2007-12-19 22:49:13.000000000 -0500
3259 @@ -39,6 +39,7 @@
3260  #include <linux/percpu.h>
3261  #include <linux/dmaengine.h>
3262  
3263 +struct net;
3264  struct vlan_group;
3265  struct ethtool_ops;
3266  struct netpoll_info;
3267 @@ -326,6 +327,7 @@
3268  #define NETIF_F_VLAN_CHALLENGED        1024    /* Device cannot handle VLAN packets */
3269  #define NETIF_F_GSO            2048    /* Enable software GSO. */
3270  #define NETIF_F_LLTX           4096    /* LockLess TX */
3271 +#define NETIF_F_NETNS_LOCAL    8192    /* Does not change network namespaces */
3272  
3273         /* Segmentation offload features */
3274  #define NETIF_F_GSO_SHIFT      16
3275 @@ -537,6 +539,9 @@
3276         void                    (*poll_controller)(struct net_device *dev);
3277  #endif
3278  
3279 +       /* Network namespace this network device is inside */
3280 +       struct net              *nd_net;
3281 +
3282         /* bridge stuff */
3283         struct net_bridge_port  *br_port;
3284  
3285 @@ -583,45 +588,48 @@
3286  #include <linux/interrupt.h>
3287  #include <linux/notifier.h>
3288  
3289 -extern struct net_device               loopback_dev;           /* The loopback */
3290 -extern struct list_head                        dev_base_head;          /* All devices */
3291  extern rwlock_t                                dev_base_lock;          /* Device list lock */
3292  
3293 -#define for_each_netdev(d)             \
3294 -               list_for_each_entry(d, &dev_base_head, dev_list)
3295 -#define for_each_netdev_safe(d, n)     \
3296 -               list_for_each_entry_safe(d, n, &dev_base_head, dev_list)
3297 -#define for_each_netdev_continue(d)            \
3298 -               list_for_each_entry_continue(d, &dev_base_head, dev_list)
3299 -#define net_device_entry(lh)   list_entry(lh, struct net_device, dev_list)
3300 -
3301 -static inline struct net_device *next_net_device(struct net_device *dev)
3302 -{
3303 -       struct list_head *lh;
3304  
3305 -       lh = dev->dev_list.next;
3306 -       return lh == &dev_base_head ? NULL : net_device_entry(lh);
3307 -}
3308 +#define for_each_netdev(net, d)                \
3309 +               list_for_each_entry(d, &(net)->dev_base_head, dev_list)
3310 +#define for_each_netdev_safe(net, d, n)        \
3311 +               list_for_each_entry_safe(d, n, &(net)->dev_base_head, dev_list)
3312 +#define for_each_netdev_continue(net, d)               \
3313 +               list_for_each_entry_continue(d, &(net)->dev_base_head, dev_list)
3314 +#define net_device_entry(lh)   list_entry(lh, struct net_device, dev_list)
3315  
3316 -static inline struct net_device *first_net_device(void)
3317 -{
3318 -       return list_empty(&dev_base_head) ? NULL :
3319 -               net_device_entry(dev_base_head.next);
3320 -}
3321 +#define next_net_device(d)                                             \
3322 +({                                                                     \
3323 +       struct net_device *dev = d;                                     \
3324 +       struct list_head *lh;                                           \
3325 +       struct net *net;                                                \
3326 +                                                                       \
3327 +       net = dev->nd_net;                                              \
3328 +       lh = dev->dev_list.next;                                        \
3329 +       lh == &net->dev_base_head ? NULL : net_device_entry(lh);        \
3330 +})
3331 +
3332 +#define first_net_device(N)                                    \
3333 +({                                                             \
3334 +       struct net *NET = (N);                                  \
3335 +       list_empty(&NET->dev_base_head) ? NULL :                \
3336 +               net_device_entry(NET->dev_base_head.next);      \
3337 +})
3338  
3339  extern int                     netdev_boot_setup_check(struct net_device *dev);
3340  extern unsigned long           netdev_boot_base(const char *prefix, int unit);
3341 -extern struct net_device    *dev_getbyhwaddr(unsigned short type, char *hwaddr);
3342 -extern struct net_device *dev_getfirstbyhwtype(unsigned short type);
3343 -extern struct net_device *__dev_getfirstbyhwtype(unsigned short type);
3344 +extern struct net_device    *dev_getbyhwaddr(struct net *net, unsigned short type, char *hwaddr);
3345 +extern struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type);
3346 +extern struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type);
3347  extern void            dev_add_pack(struct packet_type *pt);
3348  extern void            dev_remove_pack(struct packet_type *pt);
3349  extern void            __dev_remove_pack(struct packet_type *pt);
3350  
3351 -extern struct net_device       *dev_get_by_flags(unsigned short flags,
3352 +extern struct net_device       *dev_get_by_flags(struct net *net, unsigned short flags,
3353                                                   unsigned short mask);
3354 -extern struct net_device       *dev_get_by_name(const char *name);
3355 -extern struct net_device       *__dev_get_by_name(const char *name);
3356 +extern struct net_device       *dev_get_by_name(struct net *net, const char *name);
3357 +extern struct net_device       *__dev_get_by_name(struct net *net, const char *name);
3358  extern int             dev_alloc_name(struct net_device *dev, const char *name);
3359  extern int             dev_open(struct net_device *dev);
3360  extern int             dev_close(struct net_device *dev);
3361 @@ -632,9 +640,9 @@
3362  extern void            synchronize_net(void);
3363  extern int             register_netdevice_notifier(struct notifier_block *nb);
3364  extern int             unregister_netdevice_notifier(struct notifier_block *nb);
3365 -extern int             call_netdevice_notifiers(unsigned long val, void *v);
3366 -extern struct net_device       *dev_get_by_index(int ifindex);
3367 -extern struct net_device       *__dev_get_by_index(int ifindex);
3368 +extern int call_netdevice_notifiers(unsigned long val, struct net_device *dev);
3369 +extern struct net_device       *dev_get_by_index(struct net *net, int ifindex);
3370 +extern struct net_device       *__dev_get_by_index(struct net *net, int ifindex);
3371  extern int             dev_restart(struct net_device *dev);
3372  #ifdef CONFIG_NETPOLL_TRAP
3373  extern int             netpoll_trap(void);
3374 @@ -739,11 +747,13 @@
3375  #define HAVE_NETIF_RECEIVE_SKB 1
3376  extern int             netif_receive_skb(struct sk_buff *skb);
3377  extern int             dev_valid_name(const char *name);
3378 -extern int             dev_ioctl(unsigned int cmd, void __user *);
3379 -extern int             dev_ethtool(struct ifreq *);
3380 +extern int             dev_ioctl(struct net *net, unsigned int cmd, void __user *);
3381 +extern int             dev_ethtool(struct net *net, struct ifreq *);
3382  extern unsigned                dev_get_flags(const struct net_device *);
3383  extern int             dev_change_flags(struct net_device *, unsigned);
3384  extern int             dev_change_name(struct net_device *, char *);
3385 +extern int             dev_change_net_namespace(struct net_device *,
3386 +                                                struct net *, const char *);
3387  extern int             dev_set_mtu(struct net_device *, int);
3388  extern int             dev_set_mac_address(struct net_device *,
3389                                             struct sockaddr *);
3390 @@ -1013,7 +1023,7 @@
3391  extern void            netdev_state_change(struct net_device *dev);
3392  extern void            netdev_features_change(struct net_device *dev);
3393  /* Load a device via the kmod */
3394 -extern void            dev_load(const char *name);
3395 +extern void            dev_load(struct net *net, const char *name);
3396  extern void            dev_mcast_init(void);
3397  extern int             netdev_max_backlog;
3398  extern int             weight_p;
3399 diff -Nurb linux-2.6.22-try2/include/linux/netfilter/x_tables.h linux-2.6.22-try2-netns/include/linux/netfilter/x_tables.h
3400 --- linux-2.6.22-try2/include/linux/netfilter/x_tables.h        2007-12-19 13:37:51.000000000 -0500
3401 +++ linux-2.6.22-try2-netns/include/linux/netfilter/x_tables.h  2007-12-19 22:49:13.000000000 -0500
3402 @@ -289,7 +289,7 @@
3403                            unsigned int size, const char *table, unsigned int hook,
3404                            unsigned short proto, int inv_proto);
3405  
3406 -extern int xt_register_table(struct xt_table *table,
3407 +extern int xt_register_table(struct net *net, struct xt_table *table,
3408                              struct xt_table_info *bootstrap,
3409                              struct xt_table_info *newinfo);
3410  extern void *xt_unregister_table(struct xt_table *table);
3411 @@ -306,7 +306,7 @@
3412  extern int xt_find_revision(int af, const char *name, u8 revision, int target,
3413                             int *err);
3414  
3415 -extern struct xt_table *xt_find_table_lock(int af, const char *name);
3416 +extern struct xt_table *xt_find_table_lock(struct net *net, int af, const char *name);
3417  extern void xt_table_unlock(struct xt_table *t);
3418  
3419  extern int xt_proto_init(int af);
3420 diff -Nurb linux-2.6.22-try2/include/linux/netfilter.h linux-2.6.22-try2-netns/include/linux/netfilter.h
3421 --- linux-2.6.22-try2/include/linux/netfilter.h 2007-12-19 13:37:51.000000000 -0500
3422 +++ linux-2.6.22-try2-netns/include/linux/netfilter.h   2007-12-19 22:49:13.000000000 -0500
3423 @@ -362,11 +362,6 @@
3424  #endif
3425  }
3426  
3427 -#ifdef CONFIG_PROC_FS
3428 -#include <linux/proc_fs.h>
3429 -extern struct proc_dir_entry *proc_net_netfilter;
3430 -#endif
3431 -
3432  #else /* !CONFIG_NETFILTER */
3433  #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
3434  #define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb)
3435 diff -Nurb linux-2.6.22-try2/include/linux/netfilter_ipv4/ip_tables.h linux-2.6.22-try2-netns/include/linux/netfilter_ipv4/ip_tables.h
3436 --- linux-2.6.22-try2/include/linux/netfilter_ipv4/ip_tables.h  2007-12-19 13:37:52.000000000 -0500
3437 +++ linux-2.6.22-try2-netns/include/linux/netfilter_ipv4/ip_tables.h    2007-12-19 22:49:13.000000000 -0500
3438 @@ -292,7 +292,7 @@
3439  #include <linux/init.h>
3440  extern void ipt_init(void) __init;
3441  
3442 -extern int ipt_register_table(struct xt_table *table,
3443 +extern int ipt_register_table(struct net *net, struct xt_table *table,
3444                               const struct ipt_replace *repl);
3445  extern void ipt_unregister_table(struct xt_table *table);
3446  
3447 diff -Nurb linux-2.6.22-try2/include/linux/netfilter_ipv4.h linux-2.6.22-try2-netns/include/linux/netfilter_ipv4.h
3448 --- linux-2.6.22-try2/include/linux/netfilter_ipv4.h    2007-12-19 13:37:52.000000000 -0500
3449 +++ linux-2.6.22-try2-netns/include/linux/netfilter_ipv4.h      2007-12-19 22:49:13.000000000 -0500
3450 @@ -75,7 +75,7 @@
3451  #define SO_ORIGINAL_DST 80
3452  
3453  #ifdef __KERNEL__
3454 -extern int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type);
3455 +extern int ip_route_me_harder(struct net *net, struct sk_buff **pskb, unsigned addr_type);
3456  extern int ip_xfrm_me_harder(struct sk_buff **pskb);
3457  extern __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
3458                                    unsigned int dataoff, u_int8_t protocol);
3459 diff -Nurb linux-2.6.22-try2/include/linux/netlink.h linux-2.6.22-try2-netns/include/linux/netlink.h
3460 --- linux-2.6.22-try2/include/linux/netlink.h   2007-12-19 15:29:22.000000000 -0500
3461 +++ linux-2.6.22-try2-netns/include/linux/netlink.h     2007-12-19 22:49:13.000000000 -0500
3462 @@ -27,6 +27,8 @@
3463  
3464  #define MAX_LINKS 32           
3465  
3466 +struct net;
3467 +
3468  struct sockaddr_nl
3469  {
3470         sa_family_t     nl_family;      /* AF_NETLINK   */
3471 @@ -157,7 +159,8 @@
3472  #define NETLINK_CREDS(skb)     (&NETLINK_CB((skb)).creds)
3473  
3474  
3475 -extern struct sock *netlink_kernel_create(int unit, unsigned int groups,
3476 +extern struct sock *netlink_kernel_create(struct net *net,
3477 +                                         int unit,unsigned int groups,
3478                                           void (*input)(struct sock *sk, int len),
3479                                           struct mutex *cb_mutex,
3480                                           struct module *module);
3481 @@ -204,6 +207,7 @@
3482  
3483  struct netlink_notify
3484  {
3485 +       struct net *net;
3486         int pid;
3487         int protocol;
3488  };
3489 diff -Nurb linux-2.6.22-try2/include/linux/nsproxy.h linux-2.6.22-try2-netns/include/linux/nsproxy.h
3490 --- linux-2.6.22-try2/include/linux/nsproxy.h   2007-12-19 15:50:41.000000000 -0500
3491 +++ linux-2.6.22-try2-netns/include/linux/nsproxy.h     2007-12-19 22:57:59.000000000 -0500
3492 @@ -36,6 +36,7 @@
3493         struct mnt_namespace *mnt_ns;
3494         struct pid_namespace *pid_ns;
3495         struct user_namespace *user_ns;
3496 +       struct net           *net_ns;
3497  };
3498  extern struct nsproxy init_nsproxy;
3499  
3500 diff -Nurb linux-2.6.22-try2/include/linux/proc_fs.h linux-2.6.22-try2-netns/include/linux/proc_fs.h
3501 --- linux-2.6.22-try2/include/linux/proc_fs.h   2007-12-19 15:29:24.000000000 -0500
3502 +++ linux-2.6.22-try2-netns/include/linux/proc_fs.h     2007-12-19 22:49:13.000000000 -0500
3503 @@ -86,8 +86,6 @@
3504  
3505  extern struct proc_dir_entry proc_root;
3506  extern struct proc_dir_entry *proc_root_fs;
3507 -extern struct proc_dir_entry *proc_net;
3508 -extern struct proc_dir_entry *proc_net_stat;
3509  extern struct proc_dir_entry *proc_bus;
3510  extern struct proc_dir_entry *proc_root_driver;
3511  extern struct proc_dir_entry *proc_root_kcore;
3512 @@ -112,6 +110,10 @@
3513  extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
3514                                                 struct proc_dir_entry *parent);
3515  extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
3516 +static inline void remove_proc_pde(struct proc_dir_entry *pde)
3517 +{
3518 +       return remove_proc_entry(pde->name, pde->parent);
3519 +}
3520  
3521  extern struct vfsmount *proc_mnt;
3522  extern int proc_fill_super(struct super_block *,void *,int);
3523 @@ -181,42 +183,18 @@
3524         return res;
3525  }
3526   
3527 -static inline struct proc_dir_entry *proc_net_create(const char *name,
3528 -       mode_t mode, get_info_t *get_info)
3529 -{
3530 -       return create_proc_info_entry(name,mode,proc_net,get_info);
3531 -}
3532 -
3533 -static inline struct proc_dir_entry *proc_net_fops_create(const char *name,
3534 -       mode_t mode, const struct file_operations *fops)
3535 -{
3536 -       struct proc_dir_entry *res = create_proc_entry(name, mode, proc_net);
3537 -       if (res)
3538 -               res->proc_fops = fops;
3539 -       return res;
3540 -}
3541 -
3542 -static inline void proc_net_remove(const char *name)
3543 -{
3544 -       remove_proc_entry(name,proc_net);
3545 -}
3546 -
3547  #else
3548  
3549  #define proc_root_driver NULL
3550 -#define proc_net NULL
3551  #define proc_bus NULL
3552  
3553 -#define proc_net_fops_create(name, mode, fops)  ({ (void)(mode), NULL; })
3554 -#define proc_net_create(name, mode, info)      ({ (void)(mode), NULL; })
3555 -static inline void proc_net_remove(const char *name) {}
3556 -
3557  static inline void proc_flush_task(struct task_struct *task) { }
3558  
3559  static inline struct proc_dir_entry *create_proc_entry(const char *name,
3560         mode_t mode, struct proc_dir_entry *parent) { return NULL; }
3561  
3562  #define remove_proc_entry(name, parent) do {} while (0)
3563 +#define remove_proc_pde(PDE) do {} while (0)
3564  
3565  static inline struct proc_dir_entry *proc_symlink(const char *name,
3566                 struct proc_dir_entry *parent,const char *dest) {return NULL;}
3567 diff -Nurb linux-2.6.22-try2/include/linux/rtnetlink.h linux-2.6.22-try2-netns/include/linux/rtnetlink.h
3568 --- linux-2.6.22-try2/include/linux/rtnetlink.h 2007-12-19 15:29:23.000000000 -0500
3569 +++ linux-2.6.22-try2-netns/include/linux/rtnetlink.h   2007-12-19 22:49:13.000000000 -0500
3570 @@ -580,11 +580,11 @@
3571  ({     data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
3572         __rtattr_parse_nested_compat(tb, max, rta, len); })
3573  
3574 -extern int rtnetlink_send(struct sk_buff *skb, u32 pid, u32 group, int echo);
3575 -extern int rtnl_unicast(struct sk_buff *skb, u32 pid);
3576 -extern int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group,
3577 +extern int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, u32 group, int echo);
3578 +extern int rtnl_unicast(struct sk_buff *skb, struct net *net, u32 pid);
3579 +extern int rtnl_notify(struct sk_buff *skb, struct net *net, u32 pid, u32 group,
3580                        struct nlmsghdr *nlh, gfp_t flags);
3581 -extern void rtnl_set_sk_err(u32 group, int error);
3582 +extern void rtnl_set_sk_err(struct net *net, u32 group, int error);
3583  extern int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics);
3584  extern int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst,
3585                               u32 id, u32 ts, u32 tsage, long expires,
3586 diff -Nurb linux-2.6.22-try2/include/linux/sched.h linux-2.6.22-try2-netns/include/linux/sched.h
3587 --- linux-2.6.22-try2/include/linux/sched.h     2007-12-19 15:50:06.000000000 -0500
3588 +++ linux-2.6.22-try2-netns/include/linux/sched.h       2007-12-19 22:58:22.000000000 -0500
3589 @@ -28,6 +28,7 @@
3590  #define CLONE_NEWIPC           0x08000000      /* New ipcs */
3591  #define CLONE_NEWUSER          0x10000000      /* New user namespace */
3592  #define CLONE_KTHREAD          0x10000000      /* clone a kernel thread */
3593 +#define CLONE_NEWNET           0x40000000      /* New network namespace */
3594  
3595  /*
3596   * Scheduling policies
3597 diff -Nurb linux-2.6.22-try2/include/linux/socket.h linux-2.6.22-try2-netns/include/linux/socket.h
3598 --- linux-2.6.22-try2/include/linux/socket.h    2007-12-19 13:37:52.000000000 -0500
3599 +++ linux-2.6.22-try2-netns/include/linux/socket.h      2007-12-19 22:49:13.000000000 -0500
3600 @@ -24,7 +24,6 @@
3601  #include <linux/types.h>               /* pid_t                        */
3602  #include <linux/compiler.h>            /* __user                       */
3603  
3604 -extern int sysctl_somaxconn;
3605  #ifdef CONFIG_PROC_FS
3606  struct seq_file;
3607  extern void socket_seq_show(struct seq_file *seq);
3608 diff -Nurb linux-2.6.22-try2/include/linux/sysctl.h linux-2.6.22-try2-netns/include/linux/sysctl.h
3609 --- linux-2.6.22-try2/include/linux/sysctl.h    2007-12-19 15:29:24.000000000 -0500
3610 +++ linux-2.6.22-try2-netns/include/linux/sysctl.h      2007-12-19 22:49:13.000000000 -0500
3611 @@ -31,6 +31,7 @@
3612  
3613  struct file;
3614  struct completion;
3615 +struct net;
3616  
3617  #define CTL_MAXNAME 10         /* how many path components do we allow in a
3618                                    call to sysctl?   In other words, what is
3619 @@ -985,6 +986,7 @@
3620                                void __user *oldval, size_t __user *oldlenp,
3621                                void __user *newval, size_t newlen);
3622  
3623 +extern ctl_handler sysctl_data;
3624  extern ctl_handler sysctl_string;
3625  extern ctl_handler sysctl_intvec;
3626  extern ctl_handler sysctl_jiffies;
3627 @@ -1061,6 +1063,12 @@
3628  
3629  void unregister_sysctl_table(struct ctl_table_header * table);
3630  
3631 +#ifdef CONFIG_NET
3632 +extern struct ctl_table_header *register_net_sysctl_table(struct net *net, struct ctl_table *table);
3633 +extern void unregister_net_sysctl_table(struct ctl_table_header *header);
3634 +extern ctl_table net_root_table[];
3635 +#endif
3636 +
3637  #else /* __KERNEL__ */
3638  
3639  #endif /* __KERNEL__ */
3640 diff -Nurb linux-2.6.22-try2/include/linux/sysfs.h linux-2.6.22-try2-netns/include/linux/sysfs.h
3641 --- linux-2.6.22-try2/include/linux/sysfs.h     2007-12-19 15:29:23.000000000 -0500
3642 +++ linux-2.6.22-try2-netns/include/linux/sysfs.h       2007-12-19 22:49:13.000000000 -0500
3643 @@ -19,9 +19,6 @@
3644  
3645  struct kobject;
3646  struct module;
3647 -struct nameidata;
3648 -struct dentry;
3649 -struct sysfs_dirent;
3650  
3651  /* FIXME
3652   * The *owner field is no longer used, but leave around
3653 @@ -79,16 +76,23 @@
3654         ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
3655  };
3656  
3657 +struct shadow_dir_operations {
3658 +       const void *(*current_tag)(void);
3659 +       const void *(*kobject_tag)(struct kobject *kobj);
3660 +};
3661 +
3662  #define SYSFS_TYPE_MASK                0x00ff
3663  #define SYSFS_ROOT             0x0001
3664  #define SYSFS_DIR              0x0002
3665  #define SYSFS_KOBJ_ATTR        0x0004
3666  #define SYSFS_KOBJ_BIN_ATTR    0x0008
3667  #define SYSFS_KOBJ_LINK        0x0020
3668 +#define SYSFS_SHADOW_DIR       0x0040
3669  #define SYSFS_COPY_NAME                (SYSFS_DIR | SYSFS_KOBJ_LINK)
3670  
3671  #define SYSFS_FLAG_MASK                ~SYSFS_TYPE_MASK
3672  #define SYSFS_FLAG_REMOVED     0x0100
3673 +#define SYSFS_FLAG_SHADOWED    0x0200
3674  
3675  #ifdef CONFIG_SYSFS
3676  
3677 @@ -96,14 +100,13 @@
3678                 void (*func)(void *), void *data, struct module *owner);
3679  
3680  extern int __must_check
3681 -sysfs_create_dir(struct kobject *kobj, struct sysfs_dirent *shadow_parent_sd);
3682 +sysfs_create_dir(struct kobject *);
3683  
3684  extern void
3685  sysfs_remove_dir(struct kobject *);
3686  
3687  extern int __must_check
3688 -sysfs_rename_dir(struct kobject *kobj, struct sysfs_dirent *new_parent_sd,
3689 -                const char *new_name);
3690 +sysfs_rename_dir(struct kobject *kobj, const char *new_name);
3691  
3692  extern int __must_check
3693  sysfs_move_dir(struct kobject *, struct kobject *);
3694 @@ -126,6 +129,13 @@
3695  extern void
3696  sysfs_remove_link(struct kobject *, const char * name);
3697  
3698 +extern int
3699 +sysfs_rename_link(struct kobject *kobj, struct kobject *target,
3700 +                       const char *old_name, const char *new_name);
3701 +
3702 +extern void
3703 +sysfs_delete_link(struct kobject *dir, struct kobject *targ, const char *name);
3704 +
3705  int __must_check sysfs_create_bin_file(struct kobject *kobj,
3706                                         struct bin_attribute *attr);
3707  void sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr);
3708 @@ -140,11 +150,7 @@
3709  
3710  void sysfs_notify(struct kobject * k, char *dir, char *attr);
3711  
3712 -
3713 -extern int sysfs_make_shadowed_dir(struct kobject *kobj,
3714 -       void * (*follow_link)(struct dentry *, struct nameidata *));
3715 -extern struct sysfs_dirent *sysfs_create_shadow_dir(struct kobject *kobj);
3716 -extern void sysfs_remove_shadow_dir(struct sysfs_dirent *shadow_sd);
3717 +int sysfs_enable_shadowing(struct kobject *, const struct shadow_dir_operations *);
3718  
3719  extern int __must_check sysfs_init(void);
3720  
3721 @@ -156,8 +162,7 @@
3722         return -ENOSYS;
3723  }
3724  
3725 -static inline int sysfs_create_dir(struct kobject *kobj,
3726 -                                  struct sysfs_dirent *shadow_parent_sd)
3727 +static inline int sysfs_create_dir(struct kobject * kobj)
3728  {
3729         return 0;
3730  }
3731 @@ -167,9 +172,7 @@
3732         ;
3733  }
3734  
3735 -static inline int sysfs_rename_dir(struct kobject *kobj,
3736 -                                  struct sysfs_dirent *new_parent_sd,
3737 -                                  const char *new_name)
3738 +static inline int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
3739  {
3740         return 0;
3741  }
3742 @@ -208,6 +211,17 @@
3743         ;
3744  }
3745  
3746 +static inline int
3747 +sysfs_rename_link(struct kobject * k, struct kobject *t,
3748 +                       const char *old_name, const char * new_name)
3749 +{
3750 +       return 0;
3751 +}
3752 +
3753 +static inline void
3754 +sysfs_delete_link(struct kobject *k, struct kobject *t, const char *name)
3755 +{
3756 +}
3757  
3758  static inline int sysfs_create_bin_file(struct kobject * k, struct bin_attribute * a)
3759  {
3760 @@ -244,8 +258,8 @@
3761  {
3762  }
3763  
3764 -static inline int sysfs_make_shadowed_dir(struct kobject *kobj,
3765 -       void * (*follow_link)(struct dentry *, struct nameidata *))
3766 +static inline int sysfs_enable_shadowing(struct kobject *kobj,
3767 +                               const struct shadow_dir_operations *shadow_ops)
3768  {
3769         return 0;
3770  }
3771 diff -Nurb linux-2.6.22-try2/include/net/af_unix.h linux-2.6.22-try2-netns/include/net/af_unix.h
3772 --- linux-2.6.22-try2/include/net/af_unix.h     2007-12-19 13:37:54.000000000 -0500
3773 +++ linux-2.6.22-try2-netns/include/net/af_unix.h       2007-12-19 22:49:13.000000000 -0500
3774 @@ -91,12 +91,11 @@
3775  #define unix_sk(__sk) ((struct unix_sock *)__sk)
3776  
3777  #ifdef CONFIG_SYSCTL
3778 -extern int sysctl_unix_max_dgram_qlen;
3779 -extern void unix_sysctl_register(void);
3780 -extern void unix_sysctl_unregister(void);
3781 +extern void unix_sysctl_register(struct net *net);
3782 +extern void unix_sysctl_unregister(struct net *net);
3783  #else
3784 -static inline void unix_sysctl_register(void) {}
3785 -static inline void unix_sysctl_unregister(void) {}
3786 +static inline void unix_sysctl_register(struct net *net) {}
3787 +static inline void unix_sysctl_unregister(struct net *net) {}
3788  #endif
3789  #endif
3790  #endif
3791 diff -Nurb linux-2.6.22-try2/include/net/arp.h linux-2.6.22-try2-netns/include/net/arp.h
3792 --- linux-2.6.22-try2/include/net/arp.h 2007-12-19 13:37:54.000000000 -0500
3793 +++ linux-2.6.22-try2-netns/include/net/arp.h   2007-12-19 22:49:13.000000000 -0500
3794 @@ -11,7 +11,7 @@
3795  
3796  extern void    arp_init(void);
3797  extern int     arp_find(unsigned char *haddr, struct sk_buff *skb);
3798 -extern int     arp_ioctl(unsigned int cmd, void __user *arg);
3799 +extern int     arp_ioctl(struct net *net, unsigned int cmd, void __user *arg);
3800  extern void     arp_send(int type, int ptype, __be32 dest_ip,
3801                          struct net_device *dev, __be32 src_ip,
3802                          unsigned char *dest_hw, unsigned char *src_hw, unsigned char *th);
3803 diff -Nurb linux-2.6.22-try2/include/net/fib_rules.h linux-2.6.22-try2-netns/include/net/fib_rules.h
3804 --- linux-2.6.22-try2/include/net/fib_rules.h   2007-12-19 13:37:54.000000000 -0500
3805 +++ linux-2.6.22-try2-netns/include/net/fib_rules.h     2007-12-19 22:49:13.000000000 -0500
3806 @@ -56,12 +56,12 @@
3807         int                     (*fill)(struct fib_rule *, struct sk_buff *,
3808                                         struct nlmsghdr *,
3809                                         struct fib_rule_hdr *);
3810 -       u32                     (*default_pref)(void);
3811 +       u32                     (*default_pref)(struct fib_rules_ops *ops);
3812         size_t                  (*nlmsg_payload)(struct fib_rule *);
3813  
3814         /* Called after modifications to the rules set, must flush
3815          * the route cache if one exists. */
3816 -       void                    (*flush_cache)(void);
3817 +       void                    (*flush_cache)(struct fib_rules_ops *ops);
3818  
3819         int                     nlgroup;
3820         const struct nla_policy *policy;
3821 @@ -101,8 +101,8 @@
3822         return frh->table;
3823  }
3824  
3825 -extern int                     fib_rules_register(struct fib_rules_ops *);
3826 -extern int                     fib_rules_unregister(struct fib_rules_ops *);
3827 +extern int                     fib_rules_register(struct net *net, struct fib_rules_ops *);
3828 +extern int                     fib_rules_unregister(struct net *net, struct fib_rules_ops *);
3829  
3830  extern int                     fib_rules_lookup(struct fib_rules_ops *,
3831                                                  struct flowi *, int flags,
3832 diff -Nurb linux-2.6.22-try2/include/net/flow.h linux-2.6.22-try2-netns/include/net/flow.h
3833 --- linux-2.6.22-try2/include/net/flow.h        2007-12-19 15:29:23.000000000 -0500
3834 +++ linux-2.6.22-try2-netns/include/net/flow.h  2007-12-19 22:49:13.000000000 -0500
3835 @@ -8,9 +8,11 @@
3836  #define _NET_FLOW_H
3837  
3838  #include <linux/in6.h>
3839 +#include <net/net_namespace.h>
3840  #include <asm/atomic.h>
3841  
3842  struct flowi {
3843 +       struct net *fl_net;
3844         int     oif;
3845         int     iif;
3846         __u32   mark;
3847 diff -Nurb linux-2.6.22-try2/include/net/inet6_hashtables.h linux-2.6.22-try2-netns/include/net/inet6_hashtables.h
3848 --- linux-2.6.22-try2/include/net/inet6_hashtables.h    2007-12-19 13:37:54.000000000 -0500
3849 +++ linux-2.6.22-try2-netns/include/net/inet6_hashtables.h      2007-12-19 22:49:13.000000000 -0500
3850 @@ -62,31 +62,31 @@
3851                                            const __be16 sport,
3852                                            const struct in6_addr *daddr,
3853                                            const u16 hnum,
3854 -                                          const int dif);
3855 +                                          const int dif, struct net *net);
3856  
3857  extern struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
3858                                           const struct in6_addr *daddr,
3859                                           const unsigned short hnum,
3860 -                                         const int dif);
3861 +                                         const int dif, struct net *net);
3862  
3863  static inline struct sock *__inet6_lookup(struct inet_hashinfo *hashinfo,
3864                                           const struct in6_addr *saddr,
3865                                           const __be16 sport,
3866                                           const struct in6_addr *daddr,
3867                                           const u16 hnum,
3868 -                                         const int dif)
3869 +                                         const int dif, struct net *net)
3870  {
3871         struct sock *sk = __inet6_lookup_established(hashinfo, saddr, sport,
3872 -                                                    daddr, hnum, dif);
3873 +                                                    daddr, hnum, dif, net);
3874         if (sk)
3875                 return sk;
3876  
3877 -       return inet6_lookup_listener(hashinfo, daddr, hnum, dif);
3878 +       return inet6_lookup_listener(hashinfo, daddr, hnum, dif, net);
3879  }
3880  
3881  extern struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
3882                                  const struct in6_addr *saddr, const __be16 sport,
3883                                  const struct in6_addr *daddr, const __be16 dport,
3884 -                                const int dif);
3885 +                                const int dif, struct net *net);
3886  #endif /* defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) */
3887  #endif /* _INET6_HASHTABLES_H */
3888 diff -Nurb linux-2.6.22-try2/include/net/inet_hashtables.h linux-2.6.22-try2-netns/include/net/inet_hashtables.h
3889 --- linux-2.6.22-try2/include/net/inet_hashtables.h     2007-12-19 13:37:54.000000000 -0500
3890 +++ linux-2.6.22-try2-netns/include/net/inet_hashtables.h       2007-12-19 22:49:13.000000000 -0500
3891 @@ -75,6 +75,7 @@
3892   * ports are created in O(1) time?  I thought so. ;-)  -DaveM
3893   */
3894  struct inet_bind_bucket {
3895 +       struct net              *net;
3896         unsigned short          port;
3897         signed short            fastreuse;
3898         struct hlist_node       node;
3899 @@ -138,34 +139,35 @@
3900  extern struct inet_bind_bucket *
3901                     inet_bind_bucket_create(struct kmem_cache *cachep,
3902                                             struct inet_bind_hashbucket *head,
3903 +                                           struct net *net,
3904                                             const unsigned short snum);
3905  extern void inet_bind_bucket_destroy(struct kmem_cache *cachep,
3906                                      struct inet_bind_bucket *tb);
3907  
3908 -static inline int inet_bhashfn(const __u16 lport, const int bhash_size)
3909 +static inline int inet_bhashfn(struct net *net, const __u16 lport, const int bhash_size)
3910  {
3911 -       return lport & (bhash_size - 1);
3912 +       return (((unsigned long)net) ^ lport) & (bhash_size - 1);
3913  }
3914  
3915  extern void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb,
3916                            const unsigned short snum);
3917  
3918  /* These can have wildcards, don't try too hard. */
3919 -static inline int inet_lhashfn(const unsigned short num)
3920 +static inline int inet_lhashfn(struct net *net, const unsigned short num)
3921  {
3922 -       return num & (INET_LHTABLE_SIZE - 1);
3923 +       return (((unsigned long)net) ^ num) & (INET_LHTABLE_SIZE - 1);
3924  }
3925  
3926  static inline int inet_sk_listen_hashfn(const struct sock *sk)
3927  {
3928 -       return inet_lhashfn(inet_sk(sk)->num);
3929 +       return inet_lhashfn(sk->sk_net, inet_sk(sk)->num);
3930  }
3931  
3932  /* Caller must disable local BH processing. */
3933  static inline void __inet_inherit_port(struct inet_hashinfo *table,
3934                                        struct sock *sk, struct sock *child)
3935  {
3936 -       const int bhash = inet_bhashfn(inet_sk(child)->num, table->bhash_size);
3937 +       const int bhash = inet_bhashfn(sk->sk_net, inet_sk(child)->num, table->bhash_size);
3938         struct inet_bind_hashbucket *head = &table->bhash[bhash];
3939         struct inet_bind_bucket *tb;
3940  
3941 @@ -274,12 +276,13 @@
3942  extern struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
3943                                            const __be32 daddr,
3944                                            const unsigned short hnum,
3945 -                                          const int dif);
3946 +                                          const int dif, struct net *net);
3947  
3948  static inline struct sock *inet_lookup_listener(struct inet_hashinfo *hashinfo,
3949 -                                               __be32 daddr, __be16 dport, int dif)
3950 +                                               __be32 daddr, __be16 dport,
3951 +                                               int dif, struct net *net)
3952  {
3953 -       return __inet_lookup_listener(hashinfo, daddr, ntohs(dport), dif);
3954 +       return __inet_lookup_listener(hashinfo, daddr, ntohs(dport), dif, net);
3955  }
3956  
3957  /* Socket demux engine toys. */
3958 @@ -313,30 +316,34 @@
3959                                    (((__force __u64)(__be32)(__daddr)) << 32) | \
3960                                    ((__force __u64)(__be32)(__saddr)));
3961  #endif /* __BIG_ENDIAN */
3962 -#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
3963 +#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif, __net)\
3964         (((__sk)->sk_hash == (__hash))                          &&      \
3965          ((*((__addrpair *)&(inet_sk(__sk)->daddr))) == (__cookie))     &&      \
3966          ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports))      &&      \
3967 -        (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
3968 -#define INET_TW_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
3969 +        (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))) && \
3970 +        ((__sk)->sk_net == __net))
3971 +#define INET_TW_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif, __net)\
3972         (((__sk)->sk_hash == (__hash))                          &&      \
3973          ((*((__addrpair *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) &&     \
3974          ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) &&      \
3975 -        (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
3976 +        (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))) && \
3977 +        ((__sk)->sk_net == __net))
3978  #else /* 32-bit arch */
3979  #define INET_ADDR_COOKIE(__name, __saddr, __daddr)
3980 -#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)   \
3981 +#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif, __net) \
3982         (((__sk)->sk_hash == (__hash))                          &&      \
3983          (inet_sk(__sk)->daddr          == (__saddr))           &&      \
3984          (inet_sk(__sk)->rcv_saddr      == (__daddr))           &&      \
3985          ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports))      &&      \
3986 -        (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
3987 -#define INET_TW_MATCH(__sk, __hash,__cookie, __saddr, __daddr, __ports, __dif) \
3988 +        (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))) && \
3989 +        ((__sk)->sk_net == __net))
3990 +#define INET_TW_MATCH(__sk, __hash,__cookie, __saddr, __daddr, __ports, __dif, __net) \
3991         (((__sk)->sk_hash == (__hash))                          &&      \
3992          (inet_twsk(__sk)->tw_daddr     == (__saddr))           &&      \
3993          (inet_twsk(__sk)->tw_rcv_saddr == (__daddr))           &&      \
3994          ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) &&      \
3995 -        (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
3996 +        (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))) && \
3997 +        ((__sk)->sk_net == __net))
3998  #endif /* 64-bit arch */
3999  
4000  /*
4001 @@ -349,7 +356,7 @@
4002         __inet_lookup_established(struct inet_hashinfo *hashinfo,
4003                                   const __be32 saddr, const __be16 sport,
4004                                   const __be32 daddr, const u16 hnum,
4005 -                                 const int dif)
4006 +                                 const int dif, struct net *net)
4007  {
4008         INET_ADDR_COOKIE(acookie, saddr, daddr)
4009         const __portpair ports = INET_COMBINED_PORTS(sport, hnum);
4010 @@ -358,19 +365,19 @@
4011         /* Optimize here for direct hit, only listening connections can
4012          * have wildcards anyways.
4013          */
4014 -       unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport);
4015 +       unsigned int hash = inet_ehashfn(net, daddr, hnum, saddr, sport);
4016         struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);
4017  
4018         prefetch(head->chain.first);
4019         read_lock(&head->lock);
4020         sk_for_each(sk, node, &head->chain) {
4021 -               if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
4022 +               if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif, net))
4023                         goto hit; /* You sunk my battleship! */
4024         }
4025  
4026         /* Must check for a TIME_WAIT'er before going to listener hash. */
4027         sk_for_each(sk, node, &head->twchain) {
4028 -               if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
4029 +               if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif, net))
4030                         goto hit;
4031         }
4032         sk = NULL;
4033 @@ -386,32 +393,32 @@
4034         inet_lookup_established(struct inet_hashinfo *hashinfo,
4035                                 const __be32 saddr, const __be16 sport,
4036                                 const __be32 daddr, const __be16 dport,
4037 -                               const int dif)
4038 +                               const int dif, struct net *net)
4039  {
4040         return __inet_lookup_established(hashinfo, saddr, sport, daddr,
4041 -                                        ntohs(dport), dif);
4042 +                                        ntohs(dport), dif, net);
4043  }
4044  
4045  static inline struct sock *__inet_lookup(struct inet_hashinfo *hashinfo,
4046                                          const __be32 saddr, const __be16 sport,
4047                                          const __be32 daddr, const __be16 dport,
4048 -                                        const int dif)
4049 +                                        const int dif, struct net *net)
4050  {
4051         u16 hnum = ntohs(dport);
4052         struct sock *sk = __inet_lookup_established(hashinfo, saddr, sport, daddr,
4053 -                                                   hnum, dif);
4054 -       return sk ? : __inet_lookup_listener(hashinfo, daddr, hnum, dif);
4055 +                                                   hnum, dif, net);
4056 +       return sk ? : __inet_lookup_listener(hashinfo, daddr, hnum, dif, net);
4057  }
4058  
4059  static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo,
4060                                        const __be32 saddr, const __be16 sport,
4061                                        const __be32 daddr, const __be16 dport,
4062 -                                      const int dif)
4063 +                                      const int dif, struct net *net)
4064  {
4065         struct sock *sk;
4066  
4067         local_bh_disable();
4068 -       sk = __inet_lookup(hashinfo, saddr, sport, daddr, dport, dif);
4069 +       sk = __inet_lookup(hashinfo, saddr, sport, daddr, dport, dif, net);
4070         local_bh_enable();
4071  
4072         return sk;
4073 diff -Nurb linux-2.6.22-try2/include/net/inet_sock.h linux-2.6.22-try2-netns/include/net/inet_sock.h
4074 --- linux-2.6.22-try2/include/net/inet_sock.h   2007-12-19 13:37:54.000000000 -0500
4075 +++ linux-2.6.22-try2-netns/include/net/inet_sock.h     2007-12-19 22:49:13.000000000 -0500
4076 @@ -171,10 +171,12 @@
4077  extern u32 inet_ehash_secret;
4078  extern void build_ehash_secret(void);
4079  
4080 -static inline unsigned int inet_ehashfn(const __be32 laddr, const __u16 lport,
4081 +static inline unsigned int inet_ehashfn(struct net *net,
4082 +                                       const __be32 laddr, const __u16 lport,
4083                                         const __be32 faddr, const __be16 fport)
4084  {
4085 -       return jhash_2words((__force __u32) laddr ^ (__force __u32) faddr,
4086 +       return jhash_2words((__force __u32) laddr ^ (__force __u32) faddr ^
4087 +                           (__force __u32) ((unsigned long)net),
4088                             ((__u32) lport) << 16 | (__force __u32)fport,
4089                             inet_ehash_secret);
4090  }
4091 @@ -187,7 +189,7 @@
4092         const __be32 faddr = inet->daddr;
4093         const __be16 fport = inet->dport;
4094  
4095 -       return inet_ehashfn(laddr, lport, faddr, fport);
4096 +       return inet_ehashfn(sk->sk_net, laddr, lport, faddr, fport);
4097  }
4098  
4099  #endif /* _INET_SOCK_H */
4100 diff -Nurb linux-2.6.22-try2/include/net/inet_timewait_sock.h linux-2.6.22-try2-netns/include/net/inet_timewait_sock.h
4101 --- linux-2.6.22-try2/include/net/inet_timewait_sock.h  2007-12-19 13:37:54.000000000 -0500
4102 +++ linux-2.6.22-try2-netns/include/net/inet_timewait_sock.h    2007-12-19 22:58:33.000000000 -0500
4103 @@ -115,6 +115,7 @@
4104  #define tw_refcnt              __tw_common.skc_refcnt
4105  #define tw_hash                        __tw_common.skc_hash
4106  #define tw_prot                        __tw_common.skc_prot
4107 +#define tw_net                 __tw_common.skc_net
4108  #define tw_xid         __tw_common.skc_xid
4109  #define tw_vx_info             __tw_common.skc_vx_info
4110  #define tw_nid         __tw_common.skc_nid
4111 diff -Nurb linux-2.6.22-try2/include/net/inetpeer.h linux-2.6.22-try2-netns/include/net/inetpeer.h
4112 --- linux-2.6.22-try2/include/net/inetpeer.h    2007-12-19 13:37:54.000000000 -0500
4113 +++ linux-2.6.22-try2-netns/include/net/inetpeer.h      2007-12-19 22:49:13.000000000 -0500
4114 @@ -15,6 +15,8 @@
4115  #include <linux/spinlock.h>
4116  #include <asm/atomic.h>
4117  
4118 +struct net;
4119 +
4120  struct inet_peer
4121  {
4122         /* group together avl_left,avl_right,v4daddr to speedup lookups */
4123 @@ -22,7 +24,11 @@
4124         __be32                  v4daddr;        /* peer's address */
4125         __u16                   avl_height;
4126         __u16                   ip_id_count;    /* IP ID for the next packet */
4127 -       struct inet_peer        *unused_next, **unused_prevp;
4128 +       union {
4129 +               struct inet_peer        *unused_next;
4130 +               struct net              *net;
4131 +       } u;
4132 +       struct inet_peer        **unused_prevp;
4133         __u32                   dtime;          /* the time of last use of not
4134                                                  * referenced entries */
4135         atomic_t                refcnt;
4136 @@ -34,7 +40,7 @@
4137  void                   inet_initpeers(void) __init;
4138  
4139  /* can be called with or without local BH being disabled */
4140 -struct inet_peer       *inet_getpeer(__be32 daddr, int create);
4141 +struct inet_peer       *inet_getpeer(struct net *net, __be32 daddr, int create);
4142  
4143  /* can be called from BH context or outside */
4144  extern void inet_putpeer(struct inet_peer *p);
4145 diff -Nurb linux-2.6.22-try2/include/net/ip.h linux-2.6.22-try2-netns/include/net/ip.h
4146 --- linux-2.6.22-try2/include/net/ip.h  2007-12-19 13:37:54.000000000 -0500
4147 +++ linux-2.6.22-try2-netns/include/net/ip.h    2007-12-19 22:49:13.000000000 -0500
4148 @@ -149,13 +149,6 @@
4149  void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg,
4150                    unsigned int len); 
4151  
4152 -struct ipv4_config
4153 -{
4154 -       int     log_martians;
4155 -       int     no_pmtu_disc;
4156 -};
4157 -
4158 -extern struct ipv4_config ipv4_config;
4159  DECLARE_SNMP_STAT(struct ipstats_mib, ip_statistics);
4160  #define IP_INC_STATS(field)            SNMP_INC_STATS(ip_statistics, field)
4161  #define IP_INC_STATS_BH(field)         SNMP_INC_STATS_BH(ip_statistics, field)
4162 @@ -171,27 +164,6 @@
4163  extern int snmp_mib_init(void *ptr[2], size_t mibsize, size_t mibalign);
4164  extern void snmp_mib_free(void *ptr[2]);
4165  
4166 -extern int sysctl_local_port_range[2];
4167 -extern int sysctl_ip_default_ttl;
4168 -extern int sysctl_ip_nonlocal_bind;
4169 -
4170 -/* From ip_fragment.c */
4171 -extern int sysctl_ipfrag_high_thresh; 
4172 -extern int sysctl_ipfrag_low_thresh;
4173 -extern int sysctl_ipfrag_time;
4174 -extern int sysctl_ipfrag_secret_interval;
4175 -extern int sysctl_ipfrag_max_dist;
4176 -
4177 -/* From inetpeer.c */
4178 -extern int inet_peer_threshold;
4179 -extern int inet_peer_minttl;
4180 -extern int inet_peer_maxttl;
4181 -extern int inet_peer_gc_mintime;
4182 -extern int inet_peer_gc_maxtime;
4183 -
4184 -/* From ip_output.c */
4185 -extern int sysctl_ip_dynaddr;
4186 -
4187  extern void ipfrag_init(void);
4188  
4189  #ifdef CONFIG_INET
4190 @@ -332,8 +304,6 @@
4191  };
4192  
4193  struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user);
4194 -extern int ip_frag_nqueues;
4195 -extern atomic_t ip_frag_mem;
4196  
4197  /*
4198   *     Functions provided by ip_forward.c
4199 @@ -392,5 +362,6 @@
4200  #endif
4201  
4202  extern struct ctl_table ipv4_table[];
4203 +extern struct ctl_table multi_ipv4_table[];
4204  
4205  #endif /* _IP_H */
4206 diff -Nurb linux-2.6.22-try2/include/net/ip_fib.h linux-2.6.22-try2-netns/include/net/ip_fib.h
4207 --- linux-2.6.22-try2/include/net/ip_fib.h      2007-12-19 15:29:23.000000000 -0500
4208 +++ linux-2.6.22-try2-netns/include/net/ip_fib.h        2007-12-19 22:49:13.000000000 -0500
4209 @@ -85,6 +85,10 @@
4210  #ifdef CONFIG_IP_ROUTE_MULTIPATH
4211         int                     fib_power;
4212  #endif
4213 +#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
4214 +       u32                     fib_mp_alg;
4215 +#endif
4216 +       struct net *            fib_net;
4217         struct fib_nh           fib_nh[0];
4218  #define fib_dev                fib_nh[0].nh_dev
4219  };
4220 @@ -155,43 +159,43 @@
4221  
4222  #ifndef CONFIG_IP_MULTIPLE_TABLES
4223  
4224 -extern struct fib_table *ip_fib_local_table;
4225 -extern struct fib_table *ip_fib_main_table;
4226 -
4227 -static inline struct fib_table *fib_get_table(u32 id)
4228 +static inline struct fib_table *fib_get_table(struct net *net, u32 id)
4229  {
4230         if (id != RT_TABLE_LOCAL)
4231 -               return ip_fib_main_table;
4232 -       return ip_fib_local_table;
4233 +               return net->ip_fib_main_table;
4234 +       return net->ip_fib_local_table;
4235  }
4236  
4237 -static inline struct fib_table *fib_new_table(u32 id)
4238 +static inline struct fib_table *fib_new_table(struct net *net, u32 id)
4239  {
4240 -       return fib_get_table(id);
4241 +       return fib_get_table(net, id);
4242  }
4243  
4244  static inline int fib_lookup(const struct flowi *flp, struct fib_result *res)
4245  {
4246 -       if (ip_fib_local_table->tb_lookup(ip_fib_local_table, flp, res) &&
4247 -           ip_fib_main_table->tb_lookup(ip_fib_main_table, flp, res))
4248 +       struct net *net = flp->fl_net;
4249 +       struct fib_table *local_table = net->ip_fib_local_table;
4250 +       struct fib_table *main_table = net->ip_fib_main_table;
4251 +       if (local_table->tb_lookup(local_table, flp, res) &&
4252 +           main_table->tb_lookup(main_table, flp, res))
4253                 return -ENETUNREACH;
4254         return 0;
4255  }
4256  
4257  static inline void fib_select_default(const struct flowi *flp, struct fib_result *res)
4258  {
4259 +       struct net *net = flp->fl_net;
4260 +       struct fib_table *main_table = net->ip_fib_main_table;
4261         if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
4262 -               ip_fib_main_table->tb_select_default(ip_fib_main_table, flp, res);
4263 +               main_table->tb_select_default(main_table, flp, res);
4264  }
4265  
4266  #else /* CONFIG_IP_MULTIPLE_TABLES */
4267 -#define ip_fib_local_table fib_get_table(RT_TABLE_LOCAL)
4268 -#define ip_fib_main_table fib_get_table(RT_TABLE_MAIN)
4269  
4270  extern int fib_lookup(struct flowi *flp, struct fib_result *res);
4271  
4272 -extern struct fib_table *fib_new_table(u32 id);
4273 -extern struct fib_table *fib_get_table(u32 id);
4274 +extern struct fib_table *fib_new_table(struct net *net, u32 id);
4275 +extern struct fib_table *fib_get_table(struct net *net, u32 id);
4276  extern void fib_select_default(const struct flowi *flp, struct fib_result *res);
4277  
4278  #endif /* CONFIG_IP_MULTIPLE_TABLES */
4279 @@ -207,15 +211,17 @@
4280  
4281  /* Exported by fib_semantics.c */
4282  extern int ip_fib_check_default(__be32 gw, struct net_device *dev);
4283 -extern int fib_sync_down(__be32 local, struct net_device *dev, int force);
4284 +extern int fib_sync_down(struct net *net, __be32 local, struct net_device *dev, int force);
4285  extern int fib_sync_up(struct net_device *dev);
4286  extern __be32  __fib_res_prefsrc(struct fib_result *res);
4287  
4288  /* Exported by fib_hash.c */
4289  extern struct fib_table *fib_hash_init(u32 id);
4290 +extern void fib_hash_exit(struct fib_table *tb);
4291  
4292  #ifdef CONFIG_IP_MULTIPLE_TABLES
4293 -extern void __init fib4_rules_init(void);
4294 +extern void fib4_rules_init(struct net * net);
4295 +extern void fib4_rules_exit(struct net * net);
4296  
4297  #ifdef CONFIG_NET_CLS_ROUTE
4298  extern u32 fib_rules_tclass(struct fib_result *res);
4299 @@ -258,8 +264,11 @@
4300  }
4301  
4302  #ifdef CONFIG_PROC_FS
4303 -extern int  fib_proc_init(void);
4304 -extern void fib_proc_exit(void);
4305 +extern int  fib_proc_init(struct net * net);
4306 +extern void fib_proc_exit(struct net * net);
4307  #endif
4308  
4309 +extern int  fib_info_init(struct net *net);
4310 +extern void fib_info_exit(struct net *net);
4311 +
4312  #endif  /* _NET_FIB_H */
4313 diff -Nurb linux-2.6.22-try2/include/net/llc_conn.h linux-2.6.22-try2-netns/include/net/llc_conn.h
4314 --- linux-2.6.22-try2/include/net/llc_conn.h    2007-12-19 13:37:54.000000000 -0500
4315 +++ linux-2.6.22-try2-netns/include/net/llc_conn.h      2007-12-19 22:49:13.000000000 -0500
4316 @@ -93,7 +93,7 @@
4317         return skb->cb[sizeof(skb->cb) - 1];
4318  }
4319  
4320 -extern struct sock *llc_sk_alloc(int family, gfp_t priority,
4321 +extern struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority,
4322                                  struct proto *prot);
4323  extern void llc_sk_free(struct sock *sk);
4324  
4325 diff -Nurb linux-2.6.22-try2/include/net/neighbour.h linux-2.6.22-try2-netns/include/net/neighbour.h
4326 --- linux-2.6.22-try2/include/net/neighbour.h   2007-12-19 13:37:54.000000000 -0500
4327 +++ linux-2.6.22-try2-netns/include/net/neighbour.h     2007-12-19 22:49:13.000000000 -0500
4328 @@ -34,6 +34,7 @@
4329  
4330  struct neigh_parms
4331  {
4332 +       struct net *net;
4333         struct net_device *dev;
4334         struct neigh_parms *next;
4335         int     (*neigh_setup)(struct neighbour *);
4336 @@ -126,6 +127,7 @@
4337  struct pneigh_entry
4338  {
4339         struct pneigh_entry     *next;
4340 +       struct net              *net;
4341         struct net_device               *dev;
4342         u8                      flags;
4343         u8                      key[0];
4344 @@ -187,6 +189,7 @@
4345                                              const void *pkey,
4346                                              struct net_device *dev);
4347  extern struct neighbour *      neigh_lookup_nodev(struct neigh_table *tbl,
4348 +                                                  struct net *net,
4349                                                    const void *pkey);
4350  extern struct neighbour *      neigh_create(struct neigh_table *tbl,
4351                                              const void *pkey,
4352 @@ -205,21 +208,24 @@
4353                                                 struct net_device *dev);
4354  
4355  extern struct neigh_parms      *neigh_parms_alloc(struct net_device *dev, struct neigh_table *tbl);
4356 +extern struct neigh_parms      *neigh_parms_alloc_default(struct neigh_table *tbl, struct net *net);
4357  extern void                    neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms);
4358  extern void                    neigh_parms_destroy(struct neigh_parms *parms);
4359  extern unsigned long           neigh_rand_reach_time(unsigned long base);
4360  
4361  extern void                    pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
4362                                                struct sk_buff *skb);
4363 -extern struct pneigh_entry     *pneigh_lookup(struct neigh_table *tbl, const void *key, struct net_device *dev, int creat);
4364 -extern int                     pneigh_delete(struct neigh_table *tbl, const void *key, struct net_device *dev);
4365 +extern struct pneigh_entry     *pneigh_lookup(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev, int creat);
4366 +extern int                     pneigh_delete(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev);
4367  
4368  extern void neigh_app_ns(struct neighbour *n);
4369  extern void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void *), void *cookie);
4370  extern void __neigh_for_each_release(struct neigh_table *tbl, int (*cb)(struct neighbour *));
4371  extern void pneigh_for_each(struct neigh_table *tbl, void (*cb)(struct pneigh_entry *));
4372  
4373 -struct neigh_seq_state {
4374 +struct neigh_seq_state
4375 +{
4376 +       struct net *net;
4377         struct neigh_table *tbl;
4378         void *(*neigh_sub_iter)(struct neigh_seq_state *state,
4379                                 struct neighbour *n, loff_t *pos);
4380 diff -Nurb linux-2.6.22-try2/include/net/net_namespace.h linux-2.6.22-try2-netns/include/net/net_namespace.h
4381 --- linux-2.6.22-try2/include/net/net_namespace.h       1969-12-31 19:00:00.000000000 -0500
4382 +++ linux-2.6.22-try2-netns/include/net/net_namespace.h 2007-12-19 22:49:13.000000000 -0500
4383 @@ -0,0 +1,236 @@
4384 +/*
4385 + * Operations on the network namespace
4386 + */
4387 +#ifndef __NET_NET_NAMESPACE_H
4388 +#define __NET_NET_NAMESPACE_H
4389 +
4390 +#include <asm/atomic.h>
4391 +#include <linux/workqueue.h>
4392 +#include <linux/list.h>
4393 +#include <linux/proc_fs.h>
4394 +#include <linux/sysctl.h>
4395 +#include <linux/netdevice.h>
4396 +#include <linux/timer.h>
4397 +
4398 +struct sock;
4399 +struct xt_af_pernet;
4400 +struct ipv4_devconf;
4401 +struct neigh_parms;
4402 +struct inet_peer;
4403 +struct xt_table;
4404 +struct net {
4405 +       atomic_t count;         /* To decided when the network namespace
4406 +                                * should go
4407 +                                */
4408 +       atomic_t use_count;     /* For references we destroy on demand */
4409 +       struct list_head list;  /* list of network namespace structures */
4410 +       struct work_struct work;        /* work struct for freeing */
4411 +
4412 +#ifdef CONFIG_PROC_FS
4413 +       struct proc_dir_entry *proc_net;
4414 +       struct proc_dir_entry *proc_net_stat;
4415 +       struct proc_dir_entry proc_net_root;
4416 +# ifdef CONFIG_NETFILTER
4417 +       struct proc_dir_entry *proc_net_netfilter;
4418 +# endif
4419 +#endif
4420 +#ifdef CONFIG_SYSCTL
4421 +       struct ctl_table_header net_table_header;
4422 +#endif
4423 +       struct net_device       loopback_dev;           /* The loopback */
4424 +       struct list_head        dev_base_head;          /* All devices */
4425 +
4426 +       struct hlist_head       *dev_name_head;
4427 +       struct hlist_head       *dev_index_head;
4428 +
4429 +       struct sock *           rtnl;   /* rtnetlink socket */
4430 +
4431 +
4432 +       /* core netfilter */
4433 +       struct xt_af_pernet *   xtn;
4434 +
4435 +       /* core fib_rules */
4436 +       struct list_head        rules_ops;
4437 +       spinlock_t              rules_mod_lock;
4438 +
4439 +#ifdef CONFIG_XFRM
4440 +       u32                     sysctl_xfrm_aevent_etime;
4441 +       u32                     sysctl_xfrm_aevent_rseqth;
4442 +       int                     sysctl_xfrm_larval_drop;
4443 +       u32                     sysctl_xfrm_acq_expires;
4444 +#endif /* CONFIG_XFRM */
4445 +
4446 +       int                     sysctl_somaxconn;
4447 +
4448 +#ifdef CONFIG_PACKET
4449 +       /* List of all packet sockets. */
4450 +       rwlock_t                packet_sklist_lock;
4451 +       struct hlist_head       packet_sklist;
4452 +#endif /* CONFIG_PACKET */
4453 +#ifdef CONFIG_UNIX
4454 +       int                     sysctl_unix_max_dgram_qlen;
4455 +       void *                  unix_sysctl;
4456 +#endif /* CONFIG_UNIX */
4457 +#ifdef CONFIG_IP_MULTIPLE_TABLES
4458 +       void *                  fib4_table;
4459 +#endif /* CONFIG_IP_MULTIPLE_TABLES */
4460 +#ifdef CONFIG_IP_FIB_HASH
4461 +       int                     fn_hash_last_dflt;
4462 +#endif
4463 +#ifdef CONFIG_IP_FIB_TRIE
4464 +       int                     trie_last_dflt;
4465 +#endif
4466 +#ifndef CONFIG_IP_MULTIPLE_TABLES
4467 +       struct fib_table        *ip_fib_local_table;
4468 +       struct fib_table        *ip_fib_main_table;
4469 +#endif
4470 +       struct hlist_head       *ip_fib_table_hash;
4471 +       struct sock             *nlfl;
4472 +
4473 +       /* fib_semantics */
4474 +       struct hlist_head       *fib_info_hash;
4475 +       struct hlist_head       *fib_info_laddrhash;
4476 +       unsigned int            fib_info_hash_size;
4477 +       unsigned int            fib_info_cnt;
4478 +       struct hlist_head       *fib_info_devhash;
4479 +
4480 +       /* af_inet.c */
4481 +       int                     sysctl_ip_nonlocal_bind; /* __read_mostly */
4482 +       int                     sysctl_ip_default_ttl;  /* __read_mostly */
4483 +       int                     sysctl_ipfrag_high_thresh;
4484 +       int                     sysctl_ipfrag_low_thresh;
4485 +       int                     sysctl_ipfrag_time;
4486 +       int                     sysctl_ipfrag_secret_interval;
4487 +       int                     sysctl_ipfrag_max_dist;
4488 +       int                     sysctl_ipv4_no_pmtu_disc;
4489 +       int                     sysctl_local_port_range[2];
4490 +       int                     sysctl_ip_dynaddr;
4491 +       int                     sysctl_tcp_timestamps;  /* __read_mostly */
4492 +       int                     sysctl_tcp_window_scaling; /* __read_mostly */
4493 +       /* inetpeer.c */
4494 +       int                     inet_peer_threshold;
4495 +       int                     inet_peer_minttl;
4496 +       int                     inet_peer_maxttl;
4497 +       int                     inet_peer_gc_mintime;
4498 +       int                     inet_peer_gc_maxtime;
4499 +
4500 +       /* devinet */
4501 +       struct ipv4_devconf     *ipv4_devconf;
4502 +       struct ipv4_devconf     *ipv4_devconf_dflt;
4503 +
4504 +       /* arp.c */
4505 +       struct neigh_parms      *arp_neigh_parms_default;
4506 +
4507 +       /* icmp.c */
4508 +       struct socket           **__icmp_socket;
4509 +
4510 +       /* inetpeer.c */
4511 +       struct inet_peer        *peer_root;
4512 +       int                     peer_total;
4513 +       struct inet_peer        *inet_peer_unused_head;
4514 +       struct inet_peer        **inet_peer_unused_tailp;
4515 +       struct timer_list       peer_periodic_timer;
4516 +
4517 +       /* ip_fragment.c */
4518 +       struct hlist_head       *ipq_hash;
4519 +       u32                     ipfrag_hash_rnd;
4520 +       struct list_head        ipq_lru_list;
4521 +       int                     ip_frag_nqueues;
4522 +       atomic_t                ip_frag_mem;
4523 +       struct timer_list       ipfrag_secret_timer;
4524 +
4525 +       /* udp.c */
4526 +       int                     udp_port_rover;
4527 +
4528 +       /* iptable_filter.c */
4529 +       struct xt_table         *ip_packet_filter;
4530 +};
4531 +
4532 +extern struct net init_net;
4533 +extern struct list_head net_namespace_list;
4534 +
4535 +extern struct net *copy_net_ns(unsigned long flags, struct net *net_ns);
4536 +extern void __put_net(struct net *net);
4537 +
4538 +static inline struct net *get_net(struct net *net)
4539 +{
4540 +       atomic_inc(&net->count);
4541 +       return net;
4542 +}
4543 +
4544 +static inline void put_net(struct net *net)
4545 +{
4546 +       if (atomic_dec_and_test(&net->count))
4547 +               __put_net(net);
4548 +}
4549 +
4550 +static inline struct net *hold_net(struct net *net)
4551 +{
4552 +       atomic_inc(&net->use_count);
4553 +       return net;
4554 +}
4555 +
4556 +static inline void release_net(struct net *net)
4557 +{
4558 +       atomic_dec(&net->use_count);
4559 +}
4560 +
4561 +extern void net_lock(void);
4562 +extern void net_unlock(void);
4563 +
4564 +#define for_each_net(VAR)                              \
4565 +       list_for_each_entry(VAR, &net_namespace_list, list)
4566 +
4567 +
4568 +struct pernet_operations {
4569 +       struct list_head list;
4570 +       int (*init)(struct net *net);
4571 +       void (*exit)(struct net *net);
4572 +};
4573 +
4574 +extern int register_pernet_subsys(struct pernet_operations *);
4575 +extern void unregister_pernet_subsys(struct pernet_operations *);
4576 +extern int register_pernet_device(struct pernet_operations *);
4577 +extern void unregister_pernet_device(struct pernet_operations *);
4578 +
4579 +#ifdef CONFIG_PROC_FS
4580 +static inline struct net *PDE_NET(struct proc_dir_entry *pde)
4581 +{
4582 +       return pde->parent->data;
4583 +}
4584 +
4585 +static inline struct net *PROC_NET(const struct inode *inode)
4586 +{
4587 +       return PDE_NET(PDE(inode));
4588 +}
4589 +
4590 +static inline struct proc_dir_entry *proc_net_create(struct net *net,
4591 +       const char *name, mode_t mode, get_info_t *get_info)
4592 +{
4593 +       return create_proc_info_entry(name,mode, net->proc_net, get_info);
4594 +}
4595 +
4596 +static inline struct proc_dir_entry *proc_net_fops_create(struct net *net,
4597 +       const char *name, mode_t mode, const struct file_operations *fops)
4598 +{
4599 +       struct proc_dir_entry *res = 
4600 +               create_proc_entry(name, mode, net->proc_net);
4601 +       if (res)
4602 +               res->proc_fops = fops;
4603 +       return res;
4604 +}
4605 +
4606 +static inline void proc_net_remove(struct net *net, const char *name)
4607 +{
4608 +       remove_proc_entry(name, net->proc_net);
4609 +}
4610 +
4611 +#else
4612 +
4613 +#define proc_net_fops_create(net, name, mode, fops)  ({ (void)(mode), NULL; })
4614 +#define proc_net_create(net, name, mode, info) ({ (void)(mode), NULL; })
4615 +static inline void proc_net_remove(struct net *net, const char *name) {}
4616 +
4617 +#endif /* CONFIG_PROC_FS */
4618 +
4619 +#endif /* __NET_NET_NAMESPACE_H */
4620 diff -Nurb linux-2.6.22-try2/include/net/netlink.h linux-2.6.22-try2-netns/include/net/netlink.h
4621 --- linux-2.6.22-try2/include/net/netlink.h     2007-12-19 15:29:23.000000000 -0500
4622 +++ linux-2.6.22-try2-netns/include/net/netlink.h       2007-12-19 22:49:13.000000000 -0500
4623 @@ -218,6 +218,7 @@
4624  struct nl_info {
4625         struct nlmsghdr         *nlh;
4626         u32                     pid;
4627 +       struct net              *net;
4628  };
4629  
4630  extern void            netlink_run_queue(struct sock *sk, unsigned int *qlen,
4631 diff -Nurb linux-2.6.22-try2/include/net/pkt_cls.h linux-2.6.22-try2-netns/include/net/pkt_cls.h
4632 --- linux-2.6.22-try2/include/net/pkt_cls.h     2007-12-19 13:37:54.000000000 -0500
4633 +++ linux-2.6.22-try2-netns/include/net/pkt_cls.h       2007-12-19 22:49:13.000000000 -0500
4634 @@ -2,6 +2,7 @@
4635  #define __NET_PKT_CLS_H
4636  
4637  #include <linux/pkt_cls.h>
4638 +#include <net/net_namespace.h>
4639  #include <net/sch_generic.h>
4640  #include <net/act_api.h>
4641  
4642 @@ -357,7 +358,7 @@
4643         if (indev[0]) {
4644                 if  (!skb->iif)
4645                         return 0;
4646 -               dev = __dev_get_by_index(skb->iif);
4647 +               dev = __dev_get_by_index(&init_net, skb->iif);
4648                 if (!dev || strcmp(indev, dev->name))
4649                         return 0;
4650         }
4651 diff -Nurb linux-2.6.22-try2/include/net/protocol.h linux-2.6.22-try2-netns/include/net/protocol.h
4652 --- linux-2.6.22-try2/include/net/protocol.h    2007-12-19 13:37:54.000000000 -0500
4653 +++ linux-2.6.22-try2-netns/include/net/protocol.h      2007-12-19 22:49:13.000000000 -0500
4654 @@ -86,6 +86,7 @@
4655  #define INET_PROTOSW_REUSE 0x01             /* Are ports automatically reusable? */
4656  #define INET_PROTOSW_PERMANENT 0x02  /* Permanent protocols are unremovable. */
4657  #define INET_PROTOSW_ICSK      0x04  /* Is this an inet_connection_sock? */
4658 +#define INET_PROTOSW_NETNS     0x08  /* Multiple namespaces support? */
4659  
4660  extern struct net_protocol *inet_protocol_base;
4661  extern struct net_protocol *inet_protos[MAX_INET_PROTOS];
4662 diff -Nurb linux-2.6.22-try2/include/net/raw.h linux-2.6.22-try2-netns/include/net/raw.h
4663 --- linux-2.6.22-try2/include/net/raw.h 2007-12-19 13:37:54.000000000 -0500
4664 +++ linux-2.6.22-try2-netns/include/net/raw.h   2007-12-19 22:49:13.000000000 -0500
4665 @@ -34,7 +34,7 @@
4666  extern rwlock_t raw_v4_lock;
4667  
4668  
4669 -extern struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
4670 +extern struct sock *__raw_v4_lookup(struct net *net, struct sock *sk, unsigned short num,
4671                                     __be32 raddr, __be32 laddr,
4672                                     int dif, int tag);
4673  
4674 diff -Nurb linux-2.6.22-try2/include/net/route.h linux-2.6.22-try2-netns/include/net/route.h
4675 --- linux-2.6.22-try2/include/net/route.h       2007-12-19 15:29:23.000000000 -0500
4676 +++ linux-2.6.22-try2-netns/include/net/route.h 2007-12-19 22:58:46.000000000 -0500
4677 @@ -27,6 +27,7 @@
4678  #include <net/dst.h>
4679  #include <net/inetpeer.h>
4680  #include <net/flow.h>
4681 +#include <net/sock.h>
4682  #include <net/inet_sock.h>
4683  #include <linux/in_route.h>
4684  #include <linux/rtnetlink.h>
4685 @@ -122,9 +123,9 @@
4686  extern unsigned short  ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu);
4687  extern void            ip_rt_send_redirect(struct sk_buff *skb);
4688  
4689 -extern unsigned                inet_addr_type(__be32 addr);
4690 +extern unsigned                inet_addr_type(struct net *net, __be32 addr);
4691  extern void            ip_rt_multicast_event(struct in_device *);
4692 -extern int             ip_rt_ioctl(unsigned int cmd, void __user *arg);
4693 +extern int             ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg);
4694  extern void            ip_rt_get_source(u8 *src, struct rtable *rt);
4695  extern int             ip_rt_dump(struct sk_buff *skb,  struct netlink_callback *cb);
4696  
4697 @@ -153,7 +154,8 @@
4698                                    __be16 sport, __be16 dport, struct sock *sk,
4699                                    int flags)
4700  {
4701 -       struct flowi fl = { .oif = oif,
4702 +       struct flowi fl = { .fl_net = sk->sk_net,
4703 +                           .oif = oif,
4704                             .nl_u = { .ip4_u = { .daddr = dst,
4705                                                  .saddr = src,
4706                                                  .tos   = tos } },
4707 @@ -198,6 +200,7 @@
4708                 struct flowi fl;
4709  
4710                 memcpy(&fl, &(*rp)->fl, sizeof(fl));
4711 +               fl.fl_net = sk->sk_net;
4712                 fl.fl_ip_sport = sport;
4713                 fl.fl_ip_dport = dport;
4714                 fl.proto = protocol;
4715 diff -Nurb linux-2.6.22-try2/include/net/sock.h linux-2.6.22-try2-netns/include/net/sock.h
4716 --- linux-2.6.22-try2/include/net/sock.h        2007-12-19 13:37:54.000000000 -0500
4717 +++ linux-2.6.22-try2-netns/include/net/sock.h  2007-12-19 22:59:14.000000000 -0500
4718 @@ -55,6 +55,7 @@
4719  #include <asm/atomic.h>
4720  #include <net/dst.h>
4721  #include <net/checksum.h>
4722 +#include <net/net_namespace.h>
4723  
4724  /*
4725   * This structure really needs to be cleaned up.
4726 @@ -105,6 +106,7 @@
4727   *     @skc_refcnt: reference count
4728   *     @skc_hash: hash value used with various protocol lookup tables
4729   *     @skc_prot: protocol handlers inside a network family
4730 + *     @skc_net: reference to the network namespace of this socket
4731   *
4732   *     This is the minimal network layer representation of sockets, the header
4733   *     for struct sock and struct inet_timewait_sock.
4734 @@ -119,6 +121,7 @@
4735         atomic_t                skc_refcnt;
4736         unsigned int            skc_hash;
4737         struct proto            *skc_prot;
4738 +       struct net              *skc_net;
4739         xid_t                   skc_xid;
4740         struct vx_info          *skc_vx_info;
4741         nid_t                   skc_nid;
4742 @@ -199,6 +202,7 @@
4743  #define sk_refcnt              __sk_common.skc_refcnt
4744  #define sk_hash                        __sk_common.skc_hash
4745  #define sk_prot                        __sk_common.skc_prot
4746 +#define sk_net                 __sk_common.skc_net
4747  #define sk_xid                 __sk_common.skc_xid
4748  #define sk_vx_info             __sk_common.skc_vx_info
4749  #define sk_nid                 __sk_common.skc_nid
4750 @@ -781,7 +785,7 @@
4751                                 SINGLE_DEPTH_NESTING)
4752  #define bh_unlock_sock(__sk)   spin_unlock(&((__sk)->sk_lock.slock))
4753  
4754 -extern struct sock             *sk_alloc(int family,
4755 +extern struct sock             *sk_alloc(struct net *net, int family,
4756                                           gfp_t priority,
4757                                           struct proto *prot, int zero_it);
4758  extern void                    sk_free(struct sock *sk);
4759 @@ -1010,6 +1014,7 @@
4760  #endif
4761  
4762         memcpy(nsk, osk, osk->sk_prot->obj_size);
4763 +       get_net(nsk->sk_net);
4764  #ifdef CONFIG_SECURITY_NETWORK
4765         nsk->sk_security = sptr;
4766         security_sk_clone(osk, nsk);
4767 @@ -1373,6 +1378,7 @@
4768  
4769  #ifdef CONFIG_SYSCTL
4770  extern struct ctl_table core_table[];
4771 +extern struct ctl_table multi_core_table[];
4772  #endif
4773  
4774  extern int sysctl_optmem_max;
4775 diff -Nurb linux-2.6.22-try2/include/net/tcp.h linux-2.6.22-try2-netns/include/net/tcp.h
4776 --- linux-2.6.22-try2/include/net/tcp.h 2007-12-19 13:37:54.000000000 -0500
4777 +++ linux-2.6.22-try2-netns/include/net/tcp.h   2007-12-19 22:49:13.000000000 -0500
4778 @@ -191,8 +191,6 @@
4779  extern struct inet_timewait_death_row tcp_death_row;
4780  
4781  /* sysctl variables for tcp */
4782 -extern int sysctl_tcp_timestamps;
4783 -extern int sysctl_tcp_window_scaling;
4784  extern int sysctl_tcp_sack;
4785  extern int sysctl_tcp_fin_timeout;
4786  extern int sysctl_tcp_keepalive_time;
4787 @@ -1293,6 +1291,7 @@
4788  };
4789  
4790  struct tcp_iter_state {
4791 +       struct net              *net;
4792         sa_family_t             family;
4793         enum tcp_seq_states     state;
4794         struct sock             *syn_wait_sk;
4795 @@ -1300,8 +1299,8 @@
4796         struct seq_operations   seq_ops;
4797  };
4798  
4799 -extern int tcp_proc_register(struct tcp_seq_afinfo *afinfo);
4800 -extern void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo);
4801 +extern int tcp_proc_register(struct net *net, struct tcp_seq_afinfo *afinfo);
4802 +extern void tcp_proc_unregister(struct net *net, struct tcp_seq_afinfo *afinfo);
4803  
4804  extern struct request_sock_ops tcp_request_sock_ops;
4805  
4806 diff -Nurb linux-2.6.22-try2/include/net/udp.h linux-2.6.22-try2-netns/include/net/udp.h
4807 --- linux-2.6.22-try2/include/net/udp.h 2007-12-19 13:37:54.000000000 -0500
4808 +++ linux-2.6.22-try2-netns/include/net/udp.h   2007-12-19 22:49:13.000000000 -0500
4809 @@ -160,6 +160,7 @@
4810  };
4811  
4812  struct udp_iter_state {
4813 +       struct net              *net;
4814         sa_family_t             family;
4815         struct hlist_head       *hashtable;
4816         int                     bucket;
4817 @@ -167,8 +168,8 @@
4818  };
4819  
4820  #ifdef CONFIG_PROC_FS
4821 -extern int udp_proc_register(struct udp_seq_afinfo *afinfo);
4822 -extern void udp_proc_unregister(struct udp_seq_afinfo *afinfo);
4823 +extern int udp_proc_register(struct net *net, struct udp_seq_afinfo *afinfo);
4824 +extern void udp_proc_unregister(struct net *net, struct udp_seq_afinfo *afinfo);
4825  
4826  extern int  udp4_proc_init(void);
4827  extern void udp4_proc_exit(void);
4828 diff -Nurb linux-2.6.22-try2/include/net/wext.h linux-2.6.22-try2-netns/include/net/wext.h
4829 --- linux-2.6.22-try2/include/net/wext.h        2007-12-19 13:37:54.000000000 -0500
4830 +++ linux-2.6.22-try2-netns/include/net/wext.h  2007-12-19 22:49:13.000000000 -0500
4831 @@ -5,16 +5,23 @@
4832   * wireless extensions interface to the core code
4833   */
4834  
4835 +struct net;
4836 +
4837  #ifdef CONFIG_WIRELESS_EXT
4838 -extern int wext_proc_init(void);
4839 -extern int wext_handle_ioctl(struct ifreq *ifr, unsigned int cmd,
4840 +extern int wext_proc_init(struct net *net);
4841 +extern void wext_proc_exit(struct net *net);
4842 +extern int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd,
4843                              void __user *arg);
4844  #else
4845 -static inline int wext_proc_init(void)
4846 +static inline int wext_proc_init(struct net *net)
4847  {
4848         return 0;
4849  }
4850 -static inline int wext_handle_ioctl(struct ifreq *ifr, unsigned int cmd,
4851 +static inline void wext_proc_exit(struct net *net)
4852 +{
4853 +       return;
4854 +}
4855 +static inline int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd,
4856                                     void __user *arg)
4857  {
4858         return -EINVAL;
4859 diff -Nurb linux-2.6.22-try2/include/net/xfrm.h linux-2.6.22-try2-netns/include/net/xfrm.h
4860 --- linux-2.6.22-try2/include/net/xfrm.h        2007-12-19 15:29:23.000000000 -0500
4861 +++ linux-2.6.22-try2-netns/include/net/xfrm.h  2007-12-19 22:49:13.000000000 -0500
4862 @@ -34,8 +34,6 @@
4863         MODULE_ALIAS("xfrm-type-" __stringify(family) "-" __stringify(proto))
4864  
4865  extern struct sock *xfrm_nl;
4866 -extern u32 sysctl_xfrm_aevent_etime;
4867 -extern u32 sysctl_xfrm_aevent_rseqth;
4868  
4869  extern struct mutex xfrm_cfg_mutex;
4870  
4871 diff -Nurb linux-2.6.22-try2/kernel/audit.c linux-2.6.22-try2-netns/kernel/audit.c
4872 --- linux-2.6.22-try2/kernel/audit.c    2007-12-19 15:29:24.000000000 -0500
4873 +++ linux-2.6.22-try2-netns/kernel/audit.c      2007-12-19 22:49:13.000000000 -0500
4874 @@ -795,8 +795,8 @@
4875  
4876         printk(KERN_INFO "audit: initializing netlink socket (%s)\n",
4877                audit_default ? "enabled" : "disabled");
4878 -       audit_sock = netlink_kernel_create(NETLINK_AUDIT, 0, audit_receive,
4879 -                                          NULL, THIS_MODULE);
4880 +       audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, 0,
4881 +                                          audit_receive, NULL, THIS_MODULE);
4882         if (!audit_sock)
4883                 audit_panic("cannot initialize netlink socket");
4884         else
4885 diff -Nurb linux-2.6.22-try2/kernel/nsproxy.c linux-2.6.22-try2-netns/kernel/nsproxy.c
4886 --- linux-2.6.22-try2/kernel/nsproxy.c  2007-12-19 21:24:51.000000000 -0500
4887 +++ linux-2.6.22-try2-netns/kernel/nsproxy.c    2007-12-19 23:01:55.000000000 -0500
4888 @@ -19,6 +19,7 @@
4889  #include <linux/init_task.h>
4890  #include <linux/mnt_namespace.h>
4891  #include <linux/utsname.h>
4892 +#include <net/net_namespace.h>
4893  #include <linux/pid_namespace.h>
4894  #include <linux/vserver/global.h>
4895  #include <linux/vserver/debug.h>
4896 @@ -89,8 +90,17 @@
4897         if (IS_ERR(new_nsp->user_ns))
4898                 goto out_user;
4899  
4900 +       new_nsp->net_ns = copy_net_ns(flags, tsk->nsproxy->net_ns);
4901 +       if (IS_ERR(new_nsp->net_ns))
4902 +               goto out_net;
4903 +
4904         return new_nsp;
4905  
4906 +out_net:
4907 +       if (new_nsp->user_ns)
4908 +               put_user_ns(new_nsp->user_ns);
4909 +       if (ns->net_ns)
4910 +               put_net(ns->net_ns);
4911  out_user:
4912         if (new_nsp->pid_ns)
4913                 put_pid_ns(new_nsp->pid_ns);
4914 @@ -153,9 +163,15 @@
4915  
4916         get_nsproxy(old_ns);
4917  
4918 -       if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER)))
4919 +       if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER | CLONE_NEWNET)))
4920                 return 0;
4921  
4922 +        #ifndef CONFIG_NET_NS
4923 +               if (unshare_flags & CLONE_NEWNET)
4924 +                       return -EINVAL;
4925 +        #endif
4926 +
4927 +
4928         if (!capable(CAP_SYS_ADMIN)) {
4929                 err = -EPERM;
4930                 goto out;
4931 @@ -211,9 +227,13 @@
4932                 unshare_flags, current->nsproxy);
4933  
4934         if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
4935 -                              CLONE_NEWUSER)))
4936 +                              CLONE_NEWUSER | CLONE_NEWNET)))
4937                 return 0;
4938  
4939 +#ifndef CONFIG_NET_NS
4940 +       if (unshare_flags & CLONE_NEWNET)
4941 +               return -EINVAL;
4942 +#endif
4943         if (!capable(CAP_SYS_ADMIN))
4944                 return -EPERM;
4945  
4946 diff -Nurb linux-2.6.22-try2/kernel/sysctl.c linux-2.6.22-try2-netns/kernel/sysctl.c
4947 --- linux-2.6.22-try2/kernel/sysctl.c   2007-12-19 15:29:24.000000000 -0500
4948 +++ linux-2.6.22-try2-netns/kernel/sysctl.c     2007-12-19 22:49:13.000000000 -0500
4949 @@ -47,6 +47,7 @@
4950  #include <linux/acpi.h>
4951  #include <linux/reboot.h>
4952  #include <linux/fs.h>
4953 +#include <net/net_namespace.h>
4954  
4955  #include <asm/uaccess.h>
4956  #include <asm/processor.h>
4957 @@ -139,6 +140,10 @@
4958                                void __user *buffer, size_t *lenp, loff_t *ppos);
4959  #endif
4960  
4961 +#ifdef CONFIG_NET
4962 +static void sysctl_net_init(struct net *net);
4963 +#endif
4964 +
4965  static ctl_table root_table[];
4966  static struct ctl_table_header root_table_header =
4967         { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) };
4968 @@ -1151,6 +1156,11 @@
4969  {
4970         struct ctl_table_header *head;
4971         struct list_head *tmp;
4972 +       struct net *net = current->nsproxy->net_ns;
4973 +
4974 +       if (!net->net_table_header.ctl_table)
4975 +               sysctl_net_init(net);
4976 +
4977         spin_lock(&sysctl_lock);
4978         if (prev) {
4979                 tmp = &prev->ctl_entry;
4980 @@ -1168,6 +1178,10 @@
4981         next:
4982                 tmp = tmp->next;
4983                 if (tmp == &root_table_header.ctl_entry)
4984 +#ifdef CONFIG_NET
4985 +                       tmp = &net->net_table_header.ctl_entry;
4986 +               else if (tmp == &net->net_table_header.ctl_entry)
4987 +#endif
4988                         break;
4989         }
4990         spin_unlock(&sysctl_lock);
4991 @@ -1283,7 +1297,6 @@
4992                         void __user *newval, size_t newlen)
4993  {
4994         int op = 0, rc;
4995 -       size_t len;
4996  
4997         if (oldval)
4998                 op |= 004;
4999 @@ -1304,25 +1317,10 @@
5000         /* If there is no strategy routine, or if the strategy returns
5001          * zero, proceed with automatic r/w */
5002         if (table->data && table->maxlen) {
5003 -               if (oldval && oldlenp) {
5004 -                       if (get_user(len, oldlenp))
5005 -                               return -EFAULT;
5006 -                       if (len) {
5007 -                               if (len > table->maxlen)
5008 -                                       len = table->maxlen;
5009 -                               if(copy_to_user(oldval, table->data, len))
5010 -                                       return -EFAULT;
5011 -                               if(put_user(len, oldlenp))
5012 -                                       return -EFAULT;
5013 -                       }
5014 -               }
5015 -               if (newval && newlen) {
5016 -                       len = newlen;
5017 -                       if (len > table->maxlen)
5018 -                               len = table->maxlen;
5019 -                       if(copy_from_user(table->data, newval, len))
5020 -                               return -EFAULT;
5021 -               }
5022 +               rc = sysctl_data(table, name, nlen, oldval, oldlenp,
5023 +                                newval, newlen);
5024 +               if (rc < 0)
5025 +                       return rc;
5026         }
5027         return 0;
5028  }
5029 @@ -1413,7 +1411,8 @@
5030   * This routine returns %NULL on a failure to register, and a pointer
5031   * to the table header on success.
5032   */
5033 -struct ctl_table_header *register_sysctl_table(ctl_table * table)
5034 +static struct ctl_table_header *__register_sysctl_table(
5035 +       struct ctl_table_header *root, ctl_table * table)
5036  {
5037         struct ctl_table_header *tmp;
5038         tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL);
5039 @@ -1425,11 +1424,16 @@
5040         tmp->unregistering = NULL;
5041         sysctl_set_parent(NULL, table);
5042         spin_lock(&sysctl_lock);
5043 -       list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
5044 +       list_add_tail(&tmp->ctl_entry, &root->ctl_entry);
5045         spin_unlock(&sysctl_lock);
5046         return tmp;
5047  }
5048  
5049 +struct ctl_table_header *register_sysctl_table(ctl_table *table)
5050 +{
5051 +       return __register_sysctl_table(&root_table_header, table);
5052 +}
5053 +
5054  /**
5055   * unregister_sysctl_table - unregister a sysctl table hierarchy
5056   * @header: the header returned from register_sysctl_table
5057 @@ -1446,6 +1450,92 @@
5058         kfree(header);
5059  }
5060  
5061 +#ifdef CONFIG_NET
5062 +
5063 +static void *fixup_table_addr(void *addr,
5064 +                             const char *start, size_t size, const char *new)
5065 +{
5066 +       char *ptr = addr;
5067 +       if ((ptr >= start) && (ptr < (start + size)))
5068 +               ptr += new - start;
5069 +       return ptr;
5070 +}
5071 +
5072 +static void table_fixup(struct ctl_table *table,
5073 +                       const void *start, size_t size, const void *new)
5074 +{
5075 +       for (; table->ctl_name || table->procname; table++) {
5076 +               table->data   = fixup_table_addr(table->data, start, size, new);
5077 +               table->extra1 = fixup_table_addr(table->extra1, start, size, new);
5078 +               table->extra2 = fixup_table_addr(table->extra2, start, size, new);
5079 +
5080 +               /* Whee recursive functions on the kernel stack */
5081 +               if (table->child)
5082 +                       table_fixup(table->child, start, size, new);
5083 +       }
5084 +}
5085 +
5086 +static unsigned count_table_entries(struct ctl_table *table)
5087 +{
5088 +       unsigned entries = 0;
5089 +       for (; table->ctl_name || table->procname; table++) {
5090 +               entries += 1;
5091 +
5092 +               if (table->child)
5093 +                       entries += count_table_entries(table->child);
5094 +       }
5095 +       entries += 1; /* Null terminating entry */
5096 +       return entries;
5097 +}
5098 +
5099 +static struct ctl_table *copy_table_entries(
5100 +       struct ctl_table *dest, struct ctl_table *src)
5101 +{
5102 +       struct ctl_table *table = dest;
5103 +       for (; src->ctl_name || src->procname; src++) {
5104 +               *dest++ = *table;
5105 +       }
5106 +       dest++; /* Null terminating entry */
5107 +       for (; table->ctl_name || table->procname; table++) {
5108 +               if (table->child)
5109 +                       dest = copy_table_entries(dest, table->child);
5110 +       }
5111 +       return dest;
5112 +}
5113 +
5114 +static void sysctl_net_init(struct net *net)
5115 +{
5116 +       unsigned entries;
5117 +       struct ctl_table *table;
5118 +       
5119 +       entries = count_table_entries(net_root_table);
5120 +       table = kzalloc(GFP_KERNEL, sizeof(*table)*entries);
5121 +       /* FIXME free table... */
5122 +
5123 +       copy_table_entries(table, net_root_table);
5124 +       table_fixup(table, &init_net, sizeof(init_net), net);
5125 +
5126 +       net->net_table_header.ctl_table = table;
5127 +       INIT_LIST_HEAD(&net->net_table_header.ctl_entry);
5128 +}
5129 +
5130 +struct ctl_table_header *register_net_sysctl_table(struct net *net, struct ctl_table *table)
5131 +{
5132 +       if (!net->net_table_header.ctl_table)
5133 +               sysctl_net_init(net);
5134 +       table_fixup(table, &init_net, sizeof(init_net), net);
5135 +       return __register_sysctl_table(&net->net_table_header, table);
5136 +}
5137 +EXPORT_SYMBOL_GPL(register_net_sysctl_table);
5138 +
5139 +void unregister_net_sysctl_table(struct ctl_table_header *header)
5140 +{
5141 +       return unregister_sysctl_table(header);
5142 +}
5143 +EXPORT_SYMBOL_GPL(unregister_net_sysctl_table);
5144 +#endif
5145 +
5146 +
5147  #else /* !CONFIG_SYSCTL */
5148  struct ctl_table_header *register_sysctl_table(ctl_table * table)
5149  {
5150 @@ -2221,6 +2311,40 @@
5151   * General sysctl support routines 
5152   */
5153  
5154 +/* The generic sysctl data routine (used if no strategy routine supplied) */
5155 +int sysctl_data(ctl_table *table, int __user *name, int nlen,
5156 +               void __user *oldval, size_t __user *oldlenp,
5157 +               void __user *newval, size_t newlen)
5158 +{
5159 +       size_t len;
5160 +
5161 +       /* Get out of I don't have a variable */
5162 +       if (!table->data || !table->maxlen)
5163 +               return -ENOTDIR;
5164 +
5165 +       if (oldval && oldlenp) {
5166 +               if (get_user(len, oldlenp))
5167 +                       return -EFAULT;
5168 +               if (len) {
5169 +                       if (len > table->maxlen)
5170 +                               len = table->maxlen;
5171 +                       if (copy_to_user(oldval, table->data, len))
5172 +                               return -EFAULT;
5173 +                       if (put_user(len, oldlenp))
5174 +                               return -EFAULT;
5175 +               }
5176 +       }
5177 +
5178 +       if (newval && newlen) {
5179 +               if (newlen > table->maxlen)
5180 +                       newlen = table->maxlen;
5181 +
5182 +               if (copy_from_user(table->data, newval, newlen))
5183 +                       return -EFAULT;
5184 +       }
5185 +       return 1;
5186 +}
5187 +
5188  /* The generic string strategy routine: */
5189  int sysctl_string(ctl_table *table, int __user *name, int nlen,
5190                   void __user *oldval, size_t __user *oldlenp,
5191 @@ -2409,6 +2533,13 @@
5192         return -ENOSYS;
5193  }
5194  
5195 +int sysctl_data(ctl_table *table, int __user *name, int nlen,
5196 +                 void __user *oldval, size_t __user *oldlenp,
5197 +                 void __user *newval, size_t newlen)
5198 +{
5199 +       return -ENOSYS;
5200 +}
5201 +
5202  int sysctl_string(ctl_table *table, int __user *name, int nlen,
5203                   void __user *oldval, size_t __user *oldlenp,
5204                   void __user *newval, size_t newlen)
5205 @@ -2456,4 +2587,5 @@
5206  EXPORT_SYMBOL(sysctl_jiffies);
5207  EXPORT_SYMBOL(sysctl_ms_jiffies);
5208  EXPORT_SYMBOL(sysctl_string);
5209 +EXPORT_SYMBOL(sysctl_data);
5210  EXPORT_SYMBOL(unregister_sysctl_table);
5211 diff -Nurb linux-2.6.22-try2/lib/kobject.c linux-2.6.22-try2-netns/lib/kobject.c
5212 --- linux-2.6.22-try2/lib/kobject.c     2007-12-19 15:29:23.000000000 -0500
5213 +++ linux-2.6.22-try2-netns/lib/kobject.c       2007-12-19 22:49:18.000000000 -0500
5214 @@ -44,11 +44,11 @@
5215         return error;
5216  }
5217  
5218 -static int create_dir(struct kobject *kobj, struct sysfs_dirent *shadow_parent)
5219 +static int create_dir(struct kobject * kobj)
5220  {
5221         int error = 0;
5222         if (kobject_name(kobj)) {
5223 -               error = sysfs_create_dir(kobj, shadow_parent);
5224 +               error = sysfs_create_dir(kobj);
5225                 if (!error) {
5226                         if ((error = populate_dir(kobj)))
5227                                 sysfs_remove_dir(kobj);
5228 @@ -157,12 +157,11 @@
5229  }
5230  
5231  /**
5232 - *     kobject_shadow_add - add an object to the hierarchy.
5233 + *     kobject_add - add an object to the hierarchy.
5234   *     @kobj:  object.
5235 - *     @shadow_parent: sysfs directory to add to.
5236   */
5237  
5238 -int kobject_shadow_add(struct kobject *kobj, struct sysfs_dirent *shadow_parent)
5239 +int kobject_add(struct kobject * kobj)
5240  {
5241         int error = 0;
5242         struct kobject * parent;
5243 @@ -194,7 +193,7 @@
5244                 kobj->parent = parent;
5245         }
5246  
5247 -       error = create_dir(kobj, shadow_parent);
5248 +       error = create_dir(kobj);
5249         if (error) {
5250                 /* unlink does the kobject_put() for us */
5251                 unlink(kobj);
5252 @@ -216,16 +215,6 @@
5253  }
5254  
5255  /**
5256 - *     kobject_add - add an object to the hierarchy.
5257 - *     @kobj:  object.
5258 - */
5259 -int kobject_add(struct kobject * kobj)
5260 -{
5261 -       return kobject_shadow_add(kobj, NULL);
5262 -}
5263 -
5264 -
5265 -/**
5266   *     kobject_register - initialize and add an object.
5267   *     @kobj:  object in question.
5268   */
5269 @@ -338,7 +327,7 @@
5270         /* Note : if we want to send the new name alone, not the full path,
5271          * we could probably use kobject_name(kobj); */
5272  
5273 -       error = sysfs_rename_dir(kobj, kobj->parent->sd, new_name);
5274 +       error = sysfs_rename_dir(kobj, new_name);
5275  
5276         /* This function is mostly/only used for network interface.
5277          * Some hotplug package track interfaces by their name and
5278 @@ -355,27 +344,6 @@
5279  }
5280  
5281  /**
5282 - *     kobject_rename - change the name of an object
5283 - *     @kobj:  object in question.
5284 - *     @new_parent: object's new parent
5285 - *     @new_name: object's new name
5286 - */
5287 -
5288 -int kobject_shadow_rename(struct kobject *kobj,
5289 -                         struct sysfs_dirent *new_parent, const char *new_name)
5290 -{
5291 -       int error = 0;
5292 -
5293 -       kobj = kobject_get(kobj);
5294 -       if (!kobj)
5295 -               return -EINVAL;
5296 -       error = sysfs_rename_dir(kobj, new_parent, new_name);
5297 -       kobject_put(kobj);
5298 -
5299 -       return error;
5300 -}
5301 -
5302 -/**
5303   *     kobject_move - move object to another parent
5304   *     @kobj:  object in question.
5305   *     @new_parent: object's new parent (can be NULL)
5306 diff -Nurb linux-2.6.22-try2/lib/kobject_uevent.c linux-2.6.22-try2-netns/lib/kobject_uevent.c
5307 --- linux-2.6.22-try2/lib/kobject_uevent.c      2007-12-19 15:29:23.000000000 -0500
5308 +++ linux-2.6.22-try2-netns/lib/kobject_uevent.c        2007-12-19 22:49:18.000000000 -0500
5309 @@ -290,9 +290,8 @@
5310  #if defined(CONFIG_NET)
5311  static int __init kobject_uevent_init(void)
5312  {
5313 -       uevent_sock = netlink_kernel_create(NETLINK_KOBJECT_UEVENT, 1, NULL,
5314 -                                           NULL, THIS_MODULE);
5315 -
5316 +       uevent_sock = netlink_kernel_create(&init_net, NETLINK_KOBJECT_UEVENT,
5317 +                                           1, NULL, NULL, THIS_MODULE);
5318         if (!uevent_sock) {
5319                 printk(KERN_ERR
5320                        "kobject_uevent: unable to create netlink socket!\n");
5321 diff -Nurb linux-2.6.22-try2/net/802/tr.c linux-2.6.22-try2-netns/net/802/tr.c
5322 --- linux-2.6.22-try2/net/802/tr.c      2007-12-19 13:37:56.000000000 -0500
5323 +++ linux-2.6.22-try2-netns/net/802/tr.c        2007-12-19 22:49:18.000000000 -0500
5324 @@ -36,6 +36,7 @@
5325  #include <linux/seq_file.h>
5326  #include <linux/init.h>
5327  #include <net/arp.h>
5328 +#include <net/net_namespace.h>
5329  
5330  static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev);
5331  static void rif_check_expire(unsigned long dummy);
5332 @@ -532,7 +533,7 @@
5333                 seq_puts(seq,
5334                      "if     TR address       TTL   rcf   routing segments\n");
5335         else {
5336 -               struct net_device *dev = dev_get_by_index(entry->iface);
5337 +               struct net_device *dev = dev_get_by_index(&init_net, entry->iface);
5338                 long ttl = (long) (entry->last_used + sysctl_tr_rif_timeout)
5339                                 - (long) jiffies;
5340  
5341 @@ -639,7 +640,7 @@
5342         rif_timer.function = rif_check_expire;
5343         add_timer(&rif_timer);
5344  
5345 -       proc_net_fops_create("tr_rif", S_IRUGO, &rif_seq_fops);
5346 +       proc_net_fops_create(&init_net, "tr_rif", S_IRUGO, &rif_seq_fops);
5347         return 0;
5348  }
5349  
5350 diff -Nurb linux-2.6.22-try2/net/8021q/vlan.c linux-2.6.22-try2-netns/net/8021q/vlan.c
5351 --- linux-2.6.22-try2/net/8021q/vlan.c  2007-12-19 15:29:23.000000000 -0500
5352 +++ linux-2.6.22-try2-netns/net/8021q/vlan.c    2007-12-19 22:49:18.000000000 -0500
5353 @@ -31,6 +31,7 @@
5354  #include <net/arp.h>
5355  #include <linux/rtnetlink.h>
5356  #include <linux/notifier.h>
5357 +#include <net/net_namespace.h>
5358  
5359  #include <linux/if_vlan.h>
5360  #include "vlan.h"
5361 @@ -50,7 +51,7 @@
5362  static char vlan_buggyright[] = "David S. Miller <davem@redhat.com>";
5363  
5364  static int vlan_device_event(struct notifier_block *, unsigned long, void *);
5365 -static int vlan_ioctl_handler(void __user *);
5366 +static int vlan_ioctl_handler(struct net *net, void __user *);
5367  static int unregister_vlan_dev(struct net_device *, unsigned short );
5368  
5369  static struct notifier_block vlan_notifier_block = {
5370 @@ -124,7 +125,7 @@
5371         struct net_device *dev, *nxt;
5372  
5373         rtnl_lock();
5374 -       for_each_netdev_safe(dev, nxt) {
5375 +       for_each_netdev_safe(&init_net, dev, nxt) {
5376                 if (dev->priv_flags & IFF_802_1Q_VLAN) {
5377                         unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
5378                                             VLAN_DEV_INFO(dev)->vlan_id);
5379 @@ -599,6 +600,9 @@
5380         int i, flgs;
5381         struct net_device *vlandev;
5382  
5383 +       if (dev->nd_net != &init_net)
5384 +               return NOTIFY_DONE;
5385 +
5386         if (!grp)
5387                 goto out;
5388  
5389 @@ -678,7 +682,7 @@
5390   *     o execute requested action or pass command to the device driver
5391   *   arg is really a struct vlan_ioctl_args __user *.
5392   */
5393 -static int vlan_ioctl_handler(void __user *arg)
5394 +static int vlan_ioctl_handler(struct net *net, void __user *arg)
5395  {
5396         int err;
5397         unsigned short vid = 0;
5398 @@ -707,7 +711,7 @@
5399         case GET_VLAN_REALDEV_NAME_CMD:
5400         case GET_VLAN_VID_CMD:
5401                 err = -ENODEV;
5402 -               dev = __dev_get_by_name(args.device1);
5403 +               dev = __dev_get_by_name(&init_net, args.device1);
5404                 if (!dev)
5405                         goto out;
5406  
5407 diff -Nurb linux-2.6.22-try2/net/8021q/vlan_dev.c linux-2.6.22-try2-netns/net/8021q/vlan_dev.c
5408 --- linux-2.6.22-try2/net/8021q/vlan_dev.c      2007-12-19 15:29:23.000000000 -0500
5409 +++ linux-2.6.22-try2-netns/net/8021q/vlan_dev.c        2007-12-19 22:49:18.000000000 -0500
5410 @@ -132,6 +132,11 @@
5411  
5412         vhdr = (struct vlan_hdr *)(skb->data);
5413  
5414 +       if (dev->nd_net != &init_net) {
5415 +               kfree_skb(skb);
5416 +               return 0;
5417 +       }
5418 +
5419         /* vlan_TCI = ntohs(get_unaligned(&vhdr->h_vlan_TCI)); */
5420         vlan_TCI = ntohs(vhdr->h_vlan_TCI);
5421  
5422 @@ -776,7 +781,7 @@
5423                 break;
5424  
5425         case SIOCETHTOOL:
5426 -               err = dev_ethtool(&ifrr);
5427 +               err = dev_ethtool(real_dev->nd_net, &ifrr);
5428         }
5429  
5430         if (!err)
5431 diff -Nurb linux-2.6.22-try2/net/8021q/vlan_netlink.c linux-2.6.22-try2-netns/net/8021q/vlan_netlink.c
5432 --- linux-2.6.22-try2/net/8021q/vlan_netlink.c  2007-12-19 15:29:23.000000000 -0500
5433 +++ linux-2.6.22-try2-netns/net/8021q/vlan_netlink.c    2007-12-19 22:49:18.000000000 -0500
5434 @@ -11,6 +11,7 @@
5435  #include <linux/kernel.h>
5436  #include <linux/netdevice.h>
5437  #include <linux/if_vlan.h>
5438 +#include <net/net_namespace.h>
5439  #include <net/netlink.h>
5440  #include <net/rtnetlink.h>
5441  #include "vlan.h"
5442 @@ -105,7 +106,7 @@
5443  
5444         if (!tb[IFLA_LINK])
5445                 return -EINVAL;
5446 -       real_dev = __dev_get_by_index(nla_get_u32(tb[IFLA_LINK]));
5447 +       real_dev = __dev_get_by_index(&init_net, nla_get_u32(tb[IFLA_LINK]));
5448         if (!real_dev)
5449                 return -ENODEV;
5450  
5451 diff -Nurb linux-2.6.22-try2/net/8021q/vlanproc.c linux-2.6.22-try2-netns/net/8021q/vlanproc.c
5452 --- linux-2.6.22-try2/net/8021q/vlanproc.c      2007-12-19 15:29:23.000000000 -0500
5453 +++ linux-2.6.22-try2-netns/net/8021q/vlanproc.c        2007-12-19 22:49:18.000000000 -0500
5454 @@ -33,6 +33,7 @@
5455  #include <linux/fs.h>
5456  #include <linux/netdevice.h>
5457  #include <linux/if_vlan.h>
5458 +#include <net/net_namespace.h>
5459  #include "vlanproc.h"
5460  #include "vlan.h"
5461  
5462 @@ -143,7 +144,7 @@
5463                 remove_proc_entry(name_conf, proc_vlan_dir);
5464  
5465         if (proc_vlan_dir)
5466 -               proc_net_remove(name_root);
5467 +               proc_net_remove(&init_net, name_root);
5468  
5469         /* Dynamically added entries should be cleaned up as their vlan_device
5470          * is removed, so we should not have to take care of it here...
5471 @@ -156,7 +157,7 @@
5472  
5473  int __init vlan_proc_init(void)
5474  {
5475 -       proc_vlan_dir = proc_mkdir(name_root, proc_net);
5476 +       proc_vlan_dir = proc_mkdir(name_root, init_net.proc_net);
5477         if (proc_vlan_dir) {
5478                 proc_vlan_conf = create_proc_entry(name_conf,
5479                                                    S_IFREG|S_IRUSR|S_IWUSR,
5480 @@ -253,7 +254,7 @@
5481         if (*pos == 0)
5482                 return SEQ_START_TOKEN;
5483  
5484 -       for_each_netdev(dev) {
5485 +       for_each_netdev(&init_net, dev) {
5486                 if (!is_vlan_dev(dev))
5487                         continue;
5488  
5489 @@ -272,9 +273,9 @@
5490  
5491         dev = (struct net_device *)v;
5492         if (v == SEQ_START_TOKEN)
5493 -               dev = net_device_entry(&dev_base_head);
5494 +               dev = net_device_entry(&init_net.dev_base_head);
5495  
5496 -       for_each_netdev_continue(dev) {
5497 +       for_each_netdev_continue(&init_net, dev) {
5498                 if (!is_vlan_dev(dev))
5499                         continue;
5500  
5501 diff -Nurb linux-2.6.22-try2/net/Kconfig linux-2.6.22-try2-netns/net/Kconfig
5502 --- linux-2.6.22-try2/net/Kconfig       2007-12-19 13:37:56.000000000 -0500
5503 +++ linux-2.6.22-try2-netns/net/Kconfig 2007-12-19 22:49:18.000000000 -0500
5504 @@ -27,6 +27,13 @@
5505  
5506  menu "Networking options"
5507  
5508 +config NET_NS
5509 +       bool "Network namespace support"
5510 +       depends on EXPERIMENTAL
5511 +       help
5512 +         Support what appear to user space as multiple instances of the 
5513 +         network stack.
5514 +
5515  source "net/packet/Kconfig"
5516  source "net/unix/Kconfig"
5517  source "net/xfrm/Kconfig"
5518 diff -Nurb linux-2.6.22-try2/net/appletalk/aarp.c linux-2.6.22-try2-netns/net/appletalk/aarp.c
5519 --- linux-2.6.22-try2/net/appletalk/aarp.c      2007-12-19 13:37:56.000000000 -0500
5520 +++ linux-2.6.22-try2-netns/net/appletalk/aarp.c        2007-12-19 22:49:18.000000000 -0500
5521 @@ -330,15 +330,19 @@
5522  static int aarp_device_event(struct notifier_block *this, unsigned long event,
5523                              void *ptr)
5524  {
5525 +       struct net_device *dev = ptr;
5526         int ct;
5527  
5528 +       if (dev->nd_net != &init_net)
5529 +               return NOTIFY_DONE;
5530 +
5531         if (event == NETDEV_DOWN) {
5532                 write_lock_bh(&aarp_lock);
5533  
5534                 for (ct = 0; ct < AARP_HASH_SIZE; ct++) {
5535 -                       __aarp_expire_device(&resolved[ct], ptr);
5536 -                       __aarp_expire_device(&unresolved[ct], ptr);
5537 -                       __aarp_expire_device(&proxies[ct], ptr);
5538 +                       __aarp_expire_device(&resolved[ct], dev);
5539 +                       __aarp_expire_device(&unresolved[ct], dev);
5540 +                       __aarp_expire_device(&proxies[ct], dev);
5541                 }
5542  
5543                 write_unlock_bh(&aarp_lock);
5544 @@ -712,6 +716,9 @@
5545         struct atalk_addr sa, *ma, da;
5546         struct atalk_iface *ifa;
5547  
5548 +       if (dev->nd_net != &init_net)
5549 +               goto out0;
5550 +
5551         /* We only do Ethernet SNAP AARP. */
5552         if (dev->type != ARPHRD_ETHER)
5553                 goto out0;
5554 diff -Nurb linux-2.6.22-try2/net/appletalk/atalk_proc.c linux-2.6.22-try2-netns/net/appletalk/atalk_proc.c
5555 --- linux-2.6.22-try2/net/appletalk/atalk_proc.c        2007-12-19 13:37:56.000000000 -0500
5556 +++ linux-2.6.22-try2-netns/net/appletalk/atalk_proc.c  2007-12-19 22:49:18.000000000 -0500
5557 @@ -13,6 +13,7 @@
5558  #include <linux/seq_file.h>
5559  #include <net/sock.h>
5560  #include <linux/atalk.h>
5561 +#include <net/net_namespace.h>
5562  
5563  
5564  static __inline__ struct atalk_iface *atalk_get_interface_idx(loff_t pos)
5565 @@ -271,7 +272,7 @@
5566         struct proc_dir_entry *p;
5567         int rc = -ENOMEM;
5568  
5569 -       atalk_proc_dir = proc_mkdir("atalk", proc_net);
5570 +       atalk_proc_dir = proc_mkdir("atalk", init_net.proc_net);
5571         if (!atalk_proc_dir)
5572                 goto out;
5573         atalk_proc_dir->owner = THIS_MODULE;
5574 @@ -306,7 +307,7 @@
5575  out_route:
5576         remove_proc_entry("interface", atalk_proc_dir);
5577  out_interface:
5578 -       remove_proc_entry("atalk", proc_net);
5579 +       remove_proc_entry("atalk", init_net.proc_net);
5580         goto out;
5581  }
5582  
5583 @@ -316,5 +317,5 @@
5584         remove_proc_entry("route", atalk_proc_dir);
5585         remove_proc_entry("socket", atalk_proc_dir);
5586         remove_proc_entry("arp", atalk_proc_dir);
5587 -       remove_proc_entry("atalk", proc_net);
5588 +       remove_proc_entry("atalk", init_net.proc_net);
5589  }
5590 diff -Nurb linux-2.6.22-try2/net/appletalk/ddp.c linux-2.6.22-try2-netns/net/appletalk/ddp.c
5591 --- linux-2.6.22-try2/net/appletalk/ddp.c       2007-12-19 13:37:56.000000000 -0500
5592 +++ linux-2.6.22-try2-netns/net/appletalk/ddp.c 2007-12-19 22:49:18.000000000 -0500
5593 @@ -647,9 +647,14 @@
5594  static int ddp_device_event(struct notifier_block *this, unsigned long event,
5595                             void *ptr)
5596  {
5597 +       struct net_device *dev = ptr;
5598 +
5599 +       if (dev->nd_net != &init_net)
5600 +               return NOTIFY_DONE;
5601 +
5602         if (event == NETDEV_DOWN)
5603                 /* Discard any use of this */
5604 -               atalk_dev_down(ptr);
5605 +               atalk_dev_down(dev);
5606  
5607         return NOTIFY_DONE;
5608  }
5609 @@ -672,7 +677,7 @@
5610         if (copy_from_user(&atreq, arg, sizeof(atreq)))
5611                 return -EFAULT;
5612  
5613 -       dev = __dev_get_by_name(atreq.ifr_name);
5614 +       dev = __dev_get_by_name(&init_net, atreq.ifr_name);
5615         if (!dev)
5616                 return -ENODEV;
5617  
5618 @@ -896,7 +901,7 @@
5619                                 if (copy_from_user(name, rt.rt_dev, IFNAMSIZ-1))
5620                                         return -EFAULT;
5621                                 name[IFNAMSIZ-1] = '\0';
5622 -                               dev = __dev_get_by_name(name);
5623 +                               dev = __dev_get_by_name(&init_net, name);
5624                                 if (!dev)
5625                                         return -ENODEV;
5626                         }
5627 @@ -1024,11 +1029,14 @@
5628   * Create a socket. Initialise the socket, blank the addresses
5629   * set the state.
5630   */
5631 -static int atalk_create(struct socket *sock, int protocol)
5632 +static int atalk_create(struct net *net, struct socket *sock, int protocol)
5633  {
5634         struct sock *sk;
5635         int rc = -ESOCKTNOSUPPORT;
5636  
5637 +       if (net != &init_net)
5638 +               return -EAFNOSUPPORT;
5639 +
5640         /*
5641          * We permit SOCK_DGRAM and RAW is an extension. It is trivial to do
5642          * and gives you the full ELAP frame. Should be handy for CAP 8)
5643 @@ -1036,7 +1044,7 @@
5644         if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
5645                 goto out;
5646         rc = -ENOMEM;
5647 -       sk = sk_alloc(PF_APPLETALK, GFP_KERNEL, &ddp_proto, 1);
5648 +       sk = sk_alloc(net, PF_APPLETALK, GFP_KERNEL, &ddp_proto, 1);
5649         if (!sk)
5650                 goto out;
5651         rc = 0;
5652 @@ -1265,7 +1273,7 @@
5653  
5654  static int handle_ip_over_ddp(struct sk_buff *skb)
5655  {
5656 -       struct net_device *dev = __dev_get_by_name("ipddp0");
5657 +       struct net_device *dev = __dev_get_by_name(&init_net, "ipddp0");
5658         struct net_device_stats *stats;
5659  
5660         /* This needs to be able to handle ipddp"N" devices */
5661 @@ -1398,6 +1406,9 @@
5662         int origlen;
5663         __u16 len_hops;
5664  
5665 +       if (dev->nd_net != &init_net)
5666 +               goto freeit;
5667 +
5668         /* Don't mangle buffer if shared */
5669         if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
5670                 goto out;
5671 @@ -1483,6 +1494,9 @@
5672  static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev,
5673                      struct packet_type *pt, struct net_device *orig_dev)
5674  {
5675 +       if (dev->nd_net != &init_net)
5676 +               goto freeit;
5677 +
5678         /* Expand any short form frames */
5679         if (skb_mac_header(skb)[2] == 1) {
5680                 struct ddpehdr *ddp;
5681 diff -Nurb linux-2.6.22-try2/net/atm/clip.c linux-2.6.22-try2-netns/net/atm/clip.c
5682 --- linux-2.6.22-try2/net/atm/clip.c    2007-12-19 13:37:56.000000000 -0500
5683 +++ linux-2.6.22-try2-netns/net/atm/clip.c      2007-12-19 22:49:18.000000000 -0500
5684 @@ -293,7 +293,7 @@
5685         struct neigh_parms *parms;
5686  
5687         DPRINTK("clip_constructor (neigh %p, entry %p)\n", neigh, entry);
5688 -       neigh->type = inet_addr_type(entry->ip);
5689 +       neigh->type = inet_addr_type(&init_net, entry->ip);
5690         if (neigh->type != RTN_UNICAST)
5691                 return -EINVAL;
5692  
5693 @@ -525,7 +525,10 @@
5694         struct atmarp_entry *entry;
5695         int error;
5696         struct clip_vcc *clip_vcc;
5697 -       struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip, .tos = 1}} };
5698 +       struct flowi fl = { 
5699 +               .fl_net = &init_net,
5700 +               .nl_u = { .ip4_u = { .daddr = ip, .tos = 1}} 
5701 +       };
5702         struct rtable *rt;
5703  
5704         if (vcc->push != clip_push) {
5705 @@ -620,6 +623,9 @@
5706  {
5707         struct net_device *dev = arg;
5708  
5709 +       if (dev->nd_net != &init_net)
5710 +               return NOTIFY_DONE;
5711 +
5712         if (event == NETDEV_UNREGISTER) {
5713                 neigh_ifdown(&clip_tbl, dev);
5714                 return NOTIFY_DONE;
5715 @@ -954,6 +960,7 @@
5716  
5717         seq = file->private_data;
5718         seq->private = state;
5719 +       state->ns.net = get_net(PROC_NET(inode));
5720  out:
5721         return rc;
5722  
5723 @@ -962,11 +969,19 @@
5724         goto out;
5725  }
5726  
5727 +static int arp_seq_release(struct inode *inode, struct file *file)
5728 +{
5729 +       struct seq_file *seq = file->private_data;
5730 +       struct clip_seq_state *state = seq->private;
5731 +       put_net(state->ns.net);
5732 +       return seq_release_private(inode, file);
5733 +}
5734 +
5735  static const struct file_operations arp_seq_fops = {
5736         .open           = arp_seq_open,
5737         .read           = seq_read,
5738         .llseek         = seq_lseek,
5739 -       .release        = seq_release_private,
5740 +       .release        = arp_seq_release,
5741         .owner          = THIS_MODULE
5742  };
5743  #endif
5744 diff -Nurb linux-2.6.22-try2/net/atm/common.c linux-2.6.22-try2-netns/net/atm/common.c
5745 --- linux-2.6.22-try2/net/atm/common.c  2007-12-19 13:37:56.000000000 -0500
5746 +++ linux-2.6.22-try2-netns/net/atm/common.c    2007-12-19 22:49:18.000000000 -0500
5747 @@ -132,7 +132,7 @@
5748         .obj_size = sizeof(struct atm_vcc),
5749  };
5750  
5751 -int vcc_create(struct socket *sock, int protocol, int family)
5752 +int vcc_create(struct net *net, struct socket *sock, int protocol, int family)
5753  {
5754         struct sock *sk;
5755         struct atm_vcc *vcc;
5756 @@ -140,7 +140,7 @@
5757         sock->sk = NULL;
5758         if (sock->type == SOCK_STREAM)
5759                 return -EINVAL;
5760 -       sk = sk_alloc(family, GFP_KERNEL, &vcc_proto, 1);
5761 +       sk = sk_alloc(net, family, GFP_KERNEL, &vcc_proto, 1);
5762         if (!sk)
5763                 return -ENOMEM;
5764         sock_init_data(sock, sk);
5765 diff -Nurb linux-2.6.22-try2/net/atm/common.h linux-2.6.22-try2-netns/net/atm/common.h
5766 --- linux-2.6.22-try2/net/atm/common.h  2007-12-19 13:37:56.000000000 -0500
5767 +++ linux-2.6.22-try2-netns/net/atm/common.h    2007-12-19 22:49:18.000000000 -0500
5768 @@ -10,7 +10,7 @@
5769  #include <linux/poll.h> /* for poll_table */
5770  
5771  
5772 -int vcc_create(struct socket *sock, int protocol, int family);
5773 +int vcc_create(struct net *net, struct socket *sock, int protocol, int family);
5774  int vcc_release(struct socket *sock);
5775  int vcc_connect(struct socket *sock, int itf, short vpi, int vci);
5776  int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
5777 diff -Nurb linux-2.6.22-try2/net/atm/mpc.c linux-2.6.22-try2-netns/net/atm/mpc.c
5778 --- linux-2.6.22-try2/net/atm/mpc.c     2007-12-19 13:37:56.000000000 -0500
5779 +++ linux-2.6.22-try2-netns/net/atm/mpc.c       2007-12-19 22:49:18.000000000 -0500
5780 @@ -244,7 +244,7 @@
5781         char name[IFNAMSIZ];
5782  
5783         sprintf(name, "lec%d", itf);
5784 -       dev = dev_get_by_name(name);
5785 +       dev = dev_get_by_name(&init_net, name);
5786  
5787         return dev;
5788  }
5789 @@ -956,6 +956,10 @@
5790         struct lec_priv *priv;
5791  
5792         dev = (struct net_device *)dev_ptr;
5793 +
5794 +       if (dev->nd_net != &init_net)
5795 +               return NOTIFY_DONE;
5796 +
5797         if (dev->name == NULL || strncmp(dev->name, "lec", 3))
5798                 return NOTIFY_DONE; /* we are only interested in lec:s */
5799  
5800 diff -Nurb linux-2.6.22-try2/net/atm/proc.c linux-2.6.22-try2-netns/net/atm/proc.c
5801 --- linux-2.6.22-try2/net/atm/proc.c    2007-12-19 13:37:56.000000000 -0500
5802 +++ linux-2.6.22-try2-netns/net/atm/proc.c      2007-12-19 22:49:18.000000000 -0500
5803 @@ -22,6 +22,7 @@
5804  #include <linux/netdevice.h>
5805  #include <linux/atmclip.h>
5806  #include <linux/init.h> /* for __init */
5807 +#include <net/net_namespace.h>
5808  #include <net/atmclip.h>
5809  #include <asm/uaccess.h>
5810  #include <asm/atomic.h>
5811 @@ -475,7 +476,7 @@
5812                 if (e->dirent)
5813                         remove_proc_entry(e->name, atm_proc_root);
5814         }
5815 -       remove_proc_entry("net/atm", NULL);
5816 +       remove_proc_entry("atm", init_net.proc_net);
5817  }
5818  
5819  int __init atm_proc_init(void)
5820 @@ -483,7 +484,7 @@
5821         static struct atm_proc_entry *e;
5822         int ret;
5823  
5824 -       atm_proc_root = proc_mkdir("net/atm",NULL);
5825 +       atm_proc_root = proc_mkdir("atm", init_net.proc_net);
5826         if (!atm_proc_root)
5827                 goto err_out;
5828         for (e = atm_proc_ents; e->name; e++) {
5829 diff -Nurb linux-2.6.22-try2/net/atm/pvc.c linux-2.6.22-try2-netns/net/atm/pvc.c
5830 --- linux-2.6.22-try2/net/atm/pvc.c     2007-12-19 13:37:56.000000000 -0500
5831 +++ linux-2.6.22-try2-netns/net/atm/pvc.c       2007-12-19 22:49:18.000000000 -0500
5832 @@ -124,10 +124,13 @@
5833  };
5834  
5835  
5836 -static int pvc_create(struct socket *sock,int protocol)
5837 +static int pvc_create(struct net *net, struct socket *sock,int protocol)
5838  {
5839 +       if (net != &init_net)
5840 +               return -EAFNOSUPPORT;
5841 +
5842         sock->ops = &pvc_proto_ops;
5843 -       return vcc_create(sock, protocol, PF_ATMPVC);
5844 +       return vcc_create(net, sock, protocol, PF_ATMPVC);
5845  }
5846  
5847  
5848 diff -Nurb linux-2.6.22-try2/net/atm/svc.c linux-2.6.22-try2-netns/net/atm/svc.c
5849 --- linux-2.6.22-try2/net/atm/svc.c     2007-12-19 13:37:56.000000000 -0500
5850 +++ linux-2.6.22-try2-netns/net/atm/svc.c       2007-12-19 22:49:18.000000000 -0500
5851 @@ -33,7 +33,7 @@
5852  #endif
5853  
5854  
5855 -static int svc_create(struct socket *sock,int protocol);
5856 +static int svc_create(struct net *net, struct socket *sock,int protocol);
5857  
5858  
5859  /*
5860 @@ -335,7 +335,7 @@
5861  
5862         lock_sock(sk);
5863  
5864 -       error = svc_create(newsock,0);
5865 +       error = svc_create(sk->sk_net, newsock,0);
5866         if (error)
5867                 goto out;
5868  
5869 @@ -636,12 +636,15 @@
5870  };
5871  
5872  
5873 -static int svc_create(struct socket *sock,int protocol)
5874 +static int svc_create(struct net *net, struct socket *sock,int protocol)
5875  {
5876         int error;
5877  
5878 +       if (net != &init_net)
5879 +               return -EAFNOSUPPORT;
5880 +
5881         sock->ops = &svc_proto_ops;
5882 -       error = vcc_create(sock, protocol, AF_ATMSVC);
5883 +       error = vcc_create(net, sock, protocol, AF_ATMSVC);
5884         if (error) return error;
5885         ATM_SD(sock)->local.sas_family = AF_ATMSVC;
5886         ATM_SD(sock)->remote.sas_family = AF_ATMSVC;
5887 diff -Nurb linux-2.6.22-try2/net/ax25/af_ax25.c linux-2.6.22-try2-netns/net/ax25/af_ax25.c
5888 --- linux-2.6.22-try2/net/ax25/af_ax25.c        2007-12-19 13:37:56.000000000 -0500
5889 +++ linux-2.6.22-try2-netns/net/ax25/af_ax25.c  2007-12-19 22:49:18.000000000 -0500
5890 @@ -47,6 +47,7 @@
5891  #include <net/tcp_states.h>
5892  #include <net/ip.h>
5893  #include <net/arp.h>
5894 +#include <net/net_namespace.h>
5895  
5896  
5897  
5898 @@ -103,6 +104,9 @@
5899  {
5900         struct net_device *dev = (struct net_device *)ptr;
5901  
5902 +       if (dev->nd_net != &init_net)
5903 +               return NOTIFY_DONE;
5904 +
5905         /* Reject non AX.25 devices */
5906         if (dev->type != ARPHRD_AX25)
5907                 return NOTIFY_DONE;
5908 @@ -627,7 +631,7 @@
5909                         break;
5910                 }
5911  
5912 -               dev = dev_get_by_name(devname);
5913 +               dev = dev_get_by_name(&init_net, devname);
5914                 if (dev == NULL) {
5915                         res = -ENODEV;
5916                         break;
5917 @@ -779,11 +783,14 @@
5918         .obj_size = sizeof(struct sock),
5919  };
5920  
5921 -static int ax25_create(struct socket *sock, int protocol)
5922 +static int ax25_create(struct net *net, struct socket *sock, int protocol)
5923  {
5924         struct sock *sk;
5925         ax25_cb *ax25;
5926  
5927 +       if (net != &init_net)
5928 +               return -EAFNOSUPPORT;
5929 +
5930         switch (sock->type) {
5931         case SOCK_DGRAM:
5932                 if (protocol == 0 || protocol == PF_AX25)
5933 @@ -829,7 +836,7 @@
5934                 return -ESOCKTNOSUPPORT;
5935         }
5936  
5937 -       if ((sk = sk_alloc(PF_AX25, GFP_ATOMIC, &ax25_proto, 1)) == NULL)
5938 +       if ((sk = sk_alloc(net, PF_AX25, GFP_ATOMIC, &ax25_proto, 1)) == NULL)
5939                 return -ENOMEM;
5940  
5941         ax25 = sk->sk_protinfo = ax25_create_cb();
5942 @@ -854,7 +861,7 @@
5943         struct sock *sk;
5944         ax25_cb *ax25, *oax25;
5945  
5946 -       if ((sk = sk_alloc(PF_AX25, GFP_ATOMIC, osk->sk_prot, 1)) == NULL)
5947 +       if ((sk = sk_alloc(osk->sk_net, PF_AX25, GFP_ATOMIC, osk->sk_prot, 1)) == NULL)
5948                 return NULL;
5949  
5950         if ((ax25 = ax25_create_cb()) == NULL) {
5951 @@ -1998,9 +2005,9 @@
5952         register_netdevice_notifier(&ax25_dev_notifier);
5953         ax25_register_sysctl();
5954  
5955 -       proc_net_fops_create("ax25_route", S_IRUGO, &ax25_route_fops);
5956 -       proc_net_fops_create("ax25", S_IRUGO, &ax25_info_fops);
5957 -       proc_net_fops_create("ax25_calls", S_IRUGO, &ax25_uid_fops);
5958 +       proc_net_fops_create(&init_net, "ax25_route", S_IRUGO, &ax25_route_fops);
5959 +       proc_net_fops_create(&init_net, "ax25", S_IRUGO, &ax25_info_fops);
5960 +       proc_net_fops_create(&init_net, "ax25_calls", S_IRUGO, &ax25_uid_fops);
5961  out:
5962         return rc;
5963  }
5964 @@ -2014,9 +2021,9 @@
5965  
5966  static void __exit ax25_exit(void)
5967  {
5968 -       proc_net_remove("ax25_route");
5969 -       proc_net_remove("ax25");
5970 -       proc_net_remove("ax25_calls");
5971 +       proc_net_remove(&init_net, "ax25_route");
5972 +       proc_net_remove(&init_net, "ax25");
5973 +       proc_net_remove(&init_net, "ax25_calls");
5974         ax25_rt_free();
5975         ax25_uid_free();
5976         ax25_dev_free();
5977 diff -Nurb linux-2.6.22-try2/net/ax25/ax25_in.c linux-2.6.22-try2-netns/net/ax25/ax25_in.c
5978 --- linux-2.6.22-try2/net/ax25/ax25_in.c        2007-12-19 13:37:56.000000000 -0500
5979 +++ linux-2.6.22-try2-netns/net/ax25/ax25_in.c  2007-12-19 22:49:18.000000000 -0500
5980 @@ -451,6 +451,11 @@
5981         skb->sk = NULL;         /* Initially we don't know who it's for */
5982         skb->destructor = NULL; /* Who initializes this, dammit?! */
5983  
5984 +       if (dev->nd_net != &init_net) {
5985 +               kfree_skb(skb);
5986 +               return 0;
5987 +       }
5988 +
5989         if ((*skb->data & 0x0F) != 0) {
5990                 kfree_skb(skb); /* Not a KISS data frame */
5991                 return 0;
5992 diff -Nurb linux-2.6.22-try2/net/bluetooth/af_bluetooth.c linux-2.6.22-try2-netns/net/bluetooth/af_bluetooth.c
5993 --- linux-2.6.22-try2/net/bluetooth/af_bluetooth.c      2007-12-19 13:37:56.000000000 -0500
5994 +++ linux-2.6.22-try2-netns/net/bluetooth/af_bluetooth.c        2007-12-19 22:49:18.000000000 -0500
5995 @@ -95,10 +95,13 @@
5996  }
5997  EXPORT_SYMBOL(bt_sock_unregister);
5998  
5999 -static int bt_sock_create(struct socket *sock, int proto)
6000 +static int bt_sock_create(struct net *net, struct socket *sock, int proto)
6001  {
6002         int err;
6003  
6004 +       if (net != &init_net)
6005 +               return -EAFNOSUPPORT;
6006 +
6007         if (proto < 0 || proto >= BT_MAX_PROTO)
6008                 return -EINVAL;
6009  
6010 @@ -113,7 +116,7 @@
6011         read_lock(&bt_proto_lock);
6012  
6013         if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
6014 -               err = bt_proto[proto]->create(sock, proto);
6015 +               err = bt_proto[proto]->create(net, sock, proto);
6016                 module_put(bt_proto[proto]->owner);
6017         }
6018  
6019 diff -Nurb linux-2.6.22-try2/net/bluetooth/bnep/sock.c linux-2.6.22-try2-netns/net/bluetooth/bnep/sock.c
6020 --- linux-2.6.22-try2/net/bluetooth/bnep/sock.c 2007-12-19 13:37:56.000000000 -0500
6021 +++ linux-2.6.22-try2-netns/net/bluetooth/bnep/sock.c   2007-12-19 22:49:18.000000000 -0500
6022 @@ -204,7 +204,7 @@
6023         .obj_size       = sizeof(struct bt_sock)
6024  };
6025  
6026 -static int bnep_sock_create(struct socket *sock, int protocol)
6027 +static int bnep_sock_create(struct net *net, struct socket *sock, int protocol)
6028  {
6029         struct sock *sk;
6030  
6031 @@ -213,7 +213,7 @@
6032         if (sock->type != SOCK_RAW)
6033                 return -ESOCKTNOSUPPORT;
6034  
6035 -       sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, 1);
6036 +       sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, 1);
6037         if (!sk)
6038                 return -ENOMEM;
6039  
6040 diff -Nurb linux-2.6.22-try2/net/bluetooth/cmtp/sock.c linux-2.6.22-try2-netns/net/bluetooth/cmtp/sock.c
6041 --- linux-2.6.22-try2/net/bluetooth/cmtp/sock.c 2007-12-19 13:37:56.000000000 -0500
6042 +++ linux-2.6.22-try2-netns/net/bluetooth/cmtp/sock.c   2007-12-19 22:49:18.000000000 -0500
6043 @@ -195,7 +195,7 @@
6044         .obj_size       = sizeof(struct bt_sock)
6045  };
6046  
6047 -static int cmtp_sock_create(struct socket *sock, int protocol)
6048 +static int cmtp_sock_create(struct net *net, struct socket *sock, int protocol)
6049  {
6050         struct sock *sk;
6051  
6052 @@ -204,7 +204,7 @@
6053         if (sock->type != SOCK_RAW)
6054                 return -ESOCKTNOSUPPORT;
6055  
6056 -       sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, 1);
6057 +       sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, 1);
6058         if (!sk)
6059                 return -ENOMEM;
6060  
6061 diff -Nurb linux-2.6.22-try2/net/bluetooth/hci_sock.c linux-2.6.22-try2-netns/net/bluetooth/hci_sock.c
6062 --- linux-2.6.22-try2/net/bluetooth/hci_sock.c  2007-12-19 13:37:56.000000000 -0500
6063 +++ linux-2.6.22-try2-netns/net/bluetooth/hci_sock.c    2007-12-19 22:49:18.000000000 -0500
6064 @@ -618,7 +618,7 @@
6065         .obj_size       = sizeof(struct hci_pinfo)
6066  };
6067  
6068 -static int hci_sock_create(struct socket *sock, int protocol)
6069 +static int hci_sock_create(struct net *net, struct socket *sock, int protocol)
6070  {
6071         struct sock *sk;
6072  
6073 @@ -629,7 +629,7 @@
6074  
6075         sock->ops = &hci_sock_ops;
6076  
6077 -       sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, 1);
6078 +       sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, 1);
6079         if (!sk)
6080                 return -ENOMEM;
6081  
6082 diff -Nurb linux-2.6.22-try2/net/bluetooth/hidp/sock.c linux-2.6.22-try2-netns/net/bluetooth/hidp/sock.c
6083 --- linux-2.6.22-try2/net/bluetooth/hidp/sock.c 2007-12-19 13:37:56.000000000 -0500
6084 +++ linux-2.6.22-try2-netns/net/bluetooth/hidp/sock.c   2007-12-19 22:49:18.000000000 -0500
6085 @@ -246,7 +246,7 @@
6086         .obj_size       = sizeof(struct bt_sock)
6087  };
6088  
6089 -static int hidp_sock_create(struct socket *sock, int protocol)
6090 +static int hidp_sock_create(struct net *net, struct socket *sock, int protocol)
6091  {
6092         struct sock *sk;
6093  
6094 @@ -255,7 +255,7 @@
6095         if (sock->type != SOCK_RAW)
6096                 return -ESOCKTNOSUPPORT;
6097  
6098 -       sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, 1);
6099 +       sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, 1);
6100         if (!sk)
6101                 return -ENOMEM;
6102  
6103 diff -Nurb linux-2.6.22-try2/net/bluetooth/l2cap.c linux-2.6.22-try2-netns/net/bluetooth/l2cap.c
6104 --- linux-2.6.22-try2/net/bluetooth/l2cap.c     2007-12-19 13:37:56.000000000 -0500
6105 +++ linux-2.6.22-try2-netns/net/bluetooth/l2cap.c       2007-12-19 22:49:18.000000000 -0500
6106 @@ -518,11 +518,11 @@
6107         .obj_size       = sizeof(struct l2cap_pinfo)
6108  };
6109  
6110 -static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, gfp_t prio)
6111 +static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
6112  {
6113         struct sock *sk;
6114  
6115 -       sk = sk_alloc(PF_BLUETOOTH, prio, &l2cap_proto, 1);
6116 +       sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto, 1);
6117         if (!sk)
6118                 return NULL;
6119  
6120 @@ -543,7 +543,7 @@
6121         return sk;
6122  }
6123  
6124 -static int l2cap_sock_create(struct socket *sock, int protocol)
6125 +static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol)
6126  {
6127         struct sock *sk;
6128  
6129 @@ -560,7 +560,7 @@
6130  
6131         sock->ops = &l2cap_sock_ops;
6132  
6133 -       sk = l2cap_sock_alloc(sock, protocol, GFP_ATOMIC);
6134 +       sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
6135         if (!sk)
6136                 return -ENOMEM;
6137  
6138 @@ -1425,7 +1425,7 @@
6139                 goto response;
6140         }
6141  
6142 -       sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC);
6143 +       sk = l2cap_sock_alloc(parent->sk_net, NULL, BTPROTO_L2CAP, GFP_ATOMIC);
6144         if (!sk)
6145                 goto response;
6146  
6147 diff -Nurb linux-2.6.22-try2/net/bluetooth/rfcomm/sock.c linux-2.6.22-try2-netns/net/bluetooth/rfcomm/sock.c
6148 --- linux-2.6.22-try2/net/bluetooth/rfcomm/sock.c       2007-12-19 13:37:56.000000000 -0500
6149 +++ linux-2.6.22-try2-netns/net/bluetooth/rfcomm/sock.c 2007-12-19 22:49:18.000000000 -0500
6150 @@ -282,12 +282,12 @@
6151         .obj_size       = sizeof(struct rfcomm_pinfo)
6152  };
6153  
6154 -static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, gfp_t prio)
6155 +static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
6156  {
6157         struct rfcomm_dlc *d;
6158         struct sock *sk;
6159  
6160 -       sk = sk_alloc(PF_BLUETOOTH, prio, &rfcomm_proto, 1);
6161 +       sk = sk_alloc(net, PF_BLUETOOTH, prio, &rfcomm_proto, 1);
6162         if (!sk)
6163                 return NULL;
6164  
6165 @@ -323,7 +323,7 @@
6166         return sk;
6167  }
6168  
6169 -static int rfcomm_sock_create(struct socket *sock, int protocol)
6170 +static int rfcomm_sock_create(struct net *net, struct socket *sock, int protocol)
6171  {
6172         struct sock *sk;
6173  
6174 @@ -336,7 +336,7 @@
6175  
6176         sock->ops = &rfcomm_sock_ops;
6177  
6178 -       sk = rfcomm_sock_alloc(sock, protocol, GFP_ATOMIC);
6179 +       sk = rfcomm_sock_alloc(net, sock, protocol, GFP_ATOMIC);
6180         if (!sk)
6181                 return -ENOMEM;
6182  
6183 @@ -868,7 +868,7 @@
6184                 goto done;
6185         }
6186  
6187 -       sk = rfcomm_sock_alloc(NULL, BTPROTO_RFCOMM, GFP_ATOMIC);
6188 +       sk = rfcomm_sock_alloc(parent->sk_net, NULL, BTPROTO_RFCOMM, GFP_ATOMIC);
6189         if (!sk)
6190                 goto done;
6191  
6192 diff -Nurb linux-2.6.22-try2/net/bluetooth/sco.c linux-2.6.22-try2-netns/net/bluetooth/sco.c
6193 --- linux-2.6.22-try2/net/bluetooth/sco.c       2007-12-19 13:37:56.000000000 -0500
6194 +++ linux-2.6.22-try2-netns/net/bluetooth/sco.c 2007-12-19 22:49:18.000000000 -0500
6195 @@ -414,11 +414,11 @@
6196         .obj_size       = sizeof(struct sco_pinfo)
6197  };
6198  
6199 -static struct sock *sco_sock_alloc(struct socket *sock, int proto, gfp_t prio)
6200 +static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
6201  {
6202         struct sock *sk;
6203  
6204 -       sk = sk_alloc(PF_BLUETOOTH, prio, &sco_proto, 1);
6205 +       sk = sk_alloc(net, PF_BLUETOOTH, prio, &sco_proto, 1);
6206         if (!sk)
6207                 return NULL;
6208  
6209 @@ -439,7 +439,7 @@
6210         return sk;
6211  }
6212  
6213 -static int sco_sock_create(struct socket *sock, int protocol)
6214 +static int sco_sock_create(struct net *net, struct socket *sock, int protocol)
6215  {
6216         struct sock *sk;
6217  
6218 @@ -452,7 +452,7 @@
6219  
6220         sock->ops = &sco_sock_ops;
6221  
6222 -       sk = sco_sock_alloc(sock, protocol, GFP_ATOMIC);
6223 +       sk = sco_sock_alloc(net, sock, protocol, GFP_ATOMIC);
6224         if (!sk)
6225                 return -ENOMEM;
6226  
6227 @@ -807,7 +807,7 @@
6228  
6229                 bh_lock_sock(parent);
6230  
6231 -               sk = sco_sock_alloc(NULL, BTPROTO_SCO, GFP_ATOMIC);
6232 +               sk = sco_sock_alloc(parent->sk_net, NULL, BTPROTO_SCO, GFP_ATOMIC);
6233                 if (!sk) {
6234                         bh_unlock_sock(parent);
6235                         goto done;
6236 diff -Nurb linux-2.6.22-try2/net/bridge/br_if.c linux-2.6.22-try2-netns/net/bridge/br_if.c
6237 --- linux-2.6.22-try2/net/bridge/br_if.c        2007-12-19 15:29:23.000000000 -0500
6238 +++ linux-2.6.22-try2-netns/net/bridge/br_if.c  2007-12-19 22:49:18.000000000 -0500
6239 @@ -45,7 +45,7 @@
6240  
6241         old_fs = get_fs();
6242         set_fs(KERNEL_DS);
6243 -       err = dev_ethtool(&ifr);
6244 +       err = dev_ethtool(dev->nd_net, &ifr);
6245         set_fs(old_fs);
6246  
6247         if (!err) {
6248 @@ -314,7 +314,7 @@
6249         int ret = 0;
6250  
6251         rtnl_lock();
6252 -       dev = __dev_get_by_name(name);
6253 +       dev = __dev_get_by_name(&init_net, name);
6254         if (dev == NULL)
6255                 ret =  -ENXIO;  /* Could not find device */
6256  
6257 @@ -455,7 +455,7 @@
6258         struct net_device *dev, *nxt;
6259  
6260         rtnl_lock();
6261 -       for_each_netdev_safe(dev, nxt)
6262 +       for_each_netdev_safe(&init_net, dev, nxt)
6263                 if (dev->priv_flags & IFF_EBRIDGE)
6264                         del_br(dev->priv);
6265         rtnl_unlock();
6266 diff -Nurb linux-2.6.22-try2/net/bridge/br_ioctl.c linux-2.6.22-try2-netns/net/bridge/br_ioctl.c
6267 --- linux-2.6.22-try2/net/bridge/br_ioctl.c     2007-12-19 13:37:56.000000000 -0500
6268 +++ linux-2.6.22-try2-netns/net/bridge/br_ioctl.c       2007-12-19 22:49:18.000000000 -0500
6269 @@ -18,6 +18,7 @@
6270  #include <linux/if_bridge.h>
6271  #include <linux/netdevice.h>
6272  #include <linux/times.h>
6273 +#include <net/net_namespace.h>
6274  #include <asm/uaccess.h>
6275  #include "br_private.h"
6276  
6277 @@ -27,7 +28,7 @@
6278         struct net_device *dev;
6279         int i = 0;
6280  
6281 -       for_each_netdev(dev) {
6282 +       for_each_netdev(&init_net, dev) {
6283                 if (i >= num)
6284                         break;
6285                 if (dev->priv_flags & IFF_EBRIDGE)
6286 @@ -90,7 +91,7 @@
6287         if (!capable(CAP_NET_ADMIN))
6288                 return -EPERM;
6289  
6290 -       dev = dev_get_by_index(ifindex);
6291 +       dev = dev_get_by_index(&init_net, ifindex);
6292         if (dev == NULL)
6293                 return -EINVAL;
6294  
6295 @@ -364,7 +365,7 @@
6296         return -EOPNOTSUPP;
6297  }
6298  
6299 -int br_ioctl_deviceless_stub(unsigned int cmd, void __user *uarg)
6300 +int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *uarg)
6301  {
6302         switch (cmd) {
6303         case SIOCGIFBR:
6304 diff -Nurb linux-2.6.22-try2/net/bridge/br_netfilter.c linux-2.6.22-try2-netns/net/bridge/br_netfilter.c
6305 --- linux-2.6.22-try2/net/bridge/br_netfilter.c 2007-12-19 13:37:56.000000000 -0500
6306 +++ linux-2.6.22-try2-netns/net/bridge/br_netfilter.c   2007-12-19 22:49:18.000000000 -0500
6307 @@ -310,6 +310,7 @@
6308                 if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) {
6309                         struct rtable *rt;
6310                         struct flowi fl = {
6311 +                               .fl_net = &init_net,
6312                                 .nl_u = {
6313                                         .ip4_u = {
6314                                                  .daddr = iph->daddr,
6315 @@ -518,6 +519,10 @@
6316         if (unlikely(!pskb_may_pull(skb, len)))
6317                 goto out;
6318  
6319 +       /* Only filter packets in the initial network namespace */
6320 +       if ((in?in:out)->nd_net != &init_net)
6321 +               return NF_ACCEPT;
6322 +
6323         if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb) ||
6324             IS_PPPOE_IPV6(skb)) {
6325  #ifdef CONFIG_SYSCTL
6326 @@ -591,6 +596,10 @@
6327  {
6328         struct sk_buff *skb = *pskb;
6329  
6330 +       /* Only filter packets in the initial network namespace */
6331 +       if ((in?in:out)->nd_net != &init_net)
6332 +               return NF_ACCEPT;
6333 +
6334         if (skb->dst == (struct dst_entry *)&__fake_rtable) {
6335                 dst_release(skb->dst);
6336                 skb->dst = NULL;
6337 @@ -635,6 +644,10 @@
6338         struct net_device *parent;
6339         int pf;
6340  
6341 +       /* Only filter packets in the initial network namespace */
6342 +       if ((in?in:out)->nd_net != &init_net)
6343 +               return NF_ACCEPT;
6344 +
6345         if (!skb->nf_bridge)
6346                 return NF_ACCEPT;
6347  
6348 @@ -674,6 +687,10 @@
6349         struct sk_buff *skb = *pskb;
6350         struct net_device **d = (struct net_device **)(skb->cb);
6351  
6352 +       /* Only filter packets in the initial network namespace */
6353 +       if ((in?in:out)->nd_net != &init_net)
6354 +               return NF_ACCEPT;
6355 +
6356  #ifdef CONFIG_SYSCTL
6357         if (!brnf_call_arptables)
6358                 return NF_ACCEPT;
6359 @@ -718,6 +735,10 @@
6360         struct sk_buff *skb = *pskb;
6361         struct nf_bridge_info *nf_bridge;
6362  
6363 +       /* Only filter packets in the initial network namespace */
6364 +       if ((in?in:out)->nd_net != &init_net)
6365 +               return NF_ACCEPT;
6366 +
6367         if (!skb->nf_bridge)
6368                 return NF_ACCEPT;
6369  
6370 @@ -762,6 +783,10 @@
6371         struct net_device *realoutdev = bridge_parent(skb->dev);
6372         int pf;
6373  
6374 +       /* Only filter packets in the initial network namespace */
6375 +       if ((in?in:out)->nd_net != &init_net)
6376 +               return NF_ACCEPT;
6377 +
6378  #ifdef CONFIG_NETFILTER_DEBUG
6379         /* Be very paranoid. This probably won't happen anymore, but let's
6380          * keep the check just to be sure... */
6381 @@ -833,6 +858,10 @@
6382                                    const struct net_device *out,
6383                                    int (*okfn)(struct sk_buff *))
6384  {
6385 +       /* Only filter packets in the initial network namespace */
6386 +       if ((in?in:out)->nd_net != &init_net)
6387 +               return NF_ACCEPT;
6388 +
6389         if ((*pskb)->nf_bridge &&
6390             !((*pskb)->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)) {
6391                 return NF_STOP;
6392 diff -Nurb linux-2.6.22-try2/net/bridge/br_netlink.c linux-2.6.22-try2-netns/net/bridge/br_netlink.c
6393 --- linux-2.6.22-try2/net/bridge/br_netlink.c   2007-12-19 13:37:56.000000000 -0500
6394 +++ linux-2.6.22-try2-netns/net/bridge/br_netlink.c     2007-12-19 22:49:18.000000000 -0500
6395 @@ -12,6 +12,8 @@
6396  
6397  #include <linux/kernel.h>
6398  #include <net/rtnetlink.h>
6399 +#include <net/net_namespace.h>
6400 +#include <net/sock.h>
6401  #include "br_private.h"
6402  
6403  static inline size_t br_nlmsg_size(void)
6404 @@ -95,10 +97,10 @@
6405                 kfree_skb(skb);
6406                 goto errout;
6407         }
6408 -       err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
6409 +       err = rtnl_notify(skb, &init_net,0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
6410  errout:
6411         if (err < 0)
6412 -               rtnl_set_sk_err(RTNLGRP_LINK, err);
6413 +               rtnl_set_sk_err(&init_net, RTNLGRP_LINK, err);
6414  }
6415  
6416  /*
6417 @@ -106,11 +108,15 @@
6418   */
6419  static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
6420  {
6421 +       struct net *net = skb->sk->sk_net;
6422         struct net_device *dev;
6423         int idx;
6424  
6425 +       if (net != &init_net)
6426 +               return 0;
6427 +
6428         idx = 0;
6429 -       for_each_netdev(dev) {
6430 +       for_each_netdev(&init_net, dev) {
6431                 /* not a bridge port */
6432                 if (dev->br_port == NULL || idx < cb->args[0])
6433                         goto skip;
6434 @@ -134,12 +140,16 @@
6435   */
6436  static int br_rtm_setlink(struct sk_buff *skb,  struct nlmsghdr *nlh, void *arg)
6437  {
6438 +       struct net *net = skb->sk->sk_net;
6439         struct ifinfomsg *ifm;
6440         struct nlattr *protinfo;
6441         struct net_device *dev;
6442         struct net_bridge_port *p;
6443         u8 new_state;
6444  
6445 +       if (net != &init_net)
6446 +               return -EINVAL;
6447 +
6448         if (nlmsg_len(nlh) < sizeof(*ifm))
6449                 return -EINVAL;
6450  
6451 @@ -155,7 +165,7 @@
6452         if (new_state > BR_STATE_BLOCKING)
6453                 return -EINVAL;
6454  
6455 -       dev = __dev_get_by_index(ifm->ifi_index);
6456 +       dev = __dev_get_by_index(&init_net, ifm->ifi_index);
6457         if (!dev)
6458                 return -ENODEV;
6459  
6460 diff -Nurb linux-2.6.22-try2/net/bridge/br_notify.c linux-2.6.22-try2-netns/net/bridge/br_notify.c
6461 --- linux-2.6.22-try2/net/bridge/br_notify.c    2007-12-19 13:37:56.000000000 -0500
6462 +++ linux-2.6.22-try2-netns/net/bridge/br_notify.c      2007-12-19 22:49:18.000000000 -0500
6463 @@ -15,6 +15,7 @@
6464  
6465  #include <linux/kernel.h>
6466  #include <linux/rtnetlink.h>
6467 +#include <net/net_namespace.h>
6468  
6469  #include "br_private.h"
6470  
6471 @@ -36,6 +37,9 @@
6472         struct net_bridge_port *p = dev->br_port;
6473         struct net_bridge *br;
6474  
6475 +       if (dev->nd_net != &init_net)
6476 +               return NOTIFY_DONE;
6477 +
6478         /* not a port of a bridge */
6479         if (p == NULL)
6480                 return NOTIFY_DONE;
6481 diff -Nurb linux-2.6.22-try2/net/bridge/br_private.h linux-2.6.22-try2-netns/net/bridge/br_private.h
6482 --- linux-2.6.22-try2/net/bridge/br_private.h   2007-12-19 13:37:56.000000000 -0500
6483 +++ linux-2.6.22-try2-netns/net/bridge/br_private.h     2007-12-19 22:49:18.000000000 -0500
6484 @@ -196,7 +196,7 @@
6485  
6486  /* br_ioctl.c */
6487  extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
6488 -extern int br_ioctl_deviceless_stub(unsigned int cmd, void __user *arg);
6489 +extern int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *arg);
6490  
6491  /* br_netfilter.c */
6492  #ifdef CONFIG_BRIDGE_NETFILTER
6493 diff -Nurb linux-2.6.22-try2/net/bridge/br_stp_bpdu.c linux-2.6.22-try2-netns/net/bridge/br_stp_bpdu.c
6494 --- linux-2.6.22-try2/net/bridge/br_stp_bpdu.c  2007-12-19 13:37:56.000000000 -0500
6495 +++ linux-2.6.22-try2-netns/net/bridge/br_stp_bpdu.c    2007-12-19 22:49:18.000000000 -0500
6496 @@ -17,6 +17,7 @@
6497  #include <linux/netfilter_bridge.h>
6498  #include <linux/etherdevice.h>
6499  #include <linux/llc.h>
6500 +#include <net/net_namespace.h>
6501  #include <net/llc.h>
6502  #include <net/llc_pdu.h>
6503  #include <asm/unaligned.h>
6504 @@ -141,6 +142,9 @@
6505         struct net_bridge *br;
6506         const unsigned char *buf;
6507  
6508 +       if (dev->nd_net != &init_net)
6509 +               goto err;
6510 +
6511         if (!p)
6512                 goto err;
6513  
6514 diff -Nurb linux-2.6.22-try2/net/bridge/netfilter/ebt_ulog.c linux-2.6.22-try2-netns/net/bridge/netfilter/ebt_ulog.c
6515 --- linux-2.6.22-try2/net/bridge/netfilter/ebt_ulog.c   2007-12-19 13:37:56.000000000 -0500
6516 +++ linux-2.6.22-try2-netns/net/bridge/netfilter/ebt_ulog.c     2007-12-19 22:49:18.000000000 -0500
6517 @@ -301,8 +301,9 @@
6518                 spin_lock_init(&ulog_buffers[i].lock);
6519         }
6520  
6521 -       ebtulognl = netlink_kernel_create(NETLINK_NFLOG, EBT_ULOG_MAXNLGROUPS,
6522 -                                         NULL, NULL, THIS_MODULE);
6523 +       ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG,
6524 +                                         EBT_ULOG_MAXNLGROUPS, NULL, NULL,
6525 +                                         THIS_MODULE);
6526         if (!ebtulognl)
6527                 ret = -ENOMEM;
6528         else if ((ret = ebt_register_watcher(&ulog)))
6529 diff -Nurb linux-2.6.22-try2/net/bridge/netfilter/ebtable_filter.c linux-2.6.22-try2-netns/net/bridge/netfilter/ebtable_filter.c
6530 --- linux-2.6.22-try2/net/bridge/netfilter/ebtable_filter.c     2007-12-19 13:37:56.000000000 -0500
6531 +++ linux-2.6.22-try2-netns/net/bridge/netfilter/ebtable_filter.c       2007-12-19 22:49:18.000000000 -0500
6532 @@ -64,6 +64,10 @@
6533  ebt_hook (unsigned int hook, struct sk_buff **pskb, const struct net_device *in,
6534     const struct net_device *out, int (*okfn)(struct sk_buff *))
6535  {
6536 +       /* Only filter packets in the initial network namespace */
6537 +       if ((in?in:out)->nd_net != &init_net)
6538 +               return NF_ACCEPT;
6539 +
6540         return ebt_do_table(hook, pskb, in, out, &frame_filter);
6541  }
6542  
6543 diff -Nurb linux-2.6.22-try2/net/bridge/netfilter/ebtable_nat.c linux-2.6.22-try2-netns/net/bridge/netfilter/ebtable_nat.c
6544 --- linux-2.6.22-try2/net/bridge/netfilter/ebtable_nat.c        2007-12-19 13:37:56.000000000 -0500
6545 +++ linux-2.6.22-try2-netns/net/bridge/netfilter/ebtable_nat.c  2007-12-19 22:49:18.000000000 -0500
6546 @@ -64,6 +64,10 @@
6547  ebt_nat_dst(unsigned int hook, struct sk_buff **pskb, const struct net_device *in
6548     , const struct net_device *out, int (*okfn)(struct sk_buff *))
6549  {
6550 +       /* Only filter packets in the initial network namespace */
6551 +       if ((in?in:out)->nd_net != &init_net)
6552 +               return NF_ACCEPT;
6553 +
6554         return ebt_do_table(hook, pskb, in, out, &frame_nat);
6555  }
6556  
6557 @@ -71,6 +75,10 @@
6558  ebt_nat_src(unsigned int hook, struct sk_buff **pskb, const struct net_device *in
6559     , const struct net_device *out, int (*okfn)(struct sk_buff *))
6560  {
6561 +       /* Only filter packets in the initial network namespace */
6562 +       if ((in?in:out)->nd_net != &init_net)
6563 +               return NF_ACCEPT;
6564 +
6565         return ebt_do_table(hook, pskb, in, out, &frame_nat);
6566  }
6567  
6568 diff -Nurb linux-2.6.22-try2/net/bridge/netfilter/ebtables.c linux-2.6.22-try2-netns/net/bridge/netfilter/ebtables.c
6569 --- linux-2.6.22-try2/net/bridge/netfilter/ebtables.c   2007-12-19 13:37:56.000000000 -0500
6570 +++ linux-2.6.22-try2-netns/net/bridge/netfilter/ebtables.c     2007-12-19 22:49:18.000000000 -0500
6571 @@ -28,6 +28,7 @@
6572  #include <linux/smp.h>
6573  #include <linux/cpumask.h>
6574  #include <net/sock.h>
6575 +#include <net/net_namespace.h>
6576  /* needed for logical [in,out]-dev filtering */
6577  #include "../br_private.h"
6578  
6579 @@ -1438,6 +1439,9 @@
6580  {
6581         int ret;
6582  
6583 +       if (sk->sk_net != &init_net)
6584 +               return -ENOPROTOOPT;
6585 +
6586         switch(cmd) {
6587         case EBT_SO_SET_ENTRIES:
6588                 ret = do_replace(user, len);
6589 @@ -1457,6 +1461,9 @@
6590         struct ebt_replace tmp;
6591         struct ebt_table *t;
6592  
6593 +       if (sk->sk_net != &init_net)
6594 +               return -ENOPROTOOPT;
6595 +
6596         if (copy_from_user(&tmp, user, sizeof(tmp)))
6597                 return -EFAULT;
6598  
6599 diff -Nurb linux-2.6.22-try2/net/core/Makefile linux-2.6.22-try2-netns/net/core/Makefile
6600 --- linux-2.6.22-try2/net/core/Makefile 2007-12-19 13:37:56.000000000 -0500
6601 +++ linux-2.6.22-try2-netns/net/core/Makefile   2007-12-19 22:49:18.000000000 -0500
6602 @@ -3,7 +3,7 @@
6603  #
6604  
6605  obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \
6606 -        gen_stats.o gen_estimator.o
6607 +        gen_stats.o gen_estimator.o net_namespace.o
6608  
6609  obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
6610  
6611 diff -Nurb linux-2.6.22-try2/net/core/dev.c linux-2.6.22-try2-netns/net/core/dev.c
6612 --- linux-2.6.22-try2/net/core/dev.c    2007-12-19 15:29:25.000000000 -0500
6613 +++ linux-2.6.22-try2-netns/net/core/dev.c      2007-12-19 23:03:34.000000000 -0500
6614 @@ -116,6 +116,7 @@
6615  #include <linux/dmaengine.h>
6616  #include <linux/err.h>
6617  #include <linux/ctype.h>
6618 +#include <net/net_namespace.h>
6619  #include <linux/if_arp.h>
6620  #include <linux/vs_inet.h>
6621  
6622 @@ -189,25 +190,50 @@
6623   * unregister_netdevice(), which must be called with the rtnl
6624   * semaphore held.
6625   */
6626 -LIST_HEAD(dev_base_head);
6627  DEFINE_RWLOCK(dev_base_lock);
6628  
6629 -EXPORT_SYMBOL(dev_base_head);
6630  EXPORT_SYMBOL(dev_base_lock);
6631  
6632  #define NETDEV_HASHBITS        8
6633 -static struct hlist_head dev_name_head[1<<NETDEV_HASHBITS];
6634 -static struct hlist_head dev_index_head[1<<NETDEV_HASHBITS];
6635 +#define NETDEV_HASHENTRIES (1 << NETDEV_HASHBITS)
6636  
6637 -static inline struct hlist_head *dev_name_hash(const char *name)
6638 +static inline struct hlist_head *dev_name_hash(struct net *net, const char *name)
6639  {
6640         unsigned hash = full_name_hash(name, strnlen(name, IFNAMSIZ));
6641 -       return &dev_name_head[hash & ((1<<NETDEV_HASHBITS)-1)];
6642 +       return &net->dev_name_head[hash & ((1 << NETDEV_HASHBITS) - 1)];
6643  }
6644  
6645 -static inline struct hlist_head *dev_index_hash(int ifindex)
6646 +static inline struct hlist_head *dev_index_hash(struct net *net, int ifindex)
6647  {
6648 -       return &dev_index_head[ifindex & ((1<<NETDEV_HASHBITS)-1)];
6649 +       return &net->dev_index_head[ifindex & ((1 << NETDEV_HASHBITS) - 1)];
6650 +}
6651 +
6652 +/* Device list insertion */
6653 +static int list_netdevice(struct net_device *dev)
6654 +{
6655 +       struct net *net = dev->nd_net;
6656 +
6657 +       ASSERT_RTNL();
6658 +
6659 +       write_lock_bh(&dev_base_lock);
6660 +       list_add_tail(&dev->dev_list, &net->dev_base_head);
6661 +       hlist_add_head(&dev->name_hlist, dev_name_hash(net, dev->name));
6662 +       hlist_add_head(&dev->index_hlist, dev_index_hash(net, dev->ifindex));
6663 +       write_unlock_bh(&dev_base_lock);
6664 +       return 0;
6665 +}
6666 +
6667 +/* Device list removal */
6668 +static void unlist_netdevice(struct net_device *dev)
6669 +{
6670 +       ASSERT_RTNL();
6671 +
6672 +       /* Unlink dev from the device chain */
6673 +       write_lock_bh(&dev_base_lock);
6674 +       list_del(&dev->dev_list);
6675 +       hlist_del(&dev->name_hlist);
6676 +       hlist_del(&dev->index_hlist);
6677 +       write_unlock_bh(&dev_base_lock);
6678  }
6679  
6680  /*
6681 @@ -490,7 +516,7 @@
6682          * If device already registered then return base of 1
6683          * to indicate not to probe for this interface
6684          */
6685 -       if (__dev_get_by_name(name))
6686 +       if (__dev_get_by_name(&init_net, name))
6687                 return 1;
6688  
6689         for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++)
6690 @@ -545,11 +571,11 @@
6691   *     careful with locks.
6692   */
6693  
6694 -struct net_device *__dev_get_by_name(const char *name)
6695 +struct net_device *__dev_get_by_name(struct net *net, const char *name)
6696  {
6697         struct hlist_node *p;
6698  
6699 -       hlist_for_each(p, dev_name_hash(name)) {
6700 +       hlist_for_each(p, dev_name_hash(net, name)) {
6701                 struct net_device *dev
6702                         = hlist_entry(p, struct net_device, name_hlist);
6703                 if (!strncmp(dev->name, name, IFNAMSIZ))
6704 @@ -569,12 +595,12 @@
6705   *     matching device is found.
6706   */
6707  
6708 -struct net_device *dev_get_by_name(const char *name)
6709 +struct net_device *dev_get_by_name(struct net *net, const char *name)
6710  {
6711         struct net_device *dev;
6712  
6713         read_lock(&dev_base_lock);
6714 -       dev = __dev_get_by_name(name);
6715 +       dev = __dev_get_by_name(net, name);
6716         if (dev)
6717                 dev_hold(dev);
6718         read_unlock(&dev_base_lock);
6719 @@ -592,11 +618,11 @@
6720   *     or @dev_base_lock.
6721   */
6722  
6723 -struct net_device *__dev_get_by_index(int ifindex)
6724 +struct net_device *__dev_get_by_index(struct net *net, int ifindex)
6725  {
6726         struct hlist_node *p;
6727  
6728 -       hlist_for_each(p, dev_index_hash(ifindex)) {
6729 +       hlist_for_each(p, dev_index_hash(net, ifindex)) {
6730                 struct net_device *dev
6731                         = hlist_entry(p, struct net_device, index_hlist);
6732                 if (dev->ifindex == ifindex)
6733 @@ -616,12 +642,12 @@
6734   *     dev_put to indicate they have finished with it.
6735   */
6736  
6737 -struct net_device *dev_get_by_index(int ifindex)
6738 +struct net_device *dev_get_by_index(struct net *net, int ifindex)
6739  {
6740         struct net_device *dev;
6741  
6742         read_lock(&dev_base_lock);
6743 -       dev = __dev_get_by_index(ifindex);
6744 +       dev = __dev_get_by_index(net, ifindex);
6745         if (dev)
6746                 dev_hold(dev);
6747         read_unlock(&dev_base_lock);
6748 @@ -642,13 +668,13 @@
6749   *     If the API was consistent this would be __dev_get_by_hwaddr
6750   */
6751  
6752 -struct net_device *dev_getbyhwaddr(unsigned short type, char *ha)
6753 +struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, char *ha)
6754  {
6755         struct net_device *dev;
6756  
6757         ASSERT_RTNL();
6758  
6759 -       for_each_netdev(dev)
6760 +       for_each_netdev(&init_net, dev)
6761                 if (dev->type == type &&
6762                     !memcmp(dev->dev_addr, ha, dev->addr_len))
6763                         return dev;
6764 @@ -658,12 +684,12 @@
6765  
6766  EXPORT_SYMBOL(dev_getbyhwaddr);
6767  
6768 -struct net_device *__dev_getfirstbyhwtype(unsigned short type)
6769 +struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type)
6770  {
6771         struct net_device *dev;
6772  
6773         ASSERT_RTNL();
6774 -       for_each_netdev(dev)
6775 +       for_each_netdev(net, dev)
6776                 if (dev->type == type)
6777                         return dev;
6778  
6779 @@ -672,12 +698,12 @@
6780  
6781  EXPORT_SYMBOL(__dev_getfirstbyhwtype);
6782  
6783 -struct net_device *dev_getfirstbyhwtype(unsigned short type)
6784 +struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type)
6785  {
6786         struct net_device *dev;
6787  
6788         rtnl_lock();
6789 -       dev = __dev_getfirstbyhwtype(type);
6790 +       dev = __dev_getfirstbyhwtype(net, type);
6791         if (dev)
6792                 dev_hold(dev);
6793         rtnl_unlock();
6794 @@ -697,13 +723,13 @@
6795   *     dev_put to indicate they have finished with it.
6796   */
6797  
6798 -struct net_device * dev_get_by_flags(unsigned short if_flags, unsigned short mask)
6799 +struct net_device * dev_get_by_flags(struct net *net, unsigned short if_flags, unsigned short mask)
6800  {
6801         struct net_device *dev, *ret;
6802  
6803         ret = NULL;
6804         read_lock(&dev_base_lock);
6805 -       for_each_netdev(dev) {
6806 +       for_each_netdev(net, dev) {
6807                 if (((dev->flags ^ if_flags) & mask) == 0) {
6808                         dev_hold(dev);
6809                         ret = dev;
6810 @@ -740,9 +766,10 @@
6811  }
6812  
6813  /**
6814 - *     dev_alloc_name - allocate a name for a device
6815 - *     @dev: device
6816 + *     __dev_alloc_name - allocate a name for a device
6817 + *     @net: network namespace to allocate the device name in
6818   *     @name: name format string
6819 + *     @buf:  scratch buffer and result name string
6820   *
6821   *     Passed a format string - eg "lt%d" it will try and find a suitable
6822   *     id. It scans list of devices to build up a free map, then chooses
6823 @@ -753,10 +780,9 @@
6824   *     Returns the number of the unit assigned or a negative errno code.
6825   */
6826  
6827 -int dev_alloc_name(struct net_device *dev, const char *name)
6828 +static int __dev_alloc_name(struct net *net, const char *name, char *buf)
6829  {
6830         int i = 0;
6831 -       char buf[IFNAMSIZ];
6832         const char *p;
6833         const int max_netdevices = 8*PAGE_SIZE;
6834         long *inuse;
6835 @@ -777,14 +803,14 @@
6836                 if (!inuse)
6837                         return -ENOMEM;
6838  
6839 -               for_each_netdev(d) {
6840 +               for_each_netdev(net, d) {
6841                         if (!sscanf(d->name, name, &i))
6842                                 continue;
6843                         if (i < 0 || i >= max_netdevices)
6844                                 continue;
6845  
6846                         /*  avoid cases where sscanf is not exact inverse of printf */
6847 -                       snprintf(buf, sizeof(buf), name, i);
6848 +                       snprintf(buf, IFNAMSIZ, name, i);
6849                         if (!strncmp(buf, d->name, IFNAMSIZ))
6850                                 set_bit(i, inuse);
6851                 }
6852 @@ -793,11 +819,9 @@
6853                 free_page((unsigned long) inuse);
6854         }
6855  
6856 -       snprintf(buf, sizeof(buf), name, i);
6857 -       if (!__dev_get_by_name(buf)) {
6858 -               strlcpy(dev->name, buf, IFNAMSIZ);
6859 +       snprintf(buf, IFNAMSIZ, name, i);
6860 +       if (!__dev_get_by_name(net, buf))
6861                 return i;
6862 -       }
6863  
6864         /* It is possible to run out of possible slots
6865          * when the name is long and there isn't enough space left
6866 @@ -806,6 +830,34 @@
6867         return -ENFILE;
6868  }
6869  
6870 +/**
6871 + *     dev_alloc_name - allocate a name for a device
6872 + *     @dev: device
6873 + *     @name: name format string
6874 + *
6875 + *     Passed a format string - eg "lt%d" it will try and find a suitable
6876 + *     id. It scans list of devices to build up a free map, then chooses
6877 + *     the first empty slot. The caller must hold the dev_base or rtnl lock
6878 + *     while allocating the name and adding the device in order to avoid
6879 + *     duplicates.
6880 + *     Limited to bits_per_byte * page size devices (ie 32K on most platforms).
6881 + *     Returns the number of the unit assigned or a negative errno code.
6882 + */
6883 +
6884 +int dev_alloc_name(struct net_device *dev, const char *name)
6885 +{
6886 +       char buf[IFNAMSIZ];
6887 +       struct net *net;
6888 +       int ret;
6889 +
6890 +       BUG_ON(!dev->nd_net);
6891 +       net = dev->nd_net;
6892 +       ret = __dev_alloc_name(net, name, buf);
6893 +       if (ret >= 0)
6894 +               strlcpy(dev->name, buf, IFNAMSIZ);
6895 +       return ret;
6896 +}
6897 +
6898  
6899  /**
6900   *     dev_change_name - change name of a device
6901 @@ -818,9 +870,12 @@
6902  int dev_change_name(struct net_device *dev, char *newname)
6903  {
6904         int err = 0;
6905 +       struct net *net;
6906  
6907         ASSERT_RTNL();
6908 +       BUG_ON(!dev->nd_net);
6909  
6910 +       net = dev->nd_net;
6911         if (dev->flags & IFF_UP)
6912                 return -EBUSY;
6913  
6914 @@ -833,7 +888,7 @@
6915                         return err;
6916                 strcpy(newname, dev->name);
6917         }
6918 -       else if (__dev_get_by_name(newname))
6919 +       else if (__dev_get_by_name(net, newname))
6920                 return -EEXIST;
6921         else {
6922                 if (strncmp(newname, dev->name, IFNAMSIZ))
6923 @@ -844,7 +899,7 @@
6924  
6925         device_rename(&dev->dev, dev->name);
6926         hlist_del(&dev->name_hlist);
6927 -       hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name));
6928 +       hlist_add_head(&dev->name_hlist, dev_name_hash(net, dev->name));
6929         raw_notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev);
6930  
6931         return err;
6932 @@ -888,12 +943,12 @@
6933   *     available in this kernel then it becomes a nop.
6934   */
6935  
6936 -void dev_load(const char *name)
6937 +void dev_load(struct net *net, const char *name)
6938  {
6939         struct net_device *dev;
6940  
6941         read_lock(&dev_base_lock);
6942 -       dev = __dev_get_by_name(name);
6943 +       dev = __dev_get_by_name(net, name);
6944         read_unlock(&dev_base_lock);
6945  
6946         if (!dev && capable(CAP_SYS_MODULE))
6947 @@ -1036,6 +1091,8 @@
6948  }
6949  
6950  
6951 +static int dev_boot_phase = 1;
6952 +
6953  /*
6954   *     Device change register/unregister. These are not inline or static
6955   *     as we export them to the world.
6956 @@ -1062,14 +1119,17 @@
6957  
6958         rtnl_lock();
6959         err = raw_notifier_chain_register(&netdev_chain, nb);
6960 -       if (!err) {
6961 -               for_each_netdev(dev) {
6962 +       if (!err && !dev_boot_phase) {
6963 +               struct net *net;
6964 +               for_each_net(net) {
6965 +                       for_each_netdev(net, dev) {
6966                         nb->notifier_call(nb, NETDEV_REGISTER, dev);
6967  
6968                         if (dev->flags & IFF_UP)
6969                                 nb->notifier_call(nb, NETDEV_UP, dev);
6970                 }
6971         }
6972 +       }
6973         rtnl_unlock();
6974         return err;
6975  }
6976 @@ -1103,9 +1163,9 @@
6977   *     are as for raw_notifier_call_chain().
6978   */
6979  
6980 -int call_netdevice_notifiers(unsigned long val, void *v)
6981 +int call_netdevice_notifiers(unsigned long val, struct net_device *dev)
6982  {
6983 -       return raw_notifier_call_chain(&netdev_chain, val, v);
6984 +       return raw_notifier_call_chain(&netdev_chain, val, dev);
6985  }
6986  
6987  /* When > 0 there are consumers of rx skb time stamps */
6988 @@ -2083,7 +2143,7 @@
6989   *     match.  --pb
6990   */
6991  
6992 -static int dev_ifname(struct ifreq __user *arg)
6993 +static int dev_ifname(struct net *net, struct ifreq __user *arg)
6994  {
6995         struct net_device *dev;
6996         struct ifreq ifr;
6997 @@ -2096,7 +2156,7 @@
6998                 return -EFAULT;
6999  
7000         read_lock(&dev_base_lock);
7001 -       dev = __dev_get_by_index(ifr.ifr_ifindex);
7002 +       dev = __dev_get_by_index(net, ifr.ifr_ifindex);
7003         if (!dev) {
7004                 read_unlock(&dev_base_lock);
7005                 return -ENODEV;
7006 @@ -2116,7 +2176,7 @@
7007   *     Thus we will need a 'compatibility mode'.
7008   */
7009  
7010 -static int dev_ifconf(char __user *arg)
7011 +static int dev_ifconf(struct net *net, char __user *arg)
7012  {
7013         struct ifconf ifc;
7014         struct net_device *dev;
7015 @@ -2140,7 +2200,7 @@
7016          */
7017  
7018         total = 0;
7019 -       for_each_netdev(dev) {
7020 +       for_each_netdev(net, dev) {
7021                 if (!nx_dev_visible(current->nx_info, dev))
7022                         continue;
7023                 for (i = 0; i < NPROTO; i++) {
7024 @@ -2176,6 +2236,7 @@
7025   */
7026  void *dev_seq_start(struct seq_file *seq, loff_t *pos)
7027  {
7028 +       struct net *net = seq->private;
7029         loff_t off;
7030         struct net_device *dev;
7031  
7032 @@ -2184,7 +2245,7 @@
7033                 return SEQ_START_TOKEN;
7034  
7035         off = 1;
7036 -       for_each_netdev(dev)
7037 +       for_each_netdev(net, dev)
7038                 if (off++ == *pos)
7039                         return dev;
7040  
7041 @@ -2193,9 +2254,10 @@
7042  
7043  void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
7044  {
7045 +       struct net *net = seq->private;
7046         ++*pos;
7047         return v == SEQ_START_TOKEN ?
7048 -               first_net_device() : next_net_device((struct net_device *)v);
7049 +               first_net_device(net) : next_net_device((struct net_device *)v);
7050  }
7051  
7052  void dev_seq_stop(struct seq_file *seq, void *v)
7053 @@ -2294,7 +2356,22 @@
7054  
7055  static int dev_seq_open(struct inode *inode, struct file *file)
7056  {
7057 -       return seq_open(file, &dev_seq_ops);
7058 +       struct seq_file *seq;
7059 +       int res;
7060 +       res =  seq_open(file, &dev_seq_ops);
7061 +       if (!res) {
7062 +               seq = file->private_data;
7063 +               seq->private = get_net(PROC_NET(inode));
7064 +       }
7065 +       return res;
7066 +}
7067 +
7068 +static int dev_seq_release(struct inode *inode, struct file *file)
7069 +{
7070 +       struct seq_file *seq = file->private_data;
7071 +       struct net *net = seq->private;
7072 +       put_net(net);
7073 +       return seq_release(inode, file);
7074  }
7075  
7076  static const struct file_operations dev_seq_fops = {
7077 @@ -2302,7 +2379,7 @@
7078         .open    = dev_seq_open,
7079         .read    = seq_read,
7080         .llseek  = seq_lseek,
7081 -       .release = seq_release,
7082 +       .release = dev_seq_release,
7083  };
7084  
7085  static const struct seq_operations softnet_seq_ops = {
7086 @@ -2454,30 +2531,49 @@
7087  };
7088  
7089  
7090 -static int __init dev_proc_init(void)
7091 +static int dev_proc_net_init(struct net *net)
7092  {
7093         int rc = -ENOMEM;
7094  
7095 -       if (!proc_net_fops_create("dev", S_IRUGO, &dev_seq_fops))
7096 +       if (!proc_net_fops_create(net, "dev", S_IRUGO, &dev_seq_fops))
7097                 goto out;
7098 -       if (!proc_net_fops_create("softnet_stat", S_IRUGO, &softnet_seq_fops))
7099 +       if (!proc_net_fops_create(net, "softnet_stat", S_IRUGO, &softnet_seq_fops))
7100                 goto out_dev;
7101 -       if (!proc_net_fops_create("ptype", S_IRUGO, &ptype_seq_fops))
7102 -               goto out_dev2;
7103 -
7104 -       if (wext_proc_init())
7105 +       if (!proc_net_fops_create(net, "ptype", S_IRUGO, &ptype_seq_fops))
7106                 goto out_softnet;
7107 +
7108 +       if (wext_proc_init(net))
7109 +               goto out_ptype;
7110         rc = 0;
7111  out:
7112         return rc;
7113 +out_ptype:
7114 +       proc_net_remove(net, "ptype");
7115  out_softnet:
7116 -       proc_net_remove("ptype");
7117 -out_dev2:
7118 -       proc_net_remove("softnet_stat");
7119 +       proc_net_remove(net, "softnet_stat");
7120  out_dev:
7121 -       proc_net_remove("dev");
7122 +       proc_net_remove(net, "dev");
7123         goto out;
7124  }
7125 +
7126 +static void dev_proc_net_exit(struct net *net)
7127 +{
7128 +       wext_proc_exit(net);
7129 +
7130 +       proc_net_remove(net, "ptype");
7131 +       proc_net_remove(net, "softnet_stat");
7132 +       proc_net_remove(net, "dev");
7133 +}
7134 +
7135 +static struct pernet_operations dev_proc_ops = {
7136 +       .init = dev_proc_net_init,
7137 +       .exit = dev_proc_net_exit,
7138 +};
7139 +
7140 +static int __init dev_proc_init(void)
7141 +{
7142 +       return register_pernet_subsys(&dev_proc_ops);
7143 +}
7144  #else
7145  #define dev_proc_init() 0
7146  #endif /* CONFIG_PROC_FS */
7147 @@ -2711,10 +2807,10 @@
7148  /*
7149   *     Perform the SIOCxIFxxx calls.
7150   */
7151 -static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd)
7152 +static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
7153  {
7154         int err;
7155 -       struct net_device *dev = __dev_get_by_name(ifr->ifr_name);
7156 +       struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name);
7157  
7158         if (!dev)
7159                 return -ENODEV;
7160 @@ -2867,7 +2963,7 @@
7161   *     positive or a negative errno code on error.
7162   */
7163  
7164 -int dev_ioctl(unsigned int cmd, void __user *arg)
7165 +int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
7166  {
7167         struct ifreq ifr;
7168         int ret;
7169 @@ -2880,12 +2976,12 @@
7170  
7171         if (cmd == SIOCGIFCONF) {
7172                 rtnl_lock();
7173 -               ret = dev_ifconf((char __user *) arg);
7174 +               ret = dev_ifconf(net, (char __user *) arg);
7175                 rtnl_unlock();
7176                 return ret;
7177         }
7178         if (cmd == SIOCGIFNAME)
7179 -               return dev_ifname((struct ifreq __user *)arg);
7180 +               return dev_ifname(net, (struct ifreq __user *)arg);
7181  
7182         if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
7183                 return -EFAULT;
7184 @@ -2915,9 +3011,9 @@
7185                 case SIOCGIFMAP:
7186                 case SIOCGIFINDEX:
7187                 case SIOCGIFTXQLEN:
7188 -                       dev_load(ifr.ifr_name);
7189 +                       dev_load(net, ifr.ifr_name);
7190                         read_lock(&dev_base_lock);
7191 -                       ret = dev_ifsioc(&ifr, cmd);
7192 +                       ret = dev_ifsioc(net, &ifr, cmd);
7193                         read_unlock(&dev_base_lock);
7194                         if (!ret) {
7195                                 if (colon)
7196 @@ -2929,9 +3025,9 @@
7197                         return ret;
7198  
7199                 case SIOCETHTOOL:
7200 -                       dev_load(ifr.ifr_name);
7201 +                       dev_load(net, ifr.ifr_name);
7202                         rtnl_lock();
7203 -                       ret = dev_ethtool(&ifr);
7204 +                       ret = dev_ethtool(net, &ifr);
7205                         rtnl_unlock();
7206                         if (!ret) {
7207                                 if (colon)
7208 @@ -2953,9 +3049,9 @@
7209                 case SIOCSIFNAME:
7210                         if (!capable(CAP_NET_ADMIN))
7211                                 return -EPERM;
7212 -                       dev_load(ifr.ifr_name);
7213 +                       dev_load(net, ifr.ifr_name);
7214                         rtnl_lock();
7215 -                       ret = dev_ifsioc(&ifr, cmd);
7216 +                       ret = dev_ifsioc(net, &ifr, cmd);
7217                         rtnl_unlock();
7218                         if (!ret) {
7219                                 if (colon)
7220 @@ -2994,9 +3090,9 @@
7221                         /* fall through */
7222                 case SIOCBONDSLAVEINFOQUERY:
7223                 case SIOCBONDINFOQUERY:
7224 -                       dev_load(ifr.ifr_name);
7225 +                       dev_load(net, ifr.ifr_name);
7226                         rtnl_lock();
7227 -                       ret = dev_ifsioc(&ifr, cmd);
7228 +                       ret = dev_ifsioc(net, &ifr, cmd);
7229                         rtnl_unlock();
7230                         return ret;
7231  
7232 @@ -3016,9 +3112,9 @@
7233                         if (cmd == SIOCWANDEV ||
7234                             (cmd >= SIOCDEVPRIVATE &&
7235                              cmd <= SIOCDEVPRIVATE + 15)) {
7236 -                               dev_load(ifr.ifr_name);
7237 +                               dev_load(net, ifr.ifr_name);
7238                                 rtnl_lock();
7239 -                               ret = dev_ifsioc(&ifr, cmd);
7240 +                               ret = dev_ifsioc(net, &ifr, cmd);
7241                                 rtnl_unlock();
7242                                 if (!ret && copy_to_user(arg, &ifr,
7243                                                          sizeof(struct ifreq)))
7244 @@ -3027,7 +3123,7 @@
7245                         }
7246                         /* Take care of Wireless Extensions */
7247                         if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)
7248 -                               return wext_handle_ioctl(&ifr, cmd, arg);
7249 +                               return wext_handle_ioctl(net, &ifr, cmd, arg);
7250                         return -EINVAL;
7251         }
7252  }
7253 @@ -3040,19 +3136,17 @@
7254   *     number.  The caller must hold the rtnl semaphore or the
7255   *     dev_base_lock to be sure it remains unique.
7256   */
7257 -static int dev_new_index(void)
7258 +static int dev_new_index(struct net *net)
7259  {
7260         static int ifindex;
7261         for (;;) {
7262                 if (++ifindex <= 0)
7263                         ifindex = 1;
7264 -               if (!__dev_get_by_index(ifindex))
7265 +               if (!__dev_get_by_index(net, ifindex))
7266                         return ifindex;
7267         }
7268  }
7269  
7270 -static int dev_boot_phase = 1;
7271 -
7272  /* Delayed registration/unregisteration */
7273  static DEFINE_SPINLOCK(net_todo_list_lock);
7274  static struct list_head net_todo_list = LIST_HEAD_INIT(net_todo_list);
7275 @@ -3086,6 +3180,7 @@
7276         struct hlist_head *head;
7277         struct hlist_node *p;
7278         int ret;
7279 +       struct net *net;
7280  
7281         BUG_ON(dev_boot_phase);
7282         ASSERT_RTNL();
7283 @@ -3094,6 +3189,8 @@
7284  
7285         /* When net_device's are persistent, this will be fatal. */
7286         BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
7287 +       BUG_ON(!dev->nd_net);
7288 +       net = dev->nd_net;
7289  
7290         spin_lock_init(&dev->queue_lock);
7291         spin_lock_init(&dev->_xmit_lock);
7292 @@ -3118,12 +3215,12 @@
7293                 goto out;
7294         }
7295  
7296 -       dev->ifindex = dev_new_index();
7297 +       dev->ifindex = dev_new_index(net);
7298         if (dev->iflink == -1)
7299                 dev->iflink = dev->ifindex;
7300  
7301         /* Check for existence of name */
7302 -       head = dev_name_hash(dev->name);
7303 +       head = dev_name_hash(net, dev->name);
7304         hlist_for_each(p, head) {
7305                 struct net_device *d
7306                         = hlist_entry(p, struct net_device, name_hlist);
7307 @@ -3200,12 +3297,8 @@
7308         set_bit(__LINK_STATE_PRESENT, &dev->state);
7309  
7310         dev_init_scheduler(dev);
7311 -       write_lock_bh(&dev_base_lock);
7312 -       list_add_tail(&dev->dev_list, &dev_base_head);
7313 -       hlist_add_head(&dev->name_hlist, head);
7314 -       hlist_add_head(&dev->index_hlist, dev_index_hash(dev->ifindex));
7315         dev_hold(dev);
7316 -       write_unlock_bh(&dev_base_lock);
7317 +       list_netdevice(dev);
7318  
7319         /* Notify protocols, that a new device appeared. */
7320         raw_notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev);
7321 @@ -3415,6 +3508,7 @@
7322         dev = (struct net_device *)
7323                 (((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
7324         dev->padded = (char *)dev - (char *)p;
7325 +       dev->nd_net = &init_net;
7326  
7327         if (sizeof_priv)
7328                 dev->priv = netdev_priv(dev);
7329 @@ -3493,11 +3587,7 @@
7330                 dev_close(dev);
7331  
7332         /* And unlink it from device chain. */
7333 -       write_lock_bh(&dev_base_lock);
7334 -       list_del(&dev->dev_list);
7335 -       hlist_del(&dev->name_hlist);
7336 -       hlist_del(&dev->index_hlist);
7337 -       write_unlock_bh(&dev_base_lock);
7338 +       unlist_netdevice(dev);
7339  
7340         dev->reg_state = NETREG_UNREGISTERING;
7341  
7342 @@ -3555,6 +3645,122 @@
7343  
7344  EXPORT_SYMBOL(unregister_netdev);
7345  
7346 +/**
7347 + *     dev_change_net_namespace - move device to different nethost namespace
7348 + *     @dev: device
7349 + *     @net: network namespace
7350 + *     @pat: If not NULL name pattern to try if the current device name
7351 + *           is already taken in the destination network namespace.
7352 + *
7353 + *     This function shuts down a device interface and moves it
7354 + *     to a new network namespace. On success 0 is returned, on
7355 + *     a failure a netagive errno code is returned.
7356 + *
7357 + *     Callers must hold the rtnl semaphore.
7358 + */
7359 +
7360 +int dev_change_net_namespace(struct net_device *dev, struct net *net, const char *pat)
7361 +{
7362 +       char buf[IFNAMSIZ];
7363 +       const char *destname;
7364 +       int err;
7365 +
7366 +       ASSERT_RTNL();
7367 +
7368 +       /* Don't allow namespace local devices to be moved. */
7369 +       err = -EINVAL;
7370 +       if (dev->features & NETIF_F_NETNS_LOCAL)
7371 +               goto out;
7372 +
7373 +       /* Ensure the device has been registrered */
7374 +       err = -EINVAL;
7375 +       if (dev->reg_state != NETREG_REGISTERED)
7376 +               goto out;
7377 +       
7378 +       /* Get out if there is nothing todo */
7379 +       err = 0;
7380 +       if (dev->nd_net == net)
7381 +               goto out;
7382 +
7383 +       /* Pick the destination device name, and ensure
7384 +        * we can use it in the destination network namespace.
7385 +        */
7386 +       err = -EEXIST;
7387 +       destname = dev->name;
7388 +       if (__dev_get_by_name(net, destname)) {
7389 +               /* We get here if we can't use the current device name */
7390 +               if (!pat)
7391 +                       goto out;
7392 +               if (!dev_valid_name(pat))
7393 +                       goto out;
7394 +               if (strchr(pat, '%')) {
7395 +                       if (__dev_alloc_name(net, pat, buf) < 0)
7396 +                               goto out;
7397 +                       destname = buf;
7398 +               } else
7399 +                       destname = pat;
7400 +               if (__dev_get_by_name(net, destname))
7401 +                       goto out;
7402 +       }
7403 +
7404 +       /*
7405 +        * And now a mini version of register_netdevice unregister_netdevice. 
7406 +        */
7407 +
7408 +       /* If device is running close it first. */
7409 +       if (dev->flags & IFF_UP)
7410 +               dev_close(dev);
7411 +
7412 +       /* And unlink it from device chain */
7413 +       err = -ENODEV;
7414 +       unlist_netdevice(dev);
7415 +       
7416 +       synchronize_net();
7417 +       
7418 +       /* Shutdown queueing discipline. */
7419 +       dev_shutdown(dev);
7420 +
7421 +       /* Notify protocols, that we are about to destroy
7422 +          this device. They should clean all the things.
7423 +       */
7424 +       call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
7425 +       
7426 +       /*
7427 +        *      Flush the multicast chain
7428 +        */
7429 +       dev_mc_discard(dev);
7430 +
7431 +       /* Actually switch the network namespace */
7432 +       dev->nd_net = net;
7433 +       
7434 +       /* Assign the new device name */
7435 +       if (destname != dev->name)
7436 +               strcpy(dev->name, destname);
7437 +
7438 +       /* If there is an ifindex conflict assign a new one */
7439 +       if (__dev_get_by_index(net, dev->ifindex)) {
7440 +               int iflink = (dev->iflink == dev->ifindex);
7441 +               dev->ifindex = dev_new_index(net);
7442 +               if (iflink)
7443 +                       dev->iflink = dev->ifindex;
7444 +       }
7445 +
7446 +       /* Fixup sysfs */
7447 +       err = device_rename(&dev->dev, dev->name);
7448 +       BUG_ON(err);
7449 +
7450 +       /* Add the device back in the hashes */
7451 +       list_netdevice(dev);
7452 +
7453 +       /* Notify protocols, that a new device appeared. */
7454 +       call_netdevice_notifiers(NETDEV_REGISTER, dev);
7455 +
7456 +       synchronize_net();
7457 +       err = 0;
7458 +out:
7459 +       return err;
7460 +}
7461 +
7462  static int dev_cpu_callback(struct notifier_block *nfb,
7463                             unsigned long action,
7464                             void *ocpu)
7465 @@ -3745,6 +3951,75 @@
7466  }
7467  EXPORT_SYMBOL(netdev_compute_features);
7468  
7469 +/* Initialize per network namespace state */
7470 +static int netdev_init(struct net *net)
7471 +{
7472 +       int i;
7473 +       INIT_LIST_HEAD(&net->dev_base_head);
7474 +       rwlock_init(&dev_base_lock);
7475 +
7476 +       net->dev_name_head = kmalloc(
7477 +               sizeof(*net->dev_name_head)*NETDEV_HASHENTRIES, GFP_KERNEL);
7478 +       if (!net->dev_name_head)
7479 +               return -ENOMEM;
7480 +
7481 +       net->dev_index_head = kmalloc(
7482 +               sizeof(*net->dev_index_head)*NETDEV_HASHENTRIES, GFP_KERNEL);
7483 +       if (!net->dev_index_head) {
7484 +               kfree(net->dev_name_head);
7485 +               return -ENOMEM;
7486 +       }
7487 +
7488 +       for (i = 0; i < NETDEV_HASHENTRIES; i++)
7489 +               INIT_HLIST_HEAD(&net->dev_name_head[i]);
7490 +       
7491 +       for (i = 0; i < NETDEV_HASHENTRIES; i++)
7492 +               INIT_HLIST_HEAD(&net->dev_index_head[i]);
7493 +
7494 +       return 0;
7495 +}
7496 +
7497 +static void netdev_exit(struct net *net)
7498 +{
7499 +       kfree(net->dev_name_head);
7500 +       kfree(net->dev_index_head);
7501 +}
7502 +
7503 +static struct pernet_operations netdev_net_ops = {
7504 +       .init = netdev_init,
7505 +       .exit = netdev_exit,
7506 +};
7507 +
7508 +static void default_device_exit(struct net *net)
7509 +{
7510 +       struct net_device *dev, *next;
7511 +       /*
7512 +        * Push all migratable of the network devices back to the
7513 +        * initial network namespace 
7514 +        */
7515 +       rtnl_lock();
7516 +       for_each_netdev_safe(net, dev, next) {
7517 +               int err;
7518 +
7519 +               /* Ignore unmoveable devices (i.e. loopback) */
7520 +               if (dev->features & NETIF_F_NETNS_LOCAL)
7521 +                       continue;
7522 +
7523 +               /* Push remaing network devices to init_net */
7524 +               err = dev_change_net_namespace(dev, &init_net, "dev%d");
7525 +               if (err) {
7526 +                       printk(KERN_WARNING "%s: failed to move %s to init_net: %d\n",
7527 +                               __func__, dev->name, err);
7528 +                       unregister_netdevice(dev);
7529 +               }
7530 +       }
7531 +       rtnl_unlock();
7532 +}
7533 +
7534 +static struct pernet_operations default_device_ops = {
7535 +       .exit = default_device_exit,
7536 +};
7537 +
7538  /*
7539   *     Initialize the DEV module. At boot time this walks the device list and
7540   *     unhooks any devices that fail to initialise (normally hardware not
7541 @@ -3772,11 +4047,11 @@
7542         for (i = 0; i < 16; i++)
7543                 INIT_LIST_HEAD(&ptype_base[i]);
7544  
7545 -       for (i = 0; i < ARRAY_SIZE(dev_name_head); i++)
7546 -               INIT_HLIST_HEAD(&dev_name_head[i]);
7547 +       if (register_pernet_subsys(&netdev_net_ops))
7548 +               goto out;
7549  
7550 -       for (i = 0; i < ARRAY_SIZE(dev_index_head); i++)
7551 -               INIT_HLIST_HEAD(&dev_index_head[i]);
7552 +       if (register_pernet_device(&default_device_ops))
7553 +               goto out;
7554  
7555         /*
7556          *      Initialise the packet receive queues.
7557 diff -Nurb linux-2.6.22-try2/net/core/dev_mcast.c linux-2.6.22-try2-netns/net/core/dev_mcast.c
7558 --- linux-2.6.22-try2/net/core/dev_mcast.c      2007-12-19 13:37:56.000000000 -0500
7559 +++ linux-2.6.22-try2-netns/net/core/dev_mcast.c        2007-12-19 22:49:18.000000000 -0500
7560 @@ -46,6 +46,7 @@
7561  #include <linux/skbuff.h>
7562  #include <net/sock.h>
7563  #include <net/arp.h>
7564 +#include <net/net_namespace.h>
7565  
7566  
7567  /*
7568 @@ -219,11 +220,12 @@
7569  #ifdef CONFIG_PROC_FS
7570  static void *dev_mc_seq_start(struct seq_file *seq, loff_t *pos)
7571  {
7572 +       struct net *net = seq->private;
7573         struct net_device *dev;
7574         loff_t off = 0;
7575  
7576         read_lock(&dev_base_lock);
7577 -       for_each_netdev(dev) {
7578 +       for_each_netdev(net, dev) {
7579                 if (off++ == *pos)
7580                         return dev;
7581         }
7582 @@ -272,7 +274,22 @@
7583  
7584  static int dev_mc_seq_open(struct inode *inode, struct file *file)
7585  {
7586 -       return seq_open(file, &dev_mc_seq_ops);
7587 +       struct seq_file *seq;
7588 +       int res;
7589 +       res = seq_open(file, &dev_mc_seq_ops);
7590 +       if (!res) {
7591 +               seq = file->private_data;
7592 +               seq->private = get_net(PROC_NET(inode));
7593 +       }
7594 +       return res;
7595 +}
7596 +
7597 +static int dev_mc_seq_release(struct inode *inode, struct file *file)
7598 +{
7599 +       struct seq_file *seq = file->private_data;
7600 +       struct net *net = seq->private;
7601 +       put_net(net);
7602 +       return seq_release(inode, file);
7603  }
7604  
7605  static const struct file_operations dev_mc_seq_fops = {
7606 @@ -280,14 +297,31 @@
7607         .open    = dev_mc_seq_open,
7608         .read    = seq_read,
7609         .llseek  = seq_lseek,
7610 -       .release = seq_release,
7611 +       .release = dev_mc_seq_release,
7612  };
7613  
7614  #endif
7615  
7616 +static int dev_mc_net_init(struct net *net)
7617 +{
7618 +       if (!proc_net_fops_create(net, "dev_mcast", 0, &dev_mc_seq_fops))
7619 +               return -ENOMEM;
7620 +       return 0;
7621 +}
7622 +
7623 +static void dev_mc_net_exit(struct net *net)
7624 +{
7625 +       proc_net_remove(net, "dev_mcast");
7626 +}
7627 +
7628 +static struct pernet_operations dev_mc_net_ops = {
7629 +       .init = dev_mc_net_init,
7630 +       .exit = dev_mc_net_exit,
7631 +};
7632 +
7633  void __init dev_mcast_init(void)
7634  {
7635 -       proc_net_fops_create("dev_mcast", 0, &dev_mc_seq_fops);
7636 +       register_pernet_subsys(&dev_mc_net_ops);
7637  }
7638  
7639  EXPORT_SYMBOL(dev_mc_add);
7640 diff -Nurb linux-2.6.22-try2/net/core/dst.c linux-2.6.22-try2-netns/net/core/dst.c
7641 --- linux-2.6.22-try2/net/core/dst.c    2007-12-19 13:37:56.000000000 -0500
7642 +++ linux-2.6.22-try2-netns/net/core/dst.c      2007-12-19 22:49:18.000000000 -0500
7643 @@ -15,7 +15,9 @@
7644  #include <linux/skbuff.h>
7645  #include <linux/string.h>
7646  #include <linux/types.h>
7647 +#include <net/net_namespace.h>
7648  
7649 +#include <net/net_namespace.h>
7650  #include <net/dst.h>
7651  
7652  /* Locking strategy:
7653 @@ -236,13 +238,14 @@
7654         if (!unregister) {
7655                 dst->input = dst->output = dst_discard;
7656         } else {
7657 -               dst->dev = &loopback_dev;
7658 -               dev_hold(&loopback_dev);
7659 +               struct net *net = dev->nd_net;
7660 +               dst->dev = &net->loopback_dev;
7661 +               dev_hold(dst->dev);
7662                 dev_put(dev);
7663                 if (dst->neighbour && dst->neighbour->dev == dev) {
7664 -                       dst->neighbour->dev = &loopback_dev;
7665 +                       dst->neighbour->dev = &net->loopback_dev;
7666                         dev_put(dev);
7667 -                       dev_hold(&loopback_dev);
7668 +                       dev_hold(dst->neighbour->dev);
7669                 }
7670         }
7671  }
7672 @@ -252,6 +255,9 @@
7673         struct net_device *dev = ptr;
7674         struct dst_entry *dst;
7675  
7676 +       if (dev->nd_net != &init_net)
7677 +               return NOTIFY_DONE;
7678 +
7679         switch (event) {
7680         case NETDEV_UNREGISTER:
7681         case NETDEV_DOWN:
7682 diff -Nurb linux-2.6.22-try2/net/core/ethtool.c linux-2.6.22-try2-netns/net/core/ethtool.c
7683 --- linux-2.6.22-try2/net/core/ethtool.c        2007-12-19 13:37:56.000000000 -0500
7684 +++ linux-2.6.22-try2-netns/net/core/ethtool.c  2007-12-19 22:49:18.000000000 -0500
7685 @@ -798,9 +798,9 @@
7686  
7687  /* The main entry point in this file.  Called from net/core/dev.c */
7688  
7689 -int dev_ethtool(struct ifreq *ifr)
7690 +int dev_ethtool(struct net *net, struct ifreq *ifr)
7691  {
7692 -       struct net_device *dev = __dev_get_by_name(ifr->ifr_name);
7693 +       struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name);
7694         void __user *useraddr = ifr->ifr_data;
7695         u32 ethcmd;
7696         int rc;
7697 diff -Nurb linux-2.6.22-try2/net/core/fib_rules.c linux-2.6.22-try2-netns/net/core/fib_rules.c
7698 --- linux-2.6.22-try2/net/core/fib_rules.c      2007-12-19 13:37:56.000000000 -0500
7699 +++ linux-2.6.22-try2-netns/net/core/fib_rules.c        2007-12-19 22:49:18.000000000 -0500
7700 @@ -11,21 +11,20 @@
7701  #include <linux/types.h>
7702  #include <linux/kernel.h>
7703  #include <linux/list.h>
7704 +#include <net/net_namespace.h>
7705 +#include <net/sock.h>
7706  #include <net/fib_rules.h>
7707  
7708 -static LIST_HEAD(rules_ops);
7709 -static DEFINE_SPINLOCK(rules_mod_lock);
7710 -
7711 -static void notify_rule_change(int event, struct fib_rule *rule,
7712 +static void notify_rule_change(struct net *net, int event, struct fib_rule *rule,
7713                                struct fib_rules_ops *ops, struct nlmsghdr *nlh,
7714                                u32 pid);
7715  
7716 -static struct fib_rules_ops *lookup_rules_ops(int family)
7717 +static struct fib_rules_ops *lookup_rules_ops(struct net *net, int family)
7718  {
7719         struct fib_rules_ops *ops;
7720  
7721         rcu_read_lock();
7722 -       list_for_each_entry_rcu(ops, &rules_ops, list) {
7723 +       list_for_each_entry_rcu(ops, &net->rules_ops, list) {
7724                 if (ops->family == family) {
7725                         if (!try_module_get(ops->owner))
7726                                 ops = NULL;
7727 @@ -47,10 +46,10 @@
7728  static void flush_route_cache(struct fib_rules_ops *ops)
7729  {
7730         if (ops->flush_cache)
7731 -               ops->flush_cache();
7732 +               ops->flush_cache(ops);
7733  }
7734  
7735 -int fib_rules_register(struct fib_rules_ops *ops)
7736 +int fib_rules_register(struct net *net, struct fib_rules_ops *ops)
7737  {
7738         int err = -EEXIST;
7739         struct fib_rules_ops *o;
7740 @@ -63,15 +62,16 @@
7741             ops->action == NULL)
7742                 return -EINVAL;
7743  
7744 -       spin_lock(&rules_mod_lock);
7745 -       list_for_each_entry(o, &rules_ops, list)
7746 +       spin_lock(&net->rules_mod_lock);
7747 +       list_for_each_entry(o, &net->rules_ops, list)
7748                 if (ops->family == o->family)
7749                         goto errout;
7750  
7751 -       list_add_tail_rcu(&ops->list, &rules_ops);
7752 +       hold_net(net);
7753 +       list_add_tail_rcu(&ops->list, &net->rules_ops);
7754         err = 0;
7755  errout:
7756 -       spin_unlock(&rules_mod_lock);
7757 +       spin_unlock(&net->rules_mod_lock);
7758  
7759         return err;
7760  }
7761 @@ -88,13 +88,13 @@
7762         }
7763  }
7764  
7765 -int fib_rules_unregister(struct fib_rules_ops *ops)
7766 +int fib_rules_unregister(struct net *net, struct fib_rules_ops *ops)
7767  {
7768         int err = 0;
7769         struct fib_rules_ops *o;
7770  
7771 -       spin_lock(&rules_mod_lock);
7772 -       list_for_each_entry(o, &rules_ops, list) {
7773 +       spin_lock(&net->rules_mod_lock);
7774 +       list_for_each_entry(o, &net->rules_ops, list) {
7775                 if (o == ops) {
7776                         list_del_rcu(&o->list);
7777                         cleanup_ops(ops);
7778 @@ -104,9 +104,11 @@
7779  
7780         err = -ENOENT;
7781  out:
7782 -       spin_unlock(&rules_mod_lock);
7783 +       spin_unlock(&net->rules_mod_lock);
7784  
7785         synchronize_rcu();
7786 +       if (!err)
7787 +               release_net(net);
7788  
7789         return err;
7790  }
7791 @@ -197,6 +199,7 @@
7792  
7793  static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
7794  {
7795 +       struct net *net = skb->sk->sk_net;
7796         struct fib_rule_hdr *frh = nlmsg_data(nlh);
7797         struct fib_rules_ops *ops = NULL;
7798         struct fib_rule *rule, *r, *last = NULL;
7799 @@ -206,7 +209,7 @@
7800         if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh)))
7801                 goto errout;
7802  
7803 -       ops = lookup_rules_ops(frh->family);
7804 +       ops = lookup_rules_ops(net, frh->family);
7805         if (ops == NULL) {
7806                 err = EAFNOSUPPORT;
7807                 goto errout;
7808 @@ -234,7 +237,7 @@
7809  
7810                 rule->ifindex = -1;
7811                 nla_strlcpy(rule->ifname, tb[FRA_IFNAME], IFNAMSIZ);
7812 -               dev = __dev_get_by_name(rule->ifname);
7813 +               dev = __dev_get_by_name(net, rule->ifname);
7814                 if (dev)
7815                         rule->ifindex = dev->ifindex;
7816         }
7817 @@ -256,7 +259,7 @@
7818         rule->table = frh_get_table(frh, tb);
7819  
7820         if (!rule->pref && ops->default_pref)
7821 -               rule->pref = ops->default_pref();
7822 +               rule->pref = ops->default_pref(ops);
7823  
7824         err = -EINVAL;
7825         if (tb[FRA_GOTO]) {
7826 @@ -319,7 +322,7 @@
7827         else
7828                 list_add_rcu(&rule->list, ops->rules_list);
7829  
7830 -       notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).pid);
7831 +       notify_rule_change(net, RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).pid);
7832         flush_route_cache(ops);
7833         rules_ops_put(ops);
7834         return 0;
7835 @@ -333,6 +336,7 @@
7836  
7837  static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
7838  {
7839 +       struct net *net = skb->sk->sk_net;
7840         struct fib_rule_hdr *frh = nlmsg_data(nlh);
7841         struct fib_rules_ops *ops = NULL;
7842         struct fib_rule *rule, *tmp;
7843 @@ -342,7 +346,7 @@
7844         if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh)))
7845                 goto errout;
7846  
7847 -       ops = lookup_rules_ops(frh->family);
7848 +       ops = lookup_rules_ops(net, frh->family);
7849         if (ops == NULL) {
7850                 err = EAFNOSUPPORT;
7851                 goto errout;
7852 @@ -408,7 +412,7 @@
7853                 }
7854  
7855                 synchronize_rcu();
7856 -               notify_rule_change(RTM_DELRULE, rule, ops, nlh,
7857 +               notify_rule_change(net, RTM_DELRULE, rule, ops, nlh,
7858                                    NETLINK_CB(skb).pid);
7859                 fib_rule_put(rule);
7860                 flush_route_cache(ops);
7861 @@ -514,13 +518,17 @@
7862  
7863  static int fib_nl_dumprule(struct sk_buff *skb, struct netlink_callback *cb)
7864  {
7865 +       struct net *net = skb->sk->sk_net;
7866         struct fib_rules_ops *ops;
7867         int idx = 0, family;
7868  
7869 +       if (net != &init_net)
7870 +               return -EINVAL;
7871 +
7872         family = rtnl_msg_family(cb->nlh);
7873         if (family != AF_UNSPEC) {
7874                 /* Protocol specific dump request */
7875 -               ops = lookup_rules_ops(family);
7876 +               ops = lookup_rules_ops(net, family);
7877                 if (ops == NULL)
7878                         return -EAFNOSUPPORT;
7879  
7880 @@ -528,7 +536,7 @@
7881         }
7882  
7883         rcu_read_lock();
7884 -       list_for_each_entry_rcu(ops, &rules_ops, list) {
7885 +       list_for_each_entry_rcu(ops, &net->rules_ops, list) {
7886                 if (idx < cb->args[0] || !try_module_get(ops->owner))
7887                         goto skip;
7888  
7889 @@ -545,7 +553,7 @@
7890         return skb->len;
7891  }
7892  
7893 -static void notify_rule_change(int event, struct fib_rule *rule,
7894 +static void notify_rule_change(struct net *net, int event, struct fib_rule *rule,
7895                                struct fib_rules_ops *ops, struct nlmsghdr *nlh,
7896                                u32 pid)
7897  {
7898 @@ -563,10 +571,10 @@
7899                 kfree_skb(skb);
7900                 goto errout;
7901         }
7902 -       err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL);
7903 +       err = rtnl_notify(skb, net, pid, ops->nlgroup, nlh, GFP_KERNEL);
7904  errout:
7905         if (err < 0)
7906 -               rtnl_set_sk_err(ops->nlgroup, err);
7907 +               rtnl_set_sk_err(net, ops->nlgroup, err);
7908  }
7909  
7910  static void attach_rules(struct list_head *rules, struct net_device *dev)
7911 @@ -594,19 +602,23 @@
7912                             void *ptr)
7913  {
7914         struct net_device *dev = ptr;
7915 +       struct net *net = dev->nd_net;
7916         struct fib_rules_ops *ops;
7917  
7918 +       if (dev->nd_net != &init_net)
7919 +               return NOTIFY_DONE;
7920 +
7921         ASSERT_RTNL();
7922         rcu_read_lock();
7923  
7924         switch (event) {
7925         case NETDEV_REGISTER:
7926 -               list_for_each_entry(ops, &rules_ops, list)
7927 +               list_for_each_entry(ops, &net->rules_ops, list)
7928                         attach_rules(ops->rules_list, dev);
7929                 break;
7930  
7931         case NETDEV_UNREGISTER:
7932 -               list_for_each_entry(ops, &rules_ops, list)
7933 +               list_for_each_entry(ops, &net->rules_ops, list)
7934                         detach_rules(ops->rules_list, dev);
7935                 break;
7936         }
7937 @@ -620,13 +632,28 @@
7938         .notifier_call = fib_rules_event,
7939  };
7940  
7941 +static int fib_rules_net_init(struct net *net)
7942 +{
7943 +       INIT_LIST_HEAD(&net->rules_ops);
7944 +       spin_lock_init(&net->rules_mod_lock);
7945 +       return 0;
7946 +}
7947 +
7948 +static struct pernet_operations fib_rules_net_ops = {
7949 +       .init = fib_rules_net_init,
7950 +};
7951 +
7952  static int __init fib_rules_init(void)
7953  {
7954 +       int ret;
7955         rtnl_register(PF_UNSPEC, RTM_NEWRULE, fib_nl_newrule, NULL);
7956         rtnl_register(PF_UNSPEC, RTM_DELRULE, fib_nl_delrule, NULL);
7957         rtnl_register(PF_UNSPEC, RTM_GETRULE, NULL, fib_nl_dumprule);
7958  
7959 -       return register_netdevice_notifier(&fib_rules_notifier);
7960 +       ret = register_pernet_subsys(&fib_rules_net_ops);
7961 +       if (!ret)
7962 +               ret = register_netdevice_notifier(&fib_rules_notifier);
7963 +       return ret;
7964  }
7965  
7966  subsys_initcall(fib_rules_init);
7967 diff -Nurb linux-2.6.22-try2/net/core/neighbour.c linux-2.6.22-try2-netns/net/core/neighbour.c
7968 --- linux-2.6.22-try2/net/core/neighbour.c      2007-12-19 13:37:57.000000000 -0500
7969 +++ linux-2.6.22-try2-netns/net/core/neighbour.c        2007-12-19 22:49:18.000000000 -0500
7970 @@ -33,6 +33,7 @@
7971  #include <linux/rtnetlink.h>
7972  #include <linux/random.h>
7973  #include <linux/string.h>
7974 +#include <net/net_namespace.h>
7975  
7976  #define NEIGH_DEBUG 1
7977  
7978 @@ -361,7 +362,7 @@
7979         return n;
7980  }
7981  
7982 -struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, const void *pkey)
7983 +struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net * net, const void *pkey)
7984  {
7985         struct neighbour *n;
7986         int key_len = tbl->key_len;
7987 @@ -371,7 +372,8 @@
7988  
7989         read_lock_bh(&tbl->lock);
7990         for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) {
7991 -               if (!memcmp(n->primary_key, pkey, key_len)) {
7992 +               if (!memcmp(n->primary_key, pkey, key_len) &&
7993 +                   (net == n->dev->nd_net)) {
7994                         neigh_hold(n);
7995                         NEIGH_CACHE_STAT_INC(tbl, hits);
7996                         break;
7997 @@ -449,7 +451,8 @@
7998         goto out;
7999  }
8000  
8001 -struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, const void *pkey,
8002 +struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl,
8003 +                                   struct net * net, const void *pkey,
8004                                     struct net_device *dev, int creat)
8005  {
8006         struct pneigh_entry *n;
8007 @@ -465,6 +468,7 @@
8008  
8009         for (n = tbl->phash_buckets[hash_val]; n; n = n->next) {
8010                 if (!memcmp(n->key, pkey, key_len) &&
8011 +                   (n->net == net) &&
8012                     (n->dev == dev || !n->dev)) {
8013                         read_unlock_bh(&tbl->lock);
8014                         goto out;
8015 @@ -479,6 +483,7 @@
8016         if (!n)
8017                 goto out;
8018  
8019 +       n->net = hold_net(net);
8020         memcpy(n->key, pkey, key_len);
8021         n->dev = dev;
8022         if (dev)
8023 @@ -501,7 +506,7 @@
8024  }
8025  
8026  
8027 -int pneigh_delete(struct neigh_table *tbl, const void *pkey,
8028 +int pneigh_delete(struct neigh_table *tbl, struct net * net, const void *pkey,
8029                   struct net_device *dev)
8030  {
8031         struct pneigh_entry *n, **np;
8032 @@ -516,13 +521,15 @@
8033         write_lock_bh(&tbl->lock);
8034         for (np = &tbl->phash_buckets[hash_val]; (n = *np) != NULL;
8035              np = &n->next) {
8036 -               if (!memcmp(n->key, pkey, key_len) && n->dev == dev) {
8037 +               if (!memcmp(n->key, pkey, key_len) && n->dev == dev &&
8038 +                   (n->net == net)) {
8039                         *np = n->next;
8040                         write_unlock_bh(&tbl->lock);
8041                         if (tbl->pdestructor)
8042                                 tbl->pdestructor(n);
8043                         if (n->dev)
8044                                 dev_put(n->dev);
8045 +                       release_net(n->net);
8046                         kfree(n);
8047                         return 0;
8048                 }
8049 @@ -545,6 +552,7 @@
8050                                         tbl->pdestructor(n);
8051                                 if (n->dev)
8052                                         dev_put(n->dev);
8053 +                               release_net(n->net);
8054                                 kfree(n);
8055                                 continue;
8056                         }
8057 @@ -1266,12 +1274,37 @@
8058         spin_unlock(&tbl->proxy_queue.lock);
8059  }
8060  
8061 +static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
8062 +                                                     struct net * net, int ifindex)
8063 +{
8064 +       struct neigh_parms *p;
8065 +       
8066 +       for (p = &tbl->parms; p; p = p->next) {
8067 +               if (p->net != net)
8068 +                       continue;
8069 +               if ((p->dev && p->dev->ifindex == ifindex) ||
8070 +                   (!p->dev && !ifindex))
8071 +                       return p;
8072 +       }
8073 +
8074 +       return NULL;
8075 +}
8076  
8077  struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
8078                                       struct neigh_table *tbl)
8079  {
8080 -       struct neigh_parms *p = kmemdup(&tbl->parms, sizeof(*p), GFP_KERNEL);
8081 +       struct neigh_parms *p, *ref;
8082 +       struct net * net;
8083 +
8084 +       net = &init_net;
8085 +       if (dev)
8086 +               net = dev->nd_net;
8087 +
8088 +       ref = lookup_neigh_params(tbl, net, 0);
8089 +       if (!ref)
8090 +               return NULL;
8091  
8092 +       p = kmemdup(ref, sizeof(*p), GFP_KERNEL);
8093         if (p) {
8094                 p->tbl            = tbl;
8095                 atomic_set(&p->refcnt, 1);
8096 @@ -1287,6 +1320,7 @@
8097                         dev_hold(dev);
8098                         p->dev = dev;
8099                 }
8100 +               p->net = hold_net(net);
8101                 p->sysctl_table = NULL;
8102                 write_lock_bh(&tbl->lock);
8103                 p->next         = tbl->parms.next;
8104 @@ -1296,6 +1330,20 @@
8105         return p;
8106  }
8107  
8108 +struct neigh_parms *neigh_parms_alloc_default(struct neigh_table *tbl,
8109 +                                               struct net *net)
8110 +{
8111 +       struct neigh_parms *parms;
8112 +       if (net != &init_net) {
8113 +               parms = neigh_parms_alloc(NULL, tbl);
8114 +               release_net(parms->net);
8115 +               parms->net = hold_net(net);
8116 +       }
8117 +       else
8118 +               parms = neigh_parms_clone(&tbl->parms);
8119 +       return parms;
8120 +}
8121 +
8122  static void neigh_rcu_free_parms(struct rcu_head *head)
8123  {
8124         struct neigh_parms *parms =
8125 @@ -1328,6 +1376,7 @@
8126  
8127  void neigh_parms_destroy(struct neigh_parms *parms)
8128  {
8129 +       release_net(parms->net);
8130         kfree(parms);
8131  }
8132  
8133 @@ -1338,6 +1387,7 @@
8134         unsigned long now = jiffies;
8135         unsigned long phsize;
8136  
8137 +       tbl->parms.net = &init_net;
8138         atomic_set(&tbl->parms.refcnt, 1);
8139         INIT_RCU_HEAD(&tbl->parms.rcu_head);
8140         tbl->parms.reachable_time =
8141 @@ -1353,7 +1403,7 @@
8142                 panic("cannot create neighbour cache statistics");
8143  
8144  #ifdef CONFIG_PROC_FS
8145 -       tbl->pde = create_proc_entry(tbl->id, 0, proc_net_stat);
8146 +       tbl->pde = create_proc_entry(tbl->id, 0, init_net.proc_net_stat);
8147         if (!tbl->pde)
8148                 panic("cannot create neighbour proc dir entry");
8149         tbl->pde->proc_fops = &neigh_stat_seq_fops;
8150 @@ -1443,6 +1493,7 @@
8151  
8152  static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
8153  {
8154 +       struct net *net = skb->sk->sk_net;
8155         struct ndmsg *ndm;
8156         struct nlattr *dst_attr;
8157         struct neigh_table *tbl;
8158 @@ -1458,7 +1509,7 @@
8159  
8160         ndm = nlmsg_data(nlh);
8161         if (ndm->ndm_ifindex) {
8162 -               dev = dev_get_by_index(ndm->ndm_ifindex);
8163 +               dev = dev_get_by_index(net, ndm->ndm_ifindex);
8164                 if (dev == NULL) {
8165                         err = -ENODEV;
8166                         goto out;
8167 @@ -1477,7 +1528,7 @@
8168                         goto out_dev_put;
8169  
8170                 if (ndm->ndm_flags & NTF_PROXY) {
8171 -                       err = pneigh_delete(tbl, nla_data(dst_attr), dev);
8172 +                       err = pneigh_delete(tbl, net, nla_data(dst_attr), dev);
8173                         goto out_dev_put;
8174                 }
8175  
8176 @@ -1508,6 +1559,7 @@
8177  
8178  static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
8179  {
8180 +       struct net *net = skb->sk->sk_net;
8181         struct ndmsg *ndm;
8182         struct nlattr *tb[NDA_MAX+1];
8183         struct neigh_table *tbl;
8184 @@ -1524,7 +1576,7 @@
8185  
8186         ndm = nlmsg_data(nlh);
8187         if (ndm->ndm_ifindex) {
8188 -               dev = dev_get_by_index(ndm->ndm_ifindex);
8189 +               dev = dev_get_by_index(net, ndm->ndm_ifindex);
8190                 if (dev == NULL) {
8191                         err = -ENODEV;
8192                         goto out;
8193 @@ -1553,7 +1605,7 @@
8194                         struct pneigh_entry *pn;
8195  
8196                         err = -ENOBUFS;
8197 -                       pn = pneigh_lookup(tbl, dst, dev, 1);
8198 +                       pn = pneigh_lookup(tbl, net, dst, dev, 1);
8199                         if (pn) {
8200                                 pn->flags = ndm->ndm_flags;
8201                                 err = 0;
8202 @@ -1748,19 +1800,6 @@
8203         return -EMSGSIZE;
8204  }
8205  
8206 -static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
8207 -                                                     int ifindex)
8208 -{
8209 -       struct neigh_parms *p;
8210 -
8211 -       for (p = &tbl->parms; p; p = p->next)
8212 -               if ((p->dev && p->dev->ifindex == ifindex) ||
8213 -                   (!p->dev && !ifindex))
8214 -                       return p;
8215 -
8216 -       return NULL;
8217 -}
8218 -
8219  static const struct nla_policy nl_neightbl_policy[NDTA_MAX+1] = {
8220         [NDTA_NAME]             = { .type = NLA_STRING },
8221         [NDTA_THRESH1]          = { .type = NLA_U32 },
8222 @@ -1788,6 +1827,7 @@
8223  
8224  static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
8225  {
8226 +       struct net *net = skb->sk->sk_net;
8227         struct neigh_table *tbl;
8228         struct ndtmsg *ndtmsg;
8229         struct nlattr *tb[NDTA_MAX+1];
8230 @@ -1837,7 +1877,7 @@
8231                 if (tbp[NDTPA_IFINDEX])
8232                         ifindex = nla_get_u32(tbp[NDTPA_IFINDEX]);
8233  
8234 -               p = lookup_neigh_params(tbl, ifindex);
8235 +               p = lookup_neigh_params(tbl, net, ifindex);
8236                 if (p == NULL) {
8237                         err = -ENOENT;
8238                         goto errout_tbl_lock;
8239 @@ -1912,6 +1952,7 @@
8240  
8241  static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
8242  {
8243 +       struct net *net = skb->sk->sk_net;
8244         int family, tidx, nidx = 0;
8245         int tbl_skip = cb->args[0];
8246         int neigh_skip = cb->args[1];
8247 @@ -1931,8 +1972,11 @@
8248                                        NLM_F_MULTI) <= 0)
8249                         break;
8250  
8251 -               for (nidx = 0, p = tbl->parms.next; p; p = p->next, nidx++) {
8252 -                       if (nidx < neigh_skip)
8253 +               for (nidx = 0, p = tbl->parms.next; p; p = p->next) {
8254 +                       if (net != p->net)
8255 +                               continue;
8256 +
8257 +                       if (nidx++ < neigh_skip)
8258                                 continue;
8259  
8260                         if (neightbl_fill_param_info(skb, tbl, p,
8261 @@ -2003,6 +2047,7 @@
8262  static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
8263                             struct netlink_callback *cb)
8264  {
8265 +       struct net * net = skb->sk->sk_net;
8266         struct neighbour *n;
8267         int rc, h, s_h = cb->args[1];
8268         int idx, s_idx = idx = cb->args[2];
8269 @@ -2013,8 +2058,12 @@
8270                         continue;
8271                 if (h > s_h)
8272                         s_idx = 0;
8273 -               for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next, idx++) {
8274 -                       if (idx < s_idx)
8275 +               for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next) {
8276 +                       int lidx;
8277 +                       if (n->dev->nd_net != net)
8278 +                               continue;
8279 +                       lidx = idx++;
8280 +                       if (lidx < s_idx)
8281                                 continue;
8282                         if (neigh_fill_info(skb, n, NETLINK_CB(cb->skb).pid,
8283                                             cb->nlh->nlmsg_seq,
8284 @@ -2109,6 +2158,7 @@
8285  static struct neighbour *neigh_get_first(struct seq_file *seq)
8286  {
8287         struct neigh_seq_state *state = seq->private;
8288 +       struct net * net = state->net;
8289         struct neigh_table *tbl = state->tbl;
8290         struct neighbour *n = NULL;
8291         int bucket = state->bucket;
8292 @@ -2118,6 +2168,8 @@
8293                 n = tbl->hash_buckets[bucket];
8294  
8295                 while (n) {
8296 +                       if (n->dev->nd_net != net)
8297 +                               goto next;
8298                         if (state->neigh_sub_iter) {
8299                                 loff_t fakep = 0;
8300                                 void *v;
8301 @@ -2147,6 +2199,7 @@
8302                                         loff_t *pos)
8303  {
8304         struct neigh_seq_state *state = seq->private;
8305 +       struct net * net = state->net;
8306         struct neigh_table *tbl = state->tbl;
8307  
8308         if (state->neigh_sub_iter) {
8309 @@ -2158,6 +2211,8 @@
8310  
8311         while (1) {
8312                 while (n) {
8313 +                       if (n->dev->nd_net != net)
8314 +                               goto next;
8315                         if (state->neigh_sub_iter) {
8316                                 void *v = state->neigh_sub_iter(state, n, pos);
8317                                 if (v)
8318 @@ -2204,6 +2259,7 @@
8319  static struct pneigh_entry *pneigh_get_first(struct seq_file *seq)
8320  {
8321         struct neigh_seq_state *state = seq->private;
8322 +       struct net * net = state->net;
8323         struct neigh_table *tbl = state->tbl;
8324         struct pneigh_entry *pn = NULL;
8325         int bucket = state->bucket;
8326 @@ -2211,6 +2267,8 @@
8327         state->flags |= NEIGH_SEQ_IS_PNEIGH;
8328         for (bucket = 0; bucket <= PNEIGH_HASHMASK; bucket++) {
8329                 pn = tbl->phash_buckets[bucket];
8330 +               while (pn && (pn->net != net))
8331 +                       pn = pn->next;
8332                 if (pn)
8333                         break;
8334         }
8335 @@ -2224,6 +2282,7 @@
8336                                             loff_t *pos)
8337  {
8338         struct neigh_seq_state *state = seq->private;
8339 +       struct net * net = state->net;
8340         struct neigh_table *tbl = state->tbl;
8341  
8342         pn = pn->next;
8343 @@ -2231,6 +2290,8 @@
8344                 if (++state->bucket > PNEIGH_HASHMASK)
8345                         break;
8346                 pn = tbl->phash_buckets[state->bucket];
8347 +               while (pn && (pn->net != net))
8348 +                       pn = pn->next;
8349                 if (pn)
8350                         break;
8351         }
8352 @@ -2433,6 +2494,7 @@
8353  
8354  static void __neigh_notify(struct neighbour *n, int type, int flags)
8355  {
8356 +       struct net * net = n->dev->nd_net;
8357         struct sk_buff *skb;
8358         int err = -ENOBUFS;
8359  
8360 @@ -2447,10 +2509,10 @@
8361                 kfree_skb(skb);
8362                 goto errout;
8363         }
8364 -       err = rtnl_notify(skb, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
8365 +       err = rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
8366  errout:
8367         if (err < 0)
8368 -               rtnl_set_sk_err(RTNLGRP_NEIGH, err);
8369 +               rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
8370  }
8371  
8372  void neigh_app_ns(struct neighbour *n)
8373 @@ -2648,6 +2710,7 @@
8374  
8375         if (!t)
8376                 return -ENOBUFS;
8377 +
8378         t->neigh_vars[0].data  = &p->mcast_probes;
8379         t->neigh_vars[1].data  = &p->ucast_probes;
8380         t->neigh_vars[2].data  = &p->app_probes;
8381 @@ -2716,7 +2779,7 @@
8382         t->neigh_proto_dir[0].child    = t->neigh_neigh_dir;
8383         t->neigh_root_dir[0].child     = t->neigh_proto_dir;
8384  
8385 -       t->sysctl_header = register_sysctl_table(t->neigh_root_dir);
8386 +       t->sysctl_header = register_net_sysctl_table(p->net, t->neigh_root_dir);
8387         if (!t->sysctl_header) {
8388                 err = -ENOBUFS;
8389                 goto free_procname;
8390 @@ -2738,7 +2801,7 @@
8391         if (p->sysctl_table) {
8392                 struct neigh_sysctl_table *t = p->sysctl_table;
8393                 p->sysctl_table = NULL;
8394 -               unregister_sysctl_table(t->sysctl_header);
8395 +               unregister_net_sysctl_table(t->sysctl_header);
8396                 kfree(t->neigh_dev[0].procname);
8397                 kfree(t);
8398         }
8399 @@ -2771,6 +2834,7 @@
8400  EXPORT_SYMBOL(neigh_lookup);
8401  EXPORT_SYMBOL(neigh_lookup_nodev);
8402  EXPORT_SYMBOL(neigh_parms_alloc);
8403 +EXPORT_SYMBOL(neigh_parms_alloc_default);
8404  EXPORT_SYMBOL(neigh_parms_release);
8405  EXPORT_SYMBOL(neigh_rand_reach_time);
8406  EXPORT_SYMBOL(neigh_resolve_output);
8407 diff -Nurb linux-2.6.22-try2/net/core/net-sysfs.c linux-2.6.22-try2-netns/net/core/net-sysfs.c
8408 --- linux-2.6.22-try2/net/core/net-sysfs.c      2007-12-19 13:37:57.000000000 -0500
8409 +++ linux-2.6.22-try2-netns/net/core/net-sysfs.c        2007-12-19 22:49:18.000000000 -0500
8410 @@ -13,7 +13,9 @@
8411  #include <linux/kernel.h>
8412  #include <linux/netdevice.h>
8413  #include <linux/if_arp.h>
8414 +#include <linux/nsproxy.h>
8415  #include <net/sock.h>
8416 +#include <net/net_namespace.h>
8417  #include <linux/rtnetlink.h>
8418  #include <linux/wireless.h>
8419  #include <net/iw_handler.h>
8420 @@ -29,16 +31,16 @@
8421  }
8422  
8423  /* use same locking rules as GIF* ioctl's */
8424 -static ssize_t netdev_show(const struct device *dev,
8425 +static ssize_t netdev_show(const struct device *device,
8426                            struct device_attribute *attr, char *buf,
8427                            ssize_t (*format)(const struct net_device *, char *))
8428  {
8429 -       struct net_device *net = to_net_dev(dev);
8430 +       struct net_device *dev = to_net_dev(device);
8431         ssize_t ret = -EINVAL;
8432  
8433         read_lock(&dev_base_lock);
8434 -       if (dev_isalive(net))
8435 -               ret = (*format)(net, buf);
8436 +       if (dev_isalive(dev))
8437 +               ret = (*format)(dev, buf);
8438         read_unlock(&dev_base_lock);
8439  
8440         return ret;
8441 @@ -46,9 +48,9 @@
8442  
8443  /* generate a show function for simple field */
8444  #define NETDEVICE_SHOW(field, format_string)                           \
8445 -static ssize_t format_##field(const struct net_device *net, char *buf) \
8446 +static ssize_t format_##field(const struct net_device *dev, char *buf) \
8447  {                                                                      \
8448 -       return sprintf(buf, format_string, net->field);                 \
8449 +       return sprintf(buf, format_string, dev->field);                 \
8450  }                                                                      \
8451  static ssize_t show_##field(struct device *dev,                                \
8452                             struct device_attribute *attr, char *buf)   \
8453 @@ -58,11 +60,11 @@
8454  
8455  
8456  /* use same locking and permission rules as SIF* ioctl's */
8457 -static ssize_t netdev_store(struct device *dev, struct device_attribute *attr,
8458 +static ssize_t netdev_store(struct device *device, struct device_attribute *attr,
8459                             const char *buf, size_t len,
8460                             int (*set)(struct net_device *, unsigned long))
8461  {
8462 -       struct net_device *net = to_net_dev(dev);
8463 +       struct net_device *dev = to_net_dev(device);
8464         char *endp;
8465         unsigned long new;
8466         int ret = -EINVAL;
8467 @@ -75,8 +77,8 @@
8468                 goto err;
8469  
8470         rtnl_lock();
8471 -       if (dev_isalive(net)) {
8472 -               if ((ret = (*set)(net, new)) == 0)
8473 +       if (dev_isalive(dev)) {
8474 +               if ((ret = (*set)(dev, new)) == 0)
8475                         ret = len;
8476         }
8477         rtnl_unlock();
8478 @@ -103,45 +105,45 @@
8479         return cp - buf;
8480  }
8481  
8482 -static ssize_t show_address(struct device *dev, struct device_attribute *attr,
8483 +static ssize_t show_address(struct device *device, struct device_attribute *attr,
8484                             char *buf)
8485  {
8486 -       struct net_device *net = to_net_dev(dev);
8487 +       struct net_device *dev = to_net_dev(device);
8488         ssize_t ret = -EINVAL;
8489  
8490         read_lock(&dev_base_lock);
8491 -       if (dev_isalive(net))
8492 -           ret = format_addr(buf, net->dev_addr, net->addr_len);
8493 +       if (dev_isalive(dev))
8494 +           ret = format_addr(buf, dev->dev_addr, dev->addr_len);
8495         read_unlock(&dev_base_lock);
8496         return ret;
8497  }
8498  
8499 -static ssize_t show_broadcast(struct device *dev,
8500 +static ssize_t show_broadcast(struct device *device,
8501                             struct device_attribute *attr, char *buf)
8502  {
8503 -       struct net_device *net = to_net_dev(dev);
8504 -       if (dev_isalive(net))
8505 -               return format_addr(buf, net->broadcast, net->addr_len);
8506 +       struct net_device *dev = to_net_dev(device);
8507 +       if (dev_isalive(dev))
8508 +               return format_addr(buf, dev->broadcast, dev->addr_len);
8509         return -EINVAL;
8510  }
8511  
8512 -static ssize_t show_carrier(struct device *dev,
8513 +static ssize_t show_carrier(struct device *device,
8514                             struct device_attribute *attr, char *buf)
8515  {
8516 -       struct net_device *netdev = to_net_dev(dev);
8517 -       if (netif_running(netdev)) {
8518 -               return sprintf(buf, fmt_dec, !!netif_carrier_ok(netdev));
8519 +       struct net_device *dev = to_net_dev(device);
8520 +       if (netif_running(dev)) {
8521 +               return sprintf(buf, fmt_dec, !!netif_carrier_ok(dev));
8522         }
8523         return -EINVAL;
8524  }
8525  
8526 -static ssize_t show_dormant(struct device *dev,
8527 +static ssize_t show_dormant(struct device *device,
8528                             struct device_attribute *attr, char *buf)
8529  {
8530 -       struct net_device *netdev = to_net_dev(dev);
8531 +       struct net_device *dev = to_net_dev(device);
8532  
8533 -       if (netif_running(netdev))
8534 -               return sprintf(buf, fmt_dec, !!netif_dormant(netdev));
8535 +       if (netif_running(dev))
8536 +               return sprintf(buf, fmt_dec, !!netif_dormant(dev));
8537  
8538         return -EINVAL;
8539  }
8540 @@ -156,15 +158,15 @@
8541         "up"
8542  };
8543  
8544 -static ssize_t show_operstate(struct device *dev,
8545 +static ssize_t show_operstate(struct device *device,
8546                               struct device_attribute *attr, char *buf)
8547  {
8548 -       const struct net_device *netdev = to_net_dev(dev);
8549 +       const struct net_device *dev = to_net_dev(device);
8550         unsigned char operstate;
8551  
8552         read_lock(&dev_base_lock);
8553 -       operstate = netdev->operstate;
8554 -       if (!netif_running(netdev))
8555 +       operstate = dev->operstate;
8556 +       if (!netif_running(dev))
8557                 operstate = IF_OPER_DOWN;
8558         read_unlock(&dev_base_lock);
8559  
8560 @@ -177,57 +179,57 @@
8561  /* read-write attributes */
8562  NETDEVICE_SHOW(mtu, fmt_dec);
8563  
8564 -static int change_mtu(struct net_device *net, unsigned long new_mtu)
8565 +static int change_mtu(struct net_device *dev, unsigned long new_mtu)
8566  {
8567 -       return dev_set_mtu(net, (int) new_mtu);
8568 +       return dev_set_mtu(dev, (int) new_mtu);
8569  }
8570  
8571 -static ssize_t store_mtu(struct device *dev, struct device_attribute *attr,
8572 +static ssize_t store_mtu(struct device *device, struct device_attribute *attr,
8573                          const char *buf, size_t len)
8574  {
8575 -       return netdev_store(dev, attr, buf, len, change_mtu);
8576 +       return netdev_store(device, attr, buf, len, change_mtu);
8577  }
8578  
8579  NETDEVICE_SHOW(flags, fmt_hex);
8580  
8581 -static int change_flags(struct net_device *net, unsigned long new_flags)
8582 +static int change_flags(struct net_device *dev, unsigned long new_flags)
8583  {
8584 -       return dev_change_flags(net, (unsigned) new_flags);
8585 +       return dev_change_flags(dev, (unsigned) new_flags);
8586  }
8587  
8588 -static ssize_t store_flags(struct device *dev, struct device_attribute *attr,
8589 +static ssize_t store_flags(struct device *device, struct device_attribute *attr,
8590                            const char *buf, size_t len)
8591  {
8592 -       return netdev_store(dev, attr, buf, len, change_flags);
8593 +       return netdev_store(device, attr, buf, len, change_flags);
8594  }
8595  
8596  NETDEVICE_SHOW(tx_queue_len, fmt_ulong);
8597  
8598 -static int change_tx_queue_len(struct net_device *net, unsigned long new_len)
8599 +static int change_tx_queue_len(struct net_device *dev, unsigned long new_len)
8600  {
8601 -       net->tx_queue_len = new_len;
8602 +       dev->tx_queue_len = new_len;
8603         return 0;
8604  }
8605  
8606 -static ssize_t store_tx_queue_len(struct device *dev,
8607 +static ssize_t store_tx_queue_len(struct device *device,
8608                                   struct device_attribute *attr,
8609                                   const char *buf, size_t len)
8610  {
8611 -       return netdev_store(dev, attr, buf, len, change_tx_queue_len);
8612 +       return netdev_store(device, attr, buf, len, change_tx_queue_len);
8613  }
8614  
8615  NETDEVICE_SHOW(weight, fmt_dec);
8616  
8617 -static int change_weight(struct net_device *net, unsigned long new_weight)
8618 +static int change_weight(struct net_device *dev, unsigned long new_weight)
8619  {
8620 -       net->weight = new_weight;
8621 +       dev->weight = new_weight;
8622         return 0;
8623  }
8624  
8625 -static ssize_t store_weight(struct device *dev, struct device_attribute *attr,
8626 +static ssize_t store_weight(struct device *device, struct device_attribute *attr,
8627                             const char *buf, size_t len)
8628  {
8629 -       return netdev_store(dev, attr, buf, len, change_weight);
8630 +       return netdev_store(device, attr, buf, len, change_weight);
8631  }
8632  
8633  static struct device_attribute net_class_attributes[] = {
8634 @@ -447,6 +449,23 @@
8635         kfree((char *)dev - dev->padded);
8636  }
8637  
8638 +static const void *net_current_tag(void)
8639 +{
8640 +       return current->nsproxy->net_ns;
8641 +}
8642 +
8643 +static const void *net_kobject_tag(struct kobject *kobj)
8644 +{
8645 +       struct net_device *dev;
8646 +       dev = container_of(kobj, struct net_device, dev.kobj);
8647 +       return dev->nd_net;
8648 +}
8649 +
8650 +static const struct shadow_dir_operations net_shadow_dir_operations = {
8651 +       .current_tag = net_current_tag,
8652 +       .kobject_tag = net_kobject_tag,
8653 +};
8654 +
8655  static struct class net_class = {
8656         .name = "net",
8657         .dev_release = netdev_release,
8658 @@ -454,42 +473,43 @@
8659  #ifdef CONFIG_HOTPLUG
8660         .dev_uevent = netdev_uevent,
8661  #endif
8662 +       .shadow_ops = &net_shadow_dir_operations,
8663  };
8664  
8665  /* Delete sysfs entries but hold kobject reference until after all
8666   * netdev references are gone.
8667   */
8668 -void netdev_unregister_sysfs(struct net_device * net)
8669 +void netdev_unregister_sysfs(struct net_device * dev)
8670  {
8671 -       struct device *dev = &(net->dev);
8672 +       struct device *device = &(dev->dev);
8673  
8674 -       kobject_get(&dev->kobj);
8675 -       device_del(dev);
8676 +       kobject_get(&device->kobj);
8677 +       device_del(device);
8678  }
8679  
8680  /* Create sysfs entries for network device. */
8681 -int netdev_register_sysfs(struct net_device *net)
8682 +int netdev_register_sysfs(struct net_device *dev)
8683  {
8684 -       struct device *dev = &(net->dev);
8685 -       struct attribute_group **groups = net->sysfs_groups;
8686 +       struct device *device = &(dev->dev);
8687 +       struct attribute_group **groups = dev->sysfs_groups;
8688  
8689 -       device_initialize(dev);
8690 -       dev->class = &net_class;
8691 -       dev->platform_data = net;
8692 -       dev->groups = groups;
8693 +       device_initialize(device);
8694 +       device->class = &net_class;
8695 +       device->platform_data = dev;
8696 +       device->groups = groups;
8697  
8698         BUILD_BUG_ON(BUS_ID_SIZE < IFNAMSIZ);
8699 -       strlcpy(dev->bus_id, net->name, BUS_ID_SIZE);
8700 +       strlcpy(device->bus_id, dev->name, BUS_ID_SIZE);
8701  
8702 -       if (net->get_stats)
8703 +       if (dev->get_stats)
8704                 *groups++ = &netstat_group;
8705  
8706  #ifdef CONFIG_WIRELESS_EXT
8707 -       if (net->wireless_handlers && net->wireless_handlers->get_wireless_stats)
8708 +       if (dev->wireless_handlers && dev->wireless_handlers->get_wireless_stats)
8709                 *groups++ = &wireless_group;
8710  #endif
8711  
8712 -       return device_add(dev);
8713 +       return device_add(device);
8714  }
8715  
8716  int netdev_sysfs_init(void)
8717 diff -Nurb linux-2.6.22-try2/net/core/net_namespace.c linux-2.6.22-try2-netns/net/core/net_namespace.c
8718 --- linux-2.6.22-try2/net/core/net_namespace.c  1969-12-31 19:00:00.000000000 -0500
8719 +++ linux-2.6.22-try2-netns/net/core/net_namespace.c    2007-12-19 22:49:18.000000000 -0500
8720 @@ -0,0 +1,332 @@
8721 +#include <linux/workqueue.h>
8722 +#include <linux/rtnetlink.h>
8723 +#include <linux/cache.h>
8724 +#include <linux/slab.h>
8725 +#include <linux/list.h>
8726 +#include <linux/delay.h>
8727 +#include <net/net_namespace.h>
8728 +
8729 +/*
8730 + *     Our network namespace constructor/destructor lists
8731 + */
8732 +
8733 +static LIST_HEAD(pernet_list);
8734 +static struct list_head *first_device = &pernet_list;
8735 +static DEFINE_MUTEX(net_mutex);
8736 +
8737 +static DEFINE_MUTEX(net_list_mutex);
8738 +LIST_HEAD(net_namespace_list);
8739 +
8740 +static struct kmem_cache *net_cachep;
8741 +
8742 +struct net init_net;
8743 +EXPORT_SYMBOL_GPL(init_net);
8744 +
8745 +void net_lock(void)
8746 +{
8747 +       mutex_lock(&net_list_mutex);
8748 +}
8749 +
8750 +void net_unlock(void)
8751 +{
8752 +       mutex_unlock(&net_list_mutex);
8753 +}
8754 +
8755 +static struct net *net_alloc(void)
8756 +{
8757 +       return kmem_cache_alloc(net_cachep, GFP_KERNEL);
8758 +}
8759 +
8760 +static void net_free(struct net *net)
8761 +{
8762 +       if (!net)
8763 +               return;
8764 +
8765 +       if (unlikely(atomic_read(&net->use_count) != 0)) {
8766 +               printk(KERN_EMERG "network namespace not free! Usage: %d\n",
8767 +                       atomic_read(&net->use_count));
8768 +               return;
8769 +       }
8770 +
8771 +       kmem_cache_free(net_cachep, net);
8772 +}
8773 +
8774 +static void cleanup_net(struct work_struct *work)
8775 +{
8776 +       struct pernet_operations *ops;
8777 +       struct list_head *ptr;
8778 +       struct net *net;
8779 +
8780 +       net = container_of(work, struct net, work);
8781 +
8782 +       mutex_lock(&net_mutex);
8783 +
8784 +       /* Don't let anyone else find us. */
8785 +       net_lock();
8786 +       list_del(&net->list);
8787 +       net_unlock();
8788 +
8789 +       /* Run all of the network namespace exit methods */
8790 +       list_for_each_prev(ptr, &pernet_list) {
8791 +               ops = list_entry(ptr, struct pernet_operations, list);
8792 +               if (ops->exit)
8793 +                       ops->exit(net);
8794 +       }
8795 +
8796 +       mutex_unlock(&net_mutex);
8797 +
8798 +       /* Ensure there are no outstanding rcu callbacks using this
8799 +        * network namespace.
8800 +        */
8801 +       rcu_barrier();
8802 +
8803 +       /* Finally it is safe to free my network namespace structure */
8804 +       net_free(net);
8805 +}
8806 +
8807 +
8808 +void __put_net(struct net *net)
8809 +{
8810 +       /* Cleanup the network namespace in process context */
8811 +       INIT_WORK(&net->work, cleanup_net);
8812 +       schedule_work(&net->work);
8813 +}
8814 +EXPORT_SYMBOL_GPL(__put_net);
8815 +
8816 +/*
8817 + * setup_net runs the initializers for the network namespace object.
8818 + */
8819 +static int setup_net(struct net *net)
8820 +{
8821 +       /* Must be called with net_mutex held */
8822 +       struct pernet_operations *ops;
8823 +       struct list_head *ptr;
8824 +       int error;
8825 +
8826 +       memset(net, 0, sizeof(struct net));
8827 +       atomic_set(&net->count, 1);
8828 +       atomic_set(&net->use_count, 0);
8829 +
8830 +       error = 0;
8831 +       list_for_each(ptr, &pernet_list) {
8832 +               ops = list_entry(ptr, struct pernet_operations, list);
8833 +               if (ops->init) {
8834 +                       error = ops->init(net);
8835 +                       if (error < 0)
8836 +                               goto out_undo;
8837 +               }
8838 +       }
8839 +out:
8840 +       return error;
8841 +out_undo:
8842 +       /* Walk through the list backwards calling the exit functions
8843 +        * for the pernet modules whose init functions did not fail.
8844 +        */
8845 +       for (ptr = ptr->prev; ptr != &pernet_list; ptr = ptr->prev) {
8846 +               ops = list_entry(ptr, struct pernet_operations, list);
8847 +               if (ops->exit)
8848 +                       ops->exit(net);
8849 +       }
8850 +       goto out;
8851 +}
8852 +
8853 +struct net *copy_net_ns(unsigned long flags, struct net *old_net)
8854 +{
8855 +       struct net *new_net = NULL;
8856 +       int err;
8857 +
8858 +       get_net(old_net);
8859 +
8860 +       if (!(flags & CLONE_NEWNET))
8861 +               return old_net;
8862 +
8863 +       err = -EPERM;
8864 +       if (!capable(CAP_SYS_ADMIN))
8865 +               goto out;
8866 +
8867 +       err = -ENOMEM;
8868 +       new_net = net_alloc();
8869 +       if (!new_net)
8870 +               goto out;
8871 +
8872 +       mutex_lock(&net_mutex);
8873 +       err = setup_net(new_net);
8874 +       if (err)
8875 +               goto out_unlock;
8876 +
8877 +       net_lock();
8878 +       list_add_tail(&new_net->list, &net_namespace_list);
8879 +       net_unlock();
8880 +
8881 +
8882 +out_unlock:
8883 +       mutex_unlock(&net_mutex);
8884 +out:
8885 +       put_net(old_net);
8886 +       if (err) {
8887 +               net_free(new_net);
8888 +               new_net = ERR_PTR(err);
8889 +       }
8890 +       return new_net;
8891 +}
8892 +
8893 +static int __init net_ns_init(void)
8894 +{
8895 +       int err;
8896 +
8897 +       printk(KERN_INFO "net_namespace: %zd bytes\n", sizeof(struct net));
8898 +       net_cachep = kmem_cache_create("net_namespace", sizeof(struct net),
8899 +                                       SMP_CACHE_BYTES,
8900 +                                       SLAB_PANIC, NULL, NULL);
8901 +       mutex_lock(&net_mutex);
8902 +       err = setup_net(&init_net);
8903 +
8904 +       net_lock();
8905 +       list_add_tail(&init_net.list, &net_namespace_list);
8906 +       net_unlock();
8907 +
8908 +       mutex_unlock(&net_mutex);
8909 +       if (err)
8910 +               panic("Could not setup the initial network namespace");
8911 +
8912 +       return 0;
8913 +}
8914 +
8915 +pure_initcall(net_ns_init);
8916 +
8917 +static int register_pernet_operations(struct list_head *list,
8918 +                                     struct pernet_operations *ops)
8919 +{
8920 +       struct net *net, *undo_net;
8921 +       int error;
8922 +
8923 +       error = 0;
8924 +       list_add_tail(&ops->list, list);
8925 +       for_each_net(net) {
8926 +               if (ops->init) {
8927 +                       error = ops->init(net);
8928 +                       if (error)
8929 +                               goto out_undo;
8930 +               }
8931 +       }
8932 +out:
8933 +       return error;
8934 +
8935 +out_undo:
8936 +       /* If I have an error cleanup all namespaces I initialized */
8937 +       list_del(&ops->list);
8938 +       for_each_net(undo_net) {
8939 +               if (undo_net == net)
8940 +                       goto undone;
8941 +               if (ops->exit)
8942 +                       ops->exit(undo_net);
8943 +       }
8944 +undone:
8945 +       goto out;
8946 +}
8947 +
8948 +static void unregister_pernet_operations(struct pernet_operations *ops)
8949 +{
8950 +       struct net *net;
8951 +
8952 +       list_del(&ops->list);
8953 +       for_each_net(net)
8954 +               if (ops->exit)
8955 +                       ops->exit(net);
8956 +}
8957 +
8958 +/**
8959 + *      register_pernet_subsys - register a network namespace subsystem
8960 + *     @ops:  pernet operations structure for the subsystem
8961 + *
8962 + *     Register a subsystem which has init and exit functions
8963 + *     that are called when network namespaces are created and
8964 + *     destroyed respectively.
8965 + *
8966 + *     When registered all network namespace init functions are
8967 + *     called for every existing network namespace.  Allowing kernel
8968 + *     modules to have a race free view of the set of network namespaces.
8969 + *
8970 + *     When a new network namespace is created all of the init
8971 + *     methods are called in the order in which they were registered.
8972 + *
8973 + *     When a network namespace is destroyed all of the exit methods
8974 + *     are called in the reverse of the order with which they were
8975 + *     registered.
8976 + */
8977 +int register_pernet_subsys(struct pernet_operations *ops)
8978 +{
8979 +       int error;
8980 +       mutex_lock(&net_mutex);
8981 +       error =  register_pernet_operations(first_device, ops);
8982 +       mutex_unlock(&net_mutex);
8983 +       return error;
8984 +}
8985 +EXPORT_SYMBOL_GPL(register_pernet_subsys);
8986 +
8987 +/**
8988 + *      unregister_pernet_subsys - unregister a network namespace subsystem
8989 + *     @ops: pernet operations structure to manipulate
8990 + *
8991 + *     Remove the pernet operations structure from the list to be
8992 + *     used when network namespaces are created or destoryed.  In
8993 + *     addition run the exit method for all existing network
8994 + *     namespaces.
8995 + */
8996 +void unregister_pernet_subsys(struct pernet_operations *module)
8997 +{
8998 +       mutex_lock(&net_mutex);
8999 +       unregister_pernet_operations(module);
9000 +       mutex_unlock(&net_mutex);
9001 +}
9002 +EXPORT_SYMBOL_GPL(unregister_pernet_subsys);
9003 +
9004 +/**
9005 + *      register_pernet_device - register a network namespace device
9006 + *     @ops:  pernet operations structure for the subsystem
9007 + *
9008 + *     Register a device which has init and exit functions
9009 + *     that are called when network namespaces are created and
9010 + *     destroyed respectively.
9011 + *
9012 + *     When registered all network namespace init functions are
9013 + *     called for every existing network namespace.  Allowing kernel
9014 + *     modules to have a race free view of the set of network namespaces.
9015 + *
9016 + *     When a new network namespace is created all of the init
9017 + *     methods are called in the order in which they were registered.
9018 + *
9019 + *     When a network namespace is destroyed all of the exit methods
9020 + *     are called in the reverse of the order with which they were
9021 + *     registered.
9022 + */
9023 +int register_pernet_device(struct pernet_operations *ops)
9024 +{
9025 +       int error;
9026 +       mutex_lock(&net_mutex);
9027 +       error = register_pernet_operations(&pernet_list, ops);
9028 +       if (!error && (first_device == &pernet_list))
9029 +               first_device = &ops->list;
9030 +       mutex_unlock(&net_mutex);
9031 +       return error;
9032 +}
9033 +EXPORT_SYMBOL_GPL(register_pernet_device);
9034 +
9035 +/**
9036 + *      unregister_pernet_device - unregister a network namespace netdevice
9037 + *     @ops: pernet operations structure to manipulate
9038 + *
9039 + *     Remove the pernet operations structure from the list to be
9040 + *     used when network namespaces are created or destoryed.  In
9041 + *     addition run the exit method for all existing network
9042 + *     namespaces.
9043 + */
9044 +void unregister_pernet_device(struct pernet_operations *ops)
9045 +{
9046 +       mutex_lock(&net_mutex);
9047 +       if (&ops->list == first_device)
9048 +               first_device = first_device->next;
9049 +       unregister_pernet_operations(ops);
9050 +       mutex_unlock(&net_mutex);
9051 +}
9052 +EXPORT_SYMBOL_GPL(unregister_pernet_device);
9053 diff -Nurb linux-2.6.22-try2/net/core/netpoll.c linux-2.6.22-try2-netns/net/core/netpoll.c
9054 --- linux-2.6.22-try2/net/core/netpoll.c        2007-12-19 15:29:24.000000000 -0500
9055 +++ linux-2.6.22-try2-netns/net/core/netpoll.c  2007-12-19 22:49:18.000000000 -0500
9056 @@ -634,7 +634,7 @@
9057         int err;
9058  
9059         if (np->dev_name)
9060 -               ndev = dev_get_by_name(np->dev_name);
9061 +               ndev = dev_get_by_name(&init_net, np->dev_name);
9062         if (!ndev) {
9063                 printk(KERN_ERR "%s: %s doesn't exist, aborting.\n",
9064                        np->name, np->dev_name);
9065 diff -Nurb linux-2.6.22-try2/net/core/pktgen.c linux-2.6.22-try2-netns/net/core/pktgen.c
9066 --- linux-2.6.22-try2/net/core/pktgen.c 2007-12-19 15:29:24.000000000 -0500
9067 +++ linux-2.6.22-try2-netns/net/core/pktgen.c   2007-12-19 22:49:18.000000000 -0500
9068 @@ -155,6 +155,7 @@
9069  #include <net/checksum.h>
9070  #include <net/ipv6.h>
9071  #include <net/addrconf.h>
9072 +#include <net/net_namespace.h>
9073  #include <asm/byteorder.h>
9074  #include <linux/rcupdate.h>
9075  #include <asm/bitops.h>
9076 @@ -1903,6 +1904,9 @@
9077  {
9078         struct net_device *dev = ptr;
9079  
9080 +       if (dev->nd_net != &init_net)
9081 +               return NOTIFY_DONE;
9082 +
9083         /* It is OK that we do not hold the group lock right now,
9084          * as we run under the RTNL lock.
9085          */
9086 @@ -1933,7 +1937,7 @@
9087                 pkt_dev->odev = NULL;
9088         }
9089  
9090 -       odev = dev_get_by_name(ifname);
9091 +       odev = dev_get_by_name(&init_net, ifname);
9092         if (!odev) {
9093                 printk("pktgen: no such netdevice: \"%s\"\n", ifname);
9094                 return -ENODEV;
9095 @@ -3570,7 +3574,7 @@
9096  
9097         printk(version);
9098  
9099 -       pg_proc_dir = proc_mkdir(PG_PROC_DIR, proc_net);
9100 +       pg_proc_dir = proc_mkdir(PG_PROC_DIR, init_net.proc_net);
9101         if (!pg_proc_dir)
9102                 return -ENODEV;
9103         pg_proc_dir->owner = THIS_MODULE;
9104 @@ -3579,7 +3583,7 @@
9105         if (pe == NULL) {
9106                 printk("pktgen: ERROR: cannot create %s procfs entry.\n",
9107                        PGCTRL);
9108 -               proc_net_remove(PG_PROC_DIR);
9109 +               proc_net_remove(&init_net, PG_PROC_DIR);
9110                 return -EINVAL;
9111         }
9112  
9113 @@ -3602,7 +3606,7 @@
9114                 printk("pktgen: ERROR: Initialization failed for all threads\n");
9115                 unregister_netdevice_notifier(&pktgen_notifier_block);
9116                 remove_proc_entry(PGCTRL, pg_proc_dir);
9117 -               proc_net_remove(PG_PROC_DIR);
9118 +               proc_net_remove(&init_net, PG_PROC_DIR);
9119                 return -ENODEV;
9120         }
9121  
9122 @@ -3629,7 +3633,7 @@
9123  
9124         /* Clean up proc file system */
9125         remove_proc_entry(PGCTRL, pg_proc_dir);
9126 -       proc_net_remove(PG_PROC_DIR);
9127 +       proc_net_remove(&init_net, PG_PROC_DIR);
9128  }
9129  
9130  module_init(pg_init);
9131 diff -Nurb linux-2.6.22-try2/net/core/rtnetlink.c linux-2.6.22-try2-netns/net/core/rtnetlink.c
9132 --- linux-2.6.22-try2/net/core/rtnetlink.c      2007-12-19 15:29:23.000000000 -0500
9133 +++ linux-2.6.22-try2-netns/net/core/rtnetlink.c        2007-12-19 23:04:00.000000000 -0500
9134 @@ -59,7 +59,6 @@
9135  };
9136  
9137  static DEFINE_MUTEX(rtnl_mutex);
9138 -static struct sock *rtnl;
9139  
9140  void rtnl_lock(void)
9141  {
9142 @@ -73,9 +72,17 @@
9143  
9144  void rtnl_unlock(void)
9145  {
9146 +       struct net *net;
9147         mutex_unlock(&rtnl_mutex);
9148 +       
9149 +       net_lock();
9150 +       for_each_net(net) {
9151 +               struct sock *rtnl = net->rtnl;
9152         if (rtnl && rtnl->sk_receive_queue.qlen)
9153                 rtnl->sk_data_ready(rtnl, 0);
9154 +       }
9155 +       net_unlock();
9156 +
9157         netdev_run_todo();
9158  }
9159  
9160 @@ -446,8 +453,9 @@
9161         return ret;
9162  }
9163  
9164 -int rtnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo)
9165 +int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned group, int echo)
9166  {
9167 +       struct sock *rtnl = net->rtnl;
9168         int err = 0;
9169  
9170         NETLINK_CB(skb).dst_group = group;
9171 @@ -459,14 +467,17 @@
9172         return err;
9173  }
9174  
9175 -int rtnl_unicast(struct sk_buff *skb, u32 pid)
9176 +int rtnl_unicast(struct sk_buff *skb, struct net *net, u32 pid)
9177  {
9178 +       struct sock *rtnl = net->rtnl;
9179 +
9180         return nlmsg_unicast(rtnl, skb, pid);
9181  }
9182  
9183 -int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group,
9184 +int rtnl_notify(struct sk_buff *skb, struct net *net, u32 pid, u32 group,
9185                 struct nlmsghdr *nlh, gfp_t flags)
9186  {
9187 +       struct sock *rtnl = net->rtnl;
9188         int report = 0;
9189  
9190         if (nlh)
9191 @@ -475,8 +486,10 @@
9192         return nlmsg_notify(rtnl, skb, pid, group, report, flags);
9193  }
9194  
9195 -void rtnl_set_sk_err(u32 group, int error)
9196 +void rtnl_set_sk_err(struct net *net, u32 group, int error)
9197  {
9198 +       struct sock *rtnl = net->rtnl;
9199 +
9200         netlink_set_err(rtnl, 0, group, error);
9201  }
9202  
9203 @@ -687,12 +700,13 @@
9204  
9205  static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
9206  {
9207 +       struct net *net = skb->sk->sk_net;
9208         int idx;
9209         int s_idx = cb->args[0];
9210         struct net_device *dev;
9211  
9212         idx = 0;
9213 -       for_each_netdev(dev) {
9214 +       for_each_netdev(net, dev) {
9215                 if (!nx_dev_visible(skb->sk->sk_nx_info, dev))
9216                         continue;
9217                 if (idx < s_idx)
9218 @@ -857,6 +871,7 @@
9219  
9220  static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
9221  {
9222 +       struct net *net = skb->sk->sk_net;
9223         struct ifinfomsg *ifm;
9224         struct net_device *dev;
9225         int err;
9226 @@ -875,9 +890,9 @@
9227         err = -EINVAL;
9228         ifm = nlmsg_data(nlh);
9229         if (ifm->ifi_index > 0)
9230 -               dev = dev_get_by_index(ifm->ifi_index);
9231 +               dev = dev_get_by_index(net, ifm->ifi_index);
9232         else if (tb[IFLA_IFNAME])
9233 -               dev = dev_get_by_name(ifname);
9234 +               dev = dev_get_by_name(net, ifname);
9235         else
9236                 goto errout;
9237  
9238 @@ -903,6 +918,7 @@
9239  
9240  static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
9241  {
9242 +       struct net *net = skb->sk->sk_net;
9243         const struct rtnl_link_ops *ops;
9244         struct net_device *dev;
9245         struct ifinfomsg *ifm;
9246 @@ -919,9 +935,9 @@
9247  
9248         ifm = nlmsg_data(nlh);
9249         if (ifm->ifi_index > 0)
9250 -               dev = __dev_get_by_index(ifm->ifi_index);
9251 +               dev = __dev_get_by_index(net, ifm->ifi_index);
9252         else if (tb[IFLA_IFNAME])
9253 -               dev = __dev_get_by_name(ifname);
9254 +               dev = __dev_get_by_name(net, ifname);
9255         else
9256                 return -EINVAL;
9257  
9258 @@ -938,6 +954,7 @@
9259  
9260  static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
9261  {
9262 +       struct net *net = skb->sk->sk_net;
9263         const struct rtnl_link_ops *ops;
9264         struct net_device *dev;
9265         struct ifinfomsg *ifm;
9266 @@ -959,9 +976,9 @@
9267  
9268         ifm = nlmsg_data(nlh);
9269         if (ifm->ifi_index > 0)
9270 -               dev = __dev_get_by_index(ifm->ifi_index);
9271 +               dev = __dev_get_by_index(net, ifm->ifi_index);
9272         else if (ifname[0])
9273 -               dev = __dev_get_by_name(ifname);
9274 +               dev = __dev_get_by_name(net, ifname);
9275         else
9276                 dev = NULL;
9277  
9278 @@ -1079,6 +1096,7 @@
9279  
9280  static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
9281  {
9282 +       struct net *net = skb->sk->sk_net;
9283         struct ifinfomsg *ifm;
9284         struct nlattr *tb[IFLA_MAX+1];
9285         struct net_device *dev = NULL;
9286 @@ -1091,7 +1109,7 @@
9287  
9288         ifm = nlmsg_data(nlh);
9289         if (ifm->ifi_index > 0) {
9290 -               dev = dev_get_by_index(ifm->ifi_index);
9291 +               dev = dev_get_by_index(net, ifm->ifi_index);
9292                 if (dev == NULL)
9293                         return -ENODEV;
9294         } else
9295 @@ -1111,7 +1129,7 @@
9296                 kfree_skb(nskb);
9297                 goto errout;
9298         }
9299 -       err = rtnl_unicast(nskb, NETLINK_CB(skb).pid);
9300 +       err = rtnl_unicast(nskb, net, NETLINK_CB(skb).pid);
9301  errout:
9302         dev_put(dev);
9303  
9304 @@ -1144,6 +1162,7 @@
9305  
9306  void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
9307  {
9308 +       struct net *net = dev->nd_net;
9309         struct sk_buff *skb;
9310         int err = -ENOBUFS;
9311  
9312 @@ -1161,10 +1180,10 @@
9313                 kfree_skb(skb);
9314                 goto errout;
9315         }
9316 -       err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
9317 +       err = rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
9318  errout:
9319         if (err < 0)
9320 -               rtnl_set_sk_err(RTNLGRP_LINK, err);
9321 +               rtnl_set_sk_err(net, RTNLGRP_LINK, err);
9322  }
9323  
9324  /* Protected by RTNL sempahore.  */
9325 @@ -1175,6 +1194,7 @@
9326  
9327  static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
9328  {
9329 +       struct net *net = skb->sk->sk_net;
9330         rtnl_doit_func doit;
9331         int sz_idx, kind;
9332         int min_len;
9333 @@ -1203,6 +1223,7 @@
9334                 return -EPERM;
9335  
9336         if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
9337 +               struct sock *rtnl;
9338                 rtnl_dumpit_func dumpit;
9339  
9340                 dumpit = rtnl_get_dumpit(family, type);
9341 @@ -1210,6 +1231,7 @@
9342                         return -EOPNOTSUPP;
9343  
9344                 __rtnl_unlock();
9345 +               rtnl = net->rtnl;
9346                 err = netlink_dump_start(rtnl, skb, nlh, dumpit, NULL);
9347                 rtnl_lock();
9348                 return err;
9349 @@ -1259,6 +1281,10 @@
9350  static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr)
9351  {
9352         struct net_device *dev = ptr;
9353 +
9354 +       if (dev->nd_net != &init_net)
9355 +               return NOTIFY_DONE;
9356 +
9357         switch (event) {
9358         case NETDEV_UNREGISTER:
9359                 rtmsg_ifinfo(RTM_DELLINK, dev, ~0U);
9360 @@ -1284,6 +1310,36 @@
9361         .notifier_call  = rtnetlink_event,
9362  };
9363  
9364 +
9365 +static int rtnetlink_net_init(struct net *net)
9366 +{
9367 +       struct sock *sk;
9368 +       sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX,
9369 +                                  rtnetlink_rcv, &rtnl_mutex, THIS_MODULE);
9370 +       if (!sk)
9371 +               return -ENOMEM;
9372 +
9373 +       /* Don't hold an extra reference on the namespace */
9374 +       put_net(sk->sk_net);
9375 +       net->rtnl = sk;
9376 +       return 0;
9377 +}
9378 +
9379 +static void rtnetlink_net_exit(struct net *net)
9380 +{
9381 +       /* At the last minute lie and say this is a socket for the
9382 +        * initial network namespace.  So the socket will be safe to
9383 +        * free.
9384 +        */
9385 +       net->rtnl->sk_net = get_net(&init_net);
9386 +       sock_put(net->rtnl);
9387 +}
9388 +
9389 +static struct pernet_operations rtnetlink_net_ops = {
9390 +       .init = rtnetlink_net_init,
9391 +       .exit = rtnetlink_net_exit,
9392 +};
9393 +
9394  void __init rtnetlink_init(void)
9395  {
9396         int i;
9397 @@ -1296,10 +1352,9 @@
9398         if (!rta_buf)
9399                 panic("rtnetlink_init: cannot allocate rta_buf\n");
9400  
9401 -       rtnl = netlink_kernel_create(NETLINK_ROUTE, RTNLGRP_MAX, rtnetlink_rcv,
9402 -                                    &rtnl_mutex, THIS_MODULE);
9403 -       if (rtnl == NULL)
9404 +       if (register_pernet_subsys(&rtnetlink_net_ops))
9405                 panic("rtnetlink_init: cannot initialize rtnetlink\n");
9406 +
9407         netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV);
9408         register_netdevice_notifier(&rtnetlink_dev_notifier);
9409  
9410 diff -Nurb linux-2.6.22-try2/net/core/sock.c linux-2.6.22-try2-netns/net/core/sock.c
9411 --- linux-2.6.22-try2/net/core/sock.c   2007-12-19 13:37:57.000000000 -0500
9412 +++ linux-2.6.22-try2-netns/net/core/sock.c     2007-12-19 23:04:11.000000000 -0500
9413 @@ -123,6 +123,7 @@
9414  #include <net/sock.h>
9415  #include <net/xfrm.h>
9416  #include <linux/ipsec.h>
9417 +#include <net/net_namespace.h>
9418  
9419  #include <linux/filter.h>
9420  #include <linux/vs_socket.h>
9421 @@ -360,6 +361,7 @@
9422                     char __user *optval, int optlen)
9423  {
9424         struct sock *sk=sock->sk;
9425 +       struct net *net = sk->sk_net;
9426         struct sk_filter *filter;
9427         int val;
9428         int valbool;
9429 @@ -614,7 +616,7 @@
9430                         if (devname[0] == '\0') {
9431                                 sk->sk_bound_dev_if = 0;
9432                         } else {
9433 -                               struct net_device *dev = dev_get_by_name(devname);
9434 +                               struct net_device *dev = dev_get_by_name(net, devname);
9435                                 if (!dev) {
9436                                         ret = -ENODEV;
9437                                         break;
9438 @@ -867,7 +869,7 @@
9439   *     @prot: struct proto associated with this new sock instance
9440   *     @zero_it: if we should zero the newly allocated sock
9441   */
9442 -struct sock *sk_alloc(int family, gfp_t priority,
9443 +struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
9444                       struct proto *prot, int zero_it)
9445  {
9446         struct sock *sk = NULL;
9447 @@ -888,6 +890,7 @@
9448                          */
9449                         sk->sk_prot = sk->sk_prot_creator = prot;
9450                         sock_lock_init(sk);
9451 +                       sk->sk_net = get_net(net);
9452                 }
9453                 sock_vx_init(sk);
9454                 sock_nx_init(sk);
9455 @@ -929,6 +932,7 @@
9456                        __FUNCTION__, atomic_read(&sk->sk_omem_alloc));
9457  
9458         security_sk_free(sk);
9459 +       put_net(sk->sk_net);
9460         vx_sock_dec(sk);
9461         clr_vx_info(&sk->sk_vx_info);
9462         sk->sk_xid = -1;
9463 @@ -943,7 +947,7 @@
9464  
9465  struct sock *sk_clone(const struct sock *sk, const gfp_t priority)
9466  {
9467 -       struct sock *newsk = sk_alloc(sk->sk_family, priority, sk->sk_prot, 0);
9468 +       struct sock *newsk = sk_alloc(sk->sk_net, sk->sk_family, priority, sk->sk_prot, 0);
9469  
9470         if (newsk != NULL) {
9471                 struct sk_filter *filter;
9472 @@ -2017,7 +2021,7 @@
9473  static int __init proto_init(void)
9474  {
9475         /* register /proc/net/protocols */
9476 -       return proc_net_fops_create("protocols", S_IRUGO, &proto_seq_fops) == NULL ? -ENOBUFS : 0;
9477 +       return proc_net_fops_create(&init_net, "protocols", S_IRUGO, &proto_seq_fops) == NULL ? -ENOBUFS : 0;
9478  }
9479  
9480  subsys_initcall(proto_init);
9481 diff -Nurb linux-2.6.22-try2/net/core/sysctl_net_core.c linux-2.6.22-try2-netns/net/core/sysctl_net_core.c
9482 --- linux-2.6.22-try2/net/core/sysctl_net_core.c        2007-12-19 13:37:57.000000000 -0500
9483 +++ linux-2.6.22-try2-netns/net/core/sysctl_net_core.c  2007-12-19 22:49:18.000000000 -0500
9484 @@ -9,25 +9,10 @@
9485  #include <linux/sysctl.h>
9486  #include <linux/module.h>
9487  #include <linux/socket.h>
9488 +#include <linux/netdevice.h>
9489 +#include <net/xfrm.h>
9490  #include <net/sock.h>
9491  
9492 -#ifdef CONFIG_SYSCTL
9493 -
9494 -extern int netdev_max_backlog;
9495 -extern int weight_p;
9496 -
9497 -extern __u32 sysctl_wmem_max;
9498 -extern __u32 sysctl_rmem_max;
9499 -
9500 -extern int sysctl_core_destroy_delay;
9501 -
9502 -#ifdef CONFIG_XFRM
9503 -extern u32 sysctl_xfrm_aevent_etime;
9504 -extern u32 sysctl_xfrm_aevent_rseqth;
9505 -extern int sysctl_xfrm_larval_drop;
9506 -extern u32 sysctl_xfrm_acq_expires;
9507 -#endif
9508 -
9509  ctl_table core_table[] = {
9510  #ifdef CONFIG_NET
9511         {
9512 @@ -103,11 +88,32 @@
9513                 .mode           = 0644,
9514                 .proc_handler   = &proc_dointvec
9515         },
9516 +#endif /* CONFIG_NET */
9517 +       {
9518 +               .ctl_name       = NET_CORE_BUDGET,
9519 +               .procname       = "netdev_budget",
9520 +               .data           = &netdev_budget,
9521 +               .maxlen         = sizeof(int),
9522 +               .mode           = 0644,
9523 +               .proc_handler   = &proc_dointvec
9524 +       },
9525 +       {
9526 +               .ctl_name       = NET_CORE_WARNINGS,
9527 +               .procname       = "warnings",
9528 +               .data           = &net_msg_warn,
9529 +               .maxlen         = sizeof(int),
9530 +               .mode           = 0644,
9531 +               .proc_handler   = &proc_dointvec
9532 +       },
9533 +       { .ctl_name = 0 }
9534 +};
9535 +
9536 +struct ctl_table multi_core_table[] = {
9537  #ifdef CONFIG_XFRM
9538         {
9539                 .ctl_name       = NET_CORE_AEVENT_ETIME,
9540                 .procname       = "xfrm_aevent_etime",
9541 -               .data           = &sysctl_xfrm_aevent_etime,
9542 +               .data           = &init_net.sysctl_xfrm_aevent_etime,
9543                 .maxlen         = sizeof(u32),
9544                 .mode           = 0644,
9545                 .proc_handler   = &proc_dointvec
9546 @@ -115,7 +121,7 @@
9547         {
9548                 .ctl_name       = NET_CORE_AEVENT_RSEQTH,
9549                 .procname       = "xfrm_aevent_rseqth",
9550 -               .data           = &sysctl_xfrm_aevent_rseqth,
9551 +               .data           = &init_net.sysctl_xfrm_aevent_rseqth,
9552                 .maxlen         = sizeof(u32),
9553                 .mode           = 0644,
9554                 .proc_handler   = &proc_dointvec
9555 @@ -123,7 +129,7 @@
9556         {
9557                 .ctl_name       = CTL_UNNUMBERED,
9558                 .procname       = "xfrm_larval_drop",
9559 -               .data           = &sysctl_xfrm_larval_drop,
9560 +               .data           = &init_net.sysctl_xfrm_larval_drop,
9561                 .maxlen         = sizeof(int),
9562                 .mode           = 0644,
9563                 .proc_handler   = &proc_dointvec
9564 @@ -131,38 +137,19 @@
9565         {
9566                 .ctl_name       = CTL_UNNUMBERED,
9567                 .procname       = "xfrm_acq_expires",
9568 -               .data           = &sysctl_xfrm_acq_expires,
9569 +               .data           = &init_net.sysctl_xfrm_acq_expires,
9570                 .maxlen         = sizeof(int),
9571                 .mode           = 0644,
9572                 .proc_handler   = &proc_dointvec
9573         },
9574  #endif /* CONFIG_XFRM */
9575 -#endif /* CONFIG_NET */
9576         {
9577                 .ctl_name       = NET_CORE_SOMAXCONN,
9578                 .procname       = "somaxconn",
9579 -               .data           = &sysctl_somaxconn,
9580 -               .maxlen         = sizeof(int),
9581 -               .mode           = 0644,
9582 -               .proc_handler   = &proc_dointvec
9583 -       },
9584 -       {
9585 -               .ctl_name       = NET_CORE_BUDGET,
9586 -               .procname       = "netdev_budget",
9587 -               .data           = &netdev_budget,
9588 +               .data           = &init_net.sysctl_somaxconn,
9589                 .maxlen         = sizeof(int),
9590                 .mode           = 0644,
9591                 .proc_handler   = &proc_dointvec
9592         },
9593 -       {
9594 -               .ctl_name       = NET_CORE_WARNINGS,
9595 -               .procname       = "warnings",
9596 -               .data           = &net_msg_warn,
9597 -               .maxlen         = sizeof(int),
9598 -               .mode           = 0644,
9599 -               .proc_handler   = &proc_dointvec
9600 -       },
9601 -       { .ctl_name = 0 }
9602 +       {}
9603  };
9604 -
9605 -#endif
9606 diff -Nurb linux-2.6.22-try2/net/dccp/ipv4.c linux-2.6.22-try2-netns/net/dccp/ipv4.c
9607 --- linux-2.6.22-try2/net/dccp/ipv4.c   2007-12-19 13:37:57.000000000 -0500
9608 +++ linux-2.6.22-try2-netns/net/dccp/ipv4.c     2007-12-19 22:49:18.000000000 -0500
9609 @@ -202,6 +202,7 @@
9610   */
9611  static void dccp_v4_err(struct sk_buff *skb, u32 info)
9612  {
9613 +       struct net *net = skb->dev->nd_net;
9614         const struct iphdr *iph = (struct iphdr *)skb->data;
9615         const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data +
9616                                                         (iph->ihl << 2));
9617 @@ -213,13 +214,16 @@
9618         __u64 seq;
9619         int err;
9620  
9621 +       if (skb->dev->nd_net != &init_net)
9622 +               return;
9623 +
9624         if (skb->len < (iph->ihl << 2) + 8) {
9625                 ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
9626                 return;
9627         }
9628  
9629         sk = inet_lookup(&dccp_hashinfo, iph->daddr, dh->dccph_dport,
9630 -                        iph->saddr, dh->dccph_sport, inet_iif(skb));
9631 +                        iph->saddr, dh->dccph_sport, inet_iif(skb), net);
9632         if (sk == NULL) {
9633                 ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
9634                 return;
9635 @@ -441,7 +445,7 @@
9636         nsk = inet_lookup_established(&dccp_hashinfo,
9637                                       iph->saddr, dh->dccph_sport,
9638                                       iph->daddr, dh->dccph_dport,
9639 -                                     inet_iif(skb));
9640 +                                     inet_iif(skb), sk->sk_net);
9641         if (nsk != NULL) {
9642                 if (nsk->sk_state != DCCP_TIME_WAIT) {
9643                         bh_lock_sock(nsk);
9644 @@ -458,7 +462,8 @@
9645                                            struct sk_buff *skb)
9646  {
9647         struct rtable *rt;
9648 -       struct flowi fl = { .oif = ((struct rtable *)skb->dst)->rt_iif,
9649 +       struct flowi fl = { .fl_net = &init_net,
9650 +                           .oif = ((struct rtable *)skb->dst)->rt_iif,
9651                             .nl_u = { .ip4_u =
9652                                       { .daddr = ip_hdr(skb)->saddr,
9653                                         .saddr = ip_hdr(skb)->daddr,
9654 @@ -809,11 +814,16 @@
9655  /* this is called when real data arrives */
9656  static int dccp_v4_rcv(struct sk_buff *skb)
9657  {
9658 +       struct net *net = skb->dev->nd_net;
9659         const struct dccp_hdr *dh;
9660         const struct iphdr *iph;
9661         struct sock *sk;
9662         int min_cov;
9663  
9664 +       if (skb->dev->nd_net != &init_net) {
9665 +               kfree_skb(skb);
9666 +               return 0;
9667 +       }
9668         /* Step 1: Check header basics */
9669  
9670         if (dccp_invalid_packet(skb))
9671 @@ -852,7 +862,7 @@
9672          *      Look up flow ID in table and get corresponding socket */
9673         sk = __inet_lookup(&dccp_hashinfo,
9674                            iph->saddr, dh->dccph_sport,
9675 -                          iph->daddr, dh->dccph_dport, inet_iif(skb));
9676 +                          iph->daddr, dh->dccph_dport, inet_iif(skb), net);
9677         /*
9678          * Step 2:
9679          *      If no socket ...
9680 diff -Nurb linux-2.6.22-try2/net/dccp/ipv6.c linux-2.6.22-try2-netns/net/dccp/ipv6.c
9681 --- linux-2.6.22-try2/net/dccp/ipv6.c   2007-12-19 13:37:57.000000000 -0500
9682 +++ linux-2.6.22-try2-netns/net/dccp/ipv6.c     2007-12-19 22:49:18.000000000 -0500
9683 @@ -94,6 +94,7 @@
9684  static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
9685                         int type, int code, int offset, __be32 info)
9686  {
9687 +       struct net *net = skb->dev->nd_net;
9688         struct ipv6hdr *hdr = (struct ipv6hdr *)skb->data;
9689         const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset);
9690         struct ipv6_pinfo *np;
9691 @@ -102,7 +103,7 @@
9692         __u64 seq;
9693  
9694         sk = inet6_lookup(&dccp_hashinfo, &hdr->daddr, dh->dccph_dport,
9695 -                         &hdr->saddr, dh->dccph_sport, inet6_iif(skb));
9696 +                         &hdr->saddr, dh->dccph_sport, inet6_iif(skb), net);
9697  
9698         if (sk == NULL) {
9699                 ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
9700 @@ -142,6 +143,7 @@
9701                            for now.
9702                          */
9703                         memset(&fl, 0, sizeof(fl));
9704 +                       fl.fl_net = &init_net;
9705                         fl.proto = IPPROTO_DCCP;
9706                         ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
9707                         ipv6_addr_copy(&fl.fl6_src, &np->saddr);
9708 @@ -242,6 +244,7 @@
9709         int err = -1;
9710  
9711         memset(&fl, 0, sizeof(fl));
9712 +       fl.fl_net = &init_net,
9713         fl.proto = IPPROTO_DCCP;
9714         ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
9715         ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr);
9716 @@ -358,6 +361,7 @@
9717                                                       &rxip6h->daddr);
9718  
9719         memset(&fl, 0, sizeof(fl));
9720 +       fl.fl_net = &init_net;
9721         ipv6_addr_copy(&fl.fl6_dst, &rxip6h->saddr);
9722         ipv6_addr_copy(&fl.fl6_src, &rxip6h->daddr);
9723  
9724 @@ -407,7 +411,7 @@
9725         nsk = __inet6_lookup_established(&dccp_hashinfo,
9726                                          &iph->saddr, dh->dccph_sport,
9727                                          &iph->daddr, ntohs(dh->dccph_dport),
9728 -                                        inet6_iif(skb));
9729 +                                        inet6_iif(skb), sk->sk_net);
9730         if (nsk != NULL) {
9731                 if (nsk->sk_state != DCCP_TIME_WAIT) {
9732                         bh_lock_sock(nsk);
9733 @@ -584,6 +588,7 @@
9734                 struct flowi fl;
9735  
9736                 memset(&fl, 0, sizeof(fl));
9737 +               fl.fl_net = &init_net;
9738                 fl.proto = IPPROTO_DCCP;
9739                 ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
9740                 if (opt != NULL && opt->srcrt != NULL) {
9741 @@ -819,6 +824,7 @@
9742  {
9743         const struct dccp_hdr *dh;
9744         struct sk_buff *skb = *pskb;
9745 +       struct net *net = skb->dev->nd_net;
9746         struct sock *sk;
9747         int min_cov;
9748  
9749 @@ -849,7 +855,7 @@
9750         sk = __inet6_lookup(&dccp_hashinfo, &ipv6_hdr(skb)->saddr,
9751                             dh->dccph_sport,
9752                             &ipv6_hdr(skb)->daddr, ntohs(dh->dccph_dport),
9753 -                           inet6_iif(skb));
9754 +                           inet6_iif(skb), net);
9755         /*
9756          * Step 2:
9757          *      If no socket ...
9758 @@ -937,6 +943,7 @@
9759                 return -EAFNOSUPPORT;
9760  
9761         memset(&fl, 0, sizeof(fl));
9762 +       fl.fl_net = &init_net;
9763  
9764         if (np->sndflow) {
9765                 fl.fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
9766 diff -Nurb linux-2.6.22-try2/net/dccp/probe.c linux-2.6.22-try2-netns/net/dccp/probe.c
9767 --- linux-2.6.22-try2/net/dccp/probe.c  2007-12-19 13:37:57.000000000 -0500
9768 +++ linux-2.6.22-try2-netns/net/dccp/probe.c    2007-12-19 22:49:18.000000000 -0500
9769 @@ -30,6 +30,7 @@
9770  #include <linux/module.h>
9771  #include <linux/kfifo.h>
9772  #include <linux/vmalloc.h>
9773 +#include <net/net_namespace.h>
9774  
9775  #include "dccp.h"
9776  #include "ccid.h"
9777 @@ -168,7 +169,7 @@
9778         if (IS_ERR(dccpw.fifo))
9779                 return PTR_ERR(dccpw.fifo);
9780  
9781 -       if (!proc_net_fops_create(procname, S_IRUSR, &dccpprobe_fops))
9782 +       if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &dccpprobe_fops))
9783                 goto err0;
9784  
9785         ret = register_jprobe(&dccp_send_probe);
9786 @@ -178,7 +179,7 @@
9787         pr_info("DCCP watch registered (port=%d)\n", port);
9788         return 0;
9789  err1:
9790 -       proc_net_remove(procname);
9791 +       proc_net_remove(&init_net, procname);
9792  err0:
9793         kfifo_free(dccpw.fifo);
9794         return ret;
9795 @@ -188,7 +189,7 @@
9796  static __exit void dccpprobe_exit(void)
9797  {
9798         kfifo_free(dccpw.fifo);
9799 -       proc_net_remove(procname);
9800 +       proc_net_remove(&init_net, procname);
9801         unregister_jprobe(&dccp_send_probe);
9802  
9803  }
9804 diff -Nurb linux-2.6.22-try2/net/decnet/af_decnet.c linux-2.6.22-try2-netns/net/decnet/af_decnet.c
9805 --- linux-2.6.22-try2/net/decnet/af_decnet.c    2007-12-19 13:37:57.000000000 -0500
9806 +++ linux-2.6.22-try2-netns/net/decnet/af_decnet.c      2007-12-19 22:49:18.000000000 -0500
9807 @@ -131,6 +131,7 @@
9808  #include <net/neighbour.h>
9809  #include <net/dst.h>
9810  #include <net/fib_rules.h>
9811 +#include <net/net_namespace.h>
9812  #include <net/dn.h>
9813  #include <net/dn_nsp.h>
9814  #include <net/dn_dev.h>
9815 @@ -470,10 +471,10 @@
9816         .obj_size               = sizeof(struct dn_sock),
9817  };
9818  
9819 -static struct sock *dn_alloc_sock(struct socket *sock, gfp_t gfp)
9820 +static struct sock *dn_alloc_sock(struct net *net, struct socket *sock, gfp_t gfp)
9821  {
9822         struct dn_scp *scp;
9823 -       struct sock *sk = sk_alloc(PF_DECnet, gfp, &dn_proto, 1);
9824 +       struct sock *sk = sk_alloc(net, PF_DECnet, gfp, &dn_proto, 1);
9825  
9826         if  (!sk)
9827                 goto out;
9828 @@ -674,10 +675,13 @@
9829  
9830  
9831  
9832 -static int dn_create(struct socket *sock, int protocol)
9833 +static int dn_create(struct net *net, struct socket *sock, int protocol)
9834  {
9835         struct sock *sk;
9836  
9837 +       if (net != &init_net)
9838 +               return -EAFNOSUPPORT;
9839 +
9840         switch(sock->type) {
9841                 case SOCK_SEQPACKET:
9842                         if (protocol != DNPROTO_NSP)
9843 @@ -690,7 +694,7 @@
9844         }
9845  
9846  
9847 -       if ((sk = dn_alloc_sock(sock, GFP_KERNEL)) == NULL)
9848 +       if ((sk = dn_alloc_sock(net, sock, GFP_KERNEL)) == NULL)
9849                 return -ENOBUFS;
9850  
9851         sk->sk_protocol = protocol;
9852 @@ -747,7 +751,7 @@
9853                 if (dn_ntohs(saddr->sdn_nodeaddrl)) {
9854                         read_lock(&dev_base_lock);
9855                         ldev = NULL;
9856 -                       for_each_netdev(dev) {
9857 +                       for_each_netdev(&init_net, dev) {
9858                                 if (!dev->dn_ptr)
9859                                         continue;
9860                                 if (dn_dev_islocal(dev, dn_saddr2dn(saddr))) {
9861 @@ -943,6 +947,7 @@
9862  
9863         err = -EHOSTUNREACH;
9864         memset(&fl, 0, sizeof(fl));
9865 +       fl.fl_net = &init_net;
9866         fl.oif = sk->sk_bound_dev_if;
9867         fl.fld_dst = dn_saddr2dn(&scp->peer);
9868         fl.fld_src = dn_saddr2dn(&scp->addr);
9869 @@ -1090,7 +1095,7 @@
9870  
9871         cb = DN_SKB_CB(skb);
9872         sk->sk_ack_backlog--;
9873 -       newsk = dn_alloc_sock(newsock, sk->sk_allocation);
9874 +       newsk = dn_alloc_sock(sk->sk_net, newsock, sk->sk_allocation);
9875         if (newsk == NULL) {
9876                 release_sock(sk);
9877                 kfree_skb(skb);
9878 @@ -2085,6 +2090,9 @@
9879  {
9880         struct net_device *dev = (struct net_device *)ptr;
9881  
9882 +       if (dev->nd_net != &init_net)
9883 +               return NOTIFY_DONE;
9884 +
9885         switch(event) {
9886                 case NETDEV_UP:
9887                         dn_dev_up(dev);
9888 @@ -2399,7 +2407,7 @@
9889         dev_add_pack(&dn_dix_packet_type);
9890         register_netdevice_notifier(&dn_dev_notifier);
9891  
9892 -       proc_net_fops_create("decnet", S_IRUGO, &dn_socket_seq_fops);
9893 +       proc_net_fops_create(&init_net, "decnet", S_IRUGO, &dn_socket_seq_fops);
9894         dn_register_sysctl();
9895  out:
9896         return rc;
9897 @@ -2428,7 +2436,7 @@
9898         dn_neigh_cleanup();
9899         dn_fib_cleanup();
9900  
9901 -       proc_net_remove("decnet");
9902 +       proc_net_remove(&init_net, "decnet");
9903  
9904         proto_unregister(&dn_proto);
9905  }
9906 diff -Nurb linux-2.6.22-try2/net/decnet/dn_dev.c linux-2.6.22-try2-netns/net/decnet/dn_dev.c
9907 --- linux-2.6.22-try2/net/decnet/dn_dev.c       2007-12-19 13:37:57.000000000 -0500
9908 +++ linux-2.6.22-try2-netns/net/decnet/dn_dev.c 2007-12-19 22:49:18.000000000 -0500
9909 @@ -47,6 +47,7 @@
9910  #include <net/flow.h>
9911  #include <net/fib_rules.h>
9912  #include <net/netlink.h>
9913 +#include <net/net_namespace.h>
9914  #include <net/dn.h>
9915  #include <net/dn_dev.h>
9916  #include <net/dn_route.h>
9917 @@ -513,7 +514,7 @@
9918         ifr->ifr_name[IFNAMSIZ-1] = 0;
9919  
9920  #ifdef CONFIG_KMOD
9921 -       dev_load(ifr->ifr_name);
9922 +       dev_load(&init_net, ifr->ifr_name);
9923  #endif
9924  
9925         switch(cmd) {
9926 @@ -531,7 +532,7 @@
9927  
9928         rtnl_lock();
9929  
9930 -       if ((dev = __dev_get_by_name(ifr->ifr_name)) == NULL) {
9931 +       if ((dev = __dev_get_by_name(&init_net, ifr->ifr_name)) == NULL) {
9932                 ret = -ENODEV;
9933                 goto done;
9934         }
9935 @@ -629,7 +630,7 @@
9936  {
9937         struct net_device *dev;
9938         struct dn_dev *dn_dev = NULL;
9939 -       dev = dev_get_by_index(ifindex);
9940 +       dev = dev_get_by_index(&init_net, ifindex);
9941         if (dev) {
9942                 dn_dev = dev->dn_ptr;
9943                 dev_put(dev);
9944 @@ -647,12 +648,16 @@
9945  
9946  static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
9947  {
9948 +       struct net *net = skb->sk->sk_net;
9949         struct nlattr *tb[IFA_MAX+1];
9950         struct dn_dev *dn_db;
9951         struct ifaddrmsg *ifm;
9952         struct dn_ifaddr *ifa, **ifap;
9953         int err = -EADDRNOTAVAIL;
9954  
9955 +       if (net != &init_net)
9956 +               goto errout;
9957 +
9958         err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy);
9959         if (err < 0)
9960                 goto errout;
9961 @@ -679,6 +684,7 @@
9962  
9963  static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
9964  {
9965 +       struct net *net = skb->sk->sk_net;
9966         struct nlattr *tb[IFA_MAX+1];
9967         struct net_device *dev;
9968         struct dn_dev *dn_db;
9969 @@ -686,6 +692,9 @@
9970         struct dn_ifaddr *ifa;
9971         int err;
9972  
9973 +       if (net != &init_net)
9974 +               return -EINVAL;
9975 +
9976         err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy);
9977         if (err < 0)
9978                 return err;
9979 @@ -694,7 +703,7 @@
9980                 return -EINVAL;
9981  
9982         ifm = nlmsg_data(nlh);
9983 -       if ((dev = __dev_get_by_index(ifm->ifa_index)) == NULL)
9984 +       if ((dev = __dev_get_by_index(&init_net, ifm->ifa_index)) == NULL)
9985                 return -ENODEV;
9986  
9987         if ((dn_db = dev->dn_ptr) == NULL) {
9988 @@ -783,24 +792,28 @@
9989                 kfree_skb(skb);
9990                 goto errout;
9991         }
9992 -       err = rtnl_notify(skb, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL);
9993 +       err = rtnl_notify(skb, &init_net, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL);
9994  errout:
9995         if (err < 0)
9996 -               rtnl_set_sk_err(RTNLGRP_DECnet_IFADDR, err);
9997 +               rtnl_set_sk_err(&init_net, RTNLGRP_DECnet_IFADDR, err);
9998  }
9999  
10000  static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
10001  {
10002 +       struct net *net = skb->sk->sk_net;
10003         int idx, dn_idx = 0, skip_ndevs, skip_naddr;
10004         struct net_device *dev;
10005         struct dn_dev *dn_db;
10006         struct dn_ifaddr *ifa;
10007  
10008 +       if (net != &init_net)
10009 +               return 0;
10010 +
10011         skip_ndevs = cb->args[0];
10012         skip_naddr = cb->args[1];
10013  
10014         idx = 0;
10015 -       for_each_netdev(dev) {
10016 +       for_each_netdev(&init_net, dev) {
10017                 if (idx < skip_ndevs)
10018                         goto cont;
10019                 else if (idx > skip_ndevs) {
10020 @@ -869,10 +882,10 @@
10021                 rv = dn_dev_get_first(dev, addr);
10022                 read_unlock(&dev_base_lock);
10023                 dev_put(dev);
10024 -               if (rv == 0 || dev == &loopback_dev)
10025 +               if (rv == 0 || dev == &init_net.loopback_dev)
10026                         return rv;
10027         }
10028 -       dev = &loopback_dev;
10029 +       dev = &init_net.loopback_dev;
10030         dev_hold(dev);
10031         goto last_chance;
10032  }
10033 @@ -1299,7 +1312,7 @@
10034         struct net_device *dev;
10035  
10036         rtnl_lock();
10037 -       for_each_netdev(dev)
10038 +       for_each_netdev(&init_net, dev)
10039                 dn_dev_down(dev);
10040         rtnl_unlock();
10041  
10042 @@ -1310,7 +1323,7 @@
10043         struct net_device *dev;
10044  
10045         rtnl_lock();
10046 -       for_each_netdev(dev) {
10047 +       for_each_netdev(&init_net, dev) {
10048                 if (dev->flags & IFF_UP)
10049                         dn_dev_up(dev);
10050         }
10051 @@ -1344,7 +1357,7 @@
10052                 return SEQ_START_TOKEN;
10053  
10054         i = 1;
10055 -       for_each_netdev(dev) {
10056 +       for_each_netdev(&init_net, dev) {
10057                 if (!is_dn_dev(dev))
10058                         continue;
10059  
10060 @@ -1363,9 +1376,9 @@
10061  
10062         dev = (struct net_device *)v;
10063         if (v == SEQ_START_TOKEN)
10064 -               dev = net_device_entry(&dev_base_head);
10065 +               dev = net_device_entry(&init_net.dev_base_head);
10066  
10067 -       for_each_netdev_continue(dev) {
10068 +       for_each_netdev_continue(&init_net, dev) {
10069                 if (!is_dn_dev(dev))
10070                         continue;
10071  
10072 @@ -1465,7 +1478,7 @@
10073         rtnl_register(PF_DECnet, RTM_DELADDR, dn_nl_deladdr, NULL);
10074         rtnl_register(PF_DECnet, RTM_GETADDR, NULL, dn_nl_dump_ifaddr);
10075  
10076 -       proc_net_fops_create("decnet_dev", S_IRUGO, &dn_dev_seq_fops);
10077 +       proc_net_fops_create(&init_net, "decnet_dev", S_IRUGO, &dn_dev_seq_fops);
10078  
10079  #ifdef CONFIG_SYSCTL
10080         {
10081 @@ -1486,7 +1499,7 @@
10082         }
10083  #endif /* CONFIG_SYSCTL */
10084  
10085 -       proc_net_remove("decnet_dev");
10086 +       proc_net_remove(&init_net, "decnet_dev");
10087  
10088         dn_dev_devices_off();
10089  }
10090 diff -Nurb linux-2.6.22-try2/net/decnet/dn_fib.c linux-2.6.22-try2-netns/net/decnet/dn_fib.c
10091 --- linux-2.6.22-try2/net/decnet/dn_fib.c       2007-12-19 13:37:57.000000000 -0500
10092 +++ linux-2.6.22-try2-netns/net/decnet/dn_fib.c 2007-12-19 22:49:18.000000000 -0500
10093 @@ -203,8 +203,6 @@
10094                 struct flowi fl;
10095                 struct dn_fib_res res;
10096  
10097 -               memset(&fl, 0, sizeof(fl));
10098 -
10099                 if (nh->nh_flags&RTNH_F_ONLINK) {
10100                         struct net_device *dev;
10101  
10102 @@ -212,7 +210,7 @@
10103                                 return -EINVAL;
10104                         if (dnet_addr_type(nh->nh_gw) != RTN_UNICAST)
10105                                 return -EINVAL;
10106 -                       if ((dev = __dev_get_by_index(nh->nh_oif)) == NULL)
10107 +                       if ((dev = __dev_get_by_index(&init_net, nh->nh_oif)) == NULL)
10108                                 return -ENODEV;
10109                         if (!(dev->flags&IFF_UP))
10110                                 return -ENETDOWN;
10111 @@ -223,6 +221,7 @@
10112                 }
10113  
10114                 memset(&fl, 0, sizeof(fl));
10115 +               fl.fl_net = &init_net;
10116                 fl.fld_dst = nh->nh_gw;
10117                 fl.oif = nh->nh_oif;
10118                 fl.fld_scope = r->rtm_scope + 1;
10119 @@ -255,7 +254,7 @@
10120                 if (nh->nh_flags&(RTNH_F_PERVASIVE|RTNH_F_ONLINK))
10121                         return -EINVAL;
10122  
10123 -               dev = __dev_get_by_index(nh->nh_oif);
10124 +               dev = __dev_get_by_index(&init_net, nh->nh_oif);
10125                 if (dev == NULL || dev->dn_ptr == NULL)
10126                         return -ENODEV;
10127                 if (!(dev->flags&IFF_UP))
10128 @@ -355,7 +354,7 @@
10129                 if (nhs != 1 || nh->nh_gw)
10130                         goto err_inval;
10131                 nh->nh_scope = RT_SCOPE_NOWHERE;
10132 -               nh->nh_dev = dev_get_by_index(fi->fib_nh->nh_oif);
10133 +               nh->nh_dev = dev_get_by_index(&init_net, fi->fib_nh->nh_oif);
10134                 err = -ENODEV;
10135                 if (nh->nh_dev == NULL)
10136                         goto failure;
10137 @@ -506,10 +505,14 @@
10138  
10139  static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
10140  {
10141 +       struct net *net = skb->sk->sk_net;
10142         struct dn_fib_table *tb;
10143         struct rtattr **rta = arg;
10144         struct rtmsg *r = NLMSG_DATA(nlh);
10145  
10146 +       if (net != &init_net)
10147 +               return -EINVAL;
10148 +
10149         if (dn_fib_check_attr(r, rta))
10150                 return -EINVAL;
10151  
10152 @@ -522,10 +525,14 @@
10153  
10154  static int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
10155  {
10156 +       struct net *net = skb->sk->sk_net;
10157         struct dn_fib_table *tb;
10158         struct rtattr **rta = arg;
10159         struct rtmsg *r = NLMSG_DATA(nlh);
10160  
10161 +       if (net != &init_net)
10162 +               return -EINVAL;
10163 +
10164         if (dn_fib_check_attr(r, rta))
10165                 return -EINVAL;
10166  
10167 @@ -602,7 +609,7 @@
10168  
10169         /* Scan device list */
10170         read_lock(&dev_base_lock);
10171 -       for_each_netdev(dev) {
10172 +       for_each_netdev(&init_net, dev) {
10173                 dn_db = dev->dn_ptr;
10174                 if (dn_db == NULL)
10175                         continue;
10176 diff -Nurb linux-2.6.22-try2/net/decnet/dn_neigh.c linux-2.6.22-try2-netns/net/decnet/dn_neigh.c
10177 --- linux-2.6.22-try2/net/decnet/dn_neigh.c     2007-12-19 13:37:57.000000000 -0500
10178 +++ linux-2.6.22-try2-netns/net/decnet/dn_neigh.c       2007-12-19 22:49:18.000000000 -0500
10179 @@ -38,6 +38,7 @@
10180  #include <linux/rcupdate.h>
10181  #include <linux/jhash.h>
10182  #include <asm/atomic.h>
10183 +#include <net/net_namespace.h>
10184  #include <net/neighbour.h>
10185  #include <net/dst.h>
10186  #include <net/flow.h>
10187 @@ -591,6 +592,7 @@
10188  
10189         seq          = file->private_data;
10190         seq->private = s;
10191 +       s->net = get_net(PROC_NET(inode));
10192  out:
10193         return rc;
10194  out_kfree:
10195 @@ -598,12 +600,20 @@
10196         goto out;
10197  }
10198  
10199 +static int dn_neigh_seq_release(struct inode *inode, struct file *file)
10200 +{
10201 +       struct seq_file *seq = file->private_data;
10202 +       struct neigh_seq_state *state = seq->private;
10203 +       put_net(state->net);
10204 +       return seq_release_private(inode, file);
10205 +}
10206 +
10207  static const struct file_operations dn_neigh_seq_fops = {
10208         .owner          = THIS_MODULE,
10209         .open           = dn_neigh_seq_open,
10210         .read           = seq_read,
10211         .llseek         = seq_lseek,
10212 -       .release        = seq_release_private,
10213 +       .release        = dn_neigh_seq_release,
10214  };
10215  
10216  #endif
10217 @@ -611,11 +621,11 @@
10218  void __init dn_neigh_init(void)
10219  {
10220         neigh_table_init(&dn_neigh_table);
10221 -       proc_net_fops_create("decnet_neigh", S_IRUGO, &dn_neigh_seq_fops);
10222 +       proc_net_fops_create(&init_net, "decnet_neigh", S_IRUGO, &dn_neigh_seq_fops);
10223  }
10224  
10225  void __exit dn_neigh_cleanup(void)
10226  {
10227 -       proc_net_remove("decnet_neigh");
10228 +       proc_net_remove(&init_net, "decnet_neigh");
10229         neigh_table_clear(&dn_neigh_table);
10230  }
10231 diff -Nurb linux-2.6.22-try2/net/decnet/dn_nsp_out.c linux-2.6.22-try2-netns/net/decnet/dn_nsp_out.c
10232 --- linux-2.6.22-try2/net/decnet/dn_nsp_out.c   2007-12-19 13:37:57.000000000 -0500
10233 +++ linux-2.6.22-try2-netns/net/decnet/dn_nsp_out.c     2007-12-19 22:49:18.000000000 -0500
10234 @@ -91,6 +91,7 @@
10235         }
10236  
10237         memset(&fl, 0, sizeof(fl));
10238 +       fl.fl_net = &init_net;
10239         fl.oif = sk->sk_bound_dev_if;
10240         fl.fld_src = dn_saddr2dn(&scp->addr);
10241         fl.fld_dst = dn_saddr2dn(&scp->peer);
10242 diff -Nurb linux-2.6.22-try2/net/decnet/dn_route.c linux-2.6.22-try2-netns/net/decnet/dn_route.c
10243 --- linux-2.6.22-try2/net/decnet/dn_route.c     2007-12-19 13:37:57.000000000 -0500
10244 +++ linux-2.6.22-try2-netns/net/decnet/dn_route.c       2007-12-19 22:49:18.000000000 -0500
10245 @@ -82,6 +82,7 @@
10246  #include <net/dst.h>
10247  #include <net/flow.h>
10248  #include <net/fib_rules.h>
10249 +#include <net/net_namespace.h>
10250  #include <net/dn.h>
10251  #include <net/dn_dev.h>
10252  #include <net/dn_nsp.h>
10253 @@ -583,6 +584,9 @@
10254         struct dn_dev *dn = (struct dn_dev *)dev->dn_ptr;
10255         unsigned char padlen = 0;
10256  
10257 +       if (dev->nd_net != &init_net)
10258 +               goto dump_it;
10259 +
10260         if (dn == NULL)
10261                 goto dump_it;
10262  
10263 @@ -877,13 +881,14 @@
10264  
10265  static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *oldflp, int try_hard)
10266  {
10267 -       struct flowi fl = { .nl_u = { .dn_u =
10268 +       struct flowi fl = { .fl_net = &init_net,
10269 +                           .nl_u = { .dn_u =
10270                                       { .daddr = oldflp->fld_dst,
10271                                         .saddr = oldflp->fld_src,
10272                                         .scope = RT_SCOPE_UNIVERSE,
10273                                      } },
10274                             .mark = oldflp->mark,
10275 -                           .iif = loopback_dev.ifindex,
10276 +                           .iif = init_net.loopback_dev.ifindex,
10277                             .oif = oldflp->oif };
10278         struct dn_route *rt = NULL;
10279         struct net_device *dev_out = NULL, *dev;
10280 @@ -900,11 +905,11 @@
10281                        "dn_route_output_slow: dst=%04x src=%04x mark=%d"
10282                        " iif=%d oif=%d\n", dn_ntohs(oldflp->fld_dst),
10283                        dn_ntohs(oldflp->fld_src),
10284 -                      oldflp->mark, loopback_dev.ifindex, oldflp->oif);
10285 +                      oldflp->mark, init_net.loopback_dev.ifindex, oldflp->oif);
10286  
10287         /* If we have an output interface, verify its a DECnet device */
10288         if (oldflp->oif) {
10289 -               dev_out = dev_get_by_index(oldflp->oif);
10290 +               dev_out = dev_get_by_index(&init_net, oldflp->oif);
10291                 err = -ENODEV;
10292                 if (dev_out && dev_out->dn_ptr == NULL) {
10293                         dev_put(dev_out);
10294 @@ -925,7 +930,7 @@
10295                         goto out;
10296                 }
10297                 read_lock(&dev_base_lock);
10298 -               for_each_netdev(dev) {
10299 +               for_each_netdev(&init_net, dev) {
10300                         if (!dev->dn_ptr)
10301                                 continue;
10302                         if (!dn_dev_islocal(dev, oldflp->fld_src))
10303 @@ -953,7 +958,7 @@
10304                 err = -EADDRNOTAVAIL;
10305                 if (dev_out)
10306                         dev_put(dev_out);
10307 -               dev_out = &loopback_dev;
10308 +               dev_out = &init_net.loopback_dev;
10309                 dev_hold(dev_out);
10310                 if (!fl.fld_dst) {
10311                         fl.fld_dst =
10312 @@ -962,7 +967,7 @@
10313                         if (!fl.fld_dst)
10314                                 goto out;
10315                 }
10316 -               fl.oif = loopback_dev.ifindex;
10317 +               fl.oif = init_net.loopback_dev.ifindex;
10318                 res.type = RTN_LOCAL;
10319                 goto make_route;
10320         }
10321 @@ -995,7 +1000,7 @@
10322                  * here
10323                  */
10324                 if (!try_hard) {
10325 -                       neigh = neigh_lookup_nodev(&dn_neigh_table, &fl.fld_dst);
10326 +                       neigh = neigh_lookup_nodev(&dn_neigh_table, &init_net, &fl.fld_dst);
10327                         if (neigh) {
10328                                 if ((oldflp->oif &&
10329                                     (neigh->dev->ifindex != oldflp->oif)) ||
10330 @@ -1008,7 +1013,7 @@
10331                                         if (dev_out)
10332                                                 dev_put(dev_out);
10333                                         if (dn_dev_islocal(neigh->dev, fl.fld_dst)) {
10334 -                                               dev_out = &loopback_dev;
10335 +                                               dev_out = &init_net.loopback_dev;
10336                                                 res.type = RTN_LOCAL;
10337                                         } else {
10338                                                 dev_out = neigh->dev;
10339 @@ -1029,7 +1034,7 @@
10340                 /* Possible improvement - check all devices for local addr */
10341                 if (dn_dev_islocal(dev_out, fl.fld_dst)) {
10342                         dev_put(dev_out);
10343 -                       dev_out = &loopback_dev;
10344 +                       dev_out = &init_net.loopback_dev;
10345                         dev_hold(dev_out);
10346                         res.type = RTN_LOCAL;
10347                         goto select_source;
10348 @@ -1065,7 +1070,7 @@
10349                         fl.fld_src = fl.fld_dst;
10350                 if (dev_out)
10351                         dev_put(dev_out);
10352 -               dev_out = &loopback_dev;
10353 +               dev_out = &init_net.loopback_dev;
10354                 dev_hold(dev_out);
10355                 fl.oif = dev_out->ifindex;
10356                 if (res.fi)
10357 @@ -1103,6 +1108,7 @@
10358         atomic_set(&rt->u.dst.__refcnt, 1);
10359         rt->u.dst.flags   = DST_HOST;
10360  
10361 +       rt->fl.fl_net     = &init_net;
10362         rt->fl.fld_src    = oldflp->fld_src;
10363         rt->fl.fld_dst    = oldflp->fld_dst;
10364         rt->fl.oif        = oldflp->oif;
10365 @@ -1226,7 +1232,8 @@
10366         int flags = 0;
10367         __le16 gateway = 0;
10368         __le16 local_src = 0;
10369 -       struct flowi fl = { .nl_u = { .dn_u =
10370 +       struct flowi fl = { .fl_net = &init_net,
10371 +                           .nl_u = { .dn_u = 
10372                                      { .daddr = cb->dst,
10373                                        .saddr = cb->src,
10374                                        .scope = RT_SCOPE_UNIVERSE,
10375 @@ -1374,6 +1381,7 @@
10376         rt->rt_dst_map    = fl.fld_dst;
10377         rt->rt_src_map    = fl.fld_src;
10378  
10379 +       rt->fl.fl_net     = &init_net;
10380         rt->fl.fld_src    = cb->src;
10381         rt->fl.fld_dst    = cb->dst;
10382         rt->fl.oif        = 0;
10383 @@ -1526,6 +1534,7 @@
10384   */
10385  static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void *arg)
10386  {
10387 +       struct net *net = in_skb->sk->sk_net;
10388         struct rtattr **rta = arg;
10389         struct rtmsg *rtm = NLMSG_DATA(nlh);
10390         struct dn_route *rt = NULL;
10391 @@ -1534,7 +1543,11 @@
10392         struct sk_buff *skb;
10393         struct flowi fl;
10394  
10395 +       if (net != &init_net)
10396 +               return -EINVAL;
10397 +
10398         memset(&fl, 0, sizeof(fl));
10399 +       fl.fl_net = &init_net;
10400         fl.proto = DNPROTO_NSP;
10401  
10402         skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
10403 @@ -1552,7 +1565,7 @@
10404  
10405         if (fl.iif) {
10406                 struct net_device *dev;
10407 -               if ((dev = dev_get_by_index(fl.iif)) == NULL) {
10408 +               if ((dev = dev_get_by_index(&init_net, fl.iif)) == NULL) {
10409                         kfree_skb(skb);
10410                         return -ENODEV;
10411                 }
10412 @@ -1598,7 +1611,7 @@
10413                 goto out_free;
10414         }
10415  
10416 -       return rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
10417 +       return rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
10418  
10419  out_free:
10420         kfree_skb(skb);
10421 @@ -1611,10 +1624,14 @@
10422   */
10423  int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb)
10424  {
10425 +       struct net *net = skb->sk->sk_net;
10426         struct dn_route *rt;
10427         int h, s_h;
10428         int idx, s_idx;
10429  
10430 +       if (net != &init_net)
10431 +               return 0;
10432 +
10433         if (NLMSG_PAYLOAD(cb->nlh, 0) < sizeof(struct rtmsg))
10434                 return -EINVAL;
10435         if (!(((struct rtmsg *)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED))
10436 @@ -1814,7 +1831,7 @@
10437  
10438         dn_dst_ops.gc_thresh = (dn_rt_hash_mask + 1);
10439  
10440 -       proc_net_fops_create("decnet_cache", S_IRUGO, &dn_rt_cache_seq_fops);
10441 +       proc_net_fops_create(&init_net, "decnet_cache", S_IRUGO, &dn_rt_cache_seq_fops);
10442  
10443  #ifdef CONFIG_DECNET_ROUTER
10444         rtnl_register(PF_DECnet, RTM_GETROUTE, dn_cache_getroute, dn_fib_dump);
10445 @@ -1829,6 +1846,6 @@
10446         del_timer(&dn_route_timer);
10447         dn_run_flush(0);
10448  
10449 -       proc_net_remove("decnet_cache");
10450 +       proc_net_remove(&init_net, "decnet_cache");
10451  }
10452  
10453 diff -Nurb linux-2.6.22-try2/net/decnet/dn_rules.c linux-2.6.22-try2-netns/net/decnet/dn_rules.c
10454 --- linux-2.6.22-try2/net/decnet/dn_rules.c     2007-12-19 13:37:57.000000000 -0500
10455 +++ linux-2.6.22-try2-netns/net/decnet/dn_rules.c       2007-12-19 22:49:18.000000000 -0500
10456 @@ -186,7 +186,10 @@
10457  
10458  unsigned dnet_addr_type(__le16 addr)
10459  {
10460 -       struct flowi fl = { .nl_u = { .dn_u = { .daddr = addr } } };
10461 +       struct flowi fl = { 
10462 +               .fl_net = &init_net,
10463 +               .nl_u = { .dn_u = { .daddr = addr } } 
10464 +       };
10465         struct dn_fib_res res;
10466         unsigned ret = RTN_UNICAST;
10467         struct dn_fib_table *tb = dn_fib_get_table(RT_TABLE_LOCAL, 0);
10468 @@ -223,7 +226,7 @@
10469         return -ENOBUFS;
10470  }
10471  
10472 -static u32 dn_fib_rule_default_pref(void)
10473 +static u32 dn_fib_rule_default_pref(struct fib_rules_ops *ops)
10474  {
10475         struct list_head *pos;
10476         struct fib_rule *rule;
10477 @@ -240,7 +243,7 @@
10478         return 0;
10479  }
10480  
10481 -static void dn_fib_rule_flush_cache(void)
10482 +static void dn_fib_rule_flush_cache(struct fib_rules_ops *ops)
10483  {
10484         dn_rt_cache_flush(-1);
10485  }
10486 @@ -265,12 +268,12 @@
10487  void __init dn_fib_rules_init(void)
10488  {
10489         list_add_tail(&default_rule.common.list, &dn_fib_rules);
10490 -       fib_rules_register(&dn_fib_rules_ops);
10491 +       fib_rules_register(&init_net, &dn_fib_rules_ops);
10492  }
10493  
10494  void __exit dn_fib_rules_cleanup(void)
10495  {
10496 -       fib_rules_unregister(&dn_fib_rules_ops);
10497 +       fib_rules_unregister(&init_net, &dn_fib_rules_ops);
10498  }
10499  
10500  
10501 diff -Nurb linux-2.6.22-try2/net/decnet/dn_table.c linux-2.6.22-try2-netns/net/decnet/dn_table.c
10502 --- linux-2.6.22-try2/net/decnet/dn_table.c     2007-12-19 13:37:57.000000000 -0500
10503 +++ linux-2.6.22-try2-netns/net/decnet/dn_table.c       2007-12-19 22:49:18.000000000 -0500
10504 @@ -375,10 +375,10 @@
10505                 kfree_skb(skb);
10506                 goto errout;
10507         }
10508 -       err = rtnl_notify(skb, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL);
10509 +       err = rtnl_notify(skb, &init_net, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL);
10510  errout:
10511         if (err < 0)
10512 -               rtnl_set_sk_err(RTNLGRP_DECnet_ROUTE, err);
10513 +               rtnl_set_sk_err(&init_net, RTNLGRP_DECnet_ROUTE, err);
10514  }
10515  
10516  static __inline__ int dn_hash_dump_bucket(struct sk_buff *skb,
10517 @@ -463,12 +463,16 @@
10518  
10519  int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb)
10520  {
10521 +       struct net *net = skb->sk->sk_net;
10522         unsigned int h, s_h;
10523         unsigned int e = 0, s_e;
10524         struct dn_fib_table *tb;
10525         struct hlist_node *node;
10526         int dumped = 0;
10527  
10528 +       if (net != &init_net)
10529 +               return 0;
10530 +
10531         if (NLMSG_PAYLOAD(cb->nlh, 0) >= sizeof(struct rtmsg) &&
10532                 ((struct rtmsg *)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED)
10533                         return dn_cache_dump(skb, cb);
10534 diff -Nurb linux-2.6.22-try2/net/decnet/netfilter/dn_rtmsg.c linux-2.6.22-try2-netns/net/decnet/netfilter/dn_rtmsg.c
10535 --- linux-2.6.22-try2/net/decnet/netfilter/dn_rtmsg.c   2007-12-19 13:37:57.000000000 -0500
10536 +++ linux-2.6.22-try2-netns/net/decnet/netfilter/dn_rtmsg.c     2007-12-19 22:49:18.000000000 -0500
10537 @@ -93,6 +93,10 @@
10538                         const struct net_device *out,
10539                         int (*okfn)(struct sk_buff *))
10540  {
10541 +       /* Only filter packets in the initial network namespace */
10542 +       if ((in?in:out)->nd_net != &init_net)
10543 +               return NF_ACCEPT;
10544 +
10545         dnrmg_send_peer(*pskb);
10546         return NF_ACCEPT;
10547  }
10548 @@ -137,7 +141,8 @@
10549  {
10550         int rv = 0;
10551  
10552 -       dnrmg = netlink_kernel_create(NETLINK_DNRTMSG, DNRNG_NLGRP_MAX,
10553 +       dnrmg = netlink_kernel_create(&init_net,
10554 +                                     NETLINK_DNRTMSG, DNRNG_NLGRP_MAX,
10555                                       dnrmg_receive_user_sk, NULL, THIS_MODULE);
10556         if (dnrmg == NULL) {
10557                 printk(KERN_ERR "dn_rtmsg: Cannot create netlink socket");
10558 diff -Nurb linux-2.6.22-try2/net/decnet/sysctl_net_decnet.c linux-2.6.22-try2-netns/net/decnet/sysctl_net_decnet.c
10559 --- linux-2.6.22-try2/net/decnet/sysctl_net_decnet.c    2007-12-19 13:37:57.000000000 -0500
10560 +++ linux-2.6.22-try2-netns/net/decnet/sysctl_net_decnet.c      2007-12-19 22:49:18.000000000 -0500
10561 @@ -259,7 +259,7 @@
10562  
10563                 devname[newlen] = 0;
10564  
10565 -               dev = dev_get_by_name(devname);
10566 +               dev = dev_get_by_name(&init_net, devname);
10567                 if (dev == NULL)
10568                         return -ENODEV;
10569  
10570 @@ -299,7 +299,7 @@
10571                 devname[*lenp] = 0;
10572                 strip_it(devname);
10573  
10574 -               dev = dev_get_by_name(devname);
10575 +               dev = dev_get_by_name(&init_net, devname);
10576                 if (dev == NULL)
10577                         return -ENODEV;
10578  
10579 diff -Nurb linux-2.6.22-try2/net/econet/af_econet.c linux-2.6.22-try2-netns/net/econet/af_econet.c
10580 --- linux-2.6.22-try2/net/econet/af_econet.c    2007-12-19 13:37:57.000000000 -0500
10581 +++ linux-2.6.22-try2-netns/net/econet/af_econet.c      2007-12-19 22:49:18.000000000 -0500
10582 @@ -608,12 +608,15 @@
10583   *     Create an Econet socket
10584   */
10585  
10586 -static int econet_create(struct socket *sock, int protocol)
10587 +static int econet_create(struct net *net, struct socket *sock, int protocol)
10588  {
10589         struct sock *sk;
10590         struct econet_sock *eo;
10591         int err;
10592  
10593 +       if (net != &init_net)
10594 +               return -EAFNOSUPPORT;
10595 +
10596         /* Econet only provides datagram services. */
10597         if (sock->type != SOCK_DGRAM)
10598                 return -ESOCKTNOSUPPORT;
10599 @@ -621,7 +624,7 @@
10600         sock->state = SS_UNCONNECTED;
10601  
10602         err = -ENOBUFS;
10603 -       sk = sk_alloc(PF_ECONET, GFP_KERNEL, &econet_proto, 1);
10604 +       sk = sk_alloc(net, PF_ECONET, GFP_KERNEL, &econet_proto, 1);
10605         if (sk == NULL)
10606                 goto out;
10607  
10608 @@ -659,7 +662,7 @@
10609         if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
10610                 return -EFAULT;
10611  
10612 -       if ((dev = dev_get_by_name(ifr.ifr_name)) == NULL)
10613 +       if ((dev = dev_get_by_name(&init_net, ifr.ifr_name)) == NULL)
10614                 return -ENODEV;
10615  
10616         sec = (struct sockaddr_ec *)&ifr.ifr_addr;
10617 @@ -1062,6 +1065,9 @@
10618         struct sock *sk;
10619         struct ec_device *edev = dev->ec_ptr;
10620  
10621 +       if (dev->nd_net != &init_net)
10622 +               goto drop;
10623 +
10624         if (skb->pkt_type == PACKET_OTHERHOST)
10625                 goto drop;
10626  
10627 @@ -1116,6 +1122,9 @@
10628         struct net_device *dev = (struct net_device *)data;
10629         struct ec_device *edev;
10630  
10631 +       if (dev->nd_net != &init_net)
10632 +               return NOTIFY_DONE;
10633 +
10634         switch (msg) {
10635         case NETDEV_UNREGISTER:
10636                 /* A device has gone down - kill any data we hold for it. */
10637 diff -Nurb linux-2.6.22-try2/net/ieee80211/ieee80211_module.c linux-2.6.22-try2-netns/net/ieee80211/ieee80211_module.c
10638 --- linux-2.6.22-try2/net/ieee80211/ieee80211_module.c  2007-12-19 13:37:57.000000000 -0500
10639 +++ linux-2.6.22-try2-netns/net/ieee80211/ieee80211_module.c    2007-12-19 22:49:18.000000000 -0500
10640 @@ -264,7 +264,7 @@
10641         struct proc_dir_entry *e;
10642  
10643         ieee80211_debug_level = debug;
10644 -       ieee80211_proc = proc_mkdir(DRV_NAME, proc_net);
10645 +       ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net);
10646         if (ieee80211_proc == NULL) {
10647                 IEEE80211_ERROR("Unable to create " DRV_NAME
10648                                 " proc directory\n");
10649 @@ -273,7 +273,7 @@
10650         e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
10651                               ieee80211_proc);
10652         if (!e) {
10653 -               remove_proc_entry(DRV_NAME, proc_net);
10654 +               remove_proc_entry(DRV_NAME, init_net.proc_net);
10655                 ieee80211_proc = NULL;
10656                 return -EIO;
10657         }
10658 @@ -293,7 +293,7 @@
10659  #ifdef CONFIG_IEEE80211_DEBUG
10660         if (ieee80211_proc) {
10661                 remove_proc_entry("debug_level", ieee80211_proc);
10662 -               remove_proc_entry(DRV_NAME, proc_net);
10663 +               remove_proc_entry(DRV_NAME, init_net.proc_net);
10664                 ieee80211_proc = NULL;
10665         }
10666  #endif                         /* CONFIG_IEEE80211_DEBUG */
10667 diff -Nurb linux-2.6.22-try2/net/ipv4/af_inet.c linux-2.6.22-try2-netns/net/ipv4/af_inet.c
10668 --- linux-2.6.22-try2/net/ipv4/af_inet.c        2007-12-19 15:29:23.000000000 -0500
10669 +++ linux-2.6.22-try2-netns/net/ipv4/af_inet.c  2007-12-19 23:20:19.000000000 -0500
10670 @@ -244,7 +244,7 @@
10671   *     Create an inet socket.
10672   */
10673  
10674 -static int inet_create(struct socket *sock, int protocol)
10675 +static int inet_create(struct net *net, struct socket *sock, int protocol)
10676  {
10677         struct sock *sk;
10678         struct list_head *p;
10679 @@ -310,6 +310,10 @@
10680                         goto out_rcu_unlock;
10681         }
10682  
10683 +       err = -EPROTONOSUPPORT;
10684 +       if (!(answer->flags & INET_PROTOSW_NETNS) && (net != &init_net))
10685 +               goto out_rcu_unlock;
10686 +
10687         err = -EPERM;
10688         if ((protocol == IPPROTO_ICMP) &&
10689                 nx_capable(answer->capability, NXC_RAW_ICMP))
10690 @@ -326,7 +330,7 @@
10691         BUG_TRAP(answer_prot->slab != NULL);
10692  
10693         err = -ENOBUFS;
10694 -       sk = sk_alloc(PF_INET, GFP_KERNEL, answer_prot, 1);
10695 +       sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot, 1);
10696         if (sk == NULL)
10697                 goto out;
10698  
10699 @@ -344,7 +348,7 @@
10700                         inet->hdrincl = 1;
10701         }
10702  
10703 -       if (ipv4_config.no_pmtu_disc)
10704 +       if (net->sysctl_ipv4_no_pmtu_disc)
10705                 inet->pmtudisc = IP_PMTUDISC_DONT;
10706         else
10707                 inet->pmtudisc = IP_PMTUDISC_WANT;
10708 @@ -423,12 +427,12 @@
10709  }
10710  
10711  /* It is off by default, see below. */
10712 -int sysctl_ip_nonlocal_bind __read_mostly;
10713  
10714  int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
10715  {
10716         struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
10717         struct sock *sk = sock->sk;
10718 +       struct net *net = sk->sk_net;
10719         struct inet_sock *inet = inet_sk(sk);
10720         struct nx_v4_sock_addr nsa;
10721         unsigned short snum;
10722 @@ -448,7 +452,7 @@
10723         if (err)
10724                 goto out;
10725  
10726 -       chk_addr_ret = inet_addr_type(nsa.saddr);
10727 +       chk_addr_ret = inet_addr_type(net, nsa.saddr);
10728  
10729         /* Not specified by any standard per-se, however it breaks too
10730          * many applications when removed.  It is unfortunate since
10731 @@ -458,7 +462,7 @@
10732          *  is temporarily down)
10733          */
10734         err = -EADDRNOTAVAIL;
10735 -       if (!sysctl_ip_nonlocal_bind &&
10736 +       if (!net->sysctl_ip_nonlocal_bind &&
10737             !inet->freebind &&
10738             nsa.saddr != INADDR_ANY &&
10739             chk_addr_ret != RTN_LOCAL &&
10740 @@ -787,6 +791,7 @@
10741  int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
10742  {
10743         struct sock *sk = sock->sk;
10744 +       struct net *net = sk->sk_net;
10745         int err = 0;
10746  
10747         switch (cmd) {
10748 @@ -799,12 +804,12 @@
10749                 case SIOCADDRT:
10750                 case SIOCDELRT:
10751                 case SIOCRTMSG:
10752 -                       err = ip_rt_ioctl(cmd, (void __user *)arg);
10753 +                       err = ip_rt_ioctl(net, cmd, (void __user *)arg);
10754                         break;
10755                 case SIOCDARP:
10756                 case SIOCGARP:
10757                 case SIOCSARP:
10758 -                       err = arp_ioctl(cmd, (void __user *)arg);
10759 +                       err = arp_ioctl(net, cmd, (void __user *)arg);
10760                         break;
10761                 case SIOCGIFADDR:
10762                 case SIOCSIFADDR:
10763 @@ -817,7 +822,7 @@
10764                 case SIOCSIFPFLAGS:
10765                 case SIOCGIFPFLAGS:
10766                 case SIOCSIFFLAGS:
10767 -                       err = devinet_ioctl(cmd, (void __user *)arg);
10768 +                       err = devinet_ioctl(net, cmd, (void __user *)arg);
10769                         break;
10770                 default:
10771                         if (sk->sk_prot->ioctl)
10772 @@ -927,7 +932,8 @@
10773                 .capability = -1,
10774                 .no_check =   0,
10775                 .flags =      INET_PROTOSW_PERMANENT |
10776 -                             INET_PROTOSW_ICSK,
10777 +                             INET_PROTOSW_ICSK |
10778 +                             INET_PROTOSW_NETNS,
10779         },
10780  
10781         {
10782 @@ -937,7 +943,8 @@
10783                 .ops =        &inet_dgram_ops,
10784                 .capability = -1,
10785                 .no_check =   UDP_CSUM_DEFAULT,
10786 -               .flags =      INET_PROTOSW_PERMANENT,
10787 +               .flags =      INET_PROTOSW_PERMANENT |
10788 +                             INET_PROTOSW_NETNS,
10789         },
10790  
10791  
10792 @@ -948,7 +955,8 @@
10793                .ops =        &inet_sockraw_ops,
10794                .capability = CAP_NET_RAW,
10795                .no_check =   UDP_CSUM_DEFAULT,
10796 -              .flags =      INET_PROTOSW_REUSE,
10797 +              .flags =      INET_PROTOSW_REUSE |
10798 +                            INET_PROTOSW_NETNS,
10799         }
10800  };
10801  
10802 @@ -1029,8 +1037,6 @@
10803   *      Shall we try to damage output packets if routing dev changes?
10804   */
10805  
10806 -int sysctl_ip_dynaddr __read_mostly;
10807 -
10808  static int inet_sk_reselect_saddr(struct sock *sk)
10809  {
10810         struct inet_sock *inet = inet_sk(sk);
10811 @@ -1059,7 +1065,7 @@
10812         if (new_saddr == old_saddr)
10813                 return 0;
10814  
10815 -       if (sysctl_ip_dynaddr > 1) {
10816 +       if (sk->sk_net->sysctl_ip_dynaddr > 1) {
10817                 printk(KERN_INFO "%s(): shifting inet->"
10818                                  "saddr from %d.%d.%d.%d to %d.%d.%d.%d\n",
10819                        __FUNCTION__,
10820 @@ -1098,6 +1104,7 @@
10821                 daddr = inet->opt->faddr;
10822  {
10823         struct flowi fl = {
10824 +               .fl_net = sk->sk_net,
10825                 .oif = sk->sk_bound_dev_if,
10826                 .nl_u = {
10827                         .ip4_u = {
10828 @@ -1127,7 +1134,7 @@
10829                  * Other protocols have to map its equivalent state to TCP_SYN_SENT.
10830                  * DCCP maps its DCCP_REQUESTING state to TCP_SYN_SENT. -acme
10831                  */
10832 -               if (!sysctl_ip_dynaddr ||
10833 +               if (!sk->sk_net->sysctl_ip_dynaddr ||
10834                     sk->sk_state != TCP_SYN_SENT ||
10835                     (sk->sk_userlocks & SOCK_BINDADDR_LOCK) ||
10836                     (err = inet_sk_reselect_saddr(sk)) != 0)
10837 @@ -1356,6 +1363,24 @@
10838         .gso_segment = inet_gso_segment,
10839  };
10840  
10841 +
10842 +static int inet_net_init(struct net *net)
10843 +{
10844 +       net->sysctl_ip_default_ttl = IPDEFTTL;
10845 +       net->sysctl_ip_dynaddr = 0;
10846 +
10847 +       return 0;
10848 +}
10849 +
10850 +static void inet_net_exit(struct net *net)
10851 +{
10852 +}
10853 +
10854 +static struct pernet_operations inet_net_ops = {
10855 +       .init = inet_net_init,
10856 +       .exit = inet_net_exit,
10857 +};
10858 +
10859  static int __init inet_init(void)
10860  {
10861         struct sk_buff *dummy_skb;
10862 @@ -1377,6 +1402,10 @@
10863         if (rc)
10864                 goto out_unregister_udp_proto;
10865  
10866 +       rc = register_pernet_subsys(&inet_net_ops);
10867 +       if (rc)
10868 +               goto out_unregister_raw_proto;
10869 +
10870         /*
10871          *      Tell SOCKET that we are alive...
10872          */
10873 @@ -1453,6 +1482,8 @@
10874         rc = 0;
10875  out:
10876         return rc;
10877 +out_unregister_raw_proto:
10878 +       proto_unregister(&raw_prot);
10879  out_unregister_udp_proto:
10880         proto_unregister(&udp_prot);
10881  out_unregister_tcp_proto:
10882 @@ -1475,15 +1506,11 @@
10883                 goto out_tcp;
10884         if (udp4_proc_init())
10885                 goto out_udp;
10886 -       if (fib_proc_init())
10887 -               goto out_fib;
10888         if (ip_misc_proc_init())
10889                 goto out_misc;
10890  out:
10891         return rc;
10892  out_misc:
10893 -       fib_proc_exit();
10894 -out_fib:
10895         udp4_proc_exit();
10896  out_udp:
10897         tcp4_proc_exit();
10898 @@ -1519,4 +1546,3 @@
10899  EXPORT_SYMBOL(inet_stream_ops);
10900  EXPORT_SYMBOL(inet_unregister_protosw);
10901  EXPORT_SYMBOL(net_statistics);
10902 -EXPORT_SYMBOL(sysctl_ip_nonlocal_bind);
10903 diff -Nurb linux-2.6.22-try2/net/ipv4/ah4.c linux-2.6.22-try2-netns/net/ipv4/ah4.c
10904 --- linux-2.6.22-try2/net/ipv4/ah4.c    2007-12-19 15:29:23.000000000 -0500
10905 +++ linux-2.6.22-try2-netns/net/ipv4/ah4.c      2007-12-19 22:49:18.000000000 -0500
10906 @@ -198,6 +198,9 @@
10907         struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+(iph->ihl<<2));
10908         struct xfrm_state *x;
10909  
10910 +       if (skb->dev->nd_net != &init_net)
10911 +               return;
10912 +
10913         if (icmp_hdr(skb)->type != ICMP_DEST_UNREACH ||
10914             icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
10915                 return;
10916 diff -Nurb linux-2.6.22-try2/net/ipv4/arp.c linux-2.6.22-try2-netns/net/ipv4/arp.c
10917 --- linux-2.6.22-try2/net/ipv4/arp.c    2007-12-19 13:37:57.000000000 -0500
10918 +++ linux-2.6.22-try2-netns/net/ipv4/arp.c      2007-12-19 22:49:18.000000000 -0500
10919 @@ -109,6 +109,7 @@
10920  #include <net/protocol.h>
10921  #include <net/tcp.h>
10922  #include <net/sock.h>
10923 +#include <net/net_namespace.h>
10924  #include <net/arp.h>
10925  #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
10926  #include <net/ax25.h>
10927 @@ -235,10 +236,11 @@
10928  {
10929         __be32 addr = *(__be32*)neigh->primary_key;
10930         struct net_device *dev = neigh->dev;
10931 +       struct net *net = dev->nd_net;
10932         struct in_device *in_dev;
10933         struct neigh_parms *parms;
10934  
10935 -       neigh->type = inet_addr_type(addr);
10936 +       neigh->type = inet_addr_type(net, addr);
10937  
10938         rcu_read_lock();
10939         in_dev = __in_dev_get_rcu(dev);
10940 @@ -332,6 +334,7 @@
10941         __be32 saddr = 0;
10942         u8  *dst_ha = NULL;
10943         struct net_device *dev = neigh->dev;
10944 +       struct net *net = dev->nd_net;
10945         __be32 target = *(__be32*)neigh->primary_key;
10946         int probes = atomic_read(&neigh->probes);
10947         struct in_device *in_dev = in_dev_get(dev);
10948 @@ -342,14 +345,14 @@
10949         switch (IN_DEV_ARP_ANNOUNCE(in_dev)) {
10950         default:
10951         case 0:         /* By default announce any local IP */
10952 -               if (skb && inet_addr_type(ip_hdr(skb)->saddr) == RTN_LOCAL)
10953 +               if (skb && inet_addr_type(net, ip_hdr(skb)->saddr) == RTN_LOCAL)
10954                         saddr = ip_hdr(skb)->saddr;
10955                 break;
10956         case 1:         /* Restrict announcements of saddr in same subnet */
10957                 if (!skb)
10958                         break;
10959                 saddr = ip_hdr(skb)->saddr;
10960 -               if (inet_addr_type(saddr) == RTN_LOCAL) {
10961 +               if (inet_addr_type(net, saddr) == RTN_LOCAL) {
10962                         /* saddr should be known to target */
10963                         if (inet_addr_onlink(in_dev, target, saddr))
10964                                 break;
10965 @@ -386,6 +389,7 @@
10966  static int arp_ignore(struct in_device *in_dev, struct net_device *dev,
10967                       __be32 sip, __be32 tip)
10968  {
10969 +       struct net *net = dev->nd_net;
10970         int scope;
10971  
10972         switch (IN_DEV_ARP_IGNORE(in_dev)) {
10973 @@ -416,13 +420,15 @@
10974         default:
10975                 return 0;
10976         }
10977 -       return !inet_confirm_addr(dev, sip, tip, scope);
10978 +       return !inet_confirm_addr(net, dev, sip, tip, scope);
10979  }
10980  
10981  static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev)
10982  {
10983 -       struct flowi fl = { .nl_u = { .ip4_u = { .daddr = sip,
10984 -                                                .saddr = tip } } };
10985 +       struct flowi fl = {
10986 +               .fl_net = dev->nd_net,
10987 +               .nl_u = { .ip4_u = { .daddr = sip, .saddr = tip } }
10988 +       };
10989         struct rtable *rt;
10990         int flag = 0;
10991         /*unsigned long now; */
10992 @@ -469,6 +475,7 @@
10993  int arp_find(unsigned char *haddr, struct sk_buff *skb)
10994  {
10995         struct net_device *dev = skb->dev;
10996 +       struct net *net = dev->nd_net;
10997         __be32 paddr;
10998         struct neighbour *n;
10999  
11000 @@ -480,7 +487,7 @@
11001  
11002         paddr = ((struct rtable*)skb->dst)->rt_gateway;
11003  
11004 -       if (arp_set_predefined(inet_addr_type(paddr), haddr, paddr, dev))
11005 +       if (arp_set_predefined(inet_addr_type(net, paddr), haddr, paddr, dev))
11006                 return 0;
11007  
11008         n = __neigh_lookup(&arp_tbl, &paddr, dev, 1);
11009 @@ -704,6 +711,7 @@
11010  static int arp_process(struct sk_buff *skb)
11011  {
11012         struct net_device *dev = skb->dev;
11013 +       struct net *net = dev->nd_net;
11014         struct in_device *in_dev = in_dev_get(dev);
11015         struct arphdr *arp;
11016         unsigned char *arp_ptr;
11017 @@ -824,7 +832,7 @@
11018         /* Special case: IPv4 duplicate address detection packet (RFC2131) */
11019         if (sip == 0) {
11020                 if (arp->ar_op == htons(ARPOP_REQUEST) &&
11021 -                   inet_addr_type(tip) == RTN_LOCAL &&
11022 +                   inet_addr_type(net, tip) == RTN_LOCAL &&
11023                     !arp_ignore(in_dev,dev,sip,tip))
11024                         arp_send(ARPOP_REPLY,ETH_P_ARP,tip,dev,tip,sha,dev->dev_addr,dev->dev_addr);
11025                 goto out;
11026 @@ -854,7 +862,7 @@
11027                 } else if (IN_DEV_FORWARD(in_dev)) {
11028                         if ((rt->rt_flags&RTCF_DNAT) ||
11029                             (addr_type == RTN_UNICAST  && rt->u.dst.dev != dev &&
11030 -                            (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, &tip, dev, 0)))) {
11031 +                            (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, net, &tip, dev, 0)))) {
11032                                 n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
11033                                 if (n)
11034                                         neigh_release(n);
11035 @@ -877,14 +885,14 @@
11036  
11037         n = __neigh_lookup(&arp_tbl, &sip, dev, 0);
11038  
11039 -       if (IPV4_DEVCONF_ALL(ARP_ACCEPT)) {
11040 +       if (IPV4_DEVCONF_ALL(net, ARP_ACCEPT)) {
11041                 /* Unsolicited ARP is not accepted by default.
11042                    It is possible, that this option should be enabled for some
11043                    devices (strip is candidate)
11044                  */
11045                 if (n == NULL &&
11046                     arp->ar_op == htons(ARPOP_REPLY) &&
11047 -                   inet_addr_type(sip) == RTN_UNICAST)
11048 +                   inet_addr_type(net, sip) == RTN_UNICAST)
11049                         n = __neigh_lookup(&arp_tbl, &sip, dev, -1);
11050         }
11051  
11052 @@ -966,7 +974,7 @@
11053   *     Set (create) an ARP cache entry.
11054   */
11055  
11056 -static int arp_req_set(struct arpreq *r, struct net_device * dev)
11057 +static int arp_req_set(struct net *net, struct arpreq *r, struct net_device * dev)
11058  {
11059         __be32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
11060         struct neighbour *neigh;
11061 @@ -977,17 +985,17 @@
11062                 if (mask && mask != htonl(0xFFFFFFFF))
11063                         return -EINVAL;
11064                 if (!dev && (r->arp_flags & ATF_COM)) {
11065 -                       dev = dev_getbyhwaddr(r->arp_ha.sa_family, r->arp_ha.sa_data);
11066 +                       dev = dev_getbyhwaddr(net, r->arp_ha.sa_family, r->arp_ha.sa_data);
11067                         if (!dev)
11068                                 return -ENODEV;
11069                 }
11070                 if (mask) {
11071 -                       if (pneigh_lookup(&arp_tbl, &ip, dev, 1) == NULL)
11072 +                       if (pneigh_lookup(&arp_tbl, net, &ip, dev, 1) == NULL)
11073                                 return -ENOBUFS;
11074                         return 0;
11075                 }
11076                 if (dev == NULL) {
11077 -                       IPV4_DEVCONF_ALL(PROXY_ARP) = 1;
11078 +                       IPV4_DEVCONF_ALL(net, PROXY_ARP) = 1;
11079                         return 0;
11080                 }
11081                 if (__in_dev_get_rtnl(dev)) {
11082 @@ -1000,8 +1008,10 @@
11083         if (r->arp_flags & ATF_PERM)
11084                 r->arp_flags |= ATF_COM;
11085         if (dev == NULL) {
11086 -               struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip,
11087 -                                                        .tos = RTO_ONLINK } } };
11088 +               struct flowi fl = { 
11089 +                       .fl_net = net,
11090 +                       .nl_u = { .ip4_u = { .daddr = ip, .tos = RTO_ONLINK } }
11091 +               };
11092                 struct rtable * rt;
11093                 if ((err = ip_route_output_key(&rt, &fl)) != 0)
11094                         return err;
11095 @@ -1080,7 +1090,7 @@
11096         return err;
11097  }
11098  
11099 -static int arp_req_delete(struct arpreq *r, struct net_device * dev)
11100 +static int arp_req_delete(struct net *net, struct arpreq *r, struct net_device * dev)
11101  {
11102         int err;
11103         __be32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
11104 @@ -1090,10 +1100,10 @@
11105                 __be32 mask =
11106                        ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr;
11107                 if (mask == htonl(0xFFFFFFFF))
11108 -                       return pneigh_delete(&arp_tbl, &ip, dev);
11109 +                       return pneigh_delete(&arp_tbl, net, &ip, dev);
11110                 if (mask == 0) {
11111                         if (dev == NULL) {
11112 -                               IPV4_DEVCONF_ALL(PROXY_ARP) = 0;
11113 +                               IPV4_DEVCONF_ALL(net, PROXY_ARP) = 0;
11114                                 return 0;
11115                         }
11116                         if (__in_dev_get_rtnl(dev)) {
11117 @@ -1107,8 +1117,10 @@
11118         }
11119  
11120         if (dev == NULL) {
11121 -               struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip,
11122 -                                                        .tos = RTO_ONLINK } } };
11123 +               struct flowi fl = {
11124 +                       .fl_net = net,
11125 +                       .nl_u = { .ip4_u = { .daddr = ip, .tos = RTO_ONLINK } }
11126 +               };
11127                 struct rtable * rt;
11128                 if ((err = ip_route_output_key(&rt, &fl)) != 0)
11129                         return err;
11130 @@ -1133,7 +1145,7 @@
11131   *     Handle an ARP layer I/O control request.
11132   */
11133  
11134 -int arp_ioctl(unsigned int cmd, void __user *arg)
11135 +int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg)
11136  {
11137         int err;
11138         struct arpreq r;
11139 @@ -1165,7 +1177,7 @@
11140         rtnl_lock();
11141         if (r.arp_dev[0]) {
11142                 err = -ENODEV;
11143 -               if ((dev = __dev_get_by_name(r.arp_dev)) == NULL)
11144 +               if ((dev = __dev_get_by_name(net, r.arp_dev)) == NULL)
11145                         goto out;
11146  
11147                 /* Mmmm... It is wrong... ARPHRD_NETROM==0 */
11148 @@ -1181,10 +1193,10 @@
11149  
11150         switch (cmd) {
11151         case SIOCDARP:
11152 -               err = arp_req_delete(&r, dev);
11153 +               err = arp_req_delete(net, &r, dev);
11154                 break;
11155         case SIOCSARP:
11156 -               err = arp_req_set(&r, dev);
11157 +               err = arp_req_set(net, &r, dev);
11158                 break;
11159         case SIOCGARP:
11160                 err = arp_req_get(&r, dev);
11161 @@ -1201,6 +1213,9 @@
11162  {
11163         struct net_device *dev = ptr;
11164  
11165 +       if (dev->nd_net != &init_net)
11166 +               return NOTIFY_DONE;
11167 +
11168         switch (event) {
11169         case NETDEV_CHANGEADDR:
11170                 neigh_changeaddr(&arp_tbl, dev);
11171 @@ -1227,6 +1242,54 @@
11172  }
11173  
11174  
11175 +static int arp_proc_init(struct net *net);
11176 +static void arp_proc_exit(struct net *net);
11177 +
11178 +
11179 +static int arp_net_init(struct net *net)
11180 +{
11181 +       int error;
11182 +       if ((error = arp_proc_init(net)))
11183 +               goto out_proc;
11184 +
11185 +       error = -ENOMEM;
11186 +       net->arp_neigh_parms_default = neigh_parms_alloc_default(&arp_tbl, net);
11187 +       if (!net->arp_neigh_parms_default)
11188 +               goto out_parm;
11189 +
11190 +#ifdef CONFIG_SYSCTL
11191 +       if ((error = neigh_sysctl_register(
11192 +                    NULL, net->arp_neigh_parms_default,
11193 +                    NET_IPV4, NET_IPV4_NEIGH, "ipv4", NULL, NULL)))
11194 +               goto out_sysctl;
11195 +#endif
11196 +
11197 +out:
11198 +       return error;
11199 +
11200 +#ifdef CONFIG_SYSCTL
11201 +out_sysctl:
11202 +       neigh_parms_release(&arp_tbl, net->arp_neigh_parms_default);
11203 +#endif
11204 +out_parm:
11205 +       arp_proc_exit(net);
11206 +out_proc:
11207 +       goto out;
11208 +}
11209 +
11210 +static void arp_net_exit(struct net *net)
11211 +{
11212 +#ifdef CONFIG_SYSCTL
11213 +       neigh_sysctl_unregister(net->arp_neigh_parms_default);
11214 +#endif
11215 +       neigh_parms_release(&arp_tbl, net->arp_neigh_parms_default);
11216 +       arp_proc_exit(net);
11217 +}
11218 +
11219 +static struct pernet_operations arp_net_ops = {
11220 +       .init = arp_net_init,
11221 +       .exit = arp_net_exit,
11222 +};
11223  /*
11224   *     Called once on startup.
11225   */
11226 @@ -1236,18 +1299,12 @@
11227         .func = arp_rcv,
11228  };
11229  
11230 -static int arp_proc_init(void);
11231 -
11232  void __init arp_init(void)
11233  {
11234         neigh_table_init(&arp_tbl);
11235  
11236         dev_add_pack(&arp_packet_type);
11237 -       arp_proc_init();
11238 -#ifdef CONFIG_SYSCTL
11239 -       neigh_sysctl_register(NULL, &arp_tbl.parms, NET_IPV4,
11240 -                             NET_IPV4_NEIGH, "ipv4", NULL, NULL);
11241 -#endif
11242 +       register_pernet_subsys(&arp_net_ops);
11243         register_netdevice_notifier(&arp_netdev_notifier);
11244  }
11245  
11246 @@ -1383,6 +1440,8 @@
11247  
11248         seq          = file->private_data;
11249         seq->private = s;
11250 +       s->net = get_net(PROC_NET(inode));
11251 +
11252  out:
11253         return rc;
11254  out_kfree:
11255 @@ -1390,28 +1449,46 @@
11256         goto out;
11257  }
11258  
11259 +static int arp_seq_release(struct inode *inode, struct file *file)
11260 +{
11261 +       struct seq_file *seq = file->private_data;
11262 +       struct neigh_seq_state *state = seq->private;
11263 +       put_net(state->net);
11264 +       return seq_release_private(inode, file);
11265 +}
11266 +
11267  static const struct file_operations arp_seq_fops = {
11268         .owner          = THIS_MODULE,
11269         .open           = arp_seq_open,
11270         .read           = seq_read,
11271         .llseek         = seq_lseek,
11272 -       .release        = seq_release_private,
11273 +       .release        = arp_seq_release,
11274  };
11275  
11276 -static int __init arp_proc_init(void)
11277 +static int arp_proc_init(struct net *net)
11278  {
11279 -       if (!proc_net_fops_create("arp", S_IRUGO, &arp_seq_fops))
11280 +       if (!proc_net_fops_create(net, "arp", S_IRUGO, &arp_seq_fops))
11281                 return -ENOMEM;
11282         return 0;
11283  }
11284  
11285 +static void arp_proc_exit(struct net *net)
11286 +{
11287 +       proc_net_remove(net, "arp");
11288 +}
11289 +
11290  #else /* CONFIG_PROC_FS */
11291  
11292 -static int __init arp_proc_init(void)
11293 +static int arp_proc_init(struct net *net)
11294  {
11295         return 0;
11296  }
11297  
11298 +static void arp_proc_exit(struct net *net)
11299 +{
11300 +       return;
11301 +}
11302 +
11303  #endif /* CONFIG_PROC_FS */
11304  
11305  EXPORT_SYMBOL(arp_broken_ops);
11306 diff -Nurb linux-2.6.22-try2/net/ipv4/devinet.c linux-2.6.22-try2-netns/net/ipv4/devinet.c
11307 --- linux-2.6.22-try2/net/ipv4/devinet.c        2007-12-19 13:37:57.000000000 -0500
11308 +++ linux-2.6.22-try2-netns/net/ipv4/devinet.c  2007-12-19 22:49:18.000000000 -0500
11309 @@ -63,7 +63,7 @@
11310  #include <net/ip_fib.h>
11311  #include <net/rtnetlink.h>
11312  
11313 -struct ipv4_devconf ipv4_devconf = {
11314 +static struct ipv4_devconf ipv4_devconf_template = {
11315         .data = {
11316                 [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
11317                 [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
11318 @@ -72,7 +72,7 @@
11319         },
11320  };
11321  
11322 -static struct ipv4_devconf ipv4_devconf_dflt = {
11323 +static struct ipv4_devconf ipv4_devconf_dflt_template = {
11324         .data = {
11325                 [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
11326                 [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
11327 @@ -82,7 +82,7 @@
11328         },
11329  };
11330  
11331 -#define IPV4_DEVCONF_DFLT(attr) IPV4_DEVCONF(ipv4_devconf_dflt, attr)
11332 +#define IPV4_DEVCONF_DFLT(net, attr) IPV4_DEVCONF(*((net)->ipv4_devconf_dflt), attr)
11333  
11334  static const struct nla_policy ifa_ipv4_policy[IFA_MAX+1] = {
11335         [IFA_LOCAL]             = { .type = NLA_U32 },
11336 @@ -98,7 +98,7 @@
11337  static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
11338                          int destroy);
11339  #ifdef CONFIG_SYSCTL
11340 -static void devinet_sysctl_register(struct in_device *in_dev,
11341 +static void devinet_sysctl_register(struct net *net, struct in_device *in_dev,
11342                                     struct ipv4_devconf *p);
11343  static void devinet_sysctl_unregister(struct ipv4_devconf *p);
11344  #endif
11345 @@ -149,6 +149,7 @@
11346  
11347  static struct in_device *inetdev_init(struct net_device *dev)
11348  {
11349 +       struct net *net = dev->nd_net;
11350         struct in_device *in_dev;
11351  
11352         ASSERT_RTNL();
11353 @@ -157,7 +158,7 @@
11354         if (!in_dev)
11355                 goto out;
11356         INIT_RCU_HEAD(&in_dev->rcu_head);
11357 -       memcpy(&in_dev->cnf, &ipv4_devconf_dflt, sizeof(in_dev->cnf));
11358 +       memcpy(&in_dev->cnf, &net->ipv4_devconf_dflt, sizeof(in_dev->cnf));
11359         in_dev->cnf.sysctl = NULL;
11360         in_dev->dev = dev;
11361         if ((in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl)) == NULL)
11362 @@ -173,7 +174,7 @@
11363         in_dev_hold(in_dev);
11364  
11365  #ifdef CONFIG_SYSCTL
11366 -       devinet_sysctl_register(in_dev, &in_dev->cnf);
11367 +       devinet_sysctl_register(net, in_dev, &in_dev->cnf);
11368  #endif
11369         ip_mc_init_dev(in_dev);
11370         if (dev->flags & IFF_UP)
11371 @@ -203,8 +204,6 @@
11372         ASSERT_RTNL();
11373  
11374         dev = in_dev->dev;
11375 -       if (dev == &loopback_dev)
11376 -               return;
11377  
11378         in_dev->dead = 1;
11379  
11380 @@ -415,12 +414,12 @@
11381         return inet_insert_ifa(ifa);
11382  }
11383  
11384 -struct in_device *inetdev_by_index(int ifindex)
11385 +struct in_device *inetdev_by_index(struct net *net, int ifindex)
11386  {
11387         struct net_device *dev;
11388         struct in_device *in_dev = NULL;
11389         read_lock(&dev_base_lock);
11390 -       dev = __dev_get_by_index(ifindex);
11391 +       dev = __dev_get_by_index(net, ifindex);
11392         if (dev)
11393                 in_dev = in_dev_get(dev);
11394         read_unlock(&dev_base_lock);
11395 @@ -444,6 +443,7 @@
11396  
11397  static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
11398  {
11399 +       struct net *net = skb->sk->sk_net;
11400         struct nlattr *tb[IFA_MAX+1];
11401         struct in_device *in_dev;
11402         struct ifaddrmsg *ifm;
11403 @@ -457,7 +457,7 @@
11404                 goto errout;
11405  
11406         ifm = nlmsg_data(nlh);
11407 -       in_dev = inetdev_by_index(ifm->ifa_index);
11408 +       in_dev = inetdev_by_index(net, ifm->ifa_index);
11409         if (in_dev == NULL) {
11410                 err = -ENODEV;
11411                 goto errout;
11412 @@ -488,7 +488,7 @@
11413         return err;
11414  }
11415  
11416 -static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh)
11417 +static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh)
11418  {
11419         struct nlattr *tb[IFA_MAX+1];
11420         struct in_ifaddr *ifa;
11421 @@ -507,7 +507,7 @@
11422                 goto errout;
11423         }
11424  
11425 -       dev = __dev_get_by_index(ifm->ifa_index);
11426 +       dev = __dev_get_by_index(net, ifm->ifa_index);
11427         if (dev == NULL) {
11428                 err = -ENODEV;
11429                 goto errout;
11430 @@ -564,11 +564,12 @@
11431  
11432  static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
11433  {
11434 +       struct net *net = skb->sk->sk_net;
11435         struct in_ifaddr *ifa;
11436  
11437         ASSERT_RTNL();
11438  
11439 -       ifa = rtm_to_ifaddr(nlh);
11440 +       ifa = rtm_to_ifaddr(net, nlh);
11441         if (IS_ERR(ifa))
11442                 return PTR_ERR(ifa);
11443  
11444 @@ -600,7 +601,7 @@
11445  }
11446  
11447  
11448 -int devinet_ioctl(unsigned int cmd, void __user *arg)
11449 +int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
11450  {
11451         struct ifreq ifr;
11452         struct sockaddr_in sin_orig;
11453 @@ -629,7 +630,7 @@
11454                 *colon = 0;
11455  
11456  #ifdef CONFIG_KMOD
11457 -       dev_load(ifr.ifr_name);
11458 +       dev_load(net, ifr.ifr_name);
11459  #endif
11460  
11461         switch (cmd) {
11462 @@ -670,7 +671,7 @@
11463         rtnl_lock();
11464  
11465         ret = -ENODEV;
11466 -       if ((dev = __dev_get_by_name(ifr.ifr_name)) == NULL)
11467 +       if ((dev = __dev_get_by_name(net, ifr.ifr_name)) == NULL)
11468                 goto done;
11469  
11470         if (colon)
11471 @@ -889,6 +890,7 @@
11472  
11473  __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
11474  {
11475 +       struct net *net = dev->nd_net;
11476         __be32 addr = 0;
11477         struct in_device *in_dev;
11478  
11479 @@ -919,7 +921,7 @@
11480          */
11481         read_lock(&dev_base_lock);
11482         rcu_read_lock();
11483 -       for_each_netdev(dev) {
11484 +       for_each_netdev(net, dev) {
11485                 if ((in_dev = __in_dev_get_rcu(dev)) == NULL)
11486                         continue;
11487  
11488 @@ -982,7 +984,7 @@
11489   * - local: address, 0=autoselect the local address
11490   * - scope: maximum allowed scope value for the local address
11491   */
11492 -__be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope)
11493 +__be32 inet_confirm_addr(struct net *net, const struct net_device *dev, __be32 dst, __be32 local, int scope)
11494  {
11495         __be32 addr = 0;
11496         struct in_device *in_dev;
11497 @@ -998,7 +1000,7 @@
11498  
11499         read_lock(&dev_base_lock);
11500         rcu_read_lock();
11501 -       for_each_netdev(dev) {
11502 +       for_each_netdev(net, dev) {
11503                 if ((in_dev = __in_dev_get_rcu(dev))) {
11504                         addr = confirm_addr_indev(in_dev, dst, local, scope);
11505                         if (addr)
11506 @@ -1059,6 +1061,7 @@
11507                          void *ptr)
11508  {
11509         struct net_device *dev = ptr;
11510 +       struct net *net = dev->nd_net;
11511         struct in_device *in_dev = __in_dev_get_rtnl(dev);
11512  
11513         ASSERT_RTNL();
11514 @@ -1066,7 +1069,7 @@
11515         if (!in_dev) {
11516                 if (event == NETDEV_REGISTER) {
11517                         in_dev = inetdev_init(dev);
11518 -                       if (dev == &loopback_dev) {
11519 +                       if (dev == &net->loopback_dev) {
11520                                 if (!in_dev)
11521                                         panic("devinet: "
11522                                               "Failed to create loopback\n");
11523 @@ -1085,7 +1088,7 @@
11524         case NETDEV_UP:
11525                 if (dev->mtu < 68)
11526                         break;
11527 -               if (dev == &loopback_dev) {
11528 +               if (dev == &net->loopback_dev) {
11529                         struct in_ifaddr *ifa;
11530                         if ((ifa = inet_alloc_ifa()) != NULL) {
11531                                 ifa->ifa_local =
11532 @@ -1122,7 +1125,7 @@
11533                 neigh_sysctl_unregister(in_dev->arp_parms);
11534                 neigh_sysctl_register(dev, in_dev->arp_parms, NET_IPV4,
11535                                       NET_IPV4_NEIGH, "ipv4", NULL, NULL);
11536 -               devinet_sysctl_register(in_dev, &in_dev->cnf);
11537 +               devinet_sysctl_register(net, in_dev, &in_dev->cnf);
11538  #endif
11539                 break;
11540         }
11541 @@ -1185,6 +1188,7 @@
11542  
11543  static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
11544  {
11545 +       struct net *net = skb->sk->sk_net;
11546         int idx, ip_idx;
11547         struct net_device *dev;
11548         struct in_device *in_dev;
11549 @@ -1194,7 +1198,7 @@
11550  
11551         s_ip_idx = ip_idx = cb->args[1];
11552         idx = 0;
11553 -       for_each_netdev(dev) {
11554 +       for_each_netdev(net, dev) {
11555                 if (idx < s_idx)
11556                         goto cont;
11557                 if (idx > s_idx)
11558 @@ -1228,6 +1232,7 @@
11559                       u32 pid)
11560  {
11561         struct sk_buff *skb;
11562 +       struct net *net = ifa->ifa_dev->dev->nd_net;
11563         u32 seq = nlh ? nlh->nlmsg_seq : 0;
11564         int err = -ENOBUFS;
11565  
11566 @@ -1242,25 +1247,25 @@
11567                 kfree_skb(skb);
11568                 goto errout;
11569         }
11570 -       err = rtnl_notify(skb, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
11571 +       err = rtnl_notify(skb, net, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
11572  errout:
11573         if (err < 0)
11574 -               rtnl_set_sk_err(RTNLGRP_IPV4_IFADDR, err);
11575 +               rtnl_set_sk_err(net, RTNLGRP_IPV4_IFADDR, err);
11576  }
11577  
11578  #ifdef CONFIG_SYSCTL
11579  
11580 -static void devinet_copy_dflt_conf(int i)
11581 +static void devinet_copy_dflt_conf(struct net *net, int i)
11582  {
11583         struct net_device *dev;
11584  
11585         read_lock(&dev_base_lock);
11586 -       for_each_netdev(dev) {
11587 +       for_each_netdev(net, dev) {
11588                 struct in_device *in_dev;
11589                 rcu_read_lock();
11590                 in_dev = __in_dev_get_rcu(dev);
11591                 if (in_dev && !test_bit(i, in_dev->cnf.state))
11592 -                       in_dev->cnf.data[i] = ipv4_devconf_dflt.data[i];
11593 +                       in_dev->cnf.data[i] = net->ipv4_devconf_dflt->data[i];
11594                 rcu_read_unlock();
11595         }
11596         read_unlock(&dev_base_lock);
11597 @@ -1274,12 +1279,13 @@
11598  
11599         if (write) {
11600                 struct ipv4_devconf *cnf = ctl->extra1;
11601 +               struct net *net = ctl->extra2;
11602                 int i = (int *)ctl->data - cnf->data;
11603  
11604                 set_bit(i, cnf->state);
11605  
11606 -               if (cnf == &ipv4_devconf_dflt)
11607 -                       devinet_copy_dflt_conf(i);
11608 +               if (cnf == net->ipv4_devconf_dflt)
11609 +                       devinet_copy_dflt_conf(net, i);
11610         }
11611  
11612         return ret;
11613 @@ -1291,6 +1297,7 @@
11614  {
11615         struct ipv4_devconf *cnf;
11616         int *valp = table->data;
11617 +       struct net *net;
11618         int new;
11619         int i;
11620  
11621 @@ -1325,26 +1332,27 @@
11622         *valp = new;
11623  
11624         cnf = table->extra1;
11625 +       net = table->extra2;
11626         i = (int *)table->data - cnf->data;
11627  
11628         set_bit(i, cnf->state);
11629  
11630 -       if (cnf == &ipv4_devconf_dflt)
11631 -               devinet_copy_dflt_conf(i);
11632 +       if (cnf == net->ipv4_devconf_dflt)
11633 +               devinet_copy_dflt_conf(net, i);
11634  
11635         return 1;
11636  }
11637  
11638 -void inet_forward_change(void)
11639 +void inet_forward_change(struct net *net)
11640  {
11641         struct net_device *dev;
11642 -       int on = IPV4_DEVCONF_ALL(FORWARDING);
11643 +       int on = IPV4_DEVCONF_ALL(net, FORWARDING);
11644  
11645 -       IPV4_DEVCONF_ALL(ACCEPT_REDIRECTS) = !on;
11646 -       IPV4_DEVCONF_DFLT(FORWARDING) = on;
11647 +       IPV4_DEVCONF_ALL(net, ACCEPT_REDIRECTS) = !on;
11648 +       IPV4_DEVCONF_DFLT(net, FORWARDING) = on;
11649  
11650         read_lock(&dev_base_lock);
11651 -       for_each_netdev(dev) {
11652 +       for_each_netdev(net, dev) {
11653                 struct in_device *in_dev;
11654                 rcu_read_lock();
11655                 in_dev = __in_dev_get_rcu(dev);
11656 @@ -1364,11 +1372,12 @@
11657         int *valp = ctl->data;
11658         int val = *valp;
11659         int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
11660 +       struct net *net = ctl->extra2;
11661  
11662         if (write && *valp != val) {
11663 -               if (valp == &IPV4_DEVCONF_ALL(FORWARDING))
11664 -                       inet_forward_change();
11665 -               else if (valp != &IPV4_DEVCONF_DFLT(FORWARDING))
11666 +               if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING))
11667 +                       inet_forward_change(net);
11668 +               else if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING))
11669                         rt_cache_flush(0);
11670         }
11671  
11672 @@ -1407,13 +1416,14 @@
11673         { \
11674                 .ctl_name       = NET_IPV4_CONF_ ## attr, \
11675                 .procname       = name, \
11676 -               .data           = ipv4_devconf.data + \
11677 +               .data           = ipv4_devconf_template.data + \
11678                                   NET_IPV4_CONF_ ## attr - 1, \
11679                 .maxlen         = sizeof(int), \
11680                 .mode           = mval, \
11681                 .proc_handler   = proc, \
11682                 .strategy       = sysctl, \
11683 -               .extra1         = &ipv4_devconf, \
11684 +               .extra1         = &ipv4_devconf_template, \
11685 +               .extra2         = &init_net, \
11686         }
11687  
11688  #define DEVINET_SYSCTL_RW_ENTRY(attr, name) \
11689 @@ -1503,25 +1513,29 @@
11690         },
11691  };
11692  
11693 -static void devinet_sysctl_register(struct in_device *in_dev,
11694 +static void devinet_sysctl_register(struct net *net, struct in_device *in_dev,
11695                                     struct ipv4_devconf *p)
11696  {
11697         int i;
11698         struct net_device *dev = in_dev ? in_dev->dev : NULL;
11699 -       struct devinet_sysctl_table *t = kmemdup(&devinet_sysctl, sizeof(*t),
11700 -                                                GFP_KERNEL);
11701 +       struct devinet_sysctl_table *t;
11702         char *dev_name = NULL;
11703  
11704 +       t = kmemdup(&devinet_sysctl, sizeof(*t), GFP_KERNEL);
11705         if (!t)
11706                 return;
11707         for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) {
11708 -               t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf;
11709 +               t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf_template;
11710                 t->devinet_vars[i].extra1 = p;
11711 +               t->devinet_vars[i].extra2 = net;
11712         }
11713  
11714         if (dev) {
11715                 dev_name = dev->name;
11716                 t->devinet_dev[0].ctl_name = dev->ifindex;
11717 +       } else if (p == net->ipv4_devconf) {
11718 +               dev_name = "all";
11719 +               t->devinet_dev[0].ctl_name = NET_PROTO_CONF_ALL;
11720         } else {
11721                 dev_name = "default";
11722                 t->devinet_dev[0].ctl_name = NET_PROTO_CONF_DEFAULT;
11723 @@ -1542,7 +1556,7 @@
11724         t->devinet_proto_dir[0].child = t->devinet_conf_dir;
11725         t->devinet_root_dir[0].child  = t->devinet_proto_dir;
11726  
11727 -       t->sysctl_header = register_sysctl_table(t->devinet_root_dir);
11728 +       t->sysctl_header = register_net_sysctl_table(net, t->devinet_root_dir);
11729         if (!t->sysctl_header)
11730             goto free_procname;
11731  
11732 @@ -1562,26 +1576,59 @@
11733         if (p->sysctl) {
11734                 struct devinet_sysctl_table *t = p->sysctl;
11735                 p->sysctl = NULL;
11736 -               unregister_sysctl_table(t->sysctl_header);
11737 +               unregister_net_sysctl_table(t->sysctl_header);
11738                 kfree(t->devinet_dev[0].procname);
11739                 kfree(t);
11740         }
11741  }
11742  #endif
11743  
11744 +static int devinet_net_init(struct net *net)
11745 +{
11746 +#ifdef CONFIG_SYSCTL
11747 +       net->ipv4_devconf = kmemdup(&ipv4_devconf_template, 
11748 +                                   sizeof(ipv4_devconf_template), GFP_KERNEL);
11749 +       if (!net->ipv4_devconf)
11750 +               return -ENOMEM;
11751 +       
11752 +       net->ipv4_devconf_dflt = kmemdup(&ipv4_devconf_dflt_template, 
11753 +                                        sizeof(ipv4_devconf_template),
11754 +                                        GFP_KERNEL);
11755 +       if (!net->ipv4_devconf_dflt) {
11756 +               kfree(net->ipv4_devconf);
11757 +               return -ENOMEM;
11758 +       }
11759 +
11760 +       devinet_sysctl_register(net, NULL, net->ipv4_devconf);
11761 +       devinet_sysctl_register(net, NULL, net->ipv4_devconf_dflt);
11762 +
11763 +       multi_ipv4_table[0].data = &IPV4_DEVCONF_ALL(net, FORWARDING);
11764 +#endif
11765 +       return 0;
11766 +}
11767 +
11768 +static void devinet_net_exit(struct net *net)
11769 +{
11770 +#ifdef CONFIG_SYSCTL
11771 +       devinet_sysctl_unregister(net->ipv4_devconf_dflt);
11772 +       devinet_sysctl_unregister(net->ipv4_devconf);
11773 +#endif
11774 +}
11775 +
11776 +static struct pernet_operations devinet_net_ops = {
11777 +       .init = devinet_net_init,
11778 +       .exit = devinet_net_exit,
11779 +};
11780 +
11781  void __init devinet_init(void)
11782  {
11783 +       register_pernet_subsys(&devinet_net_ops);
11784         register_gifconf(PF_INET, inet_gifconf);
11785         register_netdevice_notifier(&ip_netdev_notifier);
11786  
11787         rtnl_register(PF_INET, RTM_NEWADDR, inet_rtm_newaddr, NULL);
11788         rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL);
11789         rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr);
11790 -#ifdef CONFIG_SYSCTL
11791 -       devinet_sysctl.sysctl_header =
11792 -               register_sysctl_table(devinet_sysctl.devinet_root_dir);
11793 -       devinet_sysctl_register(NULL, &ipv4_devconf_dflt);
11794 -#endif
11795  }
11796  
11797  EXPORT_SYMBOL(in_dev_finish_destroy);
11798 diff -Nurb linux-2.6.22-try2/net/ipv4/esp4.c linux-2.6.22-try2-netns/net/ipv4/esp4.c
11799 --- linux-2.6.22-try2/net/ipv4/esp4.c   2007-12-19 15:29:23.000000000 -0500
11800 +++ linux-2.6.22-try2-netns/net/ipv4/esp4.c     2007-12-19 22:49:18.000000000 -0500
11801 @@ -307,6 +307,9 @@
11802         struct ip_esp_hdr *esph = (struct ip_esp_hdr*)(skb->data+(iph->ihl<<2));
11803         struct xfrm_state *x;
11804  
11805 +       if (skb->dev->nd_net != &init_net)
11806 +               return;
11807 +
11808         if (icmp_hdr(skb)->type != ICMP_DEST_UNREACH ||
11809             icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
11810                 return;
11811 diff -Nurb linux-2.6.22-try2/net/ipv4/fib_frontend.c linux-2.6.22-try2-netns/net/ipv4/fib_frontend.c
11812 --- linux-2.6.22-try2/net/ipv4/fib_frontend.c   2007-12-19 15:29:23.000000000 -0500
11813 +++ linux-2.6.22-try2-netns/net/ipv4/fib_frontend.c     2007-12-19 22:49:18.000000000 -0500
11814 @@ -51,38 +51,34 @@
11815  
11816  #ifndef CONFIG_IP_MULTIPLE_TABLES
11817  
11818 -struct fib_table *ip_fib_local_table;
11819 -struct fib_table *ip_fib_main_table;
11820 -
11821  #define FIB_TABLE_HASHSZ 1
11822 -static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ];
11823  
11824  #else
11825  
11826  #define FIB_TABLE_HASHSZ 256
11827 -static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ];
11828  
11829 -struct fib_table *fib_new_table(u32 id)
11830 +struct fib_table *fib_new_table(struct net *net, u32 id)
11831  {
11832         struct fib_table *tb;
11833         unsigned int h;
11834  
11835         if (id == 0)
11836                 id = RT_TABLE_MAIN;
11837 -       tb = fib_get_table(id);
11838 +       tb = fib_get_table(net, id);
11839         if (tb)
11840                 return tb;
11841         tb = fib_hash_init(id);
11842         if (!tb)
11843                 return NULL;
11844         h = id & (FIB_TABLE_HASHSZ - 1);
11845 -       hlist_add_head_rcu(&tb->tb_hlist, &fib_table_hash[h]);
11846 +       hlist_add_head_rcu(&tb->tb_hlist, &net->ip_fib_table_hash[h]);
11847         return tb;
11848  }
11849  
11850 -struct fib_table *fib_get_table(u32 id)
11851 +struct fib_table *fib_get_table(struct net *net, u32 id)
11852  {
11853         struct fib_table *tb;
11854 +       struct hlist_head *head;
11855         struct hlist_node *node;
11856         unsigned int h;
11857  
11858 @@ -90,7 +86,8 @@
11859                 id = RT_TABLE_MAIN;
11860         h = id & (FIB_TABLE_HASHSZ - 1);
11861         rcu_read_lock();
11862 -       hlist_for_each_entry_rcu(tb, node, &fib_table_hash[h], tb_hlist) {
11863 +       head = &net->ip_fib_table_hash[h];
11864 +       hlist_for_each_entry_rcu(tb, node, head, tb_hlist) {
11865                 if (tb->tb_id == id) {
11866                         rcu_read_unlock();
11867                         return tb;
11868 @@ -99,9 +96,10 @@
11869         rcu_read_unlock();
11870         return NULL;
11871  }
11872 +
11873  #endif /* CONFIG_IP_MULTIPLE_TABLES */
11874  
11875 -static void fib_flush(void)
11876 +static void fib_flush(struct net *net)
11877  {
11878         int flushed = 0;
11879         struct fib_table *tb;
11880 @@ -109,7 +107,8 @@
11881         unsigned int h;
11882  
11883         for (h = 0; h < FIB_TABLE_HASHSZ; h++) {
11884 -               hlist_for_each_entry(tb, node, &fib_table_hash[h], tb_hlist)
11885 +               struct hlist_head *head = &net->ip_fib_table_hash[h];
11886 +               hlist_for_each_entry(tb, node, head, tb_hlist)
11887                         flushed += tb->tb_flush(tb);
11888         }
11889  
11890 @@ -121,18 +120,23 @@
11891   *     Find the first device with a given source address.
11892   */
11893  
11894 -struct net_device * ip_dev_find(__be32 addr)
11895 +struct net_device * ip_dev_find(struct net *net, __be32 addr)
11896  {
11897 -       struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
11898 +       struct flowi fl = { 
11899 +               .fl_net = net,
11900 +               .nl_u = { .ip4_u = { .daddr = addr } }
11901 +       };
11902         struct fib_result res;
11903         struct net_device *dev = NULL;
11904 +       struct fib_table *local_table;
11905  
11906  #ifdef CONFIG_IP_MULTIPLE_TABLES
11907         res.r = NULL;
11908  #endif
11909  
11910 -       if (!ip_fib_local_table ||
11911 -           ip_fib_local_table->tb_lookup(ip_fib_local_table, &fl, &res))
11912 +       local_table = fib_get_table(net, RT_TABLE_LOCAL);
11913 +       if (!local_table ||
11914 +           local_table->tb_lookup(local_table, &fl, &res))
11915                 return NULL;
11916         if (res.type != RTN_LOCAL)
11917                 goto out;
11918 @@ -145,11 +149,15 @@
11919         return dev;
11920  }
11921  
11922 -unsigned inet_addr_type(__be32 addr)
11923 +unsigned inet_addr_type(struct net *net, __be32 addr)
11924  {
11925 -       struct flowi            fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
11926 +       struct flowi            fl = {
11927 +               .fl_net = net,
11928 +               .nl_u = { .ip4_u = { .daddr = addr } }
11929 +       };
11930         struct fib_result       res;
11931         unsigned ret = RTN_BROADCAST;
11932 +       struct fib_table *local_table;
11933  
11934         if (ZERONET(addr) || BADCLASS(addr))
11935                 return RTN_BROADCAST;
11936 @@ -160,10 +168,10 @@
11937         res.r = NULL;
11938  #endif
11939  
11940 -       if (ip_fib_local_table) {
11941 +       local_table = fib_get_table(net, RT_TABLE_LOCAL);
11942 +       if (local_table) {
11943                 ret = RTN_UNICAST;
11944 -               if (!ip_fib_local_table->tb_lookup(ip_fib_local_table,
11945 -                                                  &fl, &res)) {
11946 +               if (!local_table->tb_lookup(local_table, &fl, &res)) {
11947                         ret = res.type;
11948                         fib_res_put(&res);
11949                 }
11950 @@ -183,7 +191,8 @@
11951                         struct net_device *dev, __be32 *spec_dst, u32 *itag)
11952  {
11953         struct in_device *in_dev;
11954 -       struct flowi fl = { .nl_u = { .ip4_u =
11955 +       struct flowi fl = { .fl_net = dev->nd_net,
11956 +                           .nl_u = { .ip4_u =
11957                                       { .daddr = src,
11958                                         .saddr = dst,
11959                                         .tos = tos } },
11960 @@ -267,13 +276,16 @@
11961         return len + nla_total_size(4);
11962  }
11963  
11964 -static int rtentry_to_fib_config(int cmd, struct rtentry *rt,
11965 +static int rtentry_to_fib_config(struct net *net, int cmd, struct rtentry *rt,
11966                                  struct fib_config *cfg)
11967  {
11968         __be32 addr;
11969         int plen;
11970  
11971         memset(cfg, 0, sizeof(*cfg));
11972 +       cfg->fc_nlinfo.pid = 0;
11973 +       cfg->fc_nlinfo.nlh = NULL;
11974 +       cfg->fc_nlinfo.net = net;
11975  
11976         if (rt->rt_dst.sa_family != AF_INET)
11977                 return -EAFNOSUPPORT;
11978 @@ -334,7 +346,7 @@
11979                 colon = strchr(devname, ':');
11980                 if (colon)
11981                         *colon = 0;
11982 -               dev = __dev_get_by_name(devname);
11983 +               dev = __dev_get_by_name(net, devname);
11984                 if (!dev)
11985                         return -ENODEV;
11986                 cfg->fc_oif = dev->ifindex;
11987 @@ -357,7 +369,7 @@
11988         if (rt->rt_gateway.sa_family == AF_INET && addr) {
11989                 cfg->fc_gw = addr;
11990                 if (rt->rt_flags & RTF_GATEWAY &&
11991 -                   inet_addr_type(addr) == RTN_UNICAST)
11992 +                   inet_addr_type(net, addr) == RTN_UNICAST)
11993                         cfg->fc_scope = RT_SCOPE_UNIVERSE;
11994         }
11995  
11996 @@ -398,7 +410,7 @@
11997   *     Handle IP routing ioctl calls. These are used to manipulate the routing tables
11998   */
11999  
12000 -int ip_rt_ioctl(unsigned int cmd, void __user *arg)
12001 +int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg)
12002  {
12003         struct fib_config cfg;
12004         struct rtentry rt;
12005 @@ -414,18 +426,18 @@
12006                         return -EFAULT;
12007  
12008                 rtnl_lock();
12009 -               err = rtentry_to_fib_config(cmd, &rt, &cfg);
12010 +               err = rtentry_to_fib_config(net, cmd, &rt, &cfg);
12011                 if (err == 0) {
12012                         struct fib_table *tb;
12013  
12014                         if (cmd == SIOCDELRT) {
12015 -                               tb = fib_get_table(cfg.fc_table);
12016 +                               tb = fib_get_table(net, cfg.fc_table);
12017                                 if (tb)
12018                                         err = tb->tb_delete(tb, &cfg);
12019                                 else
12020                                         err = -ESRCH;
12021                         } else {
12022 -                               tb = fib_new_table(cfg.fc_table);
12023 +                               tb = fib_new_table(net, cfg.fc_table);
12024                                 if (tb)
12025                                         err = tb->tb_insert(tb, &cfg);
12026                                 else
12027 @@ -480,6 +492,7 @@
12028  
12029         cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
12030         cfg->fc_nlinfo.nlh = nlh;
12031 +       cfg->fc_nlinfo.net = skb->sk->sk_net;
12032  
12033         if (cfg->fc_type > RTN_MAX) {
12034                 err = -EINVAL;
12035 @@ -527,6 +540,7 @@
12036  
12037  static int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
12038  {
12039 +       struct net *net = skb->sk->sk_net;
12040         struct fib_config cfg;
12041         struct fib_table *tb;
12042         int err;
12043 @@ -535,7 +549,7 @@
12044         if (err < 0)
12045                 goto errout;
12046  
12047 -       tb = fib_get_table(cfg.fc_table);
12048 +       tb = fib_get_table(net, cfg.fc_table);
12049         if (tb == NULL) {
12050                 err = -ESRCH;
12051                 goto errout;
12052 @@ -548,6 +562,7 @@
12053  
12054  static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
12055  {
12056 +       struct net *net = skb->sk->sk_net;
12057         struct fib_config cfg;
12058         struct fib_table *tb;
12059         int err;
12060 @@ -556,7 +571,7 @@
12061         if (err < 0)
12062                 goto errout;
12063  
12064 -       tb = fib_new_table(cfg.fc_table);
12065 +       tb = fib_new_table(net, cfg.fc_table);
12066         if (tb == NULL) {
12067                 err = -ENOBUFS;
12068                 goto errout;
12069 @@ -569,6 +584,7 @@
12070  
12071  static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
12072  {
12073 +       struct net *net = skb->sk->sk_net;
12074         unsigned int h, s_h;
12075         unsigned int e = 0, s_e;
12076         struct fib_table *tb;
12077 @@ -583,8 +599,9 @@
12078         s_e = cb->args[1];
12079  
12080         for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) {
12081 +               struct hlist_head *head = &net->ip_fib_table_hash[h];
12082                 e = 0;
12083 -               hlist_for_each_entry(tb, node, &fib_table_hash[h], tb_hlist) {
12084 +               hlist_for_each_entry(tb, node, head, tb_hlist) {
12085                         if (e < s_e)
12086                                 goto next;
12087                         if (dumped)
12088 @@ -613,6 +630,7 @@
12089  
12090  static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifaddr *ifa)
12091  {
12092 +       struct net *net = ifa->ifa_dev->dev->nd_net;
12093         struct fib_table *tb;
12094         struct fib_config cfg = {
12095                 .fc_protocol = RTPROT_KERNEL,
12096 @@ -622,12 +640,13 @@
12097                 .fc_prefsrc = ifa->ifa_local,
12098                 .fc_oif = ifa->ifa_dev->dev->ifindex,
12099                 .fc_nlflags = NLM_F_CREATE | NLM_F_APPEND,
12100 +               .fc_nlinfo.net = net,
12101         };
12102  
12103         if (type == RTN_UNICAST)
12104 -               tb = fib_new_table(RT_TABLE_MAIN);
12105 +               tb = fib_new_table(net, RT_TABLE_MAIN);
12106         else
12107 -               tb = fib_new_table(RT_TABLE_LOCAL);
12108 +               tb = fib_new_table(net, RT_TABLE_LOCAL);
12109  
12110         if (tb == NULL)
12111                 return;
12112 @@ -688,6 +707,7 @@
12113  {
12114         struct in_device *in_dev = ifa->ifa_dev;
12115         struct net_device *dev = in_dev->dev;
12116 +       struct net *net = dev->nd_net;
12117         struct in_ifaddr *ifa1;
12118         struct in_ifaddr *prim = ifa;
12119         __be32 brd = ifa->ifa_address|~ifa->ifa_mask;
12120 @@ -736,15 +756,15 @@
12121                 fib_magic(RTM_DELROUTE, RTN_LOCAL, ifa->ifa_local, 32, prim);
12122  
12123                 /* Check, that this local address finally disappeared. */
12124 -               if (inet_addr_type(ifa->ifa_local) != RTN_LOCAL) {
12125 +               if (inet_addr_type(net, ifa->ifa_local) != RTN_LOCAL) {
12126                         /* And the last, but not the least thing.
12127                            We must flush stray FIB entries.
12128  
12129                            First of all, we scan fib_info list searching
12130                            for stray nexthop entries, then ignite fib_flush.
12131                         */
12132 -                       if (fib_sync_down(ifa->ifa_local, NULL, 0))
12133 -                               fib_flush();
12134 +                       if (fib_sync_down(net, ifa->ifa_local, NULL, 0))
12135 +                               fib_flush(net);
12136                 }
12137         }
12138  #undef LOCAL_OK
12139 @@ -753,11 +773,12 @@
12140  #undef BRD1_OK
12141  }
12142  
12143 -static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb )
12144 +static void nl_fib_lookup(struct net *net, struct fib_result_nl *frn, struct fib_table *tb )
12145  {
12146  
12147         struct fib_result       res;
12148 -       struct flowi            fl = { .mark = frn->fl_mark,
12149 +       struct flowi            fl = { .fl_net = net,
12150 +                                      .mark = frn->fl_mark,
12151                                        .nl_u = { .ip4_u = { .daddr = frn->fl_addr,
12152                                                             .tos = frn->fl_tos,
12153                                                             .scope = frn->fl_scope } } };
12154 @@ -786,6 +807,7 @@
12155  
12156  static void nl_fib_input(struct sock *sk, int len)
12157  {
12158 +       struct net *net = sk->sk_net;
12159         struct sk_buff *skb = NULL;
12160         struct nlmsghdr *nlh = NULL;
12161         struct fib_result_nl *frn;
12162 @@ -804,9 +826,9 @@
12163         }
12164  
12165         frn = (struct fib_result_nl *) NLMSG_DATA(nlh);
12166 -       tb = fib_get_table(frn->tb_id_in);
12167 +       tb = fib_get_table(net, frn->tb_id_in);
12168  
12169 -       nl_fib_lookup(frn, tb);
12170 +       nl_fib_lookup(net, frn, tb);
12171  
12172         pid = NETLINK_CB(skb).pid;       /* pid of sending process */
12173         NETLINK_CB(skb).pid = 0;         /* from kernel */
12174 @@ -814,16 +836,36 @@
12175         netlink_unicast(sk, skb, pid, MSG_DONTWAIT);
12176  }
12177  
12178 -static void nl_fib_lookup_init(void)
12179 +static int nl_fib_lookup_init(struct net *net)
12180  {
12181 -      netlink_kernel_create(NETLINK_FIB_LOOKUP, 0, nl_fib_input, NULL,
12182 -                           THIS_MODULE);
12183 +       int error = -ENOMEM;
12184 +       struct sock *sk;
12185 +       sk = netlink_kernel_create(net, NETLINK_FIB_LOOKUP, 0, nl_fib_input,
12186 +                                       NULL, THIS_MODULE);
12187 +       if (sk) {
12188 +               /* Don't hold an extra reference on the namespace */
12189 +               put_net(sk->sk_net);
12190 +               net->nlfl = sk;
12191 +               error = 0;
12192 +       }
12193 +       return error;
12194 +}
12195 +
12196 +static void nl_fib_lookup_exit(struct net *net)
12197 +{
12198 +       /* At the last minute lie and say this is a socket for the
12199 +        * initial network namespace.  So the socket will  be safe to
12200 +        * free. 
12201 +        */
12202 +       net->nlfl->sk_net = get_net(&init_net);
12203 +       sock_put(net->nlfl);
12204  }
12205  
12206  static void fib_disable_ip(struct net_device *dev, int force)
12207  {
12208 -       if (fib_sync_down(0, dev, force))
12209 -               fib_flush();
12210 +       struct net *net = dev->nd_net;
12211 +       if (fib_sync_down(net, 0, dev, force))
12212 +               fib_flush(net);
12213         rt_cache_flush(0);
12214         arp_ifdown(dev);
12215  }
12216 @@ -860,6 +902,9 @@
12217         struct net_device *dev = ptr;
12218         struct in_device *in_dev = __in_dev_get_rtnl(dev);
12219  
12220 +       if (dev->nd_net != &init_net)
12221 +               return NOTIFY_DONE;
12222 +
12223         if (event == NETDEV_UNREGISTER) {
12224                 fib_disable_ip(dev, 2);
12225                 return NOTIFY_DONE;
12226 @@ -889,6 +934,85 @@
12227         return NOTIFY_DONE;
12228  }
12229  
12230 +static int ip_fib_net_init(struct net *net)
12231 +{
12232 +       unsigned int i;
12233 +
12234 +       net->ip_fib_table_hash = kzalloc(
12235 +               sizeof(struct hlist_head)*FIB_TABLE_HASHSZ, GFP_KERNEL);
12236 +       if (!net->ip_fib_table_hash)
12237 +               return -ENOMEM;
12238 +
12239 +       for (i = 0; i < FIB_TABLE_HASHSZ; i++)
12240 +               INIT_HLIST_HEAD(&net->ip_fib_table_hash[i]);
12241 +#ifndef CONFIG_IP_MULTIPLE_TABLES
12242 +       net->ip_fib_local_table = fib_hash_init(RT_TABLE_LOCAL);
12243 +       hlist_add_head_rcu(&net->ip_fib_local_table->tb_hlist,
12244 +                               &net->ip_fib_table_hash[0]);
12245 +       net->ip_fib_main_table = fib_hash_init(RT_TABLE_MAIN);
12246 +       hlist_add_head_rcu(&net->ip_fib_main_table->tb_hlist,
12247 +                               &net->ip_fib_table_hash[0]);
12248 +#else
12249 +       fib4_rules_init(net);
12250 +#endif
12251 +       return 0;
12252 +}
12253 +
12254 +static void ip_fib_net_exit(struct net *net)
12255 +{
12256 +       unsigned int i;
12257 +
12258 +#ifdef CONFIG_IP_MULTIPLE_TABLES
12259 +       fib4_rules_exit(net);
12260 +#endif
12261 +
12262 +       synchronize_rcu(); /* needed? */
12263 +       for (i = 0; i < FIB_TABLE_HASHSZ; i++) {
12264 +               struct fib_table *tb;
12265 +               struct hlist_head *head;
12266 +               struct hlist_node *node, *tmp;
12267 +
12268 +               head = &net->ip_fib_table_hash[i];
12269 +               hlist_for_each_entry_safe(tb, node, tmp, head, tb_hlist) {
12270 +                       hlist_del(node);
12271 +                       fib_hash_exit(tb);
12272 +               }
12273 +       }
12274 +       kfree(net->ip_fib_table_hash);
12275 +}
12276 +
12277 +static int fib_net_init(struct net *net)
12278 +{
12279 +       int error;
12280 +
12281 +       error = 0;
12282 +       if ((error = ip_fib_net_init(net)))
12283 +               goto out;
12284 +       if ((error = fib_info_init(net)))
12285 +               goto out_info;
12286 +       if ((error = nl_fib_lookup_init(net)))
12287 +               goto out_nlfl;
12288 +       if ((error = fib_proc_init(net)))
12289 +               goto out_proc;
12290 +out:
12291 +       return error;
12292 +out_proc:
12293 +       nl_fib_lookup_exit(net);
12294 +out_nlfl:
12295 +       fib_info_exit(net);
12296 +out_info:
12297 +       ip_fib_net_exit(net);
12298 +       goto out;
12299 +}
12300 +
12301 +static void fib_net_exit(struct net *net)
12302 +{
12303 +       fib_proc_exit(net);
12304 +       nl_fib_lookup_exit(net);
12305 +       fib_info_exit(net);
12306 +       ip_fib_net_exit(net);
12307 +}
12308 +
12309  static struct notifier_block fib_inetaddr_notifier = {
12310         .notifier_call =fib_inetaddr_event,
12311  };
12312 @@ -897,28 +1021,20 @@
12313         .notifier_call =fib_netdev_event,
12314  };
12315  
12316 +static struct pernet_operations fib_net_ops = {
12317 +       .init = fib_net_init,
12318 +       .exit = fib_net_exit,
12319 +};
12320 +
12321  void __init ip_fib_init(void)
12322  {
12323 -       unsigned int i;
12324 -
12325 -       for (i = 0; i < FIB_TABLE_HASHSZ; i++)
12326 -               INIT_HLIST_HEAD(&fib_table_hash[i]);
12327 -#ifndef CONFIG_IP_MULTIPLE_TABLES
12328 -       ip_fib_local_table = fib_hash_init(RT_TABLE_LOCAL);
12329 -       hlist_add_head_rcu(&ip_fib_local_table->tb_hlist, &fib_table_hash[0]);
12330 -       ip_fib_main_table  = fib_hash_init(RT_TABLE_MAIN);
12331 -       hlist_add_head_rcu(&ip_fib_main_table->tb_hlist, &fib_table_hash[0]);
12332 -#else
12333 -       fib4_rules_init();
12334 -#endif
12335 -
12336 -       register_netdevice_notifier(&fib_netdev_notifier);
12337 -       register_inetaddr_notifier(&fib_inetaddr_notifier);
12338 -       nl_fib_lookup_init();
12339 -
12340         rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL);
12341         rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL);
12342         rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib);
12343 +
12344 +       register_pernet_subsys(&fib_net_ops);
12345 +       register_netdevice_notifier(&fib_netdev_notifier);
12346 +       register_inetaddr_notifier(&fib_inetaddr_notifier);
12347  }
12348  
12349  EXPORT_SYMBOL(inet_addr_type);
12350 diff -Nurb linux-2.6.22-try2/net/ipv4/fib_hash.c linux-2.6.22-try2-netns/net/ipv4/fib_hash.c
12351 --- linux-2.6.22-try2/net/ipv4/fib_hash.c       2007-12-19 13:37:57.000000000 -0500
12352 +++ linux-2.6.22-try2-netns/net/ipv4/fib_hash.c 2007-12-19 22:49:18.000000000 -0500
12353 @@ -40,6 +40,7 @@
12354  #include <net/route.h>
12355  #include <net/tcp.h>
12356  #include <net/sock.h>
12357 +#include <net/net_namespace.h>
12358  #include <net/ip_fib.h>
12359  
12360  #include "fib_lookup.h"
12361 @@ -274,11 +275,10 @@
12362         return err;
12363  }
12364  
12365 -static int fn_hash_last_dflt=-1;
12366 -
12367  static void
12368  fn_hash_select_default(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
12369  {
12370 +       struct net *net = flp->fl_net;
12371         int order, last_idx;
12372         struct hlist_node *node;
12373         struct fib_node *f;
12374 @@ -316,12 +316,12 @@
12375                                 if (next_fi != res->fi)
12376                                         break;
12377                         } else if (!fib_detect_death(fi, order, &last_resort,
12378 -                                                    &last_idx, &fn_hash_last_dflt)) {
12379 +                                                    &last_idx, &net->fn_hash_last_dflt)) {
12380                                 if (res->fi)
12381                                         fib_info_put(res->fi);
12382                                 res->fi = fi;
12383                                 atomic_inc(&fi->fib_clntref);
12384 -                               fn_hash_last_dflt = order;
12385 +                               net->fn_hash_last_dflt = order;
12386                                 goto out;
12387                         }
12388                         fi = next_fi;
12389 @@ -330,16 +330,16 @@
12390         }
12391  
12392         if (order <= 0 || fi == NULL) {
12393 -               fn_hash_last_dflt = -1;
12394 +               net->fn_hash_last_dflt = -1;
12395                 goto out;
12396         }
12397  
12398 -       if (!fib_detect_death(fi, order, &last_resort, &last_idx, &fn_hash_last_dflt)) {
12399 +       if (!fib_detect_death(fi, order, &last_resort, &last_idx, &net->fn_hash_last_dflt)) {
12400                 if (res->fi)
12401                         fib_info_put(res->fi);
12402                 res->fi = fi;
12403                 atomic_inc(&fi->fib_clntref);
12404 -               fn_hash_last_dflt = order;
12405 +               net->fn_hash_last_dflt = order;
12406                 goto out;
12407         }
12408  
12409 @@ -350,7 +350,7 @@
12410                 if (last_resort)
12411                         atomic_inc(&last_resort->fib_clntref);
12412         }
12413 -       fn_hash_last_dflt = last_idx;
12414 +       net->fn_hash_last_dflt = last_idx;
12415  out:
12416         read_unlock(&fib_hash_lock);
12417  }
12418 @@ -759,11 +759,15 @@
12419         return skb->len;
12420  }
12421  
12422 -#ifdef CONFIG_IP_MULTIPLE_TABLES
12423 +void fib_hash_exit(struct fib_table *tb)
12424 +{
12425 +       if (!tb)
12426 +               return;
12427 +       fn_hash_flush(tb);
12428 +       kfree(tb);
12429 +}
12430 +
12431  struct fib_table * fib_hash_init(u32 id)
12432 -#else
12433 -struct fib_table * __init fib_hash_init(u32 id)
12434 -#endif
12435  {
12436         struct fib_table *tb;
12437  
12438 @@ -799,6 +803,7 @@
12439  #ifdef CONFIG_PROC_FS
12440  
12441  struct fib_iter_state {
12442 +       struct net *net;
12443         struct fn_zone  *zone;
12444         int             bucket;
12445         struct hlist_head *hash_head;
12446 @@ -812,7 +817,8 @@
12447  static struct fib_alias *fib_get_first(struct seq_file *seq)
12448  {
12449         struct fib_iter_state *iter = seq->private;
12450 -       struct fn_hash *table = (struct fn_hash *) ip_fib_main_table->tb_data;
12451 +       struct fib_table *main_table = fib_get_table(iter->net, RT_TABLE_MAIN);
12452 +       struct fn_hash *table = (struct fn_hash *) main_table->tb_data;
12453  
12454         iter->bucket    = 0;
12455         iter->hash_head = NULL;
12456 @@ -948,10 +954,11 @@
12457  
12458  static void *fib_seq_start(struct seq_file *seq, loff_t *pos)
12459  {
12460 +       struct fib_iter_state *iter = seq->private;
12461         void *v = NULL;
12462  
12463         read_lock(&fib_hash_lock);
12464 -       if (ip_fib_main_table)
12465 +       if (fib_get_table(iter->net, RT_TABLE_MAIN))
12466                 v = *pos ? fib_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
12467         return v;
12468  }
12469 @@ -1051,6 +1058,7 @@
12470  
12471         seq          = file->private_data;
12472         seq->private = s;
12473 +       s->net = get_net(PROC_NET(inode));
12474  out:
12475         return rc;
12476  out_kfree:
12477 @@ -1058,23 +1066,32 @@
12478         goto out;
12479  }
12480  
12481 +static int fib_seq_release(struct inode *inode, struct file *file)
12482 +{
12483 +       struct seq_file *seq = file->private_data;
12484 +       struct fib_iter_state *iter = seq->private;
12485 +       put_net(iter->net);
12486 +       return seq_release_private(inode, file);
12487 +}
12488 +
12489  static const struct file_operations fib_seq_fops = {
12490         .owner          = THIS_MODULE,
12491         .open           = fib_seq_open,
12492         .read           = seq_read,
12493         .llseek         = seq_lseek,
12494 -       .release        = seq_release_private,
12495 +       .release        = fib_seq_release,
12496  };
12497  
12498 -int __init fib_proc_init(void)
12499 +int fib_proc_init(struct net *net)
12500  {
12501 -       if (!proc_net_fops_create("route", S_IRUGO, &fib_seq_fops))
12502 +       net->fn_hash_last_dflt = -1;
12503 +       if (!proc_net_fops_create(net, "route", S_IRUGO, &fib_seq_fops))
12504                 return -ENOMEM;
12505         return 0;
12506  }
12507  
12508 -void __init fib_proc_exit(void)
12509 +void fib_proc_exit(struct net *net)
12510  {
12511 -       proc_net_remove("route");
12512 +       proc_net_remove(net, "route");
12513  }
12514  #endif /* CONFIG_PROC_FS */
12515 diff -Nurb linux-2.6.22-try2/net/ipv4/fib_rules.c linux-2.6.22-try2-netns/net/ipv4/fib_rules.c
12516 --- linux-2.6.22-try2/net/ipv4/fib_rules.c      2007-12-19 13:37:57.000000000 -0500
12517 +++ linux-2.6.22-try2-netns/net/ipv4/fib_rules.c        2007-12-19 22:49:18.000000000 -0500
12518 @@ -32,8 +32,6 @@
12519  #include <net/ip_fib.h>
12520  #include <net/fib_rules.h>
12521  
12522 -static struct fib_rules_ops fib4_rules_ops;
12523 -
12524  struct fib4_rule
12525  {
12526         struct fib_rule         common;
12527 @@ -49,35 +47,14 @@
12528  #endif
12529  };
12530  
12531 -static struct fib4_rule default_rule = {
12532 -       .common = {
12533 -               .refcnt =       ATOMIC_INIT(2),
12534 -               .pref =         0x7FFF,
12535 -               .table =        RT_TABLE_DEFAULT,
12536 -               .action =       FR_ACT_TO_TBL,
12537 -       },
12538 +struct fib4_rule_table {
12539 +       struct list_head        fib4_rules;
12540 +       struct fib4_rule        default_rule;
12541 +       struct fib4_rule        main_rule;
12542 +       struct fib4_rule        local_rule;
12543 +       struct fib_rules_ops    fib4_rules_ops;
12544  };
12545  
12546 -static struct fib4_rule main_rule = {
12547 -       .common = {
12548 -               .refcnt =       ATOMIC_INIT(2),
12549 -               .pref =         0x7FFE,
12550 -               .table =        RT_TABLE_MAIN,
12551 -               .action =       FR_ACT_TO_TBL,
12552 -       },
12553 -};
12554 -
12555 -static struct fib4_rule local_rule = {
12556 -       .common = {
12557 -               .refcnt =       ATOMIC_INIT(2),
12558 -               .table =        RT_TABLE_LOCAL,
12559 -               .action =       FR_ACT_TO_TBL,
12560 -               .flags =        FIB_RULE_PERMANENT,
12561 -       },
12562 -};
12563 -
12564 -static LIST_HEAD(fib4_rules);
12565 -
12566  #ifdef CONFIG_NET_CLS_ROUTE
12567  u32 fib_rules_tclass(struct fib_result *res)
12568  {
12569 @@ -87,12 +64,14 @@
12570  
12571  int fib_lookup(struct flowi *flp, struct fib_result *res)
12572  {
12573 +       struct net *net = flp->fl_net;
12574 +       struct fib4_rule_table *table = net->fib4_table;
12575         struct fib_lookup_arg arg = {
12576                 .result = res,
12577         };
12578         int err;
12579  
12580 -       err = fib_rules_lookup(&fib4_rules_ops, flp, 0, &arg);
12581 +       err = fib_rules_lookup(&table->fib4_rules_ops, flp, 0, &arg);
12582         res->r = arg.rule;
12583  
12584         return err;
12585 @@ -122,7 +101,7 @@
12586                 goto errout;
12587         }
12588  
12589 -       if ((tbl = fib_get_table(rule->table)) == NULL)
12590 +       if ((tbl = fib_get_table(flp->fl_net, rule->table)) == NULL)
12591                 goto errout;
12592  
12593         err = tbl->tb_lookup(tbl, flp, (struct fib_result *) arg->result);
12594 @@ -138,7 +117,7 @@
12595         if (res->r && res->r->action == FR_ACT_TO_TBL &&
12596             FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) {
12597                 struct fib_table *tb;
12598 -               if ((tb = fib_get_table(res->r->table)) != NULL)
12599 +               if ((tb = fib_get_table(flp->fl_net, res->r->table)) != NULL)
12600                         tb->tb_select_default(tb, flp, res);
12601         }
12602  }
12603 @@ -159,13 +138,13 @@
12604         return 1;
12605  }
12606  
12607 -static struct fib_table *fib_empty_table(void)
12608 +static struct fib_table *fib_empty_table(struct net *net)
12609  {
12610         u32 id;
12611  
12612         for (id = 1; id <= RT_TABLE_MAX; id++)
12613 -               if (fib_get_table(id) == NULL)
12614 -                       return fib_new_table(id);
12615 +               if (fib_get_table(net, id) == NULL)
12616 +                       return fib_new_table(net, id);
12617         return NULL;
12618  }
12619  
12620 @@ -178,6 +157,7 @@
12621                                struct nlmsghdr *nlh, struct fib_rule_hdr *frh,
12622                                struct nlattr **tb)
12623  {
12624 +       struct net *net = skb->sk->sk_net;
12625         int err = -EINVAL;
12626         struct fib4_rule *rule4 = (struct fib4_rule *) rule;
12627  
12628 @@ -188,7 +168,7 @@
12629                 if (rule->action == FR_ACT_TO_TBL) {
12630                         struct fib_table *table;
12631  
12632 -                       table = fib_empty_table();
12633 +                       table = fib_empty_table(net);
12634                         if (table == NULL) {
12635                                 err = -ENOBUFS;
12636                                 goto errout;
12637 @@ -274,14 +254,15 @@
12638         return -ENOBUFS;
12639  }
12640  
12641 -static u32 fib4_rule_default_pref(void)
12642 +static u32 fib4_rule_default_pref(struct fib_rules_ops *ops)
12643  {
12644 -       struct list_head *pos;
12645 +       struct list_head *list, *pos;
12646         struct fib_rule *rule;
12647  
12648 -       if (!list_empty(&fib4_rules)) {
12649 -               pos = fib4_rules.next;
12650 -               if (pos->next != &fib4_rules) {
12651 +       list = ops->rules_list;
12652 +       if (!list_empty(list)) {
12653 +               pos = list->next;
12654 +               if (pos->next != list) {
12655                         rule = list_entry(pos->next, struct fib_rule, list);
12656                         if (rule->pref)
12657                                 return rule->pref - 1;
12658 @@ -298,12 +279,37 @@
12659                + nla_total_size(4); /* flow */
12660  }
12661  
12662 -static void fib4_rule_flush_cache(void)
12663 +static void fib4_rule_flush_cache(struct fib_rules_ops *ops)
12664  {
12665         rt_cache_flush(-1);
12666  }
12667  
12668 -static struct fib_rules_ops fib4_rules_ops = {
12669 +static struct fib4_rule_table fib4_rule_table = {
12670 +       .default_rule = {
12671 +               .common = {
12672 +                       .refcnt =       ATOMIC_INIT(2),
12673 +                       .pref =         0x7FFF,
12674 +                       .table =        RT_TABLE_DEFAULT,
12675 +                       .action =       FR_ACT_TO_TBL,
12676 +               },
12677 +       },
12678 +       .main_rule = {
12679 +               .common = {
12680 +                       .refcnt =       ATOMIC_INIT(2),
12681 +                       .pref =         0x7FFE,
12682 +                       .table =        RT_TABLE_MAIN,
12683 +                       .action =       FR_ACT_TO_TBL,
12684 +               },
12685 +       },
12686 +       .local_rule = {
12687 +               .common = {
12688 +                       .refcnt =       ATOMIC_INIT(2),
12689 +                       .table =        RT_TABLE_LOCAL,
12690 +                       .action =       FR_ACT_TO_TBL,
12691 +                       .flags =        FIB_RULE_PERMANENT,
12692 +               },
12693 +       },
12694 +       .fib4_rules_ops = {
12695         .family         = AF_INET,
12696         .rule_size      = sizeof(struct fib4_rule),
12697         .addr_size      = sizeof(u32),
12698 @@ -317,15 +323,34 @@
12699         .flush_cache    = fib4_rule_flush_cache,
12700         .nlgroup        = RTNLGRP_IPV4_RULE,
12701         .policy         = fib4_rule_policy,
12702 -       .rules_list     = &fib4_rules,
12703 +               .rules_list     = &fib4_rule_table.fib4_rules, /* &fib4_rules, */
12704         .owner          = THIS_MODULE,
12705 +       },
12706  };
12707  
12708 -void __init fib4_rules_init(void)
12709 +
12710 +void fib4_rules_init(struct net *net)
12711  {
12712 -       list_add_tail(&local_rule.common.list, &fib4_rules);
12713 -       list_add_tail(&main_rule.common.list, &fib4_rules);
12714 -       list_add_tail(&default_rule.common.list, &fib4_rules);
12715 +       struct fib4_rule_table *table;
12716 +       table = kmemdup(&fib4_rule_table, sizeof(*table), GFP_KERNEL);
12717 +       if (!table)
12718 +               return;
12719 +       INIT_LIST_HEAD(&table->fib4_rules);
12720 +       list_add_tail(&table->local_rule.common.list,   &table->fib4_rules);
12721 +       list_add_tail(&table->main_rule.common.list,    &table->fib4_rules);
12722 +       list_add_tail(&table->default_rule.common.list, &table->fib4_rules);
12723 +       table->fib4_rules_ops.rules_list = &table->fib4_rules;
12724 +       if (fib_rules_register(net, &table->fib4_rules_ops)) {
12725 +               kfree(table);
12726 +               return;
12727 +       }
12728 +       net->fib4_table = table;
12729 +}
12730  
12731 -       fib_rules_register(&fib4_rules_ops);
12732 +void fib4_rules_exit(struct net *net)
12733 +{
12734 +       struct fib4_rule_table *table = net->fib4_table;
12735 +       if (table)
12736 +               fib_rules_unregister(net, &table->fib4_rules_ops);
12737 +       kfree(table);
12738  }
12739 diff -Nurb linux-2.6.22-try2/net/ipv4/fib_semantics.c linux-2.6.22-try2-netns/net/ipv4/fib_semantics.c
12740 --- linux-2.6.22-try2/net/ipv4/fib_semantics.c  2007-12-19 15:29:23.000000000 -0500
12741 +++ linux-2.6.22-try2-netns/net/ipv4/fib_semantics.c    2007-12-19 22:49:18.000000000 -0500
12742 @@ -50,14 +50,9 @@
12743  #define FSprintk(a...)
12744  
12745  static DEFINE_SPINLOCK(fib_info_lock);
12746 -static struct hlist_head *fib_info_hash;
12747 -static struct hlist_head *fib_info_laddrhash;
12748 -static unsigned int fib_hash_size;
12749 -static unsigned int fib_info_cnt;
12750  
12751  #define DEVINDEX_HASHBITS 8
12752  #define DEVINDEX_HASHSIZE (1U << DEVINDEX_HASHBITS)
12753 -static struct hlist_head fib_info_devhash[DEVINDEX_HASHSIZE];
12754  
12755  #ifdef CONFIG_IP_ROUTE_MULTIPATH
12756  
12757 @@ -153,7 +148,8 @@
12758                         dev_put(nh->nh_dev);
12759                 nh->nh_dev = NULL;
12760         } endfor_nexthops(fi);
12761 -       fib_info_cnt--;
12762 +       fi->fib_net->fib_info_cnt--;
12763 +       release_net(fi->fib_net);
12764         kfree(fi);
12765  }
12766  
12767 @@ -196,9 +192,9 @@
12768         return 0;
12769  }
12770  
12771 -static inline unsigned int fib_info_hashfn(const struct fib_info *fi)
12772 +static inline unsigned int fib_info_hashfn(struct net *net, const struct fib_info *fi)
12773  {
12774 -       unsigned int mask = (fib_hash_size - 1);
12775 +       unsigned int mask = net->fib_info_hash_size - 1;
12776         unsigned int val = fi->fib_nhs;
12777  
12778         val ^= fi->fib_protocol;
12779 @@ -208,15 +204,15 @@
12780         return (val ^ (val >> 7) ^ (val >> 12)) & mask;
12781  }
12782  
12783 -static struct fib_info *fib_find_info(const struct fib_info *nfi)
12784 +static struct fib_info *fib_find_info(struct net *net, const struct fib_info *nfi)
12785  {
12786         struct hlist_head *head;
12787         struct hlist_node *node;
12788         struct fib_info *fi;
12789         unsigned int hash;
12790  
12791 -       hash = fib_info_hashfn(nfi);
12792 -       head = &fib_info_hash[hash];
12793 +       hash = fib_info_hashfn(net, nfi);
12794 +       head = &net->fib_info_hash[hash];
12795  
12796         hlist_for_each_entry(fi, node, head, fib_hash) {
12797                 if (fi->fib_nhs != nfi->fib_nhs)
12798 @@ -249,6 +245,7 @@
12799  
12800  int ip_fib_check_default(__be32 gw, struct net_device *dev)
12801  {
12802 +       struct net *net = dev->nd_net;
12803         struct hlist_head *head;
12804         struct hlist_node *node;
12805         struct fib_nh *nh;
12806 @@ -257,7 +254,7 @@
12807         spin_lock(&fib_info_lock);
12808  
12809         hash = fib_devindex_hashfn(dev->ifindex);
12810 -       head = &fib_info_devhash[hash];
12811 +       head = &net->fib_info_devhash[hash];
12812         hlist_for_each_entry(nh, node, head, nh_hash) {
12813                 if (nh->nh_dev == dev &&
12814                     nh->nh_gw == gw &&
12815 @@ -320,11 +317,11 @@
12816                 kfree_skb(skb);
12817                 goto errout;
12818         }
12819 -       err = rtnl_notify(skb, info->pid, RTNLGRP_IPV4_ROUTE,
12820 +       err = rtnl_notify(skb, info->net, info->pid, RTNLGRP_IPV4_ROUTE,
12821                           info->nlh, GFP_KERNEL);
12822  errout:
12823         if (err < 0)
12824 -               rtnl_set_sk_err(RTNLGRP_IPV4_ROUTE, err);
12825 +               rtnl_set_sk_err(info->net, RTNLGRP_IPV4_ROUTE, err);
12826  }
12827  
12828  /* Return the first fib alias matching TOS with
12829 @@ -517,6 +514,7 @@
12830  static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
12831                         struct fib_nh *nh)
12832  {
12833 +       struct net *net = cfg->fc_nlinfo.net;
12834         int err;
12835  
12836         if (nh->nh_gw) {
12837 @@ -531,9 +529,9 @@
12838  
12839                         if (cfg->fc_scope >= RT_SCOPE_LINK)
12840                                 return -EINVAL;
12841 -                       if (inet_addr_type(nh->nh_gw) != RTN_UNICAST)
12842 +                       if (inet_addr_type(net, nh->nh_gw) != RTN_UNICAST)
12843                                 return -EINVAL;
12844 -                       if ((dev = __dev_get_by_index(nh->nh_oif)) == NULL)
12845 +                       if ((dev = __dev_get_by_index(net, nh->nh_oif)) == NULL)
12846                                 return -ENODEV;
12847                         if (!(dev->flags&IFF_UP))
12848                                 return -ENETDOWN;
12849 @@ -544,6 +542,7 @@
12850                 }
12851                 {
12852                         struct flowi fl = {
12853 +                               .fl_net = net,
12854                                 .nl_u = {
12855                                         .ip4_u = {
12856                                                 .daddr = nh->nh_gw,
12857 @@ -580,7 +579,7 @@
12858                 if (nh->nh_flags&(RTNH_F_PERVASIVE|RTNH_F_ONLINK))
12859                         return -EINVAL;
12860  
12861 -               in_dev = inetdev_by_index(nh->nh_oif);
12862 +               in_dev = inetdev_by_index(net, nh->nh_oif);
12863                 if (in_dev == NULL)
12864                         return -ENODEV;
12865                 if (!(in_dev->dev->flags&IFF_UP)) {
12866 @@ -595,9 +594,9 @@
12867         return 0;
12868  }
12869  
12870 -static inline unsigned int fib_laddr_hashfn(__be32 val)
12871 +static inline unsigned int fib_laddr_hashfn(struct net *net, __be32 val)
12872  {
12873 -       unsigned int mask = (fib_hash_size - 1);
12874 +       unsigned int mask = net->fib_info_hash_size - 1;
12875  
12876         return ((__force u32)val ^ ((__force u32)val >> 7) ^ ((__force u32)val >> 14)) & mask;
12877  }
12878 @@ -622,21 +621,22 @@
12879                 free_pages((unsigned long) hash, get_order(bytes));
12880  }
12881  
12882 -static void fib_hash_move(struct hlist_head *new_info_hash,
12883 +static void fib_hash_move(struct net *net,
12884 +                         struct hlist_head *new_info_hash,
12885                           struct hlist_head *new_laddrhash,
12886                           unsigned int new_size)
12887  {
12888         struct hlist_head *old_info_hash, *old_laddrhash;
12889 -       unsigned int old_size = fib_hash_size;
12890 +       unsigned int old_size = net->fib_info_hash_size;
12891         unsigned int i, bytes;
12892  
12893         spin_lock_bh(&fib_info_lock);
12894 -       old_info_hash = fib_info_hash;
12895 -       old_laddrhash = fib_info_laddrhash;
12896 -       fib_hash_size = new_size;
12897 +       old_info_hash = net->fib_info_hash;
12898 +       old_laddrhash = net->fib_info_laddrhash;
12899 +       net->fib_info_hash_size = new_size;
12900  
12901         for (i = 0; i < old_size; i++) {
12902 -               struct hlist_head *head = &fib_info_hash[i];
12903 +               struct hlist_head *head = &net->fib_info_hash[i];
12904                 struct hlist_node *node, *n;
12905                 struct fib_info *fi;
12906  
12907 @@ -646,15 +646,15 @@
12908  
12909                         hlist_del(&fi->fib_hash);
12910  
12911 -                       new_hash = fib_info_hashfn(fi);
12912 +                       new_hash = fib_info_hashfn(net, fi);
12913                         dest = &new_info_hash[new_hash];
12914                         hlist_add_head(&fi->fib_hash, dest);
12915                 }
12916         }
12917 -       fib_info_hash = new_info_hash;
12918 +       net->fib_info_hash = new_info_hash;
12919  
12920         for (i = 0; i < old_size; i++) {
12921 -               struct hlist_head *lhead = &fib_info_laddrhash[i];
12922 +               struct hlist_head *lhead = &net->fib_info_laddrhash[i];
12923                 struct hlist_node *node, *n;
12924                 struct fib_info *fi;
12925  
12926 @@ -664,12 +664,12 @@
12927  
12928                         hlist_del(&fi->fib_lhash);
12929  
12930 -                       new_hash = fib_laddr_hashfn(fi->fib_prefsrc);
12931 +                       new_hash = fib_laddr_hashfn(net, fi->fib_prefsrc);
12932                         ldest = &new_laddrhash[new_hash];
12933                         hlist_add_head(&fi->fib_lhash, ldest);
12934                 }
12935         }
12936 -       fib_info_laddrhash = new_laddrhash;
12937 +       net->fib_info_laddrhash = new_laddrhash;
12938  
12939         spin_unlock_bh(&fib_info_lock);
12940  
12941 @@ -680,6 +680,7 @@
12942  
12943  struct fib_info *fib_create_info(struct fib_config *cfg)
12944  {
12945 +       struct net *net = cfg->fc_nlinfo.net;
12946         int err;
12947         struct fib_info *fi = NULL;
12948         struct fib_info *ofi;
12949 @@ -698,8 +699,8 @@
12950  #endif
12951  
12952         err = -ENOBUFS;
12953 -       if (fib_info_cnt >= fib_hash_size) {
12954 -               unsigned int new_size = fib_hash_size << 1;
12955 +       if (net->fib_info_cnt >= net->fib_info_hash_size) {
12956 +               unsigned int new_size = net->fib_info_hash_size << 1;
12957                 struct hlist_head *new_info_hash;
12958                 struct hlist_head *new_laddrhash;
12959                 unsigned int bytes;
12960 @@ -716,18 +717,19 @@
12961                         memset(new_info_hash, 0, bytes);
12962                         memset(new_laddrhash, 0, bytes);
12963  
12964 -                       fib_hash_move(new_info_hash, new_laddrhash, new_size);
12965 +                       fib_hash_move(net, new_info_hash, new_laddrhash, new_size);
12966                 }
12967  
12968 -               if (!fib_hash_size)
12969 +               if (!net->fib_info_hash_size)
12970                         goto failure;
12971         }
12972  
12973         fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL);
12974         if (fi == NULL)
12975                 goto failure;
12976 -       fib_info_cnt++;
12977 +       net->fib_info_cnt++;
12978  
12979 +       fi->fib_net = hold_net(net);
12980         fi->fib_protocol = cfg->fc_protocol;
12981         fi->fib_flags = cfg->fc_flags;
12982         fi->fib_priority = cfg->fc_priority;
12983 @@ -799,7 +801,7 @@
12984                 if (nhs != 1 || nh->nh_gw)
12985                         goto err_inval;
12986                 nh->nh_scope = RT_SCOPE_NOWHERE;
12987 -               nh->nh_dev = dev_get_by_index(fi->fib_nh->nh_oif);
12988 +               nh->nh_dev = dev_get_by_index(net, fi->fib_nh->nh_oif);
12989                 err = -ENODEV;
12990                 if (nh->nh_dev == NULL)
12991                         goto failure;
12992 @@ -813,12 +815,12 @@
12993         if (fi->fib_prefsrc) {
12994                 if (cfg->fc_type != RTN_LOCAL || !cfg->fc_dst ||
12995                     fi->fib_prefsrc != cfg->fc_dst)
12996 -                       if (inet_addr_type(fi->fib_prefsrc) != RTN_LOCAL)
12997 +                       if (inet_addr_type(net, fi->fib_prefsrc) != RTN_LOCAL)
12998                                 goto err_inval;
12999         }
13000  
13001  link_it:
13002 -       if ((ofi = fib_find_info(fi)) != NULL) {
13003 +       if ((ofi = fib_find_info(net, fi)) != NULL) {
13004                 fi->fib_dead = 1;
13005                 free_fib_info(fi);
13006                 ofi->fib_treeref++;
13007 @@ -829,11 +831,13 @@
13008         atomic_inc(&fi->fib_clntref);
13009         spin_lock_bh(&fib_info_lock);
13010         hlist_add_head(&fi->fib_hash,
13011 -                      &fib_info_hash[fib_info_hashfn(fi)]);
13012 +                      &net->fib_info_hash[fib_info_hashfn(net, fi)]);
13013         if (fi->fib_prefsrc) {
13014                 struct hlist_head *head;
13015 +               unsigned int hash;
13016  
13017 -               head = &fib_info_laddrhash[fib_laddr_hashfn(fi->fib_prefsrc)];
13018 +               hash = fib_laddr_hashfn(net, fi->fib_prefsrc);
13019 +               head = &net->fib_info_laddrhash[hash];
13020                 hlist_add_head(&fi->fib_lhash, head);
13021         }
13022         change_nexthops(fi) {
13023 @@ -843,7 +847,7 @@
13024                 if (!nh->nh_dev)
13025                         continue;
13026                 hash = fib_devindex_hashfn(nh->nh_dev->ifindex);
13027 -               head = &fib_info_devhash[hash];
13028 +               head = &net->fib_info_devhash[hash];
13029                 hlist_add_head(&nh->nh_hash, head);
13030         } endfor_nexthops(fi)
13031         spin_unlock_bh(&fib_info_lock);
13032 @@ -1030,7 +1034,7 @@
13033     - device went down -> we must shutdown all nexthops going via it.
13034   */
13035  
13036 -int fib_sync_down(__be32 local, struct net_device *dev, int force)
13037 +int fib_sync_down(struct net *net, __be32 local, struct net_device *dev, int force)
13038  {
13039         int ret = 0;
13040         int scope = RT_SCOPE_NOWHERE;
13041 @@ -1038,9 +1042,9 @@
13042         if (force)
13043                 scope = -1;
13044  
13045 -       if (local && fib_info_laddrhash) {
13046 -               unsigned int hash = fib_laddr_hashfn(local);
13047 -               struct hlist_head *head = &fib_info_laddrhash[hash];
13048 +       if (local && net->fib_info_laddrhash) {
13049 +               unsigned int hash = fib_laddr_hashfn(net, local);
13050 +               struct hlist_head *head = &net->fib_info_laddrhash[hash];
13051                 struct hlist_node *node;
13052                 struct fib_info *fi;
13053  
13054 @@ -1055,7 +1059,7 @@
13055         if (dev) {
13056                 struct fib_info *prev_fi = NULL;
13057                 unsigned int hash = fib_devindex_hashfn(dev->ifindex);
13058 -               struct hlist_head *head = &fib_info_devhash[hash];
13059 +               struct hlist_head *head = &net->fib_info_devhash[hash];
13060                 struct hlist_node *node;
13061                 struct fib_nh *nh;
13062  
13063 @@ -1108,6 +1112,7 @@
13064  
13065  int fib_sync_up(struct net_device *dev)
13066  {
13067 +       struct net *net = dev->nd_net;
13068         struct fib_info *prev_fi;
13069         unsigned int hash;
13070         struct hlist_head *head;
13071 @@ -1120,7 +1125,7 @@
13072  
13073         prev_fi = NULL;
13074         hash = fib_devindex_hashfn(dev->ifindex);
13075 -       head = &fib_info_devhash[hash];
13076 +       head = &net->fib_info_devhash[hash];
13077         ret = 0;
13078  
13079         hlist_for_each_entry(nh, node, head, nh_hash) {
13080 @@ -1210,3 +1215,17 @@
13081         spin_unlock_bh(&fib_multipath_lock);
13082  }
13083  #endif
13084 +
13085 +int fib_info_init(struct net *net)
13086 +{
13087 +       net->fib_info_devhash = kzalloc(
13088 +               sizeof(struct hlist_head)*DEVINDEX_HASHSIZE, GFP_KERNEL);
13089 +       if (!net->fib_info_devhash)
13090 +               return -ENOMEM;
13091 +       return 0;
13092 +}
13093 +
13094 +void fib_info_exit(struct net *net)
13095 +{
13096 +       kfree(net->fib_info_devhash);
13097 +}
13098 diff -Nurb linux-2.6.22-try2/net/ipv4/fib_trie.c linux-2.6.22-try2-netns/net/ipv4/fib_trie.c
13099 --- linux-2.6.22-try2/net/ipv4/fib_trie.c       2007-12-19 13:37:57.000000000 -0500
13100 +++ linux-2.6.22-try2-netns/net/ipv4/fib_trie.c 2007-12-19 22:49:18.000000000 -0500
13101 @@ -78,6 +78,7 @@
13102  #include <net/route.h>
13103  #include <net/tcp.h>
13104  #include <net/sock.h>
13105 +#include <net/net_namespace.h>
13106  #include <net/ip_fib.h>
13107  #include "fib_lookup.h"
13108  
13109 @@ -172,7 +173,6 @@
13110  static void tnode_free(struct tnode *tn);
13111  
13112  static struct kmem_cache *fn_alias_kmem __read_mostly;
13113 -static struct trie *trie_local = NULL, *trie_main = NULL;
13114  
13115  
13116  /* rcu_read_lock needs to be hold by caller from readside */
13117 @@ -290,11 +290,10 @@
13118         WARN_ON(tn && tn->pos+tn->bits > 32);
13119  }
13120  
13121 -static int halve_threshold = 25;
13122 -static int inflate_threshold = 50;
13123 -static int halve_threshold_root = 8;
13124 -static int inflate_threshold_root = 15;
13125 -
13126 +static const int halve_threshold = 25;
13127 +static const int inflate_threshold = 50;
13128 +static const int halve_threshold_root = 15;
13129 +static const int inflate_threshold_root = 25;
13130  
13131  static void __alias_free_mem(struct rcu_head *head)
13132  {
13133 @@ -1771,11 +1770,10 @@
13134         return found;
13135  }
13136  
13137 -static int trie_last_dflt = -1;
13138 -
13139  static void
13140  fn_trie_select_default(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
13141  {
13142 +       struct net *net = flp->fl_net;
13143         struct trie *t = (struct trie *) tb->tb_data;
13144         int order, last_idx;
13145         struct fib_info *fi = NULL;
13146 @@ -1819,28 +1817,28 @@
13147                         if (next_fi != res->fi)
13148                                 break;
13149                 } else if (!fib_detect_death(fi, order, &last_resort,
13150 -                                            &last_idx, &trie_last_dflt)) {
13151 +                                            &last_idx, &net->trie_last_dflt)) {
13152                         if (res->fi)
13153                                 fib_info_put(res->fi);
13154                         res->fi = fi;
13155                         atomic_inc(&fi->fib_clntref);
13156 -                       trie_last_dflt = order;
13157 +                       net->trie_last_dflt = order;
13158                         goto out;
13159                 }
13160                 fi = next_fi;
13161                 order++;
13162         }
13163         if (order <= 0 || fi == NULL) {
13164 -               trie_last_dflt = -1;
13165 +               net->trie_last_dflt = -1;
13166                 goto out;
13167         }
13168  
13169 -       if (!fib_detect_death(fi, order, &last_resort, &last_idx, &trie_last_dflt)) {
13170 +       if (!fib_detect_death(fi, order, &last_resort, &last_idx, &net->trie_last_dflt)) {
13171                 if (res->fi)
13172                         fib_info_put(res->fi);
13173                 res->fi = fi;
13174                 atomic_inc(&fi->fib_clntref);
13175 -               trie_last_dflt = order;
13176 +               net->trie_last_dflt = order;
13177                 goto out;
13178         }
13179         if (last_idx >= 0) {
13180 @@ -1850,7 +1848,7 @@
13181                 if (last_resort)
13182                         atomic_inc(&last_resort->fib_clntref);
13183         }
13184 -       trie_last_dflt = last_idx;
13185 +       net->trie_last_dflt = last_idx;
13186   out:;
13187         rcu_read_unlock();
13188  }
13189 @@ -1957,11 +1955,15 @@
13190  
13191  /* Fix more generic FIB names for init later */
13192  
13193 -#ifdef CONFIG_IP_MULTIPLE_TABLES
13194 +void fib_hash_exit(struct fib_table *tb)
13195 +{
13196 +       if (!tb)
13197 +               return;
13198 +       fn_trie_flush(tb);
13199 +       kfree(tb);
13200 +}
13201 +
13202  struct fib_table * fib_hash_init(u32 id)
13203 -#else
13204 -struct fib_table * __init fib_hash_init(u32 id)
13205 -#endif
13206  {
13207         struct fib_table *tb;
13208         struct trie *t;
13209 @@ -1991,11 +1993,6 @@
13210         trie_init(t);
13211  
13212         if (id == RT_TABLE_LOCAL)
13213 -               trie_local = t;
13214 -       else if (id == RT_TABLE_MAIN)
13215 -               trie_main = t;
13216 -
13217 -       if (id == RT_TABLE_LOCAL)
13218                 printk(KERN_INFO "IPv4 FIB: Using LC-trie version %s\n", VERSION);
13219  
13220         return tb;
13221 @@ -2004,6 +2001,8 @@
13222  #ifdef CONFIG_PROC_FS
13223  /* Depth first Trie walk iterator */
13224  struct fib_trie_iter {
13225 +       struct net *net;
13226 +       struct trie *trie_local, *trie_main;
13227         struct tnode *tnode;
13228         struct trie *trie;
13229         unsigned index;
13230 @@ -2170,7 +2169,21 @@
13231  
13232  static int fib_triestat_seq_show(struct seq_file *seq, void *v)
13233  {
13234 +       struct net *net = seq->private;
13235 +       struct trie *trie_local, *trie_main;
13236         struct trie_stat *stat;
13237 +       struct fib_table *tb;
13238 +
13239 +       trie_local = NULL;
13240 +       tb = fib_get_table(net, RT_TABLE_LOCAL);
13241 +       if (tb)
13242 +               trie_local = (struct trie *) tb->tb_data;
13243 +
13244 +       trie_main = NULL;
13245 +       tb = fib_get_table(net, RT_TABLE_MAIN);
13246 +       if (tb)
13247 +               trie_main = (struct trie *) tb->tb_data;
13248 +
13249  
13250         stat = kmalloc(sizeof(*stat), GFP_KERNEL);
13251         if (!stat)
13252 @@ -2197,7 +2210,15 @@
13253  
13254  static int fib_triestat_seq_open(struct inode *inode, struct file *file)
13255  {
13256 -       return single_open(file, fib_triestat_seq_show, NULL);
13257 +       return single_open(file, fib_triestat_seq_show, 
13258 +                               get_net(PROC_NET(inode)));
13259 +}
13260 +
13261 +static int fib_triestat_seq_release(struct inode *inode, struct file *file)
13262 +{
13263 +       struct seq_file *seq = file->private_data;
13264 +       put_net(seq->private);
13265 +       return single_release(inode, file);
13266  }
13267  
13268  static const struct file_operations fib_triestat_fops = {
13269 @@ -2205,7 +2226,7 @@
13270         .open   = fib_triestat_seq_open,
13271         .read   = seq_read,
13272         .llseek = seq_lseek,
13273 -       .release = single_release,
13274 +       .release = fib_triestat_seq_release,
13275  };
13276  
13277  static struct node *fib_trie_get_idx(struct fib_trie_iter *iter,
13278 @@ -2214,13 +2235,13 @@
13279         loff_t idx = 0;
13280         struct node *n;
13281  
13282 -       for (n = fib_trie_get_first(iter, trie_local);
13283 +       for (n = fib_trie_get_first(iter, iter->trie_local);
13284              n; ++idx, n = fib_trie_get_next(iter)) {
13285                 if (pos == idx)
13286                         return n;
13287         }
13288  
13289 -       for (n = fib_trie_get_first(iter, trie_main);
13290 +       for (n = fib_trie_get_first(iter, iter->trie_main);
13291              n; ++idx, n = fib_trie_get_next(iter)) {
13292                 if (pos == idx)
13293                         return n;
13294 @@ -2230,10 +2251,23 @@
13295  
13296  static void *fib_trie_seq_start(struct seq_file *seq, loff_t *pos)
13297  {
13298 +       struct fib_trie_iter *iter = seq->private;
13299 +       struct fib_table *tb;
13300 +
13301 +       if (!iter->trie_local) {
13302 +               tb = fib_get_table(iter->net, RT_TABLE_LOCAL);
13303 +               if (tb)
13304 +                       iter->trie_local = (struct trie *) tb->tb_data;
13305 +       }
13306 +       if (!iter->trie_main) {
13307 +               tb = fib_get_table(iter->net, RT_TABLE_MAIN);
13308 +               if (tb)
13309 +                       iter->trie_main = (struct trie *) tb->tb_data;
13310 +       }
13311         rcu_read_lock();
13312         if (*pos == 0)
13313                 return SEQ_START_TOKEN;
13314 -       return fib_trie_get_idx(seq->private, *pos - 1);
13315 +       return fib_trie_get_idx(iter, *pos - 1);
13316  }
13317  
13318  static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos)
13319 @@ -2251,8 +2285,8 @@
13320                 return v;
13321  
13322         /* continue scan in next trie */
13323 -       if (iter->trie == trie_local)
13324 -               return fib_trie_get_first(iter, trie_main);
13325 +       if (iter->trie == iter->trie_local)
13326 +               return fib_trie_get_first(iter, iter->trie_main);
13327  
13328         return NULL;
13329  }
13330 @@ -2318,7 +2352,7 @@
13331                 return 0;
13332  
13333         if (!NODE_PARENT(n)) {
13334 -               if (iter->trie == trie_local)
13335 +               if (iter->trie == iter->trie_local)
13336                         seq_puts(seq, "<local>:\n");
13337                 else
13338                         seq_puts(seq, "<main>:\n");
13339 @@ -2384,6 +2418,7 @@
13340         seq          = file->private_data;
13341         seq->private = s;
13342         memset(s, 0, sizeof(*s));
13343 +       s->net = get_net(PROC_NET(inode));
13344  out:
13345         return rc;
13346  out_kfree:
13347 @@ -2391,12 +2426,20 @@
13348         goto out;
13349  }
13350  
13351 +static int fib_trie_seq_release(struct inode *inode, struct file *file)
13352 +{
13353 +       struct seq_file *seq = file->private_data;
13354 +       struct fib_trie_iter *iter = seq->private;
13355 +       put_net(iter->net);
13356 +       return seq_release_private(inode, file);
13357 +}
13358 +
13359  static const struct file_operations fib_trie_fops = {
13360         .owner  = THIS_MODULE,
13361         .open   = fib_trie_seq_open,
13362         .read   = seq_read,
13363         .llseek = seq_lseek,
13364 -       .release = seq_release_private,
13365 +       .release = fib_trie_seq_release,
13366  };
13367  
13368  static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi)
13369 @@ -2434,7 +2477,7 @@
13370                 return 0;
13371         }
13372  
13373 -       if (iter->trie == trie_local)
13374 +       if (iter->trie == iter->trie_local)
13375                 return 0;
13376         if (IS_TNODE(l))
13377                 return 0;
13378 @@ -2505,6 +2548,7 @@
13379         seq          = file->private_data;
13380         seq->private = s;
13381         memset(s, 0, sizeof(*s));
13382 +       s->net = get_net(PROC_NET(inode));
13383  out:
13384         return rc;
13385  out_kfree:
13386 @@ -2517,35 +2561,37 @@
13387         .open   = fib_route_seq_open,
13388         .read   = seq_read,
13389         .llseek = seq_lseek,
13390 -       .release = seq_release_private,
13391 +       .release = fib_trie_seq_release,
13392  };
13393  
13394 -int __init fib_proc_init(void)
13395 +int fib_proc_init(struct net *net)
13396  {
13397 -       if (!proc_net_fops_create("fib_trie", S_IRUGO, &fib_trie_fops))
13398 +       net->trie_last_dflt = -1;
13399 +
13400 +       if (!proc_net_fops_create(net, "fib_trie", S_IRUGO, &fib_trie_fops))
13401                 goto out1;
13402  
13403 -       if (!proc_net_fops_create("fib_triestat", S_IRUGO, &fib_triestat_fops))
13404 +       if (!proc_net_fops_create(net, "fib_triestat", S_IRUGO, &fib_triestat_fops))
13405                 goto out2;
13406  
13407 -       if (!proc_net_fops_create("route", S_IRUGO, &fib_route_fops))
13408 +       if (!proc_net_fops_create(net, "route", S_IRUGO, &fib_route_fops))
13409                 goto out3;
13410  
13411         return 0;
13412  
13413  out3:
13414 -       proc_net_remove("fib_triestat");
13415 +       proc_net_remove(net, "fib_triestat");
13416  out2:
13417 -       proc_net_remove("fib_trie");
13418 +       proc_net_remove(net, "fib_trie");
13419  out1:
13420         return -ENOMEM;
13421  }
13422  
13423 -void __init fib_proc_exit(void)
13424 +void fib_proc_exit(struct net *net)
13425  {
13426 -       proc_net_remove("fib_trie");
13427 -       proc_net_remove("fib_triestat");
13428 -       proc_net_remove("route");
13429 +       proc_net_remove(net, "fib_trie");
13430 +       proc_net_remove(net, "fib_triestat");
13431 +       proc_net_remove(net, "route");
13432  }
13433  
13434  #endif /* CONFIG_PROC_FS */
13435 diff -Nurb linux-2.6.22-try2/net/ipv4/icmp.c linux-2.6.22-try2-netns/net/ipv4/icmp.c
13436 --- linux-2.6.22-try2/net/ipv4/icmp.c   2007-12-19 13:37:57.000000000 -0500
13437 +++ linux-2.6.22-try2-netns/net/ipv4/icmp.c     2007-12-19 22:49:18.000000000 -0500
13438 @@ -229,14 +229,13 @@
13439   *
13440   *     On SMP we have one ICMP socket per-cpu.
13441   */
13442 -static DEFINE_PER_CPU(struct socket *, __icmp_socket) = NULL;
13443 -#define icmp_socket    __get_cpu_var(__icmp_socket)
13444 +#define icmp_socket(NET) (*per_cpu_ptr((NET)->__icmp_socket, smp_processor_id()))
13445  
13446 -static __inline__ int icmp_xmit_lock(void)
13447 +static __inline__ int icmp_xmit_lock(struct net *net)
13448  {
13449         local_bh_disable();
13450  
13451 -       if (unlikely(!spin_trylock(&icmp_socket->sk->sk_lock.slock))) {
13452 +       if (unlikely(!spin_trylock(&icmp_socket(net)->sk->sk_lock.slock))) {
13453                 /* This can happen if the output path signals a
13454                  * dst_link_failure() for an outgoing ICMP packet.
13455                  */
13456 @@ -246,9 +245,9 @@
13457         return 0;
13458  }
13459  
13460 -static void icmp_xmit_unlock(void)
13461 +static void icmp_xmit_unlock(struct net *net)
13462  {
13463 -       spin_unlock_bh(&icmp_socket->sk->sk_lock.slock);
13464 +       spin_unlock_bh(&icmp_socket(net)->sk->sk_lock.slock);
13465  }
13466  
13467  /*
13468 @@ -347,19 +346,20 @@
13469  static void icmp_push_reply(struct icmp_bxm *icmp_param,
13470                             struct ipcm_cookie *ipc, struct rtable *rt)
13471  {
13472 +       struct net *net = icmp_param->skb->dev->nd_net;
13473         struct sk_buff *skb;
13474  
13475 -       if (ip_append_data(icmp_socket->sk, icmp_glue_bits, icmp_param,
13476 +       if (ip_append_data(icmp_socket(net)->sk, icmp_glue_bits, icmp_param,
13477                            icmp_param->data_len+icmp_param->head_len,
13478                            icmp_param->head_len,
13479                            ipc, rt, MSG_DONTWAIT) < 0)
13480 -               ip_flush_pending_frames(icmp_socket->sk);
13481 -       else if ((skb = skb_peek(&icmp_socket->sk->sk_write_queue)) != NULL) {
13482 +               ip_flush_pending_frames(icmp_socket(net)->sk);
13483 +       else if ((skb = skb_peek(&icmp_socket(net)->sk->sk_write_queue)) != NULL) {
13484                 struct icmphdr *icmph = icmp_hdr(skb);
13485                 __wsum csum = 0;
13486                 struct sk_buff *skb1;
13487  
13488 -               skb_queue_walk(&icmp_socket->sk->sk_write_queue, skb1) {
13489 +               skb_queue_walk(&icmp_socket(net)->sk->sk_write_queue, skb1) {
13490                         csum = csum_add(csum, skb1->csum);
13491                 }
13492                 csum = csum_partial_copy_nocheck((void *)&icmp_param->data,
13493 @@ -367,7 +367,7 @@
13494                                                  icmp_param->head_len, csum);
13495                 icmph->checksum = csum_fold(csum);
13496                 skb->ip_summed = CHECKSUM_NONE;
13497 -               ip_push_pending_frames(icmp_socket->sk);
13498 +               ip_push_pending_frames(icmp_socket(net)->sk);
13499         }
13500  }
13501  
13502 @@ -377,7 +377,8 @@
13503  
13504  static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
13505  {
13506 -       struct sock *sk = icmp_socket->sk;
13507 +       struct net *net = icmp_param->skb->dev->nd_net;
13508 +       struct sock *sk = icmp_socket(net)->sk;
13509         struct inet_sock *inet = inet_sk(sk);
13510         struct ipcm_cookie ipc;
13511         struct rtable *rt = (struct rtable *)skb->dst;
13512 @@ -386,7 +387,7 @@
13513         if (ip_options_echo(&icmp_param->replyopts, skb))
13514                 return;
13515  
13516 -       if (icmp_xmit_lock())
13517 +       if (icmp_xmit_lock(net))
13518                 return;
13519  
13520         icmp_param->data.icmph.checksum = 0;
13521 @@ -401,7 +402,8 @@
13522                         daddr = icmp_param->replyopts.faddr;
13523         }
13524         {
13525 -               struct flowi fl = { .nl_u = { .ip4_u =
13526 +               struct flowi fl = { .fl_net = net,
13527 +                                   .nl_u = { .ip4_u =
13528                                               { .daddr = daddr,
13529                                                 .saddr = rt->rt_spec_dst,
13530                                                 .tos = RT_TOS(ip_hdr(skb)->tos) } },
13531 @@ -415,7 +417,7 @@
13532                 icmp_push_reply(icmp_param, &ipc, rt);
13533         ip_rt_put(rt);
13534  out_unlock:
13535 -       icmp_xmit_unlock();
13536 +       icmp_xmit_unlock(net);
13537  }
13538  
13539  
13540 @@ -436,6 +438,7 @@
13541         int room;
13542         struct icmp_bxm icmp_param;
13543         struct rtable *rt = (struct rtable *)skb_in->dst;
13544 +       struct net *net;
13545         struct ipcm_cookie ipc;
13546         __be32 saddr;
13547         u8  tos;
13548 @@ -443,6 +446,7 @@
13549         if (!rt)
13550                 goto out;
13551  
13552 +       net = rt->fl.fl_net;
13553         /*
13554          *      Find the original header. It is expected to be valid, of course.
13555          *      Check this, icmp_send is called from the most obscure devices
13556 @@ -505,7 +509,7 @@
13557                 }
13558         }
13559  
13560 -       if (icmp_xmit_lock())
13561 +       if (icmp_xmit_lock(net))
13562                 return;
13563  
13564         /*
13565 @@ -517,7 +521,7 @@
13566                 struct net_device *dev = NULL;
13567  
13568                 if (rt->fl.iif && sysctl_icmp_errors_use_inbound_ifaddr)
13569 -                       dev = dev_get_by_index(rt->fl.iif);
13570 +                       dev = dev_get_by_index(&init_net, rt->fl.iif);
13571  
13572                 if (dev) {
13573                         saddr = inet_select_addr(dev, 0, RT_SCOPE_LINK);
13574 @@ -545,12 +549,13 @@
13575         icmp_param.skb    = skb_in;
13576         icmp_param.offset = skb_network_offset(skb_in);
13577         icmp_out_count(icmp_param.data.icmph.type);
13578 -       inet_sk(icmp_socket->sk)->tos = tos;
13579 +       inet_sk(icmp_socket(net)->sk)->tos = tos;
13580         ipc.addr = iph->saddr;
13581         ipc.opt = &icmp_param.replyopts;
13582  
13583         {
13584                 struct flowi fl = {
13585 +                       .fl_net = net,
13586                         .nl_u = {
13587                                 .ip4_u = {
13588                                         .daddr = icmp_param.replyopts.srr ?
13589 @@ -593,7 +598,7 @@
13590  ende:
13591         ip_rt_put(rt);
13592  out_unlock:
13593 -       icmp_xmit_unlock();
13594 +       icmp_xmit_unlock(net);
13595  out:;
13596  }
13597  
13598 @@ -604,6 +609,7 @@
13599  
13600  static void icmp_unreach(struct sk_buff *skb)
13601  {
13602 +       struct net *net = skb->dev->nd_net;
13603         struct iphdr *iph;
13604         struct icmphdr *icmph;
13605         int hash, protocol;
13606 @@ -634,7 +640,7 @@
13607                 case ICMP_PORT_UNREACH:
13608                         break;
13609                 case ICMP_FRAG_NEEDED:
13610 -                       if (ipv4_config.no_pmtu_disc) {
13611 +                       if (net->sysctl_ipv4_no_pmtu_disc) {
13612                                 LIMIT_NETDEBUG(KERN_INFO "ICMP: %u.%u.%u.%u: "
13613                                                          "fragmentation needed "
13614                                                          "and DF set.\n",
13615 @@ -678,7 +684,7 @@
13616          */
13617  
13618         if (!sysctl_icmp_ignore_bogus_error_responses &&
13619 -           inet_addr_type(iph->daddr) == RTN_BROADCAST) {
13620 +           inet_addr_type(net, iph->daddr) == RTN_BROADCAST) {
13621                 if (net_ratelimit())
13622                         printk(KERN_WARNING "%u.%u.%u.%u sent an invalid ICMP "
13623                                             "type %u, code %u "
13624 @@ -707,7 +713,7 @@
13625         hash = protocol & (MAX_INET_PROTOS - 1);
13626         read_lock(&raw_v4_lock);
13627         if ((raw_sk = sk_head(&raw_v4_htable[hash])) != NULL) {
13628 -               while ((raw_sk = __raw_v4_lookup(raw_sk, protocol, iph->daddr,
13629 +               while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol, iph->daddr,
13630                                                  iph->saddr,
13631                                                  skb->dev->ifindex, skb->skb_tag)) != NULL) {
13632                         raw_err(raw_sk, skb, info);
13633 @@ -1179,29 +1185,54 @@
13634         },
13635  };
13636  
13637 -void __init icmp_init(struct net_proto_family *ops)
13638 +static void icmp_net_exit(struct net *net)
13639  {
13640 -       struct inet_sock *inet;
13641 +       struct socket **sock;
13642         int i;
13643  
13644         for_each_possible_cpu(i) {
13645 +               sock = percpu_ptr(net->__icmp_socket, i);
13646 +               if (!*sock)
13647 +                       continue;
13648 +               /* At the last minute lie and say this is a socket for
13649 +                * the initial network namespace.  So the socket will
13650 +                * be safe to free. 
13651 +                */
13652 +               (*sock)->sk->sk_net = get_net(&init_net);
13653 +               sock_release(*sock);
13654 +               *sock = NULL;
13655 +       }
13656 +       percpu_free(net->__icmp_socket);
13657 +}
13658 +
13659 +static int icmp_net_init(struct net *net)
13660 +{
13661 +       struct socket **sock;
13662 +       struct inet_sock *inet;
13663                 int err;
13664 +       int i;
13665 +
13666 +       net->__icmp_socket = alloc_percpu(struct socket *);
13667 +       if (!net->__icmp_socket)
13668 +               return -ENOMEM;
13669 +       
13670 +       for_each_possible_cpu(i) {
13671  
13672 -               err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP,
13673 -                                      &per_cpu(__icmp_socket, i));
13674 +               sock = percpu_ptr(net->__icmp_socket, i);
13675  
13676 +               err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP, sock);
13677                 if (err < 0)
13678 -                       panic("Failed to create the ICMP control socket.\n");
13679 +                       goto fail;
13680  
13681 -               per_cpu(__icmp_socket, i)->sk->sk_allocation = GFP_ATOMIC;
13682 +               (*sock)->sk->sk_allocation = GFP_ATOMIC;
13683  
13684                 /* Enough space for 2 64K ICMP packets, including
13685                  * sk_buff struct overhead.
13686                  */
13687 -               per_cpu(__icmp_socket, i)->sk->sk_sndbuf =
13688 +               (*sock)->sk->sk_sndbuf =
13689                         (2 * ((64 * 1024) + sizeof(struct sk_buff)));
13690  
13691 -               inet = inet_sk(per_cpu(__icmp_socket, i)->sk);
13692 +               inet = inet_sk((*sock)->sk);
13693                 inet->uc_ttl = -1;
13694                 inet->pmtudisc = IP_PMTUDISC_DONT;
13695  
13696 @@ -1209,8 +1240,27 @@
13697                  * see it, we do not wish this socket to see incoming
13698                  * packets.
13699                  */
13700 -               per_cpu(__icmp_socket, i)->sk->sk_prot->unhash(per_cpu(__icmp_socket, i)->sk);
13701 +               (*sock)->sk->sk_prot->unhash((*sock)->sk);
13702 +
13703 +               /* Don't hold an extra reference on the namespace */
13704 +               put_net((*sock)->sk->sk_net);
13705         }
13706 +       return 0;
13707 +fail:
13708 +       icmp_net_exit(net);
13709 +       return err;
13710 +
13711 +}
13712 +
13713 +static struct pernet_operations icmp_net_ops = {
13714 +       .init = icmp_net_init,
13715 +       .exit = icmp_net_exit,
13716 +};
13717 +
13718 +void __init icmp_init(struct net_proto_family *ops)
13719 +{
13720 +       if (register_pernet_subsys(&icmp_net_ops))
13721 +               panic("Failed to create the ICMP control socket.\n");
13722  }
13723  
13724  EXPORT_SYMBOL(icmp_err_convert);
13725 diff -Nurb linux-2.6.22-try2/net/ipv4/igmp.c linux-2.6.22-try2-netns/net/ipv4/igmp.c
13726 --- linux-2.6.22-try2/net/ipv4/igmp.c   2007-12-19 13:37:57.000000000 -0500
13727 +++ linux-2.6.22-try2-netns/net/ipv4/igmp.c     2007-12-19 22:49:18.000000000 -0500
13728 @@ -97,6 +97,7 @@
13729  #include <net/route.h>
13730  #include <net/sock.h>
13731  #include <net/checksum.h>
13732 +#include <net/net_namespace.h>
13733  #include <linux/netfilter_ipv4.h>
13734  #ifdef CONFIG_IP_MROUTE
13735  #include <linux/mroute.h>
13736 @@ -129,12 +130,12 @@
13737   */
13738  
13739  #define IGMP_V1_SEEN(in_dev) \
13740 -       (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 1 || \
13741 +       (IPV4_DEVCONF_ALL((in_dev)->dev->nd_net, FORCE_IGMP_VERSION) == 1 || \
13742          IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 1 || \
13743          ((in_dev)->mr_v1_seen && \
13744           time_before(jiffies, (in_dev)->mr_v1_seen)))
13745  #define IGMP_V2_SEEN(in_dev) \
13746 -       (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 2 || \
13747 +       (IPV4_DEVCONF_ALL((in_dev)->dev->nd_net, FORCE_IGMP_VERSION) == 2 || \
13748          IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 2 || \
13749          ((in_dev)->mr_v2_seen && \
13750           time_before(jiffies, (in_dev)->mr_v2_seen)))
13751 @@ -296,7 +297,8 @@
13752                 return NULL;
13753  
13754         {
13755 -               struct flowi fl = { .oif = dev->ifindex,
13756 +               struct flowi fl = { .fl_net = &init_net,
13757 +                                   .oif = dev->ifindex,
13758                                     .nl_u = { .ip4_u = {
13759                                     .daddr = IGMPV3_ALL_MCR } },
13760                                     .proto = IPPROTO_IGMP };
13761 @@ -646,7 +648,8 @@
13762                 dst = group;
13763  
13764         {
13765 -               struct flowi fl = { .oif = dev->ifindex,
13766 +               struct flowi fl = { .fl_net = &init_net,
13767 +                                   .oif = dev->ifindex,
13768                                     .nl_u = { .ip4_u = { .daddr = dst } },
13769                                     .proto = IPPROTO_IGMP };
13770                 if (ip_route_output_key(&rt, &fl))
13771 @@ -929,6 +932,11 @@
13772         struct in_device *in_dev = in_dev_get(skb->dev);
13773         int len = skb->len;
13774  
13775 +       if (skb->dev->nd_net != &init_net) {
13776 +               kfree_skb(skb);
13777 +               return 0;
13778 +       }
13779 +
13780         if (in_dev==NULL) {
13781                 kfree_skb(skb);
13782                 return 0;
13783 @@ -1393,20 +1401,22 @@
13784  
13785  static struct in_device * ip_mc_find_dev(struct ip_mreqn *imr)
13786  {
13787 -       struct flowi fl = { .nl_u = { .ip4_u =
13788 -                                     { .daddr = imr->imr_multiaddr.s_addr } } };
13789 +       struct flowi fl = { 
13790 +               .fl_net = &init_net,
13791 +               .nl_u = { .ip4_u = { .daddr = imr->imr_multiaddr.s_addr } }
13792 +       };
13793         struct rtable *rt;
13794         struct net_device *dev = NULL;
13795         struct in_device *idev = NULL;
13796  
13797         if (imr->imr_ifindex) {
13798 -               idev = inetdev_by_index(imr->imr_ifindex);
13799 +               idev = inetdev_by_index(&init_net, imr->imr_ifindex);
13800                 if (idev)
13801                         __in_dev_put(idev);
13802                 return idev;
13803         }
13804         if (imr->imr_address.s_addr) {
13805 -               dev = ip_dev_find(imr->imr_address.s_addr);
13806 +               dev = ip_dev_find(&init_net, imr->imr_address.s_addr);
13807                 if (!dev)
13808                         return NULL;
13809                 dev_put(dev);
13810 @@ -2234,7 +2244,7 @@
13811                 struct in_device *in_dev;
13812                 inet->mc_list = iml->next;
13813  
13814 -               in_dev = inetdev_by_index(iml->multi.imr_ifindex);
13815 +               in_dev = inetdev_by_index(&init_net, iml->multi.imr_ifindex);
13816                 (void) ip_mc_leave_src(sk, iml, in_dev);
13817                 if (in_dev != NULL) {
13818                         ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr);
13819 @@ -2291,7 +2301,7 @@
13820         struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq);
13821  
13822         state->in_dev = NULL;
13823 -       for_each_netdev(state->dev) {
13824 +       for_each_netdev(&init_net, state->dev) {
13825                 struct in_device *in_dev;
13826                 in_dev = in_dev_get(state->dev);
13827                 if (!in_dev)
13828 @@ -2453,7 +2463,7 @@
13829  
13830         state->idev = NULL;
13831         state->im = NULL;
13832 -       for_each_netdev(state->dev) {
13833 +       for_each_netdev(&init_net, state->dev) {
13834                 struct in_device *idev;
13835                 idev = in_dev_get(state->dev);
13836                 if (unlikely(idev == NULL))
13837 @@ -2613,8 +2623,8 @@
13838  
13839  int __init igmp_mc_proc_init(void)
13840  {
13841 -       proc_net_fops_create("igmp", S_IRUGO, &igmp_mc_seq_fops);
13842 -       proc_net_fops_create("mcfilter", S_IRUGO, &igmp_mcf_seq_fops);
13843 +       proc_net_fops_create(&init_net, "igmp", S_IRUGO, &igmp_mc_seq_fops);
13844 +       proc_net_fops_create(&init_net, "mcfilter", S_IRUGO, &igmp_mcf_seq_fops);
13845         return 0;
13846  }
13847  #endif
13848 diff -Nurb linux-2.6.22-try2/net/ipv4/inet_connection_sock.c linux-2.6.22-try2-netns/net/ipv4/inet_connection_sock.c
13849 --- linux-2.6.22-try2/net/ipv4/inet_connection_sock.c   2007-12-19 13:37:57.000000000 -0500
13850 +++ linux-2.6.22-try2-netns/net/ipv4/inet_connection_sock.c     2007-12-19 23:25:05.000000000 -0500
13851 @@ -32,7 +32,7 @@
13852  /*
13853   * This array holds the first and last local port number.
13854   */
13855 -int sysctl_local_port_range[2] = { 32768, 61000 };
13856 +//int sysctl_local_port_range[2] = { 32768, 61000 };
13857  
13858  int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
13859  {
13860 @@ -74,6 +74,7 @@
13861  
13862         sk_for_each_bound(sk2, node, &tb->owners) {
13863                 if (sk != sk2 &&
13864 +                   (sk->sk_net == sk2->sk_net) &&
13865                     !inet_v6_ipv6only(sk2) &&
13866                     (!sk->sk_bound_dev_if ||
13867                      !sk2->sk_bound_dev_if ||
13868 @@ -98,6 +99,7 @@
13869                       int (*bind_conflict)(const struct sock *sk,
13870                                            const struct inet_bind_bucket *tb))
13871  {
13872 +       struct net *net = sk->sk_net;
13873         struct inet_bind_hashbucket *head;
13874         struct hlist_node *node;
13875         struct inet_bind_bucket *tb;
13876 @@ -105,16 +107,16 @@
13877  
13878         local_bh_disable();
13879         if (!snum) {
13880 -               int low = sysctl_local_port_range[0];
13881 -               int high = sysctl_local_port_range[1];
13882 +               int low = sk->sk_net->sysctl_local_port_range[0];
13883 +               int high = sk->sk_net->sysctl_local_port_range[1];
13884                 int remaining = (high - low) + 1;
13885                 int rover = net_random() % (high - low) + low;
13886  
13887                 do {
13888 -                       head = &hashinfo->bhash[inet_bhashfn(rover, hashinfo->bhash_size)];
13889 +                       head = &hashinfo->bhash[inet_bhashfn(net, rover, hashinfo->bhash_size)];
13890                         spin_lock(&head->lock);
13891                         inet_bind_bucket_for_each(tb, node, &head->chain)
13892 -                               if (tb->port == rover)
13893 +                               if ((tb->port == rover) && (tb->net == net))
13894                                         goto next;
13895                         break;
13896                 next:
13897 @@ -138,10 +140,10 @@
13898                  */
13899                 snum = rover;
13900         } else {
13901 -               head = &hashinfo->bhash[inet_bhashfn(snum, hashinfo->bhash_size)];
13902 +               head = &hashinfo->bhash[inet_bhashfn(net, snum, hashinfo->bhash_size)];
13903                 spin_lock(&head->lock);
13904                 inet_bind_bucket_for_each(tb, node, &head->chain)
13905 -                       if (tb->port == snum)
13906 +                       if ((tb->port == snum) && (tb->net==net))
13907                                 goto tb_found;
13908         }
13909         tb = NULL;
13910 @@ -161,7 +163,7 @@
13911         }
13912  tb_not_found:
13913         ret = 1;
13914 -       if (!tb && (tb = inet_bind_bucket_create(hashinfo->bind_bucket_cachep, head, snum)) == NULL)
13915 +       if (!tb && (tb = inet_bind_bucket_create(hashinfo->bind_bucket_cachep, head, net, snum)) == NULL)
13916                 goto fail_unlock;
13917         if (hlist_empty(&tb->owners)) {
13918                 if (sk->sk_reuse && sk->sk_state != TCP_LISTEN)
13919 @@ -341,7 +343,8 @@
13920         struct rtable *rt;
13921         const struct inet_request_sock *ireq = inet_rsk(req);
13922         struct ip_options *opt = inet_rsk(req)->opt;
13923 -       struct flowi fl = { .oif = sk->sk_bound_dev_if,
13924 +       struct flowi fl = { .fl_net = sk->sk_net,
13925 +                       .oif = sk->sk_bound_dev_if,
13926                             .nl_u = { .ip4_u =
13927                                       { .daddr = ((opt && opt->srr) ?
13928                                                   opt->faddr :
13929 diff -Nurb linux-2.6.22-try2/net/ipv4/inet_diag.c linux-2.6.22-try2-netns/net/ipv4/inet_diag.c
13930 --- linux-2.6.22-try2/net/ipv4/inet_diag.c      2007-12-19 13:37:57.000000000 -0500
13931 +++ linux-2.6.22-try2-netns/net/ipv4/inet_diag.c        2007-12-19 22:49:20.000000000 -0500
13932 @@ -227,6 +227,7 @@
13933  static int inet_diag_get_exact(struct sk_buff *in_skb,
13934                                const struct nlmsghdr *nlh)
13935  {
13936 +       struct net *net = in_skb->sk->sk_net;
13937         int err;
13938         struct sock *sk;
13939         struct inet_diag_req *req = NLMSG_DATA(nlh);
13940 @@ -242,7 +243,7 @@
13941                 /* TODO: lback */
13942                 sk = inet_lookup(hashinfo, req->id.idiag_dst[0],
13943                                  req->id.idiag_dport, req->id.idiag_src[0],
13944 -                                req->id.idiag_sport, req->id.idiag_if);
13945 +                                req->id.idiag_sport, req->id.idiag_if, net);
13946         }
13947  #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
13948         else if (req->idiag_family == AF_INET6) {
13949 @@ -251,7 +252,7 @@
13950                                   req->id.idiag_dport,
13951                                   (struct in6_addr *)req->id.idiag_src,
13952                                   req->id.idiag_sport,
13953 -                                 req->id.idiag_if);
13954 +                                 req->id.idiag_if, net);
13955         }
13956  #endif
13957         else {
13958 @@ -906,8 +907,8 @@
13959         if (!inet_diag_table)
13960                 goto out;
13961  
13962 -       idiagnl = netlink_kernel_create(NETLINK_INET_DIAG, 0, inet_diag_rcv,
13963 -                                       NULL, THIS_MODULE);
13964 +       idiagnl = netlink_kernel_create(&init_net, NETLINK_INET_DIAG, 0,
13965 +                                       inet_diag_rcv, NULL, THIS_MODULE);
13966         if (idiagnl == NULL)
13967                 goto out_free_table;
13968         err = 0;
13969 diff -Nurb linux-2.6.22-try2/net/ipv4/inet_hashtables.c linux-2.6.22-try2-netns/net/ipv4/inet_hashtables.c
13970 --- linux-2.6.22-try2/net/ipv4/inet_hashtables.c        2007-12-19 13:37:57.000000000 -0500
13971 +++ linux-2.6.22-try2-netns/net/ipv4/inet_hashtables.c  2007-12-19 23:27:05.000000000 -0500
13972 @@ -29,11 +29,13 @@
13973   */
13974  struct inet_bind_bucket *inet_bind_bucket_create(struct kmem_cache *cachep,
13975                                                  struct inet_bind_hashbucket *head,
13976 +                                                struct net *net,
13977                                                  const unsigned short snum)
13978  {
13979         struct inet_bind_bucket *tb = kmem_cache_alloc(cachep, GFP_ATOMIC);
13980  
13981         if (tb != NULL) {
13982 +               tb->net       = net;
13983                 tb->port      = snum;
13984                 tb->fastreuse = 0;
13985                 INIT_HLIST_HEAD(&tb->owners);
13986 @@ -66,7 +68,7 @@
13987   */
13988  static void __inet_put_port(struct inet_hashinfo *hashinfo, struct sock *sk)
13989  {
13990 -       const int bhash = inet_bhashfn(inet_sk(sk)->num, hashinfo->bhash_size);
13991 +       const int bhash = inet_bhashfn(sk->sk_net, inet_sk(sk)->num, hashinfo->bhash_size);
13992         struct inet_bind_hashbucket *head = &hashinfo->bhash[bhash];
13993         struct inet_bind_bucket *tb;
13994  
13995 @@ -127,7 +129,7 @@
13996  static struct sock *inet_lookup_listener_slow(const struct hlist_head *head,
13997                                               const __be32 daddr,
13998                                               const unsigned short hnum,
13999 -                                             const int dif)
14000 +                                             const int dif, struct net *net)
14001  {
14002         struct sock *result = NULL, *sk;
14003         const struct hlist_node *node;
14004 @@ -149,6 +151,8 @@
14005                                         continue;
14006                                 score += 2;
14007                         }
14008 +                       if (sk->sk_net != net)
14009 +                               continue;
14010                         if (score == 5)
14011                                 return sk;
14012                         if (score > hiscore) {
14013 @@ -163,22 +167,22 @@
14014  /* Optimize the common listener case. */
14015  struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
14016                                     const __be32 daddr, const unsigned short hnum,
14017 -                                   const int dif)
14018 +                                   const int dif, struct net *net)
14019  {
14020         struct sock *sk = NULL;
14021         const struct hlist_head *head;
14022  
14023         read_lock(&hashinfo->lhash_lock);
14024 -       head = &hashinfo->listening_hash[inet_lhashfn(hnum)];
14025 +       head = &hashinfo->listening_hash[net, inet_lhashfn(hnum)];
14026         if (!hlist_empty(head)) {
14027                 const struct inet_sock *inet = inet_sk((sk = __sk_head(head)));
14028  
14029                 if (inet->num == hnum && !sk->sk_node.next &&
14030                     v4_inet_addr_match(sk->sk_nx_info, daddr, inet->rcv_saddr) &&
14031                     (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) &&
14032 -                   !sk->sk_bound_dev_if)
14033 +                   !sk->sk_bound_dev_if && (sk->sk_net == net))
14034                         goto sherry_cache;
14035 -               sk = inet_lookup_listener_slow(head, daddr, hnum, dif);
14036 +               sk = inet_lookup_listener_slow(head, daddr, hnum, dif,net );
14037         }
14038         if (sk) {
14039  sherry_cache:
14040 @@ -196,12 +200,13 @@
14041  {
14042         struct inet_hashinfo *hinfo = death_row->hashinfo;
14043         struct inet_sock *inet = inet_sk(sk);
14044 +       struct net *net = sk->sk_net;
14045         __be32 daddr = inet->rcv_saddr;
14046         __be32 saddr = inet->daddr;
14047         int dif = sk->sk_bound_dev_if;
14048         INET_ADDR_COOKIE(acookie, saddr, daddr)
14049         const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport);
14050 -       unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport);
14051 +       unsigned int hash = inet_ehashfn(net, daddr, lport, saddr, inet->dport);
14052         struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
14053         struct sock *sk2;
14054         const struct hlist_node *node;
14055 @@ -214,7 +219,7 @@
14056         sk_for_each(sk2, node, &head->twchain) {
14057                 tw = inet_twsk(sk2);
14058  
14059 -               if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) {
14060 +               if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif, net)) {
14061                         if (twsk_unique(sk, sk2, twp))
14062                                 goto unique;
14063                         else
14064 @@ -225,7 +230,7 @@
14065  
14066         /* And established part... */
14067         sk_for_each(sk2, node, &head->chain) {
14068 -               if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
14069 +               if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif, net))
14070                         goto not_unique;
14071         }
14072  
14073 @@ -271,6 +276,7 @@
14074  int inet_hash_connect(struct inet_timewait_death_row *death_row,
14075                       struct sock *sk)
14076  {
14077 +       struct net *net = sk->sk_net;
14078         struct inet_hashinfo *hinfo = death_row->hashinfo;
14079         const unsigned short snum = inet_sk(sk)->num;
14080         struct inet_bind_hashbucket *head;
14081 @@ -278,8 +284,8 @@
14082         int ret;
14083  
14084         if (!snum) {
14085 -               int low = sysctl_local_port_range[0];
14086 -               int high = sysctl_local_port_range[1];
14087 +               int low = sk->sk_net->sysctl_local_port_range[0];
14088 +               int high = sk->sk_net->sysctl_local_port_range[1];
14089                 int range = high - low;
14090                 int i;
14091                 int port;
14092 @@ -291,7 +297,7 @@
14093                 local_bh_disable();
14094                 for (i = 1; i <= range; i++) {
14095                         port = low + (i + offset) % range;
14096 -                       head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)];
14097 +                       head = &hinfo->bhash[inet_bhashfn(net, port, hinfo->bhash_size)];
14098                         spin_lock(&head->lock);
14099  
14100                         /* Does not bother with rcv_saddr checks,
14101 @@ -299,7 +305,7 @@
14102                          * unique enough.
14103                          */
14104                         inet_bind_bucket_for_each(tb, node, &head->chain) {
14105 -                               if (tb->port == port) {
14106 +                               if ((tb->port == port) && (tb->net == net)) {
14107                                         BUG_TRAP(!hlist_empty(&tb->owners));
14108                                         if (tb->fastreuse >= 0)
14109                                                 goto next_port;
14110 @@ -311,7 +317,7 @@
14111                                 }
14112                         }
14113  
14114 -                       tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep, head, port);
14115 +                       tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep, head, net, port);
14116                         if (!tb) {
14117                                 spin_unlock(&head->lock);
14118                                 break;
14119 @@ -346,7 +352,7 @@
14120                 goto out;
14121         }
14122  
14123 -       head = &hinfo->bhash[inet_bhashfn(snum, hinfo->bhash_size)];
14124 +       head = &hinfo->bhash[inet_bhashfn(net, snum, hinfo->bhash_size)];
14125         tb  = inet_csk(sk)->icsk_bind_hash;
14126         spin_lock_bh(&head->lock);
14127         if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
14128 diff -Nurb linux-2.6.22-try2/net/ipv4/inet_timewait_sock.c linux-2.6.22-try2-netns/net/ipv4/inet_timewait_sock.c
14129 --- linux-2.6.22-try2/net/ipv4/inet_timewait_sock.c     2007-12-19 13:37:57.000000000 -0500
14130 +++ linux-2.6.22-try2-netns/net/ipv4/inet_timewait_sock.c       2007-12-19 22:49:20.000000000 -0500
14131 @@ -31,7 +31,7 @@
14132         write_unlock(&ehead->lock);
14133  
14134         /* Disassociate with bind bucket. */
14135 -       bhead = &hashinfo->bhash[inet_bhashfn(tw->tw_num, hashinfo->bhash_size)];
14136 +       bhead = &hashinfo->bhash[inet_bhashfn(tw->tw_net, tw->tw_num, hashinfo->bhash_size)];
14137         spin_lock(&bhead->lock);
14138         tb = tw->tw_tb;
14139         __hlist_del(&tw->tw_bind_node);
14140 @@ -65,7 +65,7 @@
14141            Note, that any socket with inet->num != 0 MUST be bound in
14142            binding cache, even if it is closed.
14143          */
14144 -       bhead = &hashinfo->bhash[inet_bhashfn(inet->num, hashinfo->bhash_size)];
14145 +       bhead = &hashinfo->bhash[inet_bhashfn(sk->sk_net, inet->num, hashinfo->bhash_size)];
14146         spin_lock(&bhead->lock);
14147         tw->tw_tb = icsk->icsk_bind_hash;
14148         BUG_TRAP(icsk->icsk_bind_hash);
14149 diff -Nurb linux-2.6.22-try2/net/ipv4/inetpeer.c linux-2.6.22-try2-netns/net/ipv4/inetpeer.c
14150 --- linux-2.6.22-try2/net/ipv4/inetpeer.c       2007-12-19 13:37:57.000000000 -0500
14151 +++ linux-2.6.22-try2-netns/net/ipv4/inetpeer.c 2007-12-19 22:49:20.000000000 -0500
14152 @@ -81,71 +81,94 @@
14153         .avl_height     = 0
14154  };
14155  #define peer_avl_empty (&peer_fake_node)
14156 -static struct inet_peer *peer_root = peer_avl_empty;
14157  static DEFINE_RWLOCK(peer_pool_lock);
14158  #define PEER_MAXDEPTH 40 /* sufficient for about 2^27 nodes */
14159  
14160 -static int peer_total;
14161 -/* Exported for sysctl_net_ipv4.  */
14162 -int inet_peer_threshold __read_mostly = 65536 + 128;   /* start to throw entries more
14163 -                                        * aggressively at this stage */
14164 -int inet_peer_minttl __read_mostly = 120 * HZ; /* TTL under high load: 120 sec */
14165 -int inet_peer_maxttl __read_mostly = 10 * 60 * HZ;     /* usual time to live: 10 min */
14166 -int inet_peer_gc_mintime __read_mostly = 10 * HZ;
14167 -int inet_peer_gc_maxtime __read_mostly = 120 * HZ;
14168 -
14169 -static struct inet_peer *inet_peer_unused_head;
14170 -static struct inet_peer **inet_peer_unused_tailp = &inet_peer_unused_head;
14171  static DEFINE_SPINLOCK(inet_peer_unused_lock);
14172  
14173  static void peer_check_expire(unsigned long dummy);
14174 -static DEFINE_TIMER(peer_periodic_timer, peer_check_expire, 0, 0);
14175  
14176 +static int inet_peers_net_init(struct net *net);
14177 +static void inet_peers_net_exit(struct net *net);
14178 +static struct pernet_operations inet_peers_net_ops = {
14179 +       .init = inet_peers_net_init,
14180 +       .exit = inet_peers_net_exit,
14181 +};
14182  
14183  /* Called from ip_output.c:ip_init  */
14184  void __init inet_initpeers(void)
14185  {
14186 +       peer_cachep = kmem_cache_create("inet_peer_cache",
14187 +                       sizeof(struct inet_peer),
14188 +                       0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
14189 +                       NULL, NULL);
14190 +
14191 +       register_pernet_subsys(&inet_peers_net_ops);
14192 +}
14193 +
14194 +static int inet_peers_net_init(struct net *net)
14195 +{
14196         struct sysinfo si;
14197  
14198 +       net->peer_root = peer_avl_empty;
14199 +       net->inet_peer_unused_tailp = &net->inet_peer_unused_head;
14200 +
14201 +       net->inet_peer_threshold = 65536 + 128; /* start to throw entries more
14202 +                                                * aggressively at this stage */
14203 +       net->inet_peer_minttl = 120 * HZ;       /* TTL under high load: 120 sec */
14204 +       net->inet_peer_maxttl = 10 * 60 * HZ;   /* usual time to live: 10 min */
14205 +       net->inet_peer_gc_mintime = 10 * HZ;
14206 +       net->inet_peer_gc_maxtime = 120 * HZ;
14207 +
14208         /* Use the straight interface to information about memory. */
14209         si_meminfo(&si);
14210 +
14211         /* The values below were suggested by Alexey Kuznetsov
14212          * <kuznet@ms2.inr.ac.ru>.  I don't have any opinion about the values
14213          * myself.  --SAW
14214          */
14215         if (si.totalram <= (32768*1024)/PAGE_SIZE)
14216 -               inet_peer_threshold >>= 1; /* max pool size about 1MB on IA32 */
14217 +               net->inet_peer_threshold >>= 1; /* max pool size about 1MB on IA32 */
14218         if (si.totalram <= (16384*1024)/PAGE_SIZE)
14219 -               inet_peer_threshold >>= 1; /* about 512KB */
14220 +               net->inet_peer_threshold >>= 1; /* about 512KB */
14221         if (si.totalram <= (8192*1024)/PAGE_SIZE)
14222 -               inet_peer_threshold >>= 2; /* about 128KB */
14223 +               net->inet_peer_threshold >>= 2; /* about 128KB */
14224  
14225 -       peer_cachep = kmem_cache_create("inet_peer_cache",
14226 -                       sizeof(struct inet_peer),
14227 -                       0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
14228 -                       NULL, NULL);
14229  
14230 +       init_timer(&net->peer_periodic_timer);
14231 +       net->peer_periodic_timer.function = peer_check_expire;
14232         /* All the timers, started at system startup tend
14233            to synchronize. Perturb it a bit.
14234          */
14235 -       peer_periodic_timer.expires = jiffies
14236 -               + net_random() % inet_peer_gc_maxtime
14237 -               + inet_peer_gc_maxtime;
14238 -       add_timer(&peer_periodic_timer);
14239 +       net->peer_periodic_timer.expires = jiffies
14240 +               + net_random() % net->inet_peer_gc_maxtime
14241 +               + net->inet_peer_gc_maxtime;
14242 +       /* Remember our namespace */
14243 +       net->peer_periodic_timer.data = (unsigned long)net;
14244 +       add_timer(&net->peer_periodic_timer);
14245 +       
14246 +       return 0;
14247 +}
14248 +
14249 +static void inet_peers_net_exit(struct net *net)
14250 +{
14251 +       del_timer(&net->peer_periodic_timer);
14252 +       /* CHECKME do I need to do something to release all of the peers */
14253  }
14254  
14255  /* Called with or without local BH being disabled. */
14256 -static void unlink_from_unused(struct inet_peer *p)
14257 +static void unlink_from_unused(struct net *net, struct inet_peer *p)
14258  {
14259         spin_lock_bh(&inet_peer_unused_lock);
14260         if (p->unused_prevp != NULL) {
14261                 /* On unused list. */
14262 -               *p->unused_prevp = p->unused_next;
14263 -               if (p->unused_next != NULL)
14264 -                       p->unused_next->unused_prevp = p->unused_prevp;
14265 +               *p->unused_prevp = p->u.unused_next;
14266 +               if (p->u.unused_next != NULL)
14267 +                       p->u.unused_next->unused_prevp = p->unused_prevp;
14268                 else
14269 -                       inet_peer_unused_tailp = p->unused_prevp;
14270 +                       net->inet_peer_unused_tailp = p->unused_prevp;
14271                 p->unused_prevp = NULL; /* mark it as removed */
14272 +               p->u.net = hold_net(net); /* Remember the net */
14273         }
14274         spin_unlock_bh(&inet_peer_unused_lock);
14275  }
14276 @@ -160,9 +183,9 @@
14277         struct inet_peer *u, **v;                               \
14278         if (_stack) {                                           \
14279                 stackptr = _stack;                              \
14280 -               *stackptr++ = &peer_root;                       \
14281 +               *stackptr++ = &net->peer_root;                  \
14282         }                                                       \
14283 -       for (u = peer_root; u != peer_avl_empty; ) {            \
14284 +       for (u = net->peer_root; u != peer_avl_empty; ) {       \
14285                 if (_daddr == u->v4daddr)                       \
14286                         break;                                  \
14287                 if ((__force __u32)_daddr < (__force __u32)u->v4daddr)  \
14288 @@ -279,7 +302,7 @@
14289  } while(0)
14290  
14291  /* May be called with local BH enabled. */
14292 -static void unlink_from_pool(struct inet_peer *p)
14293 +static void unlink_from_pool(struct net *net, struct inet_peer *p)
14294  {
14295         int do_free;
14296  
14297 @@ -317,7 +340,7 @@
14298                         delp[1] = &t->avl_left; /* was &p->avl_left */
14299                 }
14300                 peer_avl_rebalance(stack, stackptr);
14301 -               peer_total--;
14302 +               net->peer_total--;
14303                 do_free = 1;
14304         }
14305         write_unlock_bh(&peer_pool_lock);
14306 @@ -335,13 +358,13 @@
14307  }
14308  
14309  /* May be called with local BH enabled. */
14310 -static int cleanup_once(unsigned long ttl)
14311 +static int cleanup_once(struct net *net, unsigned long ttl)
14312  {
14313         struct inet_peer *p;
14314  
14315         /* Remove the first entry from the list of unused nodes. */
14316         spin_lock_bh(&inet_peer_unused_lock);
14317 -       p = inet_peer_unused_head;
14318 +       p = net->inet_peer_unused_head;
14319         if (p != NULL) {
14320                 __u32 delta = (__u32)jiffies - p->dtime;
14321                 if (delta < ttl) {
14322 @@ -349,12 +372,13 @@
14323                         spin_unlock_bh(&inet_peer_unused_lock);
14324                         return -1;
14325                 }
14326 -               inet_peer_unused_head = p->unused_next;
14327 -               if (p->unused_next != NULL)
14328 -                       p->unused_next->unused_prevp = p->unused_prevp;
14329 +               net->inet_peer_unused_head = p->u.unused_next;
14330 +               if (p->u.unused_next != NULL)
14331 +                       p->u.unused_next->unused_prevp = p->unused_prevp;
14332                 else
14333 -                       inet_peer_unused_tailp = p->unused_prevp;
14334 +                       net->inet_peer_unused_tailp = p->unused_prevp;
14335                 p->unused_prevp = NULL; /* mark as not on the list */
14336 +               p->u.net = hold_net(net);
14337                 /* Grab an extra reference to prevent node disappearing
14338                  * before unlink_from_pool() call. */
14339                 atomic_inc(&p->refcnt);
14340 @@ -367,12 +391,12 @@
14341                  * happen because of entry limits in route cache. */
14342                 return -1;
14343  
14344 -       unlink_from_pool(p);
14345 +       unlink_from_pool(net, p);
14346         return 0;
14347  }
14348  
14349  /* Called with or without local BH being disabled. */
14350 -struct inet_peer *inet_getpeer(__be32 daddr, int create)
14351 +struct inet_peer *inet_getpeer(struct net *net, __be32 daddr, int create)
14352  {
14353         struct inet_peer *p, *n;
14354         struct inet_peer **stack[PEER_MAXDEPTH], ***stackptr;
14355 @@ -387,7 +411,7 @@
14356         if (p != peer_avl_empty) {
14357                 /* The existing node has been found. */
14358                 /* Remove the entry from unused list if it was there. */
14359 -               unlink_from_unused(p);
14360 +               unlink_from_unused(net, p);
14361                 return p;
14362         }
14363  
14364 @@ -413,13 +437,13 @@
14365         /* Link the node. */
14366         link_to_pool(n);
14367         n->unused_prevp = NULL; /* not on the list */
14368 -       peer_total++;
14369 +       n->u.net = hold_net(net); /* Remember the net */
14370 +       net->peer_total++;
14371         write_unlock_bh(&peer_pool_lock);
14372  
14373 -       if (peer_total >= inet_peer_threshold)
14374 +       if (net->peer_total >= net->inet_peer_threshold)
14375                 /* Remove one less-recently-used entry. */
14376 -               cleanup_once(0);
14377 -
14378 +               cleanup_once(net, 0);
14379         return n;
14380  
14381  out_free:
14382 @@ -427,25 +451,26 @@
14383         atomic_inc(&p->refcnt);
14384         write_unlock_bh(&peer_pool_lock);
14385         /* Remove the entry from unused list if it was there. */
14386 -       unlink_from_unused(p);
14387 +       unlink_from_unused(net, p);
14388         /* Free preallocated the preallocated node. */
14389         kmem_cache_free(peer_cachep, n);
14390         return p;
14391  }
14392  
14393  /* Called with local BH disabled. */
14394 -static void peer_check_expire(unsigned long dummy)
14395 +static void peer_check_expire(unsigned long arg)
14396  {
14397 +       struct net *net = (void *)arg;
14398         unsigned long now = jiffies;
14399         int ttl;
14400  
14401 -       if (peer_total >= inet_peer_threshold)
14402 -               ttl = inet_peer_minttl;
14403 +       if (net->peer_total >= net->inet_peer_threshold)
14404 +               ttl = net->inet_peer_minttl;
14405         else
14406 -               ttl = inet_peer_maxttl
14407 -                               - (inet_peer_maxttl - inet_peer_minttl) / HZ *
14408 -                                       peer_total / inet_peer_threshold * HZ;
14409 -       while (!cleanup_once(ttl)) {
14410 +               ttl = net->inet_peer_maxttl
14411 +                       - (net->inet_peer_maxttl - net->inet_peer_minttl) / HZ *
14412 +                               net->peer_total / net->inet_peer_threshold * HZ;
14413 +       while (!cleanup_once(net, ttl)) {
14414                 if (jiffies != now)
14415                         break;
14416         }
14417 @@ -453,25 +478,30 @@
14418         /* Trigger the timer after inet_peer_gc_mintime .. inet_peer_gc_maxtime
14419          * interval depending on the total number of entries (more entries,
14420          * less interval). */
14421 -       if (peer_total >= inet_peer_threshold)
14422 -               peer_periodic_timer.expires = jiffies + inet_peer_gc_mintime;
14423 +       if (net->peer_total >= net->inet_peer_threshold)
14424 +               net->peer_periodic_timer.expires = jiffies 
14425 +                       + net->inet_peer_gc_mintime;
14426         else
14427 -               peer_periodic_timer.expires = jiffies
14428 -                       + inet_peer_gc_maxtime
14429 -                       - (inet_peer_gc_maxtime - inet_peer_gc_mintime) / HZ *
14430 -                               peer_total / inet_peer_threshold * HZ;
14431 -       add_timer(&peer_periodic_timer);
14432 +               net->peer_periodic_timer.expires = jiffies
14433 +                       + net->inet_peer_gc_maxtime
14434 +                       - (net->inet_peer_gc_maxtime - net->inet_peer_gc_mintime) / HZ *
14435 +                               net->peer_total / net->inet_peer_threshold * HZ;
14436 +       add_timer(&net->peer_periodic_timer);
14437  }
14438  
14439  void inet_putpeer(struct inet_peer *p)
14440  {
14441         spin_lock_bh(&inet_peer_unused_lock);
14442         if (atomic_dec_and_test(&p->refcnt)) {
14443 -               p->unused_prevp = inet_peer_unused_tailp;
14444 -               p->unused_next = NULL;
14445 -               *inet_peer_unused_tailp = p;
14446 -               inet_peer_unused_tailp = &p->unused_next;
14447 +               struct net *net = p->u.net;
14448 +
14449 +               p->unused_prevp = net->inet_peer_unused_tailp;
14450 +               p->u.unused_next = NULL;
14451 +               *net->inet_peer_unused_tailp = p;
14452 +               net->inet_peer_unused_tailp = &p->u.unused_next;
14453                 p->dtime = (__u32)jiffies;
14454 +
14455 +               release_net(net);
14456         }
14457         spin_unlock_bh(&inet_peer_unused_lock);
14458  }
14459 diff -Nurb linux-2.6.22-try2/net/ipv4/ip_fragment.c linux-2.6.22-try2-netns/net/ipv4/ip_fragment.c
14460 --- linux-2.6.22-try2/net/ipv4/ip_fragment.c    2007-12-19 13:37:57.000000000 -0500
14461 +++ linux-2.6.22-try2-netns/net/ipv4/ip_fragment.c      2007-12-19 22:49:20.000000000 -0500
14462 @@ -49,21 +49,6 @@
14463   * as well. Or notify me, at least. --ANK
14464   */
14465  
14466 -/* Fragment cache limits. We will commit 256K at one time. Should we
14467 - * cross that limit we will prune down to 192K. This should cope with
14468 - * even the most extreme cases without allowing an attacker to measurably
14469 - * harm machine performance.
14470 - */
14471 -int sysctl_ipfrag_high_thresh __read_mostly = 256*1024;
14472 -int sysctl_ipfrag_low_thresh __read_mostly = 192*1024;
14473 -
14474 -int sysctl_ipfrag_max_dist __read_mostly = 64;
14475 -
14476 -/* Important NOTE! Fragment queue must be destroyed before MSL expires.
14477 - * RFC791 is wrong proposing to prolongate timer each fragment arrival by TTL.
14478 - */
14479 -int sysctl_ipfrag_time __read_mostly = IP_FRAG_TIME;
14480 -
14481  struct ipfrag_skb_cb
14482  {
14483         struct inet_skb_parm    h;
14484 @@ -96,6 +81,7 @@
14485         int             iif;
14486         unsigned int    rid;
14487         struct inet_peer *peer;
14488 +       struct net      *net;
14489  };
14490  
14491  /* Hash table. */
14492 @@ -103,17 +89,13 @@
14493  #define IPQ_HASHSZ     64
14494  
14495  /* Per-bucket lock is easy to add now. */
14496 -static struct hlist_head ipq_hash[IPQ_HASHSZ];
14497  static DEFINE_RWLOCK(ipfrag_lock);
14498 -static u32 ipfrag_hash_rnd;
14499 -static LIST_HEAD(ipq_lru_list);
14500 -int ip_frag_nqueues = 0;
14501  
14502  static __inline__ void __ipq_unlink(struct ipq *qp)
14503  {
14504         hlist_del(&qp->list);
14505         list_del(&qp->lru_list);
14506 -       ip_frag_nqueues--;
14507 +       qp->net->ip_frag_nqueues--;
14508  }
14509  
14510  static __inline__ void ipq_unlink(struct ipq *ipq)
14511 @@ -123,70 +105,71 @@
14512         write_unlock(&ipfrag_lock);
14513  }
14514  
14515 -static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot)
14516 +static unsigned int ipqhashfn(struct net *net, __be16 id, __be32 saddr, __be32 daddr, u8 prot)
14517  {
14518         return jhash_3words((__force u32)id << 16 | prot,
14519                             (__force u32)saddr, (__force u32)daddr,
14520 -                           ipfrag_hash_rnd) & (IPQ_HASHSZ - 1);
14521 +                           net->ipfrag_hash_rnd) & (IPQ_HASHSZ - 1);
14522  }
14523  
14524 -static struct timer_list ipfrag_secret_timer;
14525 -int sysctl_ipfrag_secret_interval __read_mostly = 10 * 60 * HZ;
14526 -
14527 -static void ipfrag_secret_rebuild(unsigned long dummy)
14528 +static void ipfrag_secret_rebuild(unsigned long arg)
14529  {
14530 +       struct net *net = (void *)arg;
14531         unsigned long now = jiffies;
14532         int i;
14533  
14534         write_lock(&ipfrag_lock);
14535 -       get_random_bytes(&ipfrag_hash_rnd, sizeof(u32));
14536 +       get_random_bytes(&net->ipfrag_hash_rnd, sizeof(u32));
14537         for (i = 0; i < IPQ_HASHSZ; i++) {
14538                 struct ipq *q;
14539 +               struct hlist_head *head;
14540                 struct hlist_node *p, *n;
14541  
14542 -               hlist_for_each_entry_safe(q, p, n, &ipq_hash[i], list) {
14543 -                       unsigned int hval = ipqhashfn(q->id, q->saddr,
14544 +               head = &net->ipq_hash[i];
14545 +               hlist_for_each_entry_safe(q, p, n, head, list) {
14546 +                       unsigned int hval = ipqhashfn(net, q->id, q->saddr,
14547                                                       q->daddr, q->protocol);
14548  
14549                         if (hval != i) {
14550                                 hlist_del(&q->list);
14551  
14552                                 /* Relink to new hash chain. */
14553 -                               hlist_add_head(&q->list, &ipq_hash[hval]);
14554 +                               hlist_add_head(&q->list, &net->ipq_hash[hval]);
14555                         }
14556                 }
14557         }
14558         write_unlock(&ipfrag_lock);
14559  
14560 -       mod_timer(&ipfrag_secret_timer, now + sysctl_ipfrag_secret_interval);
14561 +       mod_timer(&net->ipfrag_secret_timer, 
14562 +               now + net->sysctl_ipfrag_secret_interval);
14563  }
14564  
14565 -atomic_t ip_frag_mem = ATOMIC_INIT(0); /* Memory used for fragments */
14566 -
14567  /* Memory Tracking Functions. */
14568 -static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work)
14569 +static __inline__ void frag_kfree_skb(struct net *net, struct sk_buff *skb, int *work)
14570  {
14571         if (work)
14572                 *work -= skb->truesize;
14573 -       atomic_sub(skb->truesize, &ip_frag_mem);
14574 +       atomic_sub(skb->truesize, &net->ip_frag_mem);
14575         kfree_skb(skb);
14576  }
14577  
14578  static __inline__ void frag_free_queue(struct ipq *qp, int *work)
14579  {
14580 +       struct net *net = qp->net;
14581         if (work)
14582                 *work -= sizeof(struct ipq);
14583 -       atomic_sub(sizeof(struct ipq), &ip_frag_mem);
14584 +       atomic_sub(sizeof(struct ipq), &net->ip_frag_mem);
14585 +       release_net(net);
14586         kfree(qp);
14587  }
14588  
14589 -static __inline__ struct ipq *frag_alloc_queue(void)
14590 +static __inline__ struct ipq *frag_alloc_queue(struct net *net)
14591  {
14592         struct ipq *qp = kmalloc(sizeof(struct ipq), GFP_ATOMIC);
14593  
14594         if (!qp)
14595                 return NULL;
14596 -       atomic_add(sizeof(struct ipq), &ip_frag_mem);
14597 +       atomic_add(sizeof(struct ipq), &net->ip_frag_mem);
14598         return qp;
14599  }
14600  
14601 @@ -209,7 +192,7 @@
14602         while (fp) {
14603                 struct sk_buff *xp = fp->next;
14604  
14605 -               frag_kfree_skb(fp, work);
14606 +               frag_kfree_skb(qp->net, fp, work);
14607                 fp = xp;
14608         }
14609  
14610 @@ -241,23 +224,23 @@
14611  /* Memory limiting on fragments.  Evictor trashes the oldest
14612   * fragment queue until we are back under the threshold.
14613   */
14614 -static void ip_evictor(void)
14615 +static void ip_evictor(struct net *net)
14616  {
14617         struct ipq *qp;
14618         struct list_head *tmp;
14619         int work;
14620  
14621 -       work = atomic_read(&ip_frag_mem) - sysctl_ipfrag_low_thresh;
14622 +       work = atomic_read(&net->ip_frag_mem) - net->sysctl_ipfrag_low_thresh;
14623         if (work <= 0)
14624                 return;
14625  
14626         while (work > 0) {
14627                 read_lock(&ipfrag_lock);
14628 -               if (list_empty(&ipq_lru_list)) {
14629 +               if (list_empty(&net->ipq_lru_list)) {
14630                         read_unlock(&ipfrag_lock);
14631                         return;
14632                 }
14633 -               tmp = ipq_lru_list.next;
14634 +               tmp = net->ipq_lru_list.next;
14635                 qp = list_entry(tmp, struct ipq, lru_list);
14636                 atomic_inc(&qp->refcnt);
14637                 read_unlock(&ipfrag_lock);
14638 @@ -292,7 +275,7 @@
14639         if ((qp->last_in&FIRST_IN) && qp->fragments != NULL) {
14640                 struct sk_buff *head = qp->fragments;
14641                 /* Send an ICMP "Fragment Reassembly Timeout" message. */
14642 -               if ((head->dev = dev_get_by_index(qp->iif)) != NULL) {
14643 +               if ((head->dev = dev_get_by_index(qp->net, qp->iif)) != NULL) {
14644                         icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0);
14645                         dev_put(head->dev);
14646                 }
14647 @@ -304,7 +287,7 @@
14648  
14649  /* Creation primitives. */
14650  
14651 -static struct ipq *ip_frag_intern(struct ipq *qp_in)
14652 +static struct ipq *ip_frag_intern(struct net *net, struct ipq *qp_in)
14653  {
14654         struct ipq *qp;
14655  #ifdef CONFIG_SMP
14656 @@ -313,14 +296,14 @@
14657         unsigned int hash;
14658  
14659         write_lock(&ipfrag_lock);
14660 -       hash = ipqhashfn(qp_in->id, qp_in->saddr, qp_in->daddr,
14661 +       hash = ipqhashfn(net, qp_in->id, qp_in->saddr, qp_in->daddr,
14662                          qp_in->protocol);
14663  #ifdef CONFIG_SMP
14664         /* With SMP race we have to recheck hash table, because
14665          * such entry could be created on other cpu, while we
14666          * promoted read lock to write lock.
14667          */
14668 -       hlist_for_each_entry(qp, n, &ipq_hash[hash], list) {
14669 +       hlist_for_each_entry(qp, n, &net->ipq_hash[hash], list) {
14670                 if (qp->id == qp_in->id         &&
14671                     qp->saddr == qp_in->saddr   &&
14672                     qp->daddr == qp_in->daddr   &&
14673 @@ -336,26 +319,27 @@
14674  #endif
14675         qp = qp_in;
14676  
14677 -       if (!mod_timer(&qp->timer, jiffies + sysctl_ipfrag_time))
14678 +       if (!mod_timer(&qp->timer, jiffies + net->sysctl_ipfrag_time))
14679                 atomic_inc(&qp->refcnt);
14680  
14681         atomic_inc(&qp->refcnt);
14682 -       hlist_add_head(&qp->list, &ipq_hash[hash]);
14683 +       hlist_add_head(&qp->list, &net->ipq_hash[hash]);
14684         INIT_LIST_HEAD(&qp->lru_list);
14685 -       list_add_tail(&qp->lru_list, &ipq_lru_list);
14686 -       ip_frag_nqueues++;
14687 +       list_add_tail(&qp->lru_list, &net->ipq_lru_list);
14688 +       net->ip_frag_nqueues++;
14689         write_unlock(&ipfrag_lock);
14690         return qp;
14691  }
14692  
14693  /* Add an entry to the 'ipq' queue for a newly received IP datagram. */
14694 -static struct ipq *ip_frag_create(struct iphdr *iph, u32 user)
14695 +static struct ipq *ip_frag_create(struct net *net, struct iphdr *iph, u32 user)
14696  {
14697         struct ipq *qp;
14698  
14699 -       if ((qp = frag_alloc_queue()) == NULL)
14700 +       if ((qp = frag_alloc_queue(net)) == NULL)
14701                 goto out_nomem;
14702  
14703 +       qp->net = hold_net(net);
14704         qp->protocol = iph->protocol;
14705         qp->last_in = 0;
14706         qp->id = iph->id;
14707 @@ -366,7 +350,8 @@
14708         qp->meat = 0;
14709         qp->fragments = NULL;
14710         qp->iif = 0;
14711 -       qp->peer = sysctl_ipfrag_max_dist ? inet_getpeer(iph->saddr, 1) : NULL;
14712 +       qp->peer = net->sysctl_ipfrag_max_dist ?
14713 +               inet_getpeer(net, iph->saddr, 1) : NULL;
14714  
14715         /* Initialize a timer for this entry. */
14716         init_timer(&qp->timer);
14717 @@ -375,7 +360,7 @@
14718         spin_lock_init(&qp->lock);
14719         atomic_set(&qp->refcnt, 1);
14720  
14721 -       return ip_frag_intern(qp);
14722 +       return ip_frag_intern(net, qp);
14723  
14724  out_nomem:
14725         LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n");
14726 @@ -385,7 +370,7 @@
14727  /* Find the correct entry in the "incomplete datagrams" queue for
14728   * this IP datagram, and create new one, if nothing is found.
14729   */
14730 -static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
14731 +static inline struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user)
14732  {
14733         __be16 id = iph->id;
14734         __be32 saddr = iph->saddr;
14735 @@ -396,8 +381,8 @@
14736         struct hlist_node *n;
14737  
14738         read_lock(&ipfrag_lock);
14739 -       hash = ipqhashfn(id, saddr, daddr, protocol);
14740 -       hlist_for_each_entry(qp, n, &ipq_hash[hash], list) {
14741 +       hash = ipqhashfn(net, id, saddr, daddr, protocol);
14742 +       hlist_for_each_entry(qp, n, &net->ipq_hash[hash], list) {
14743                 if (qp->id == id                &&
14744                     qp->saddr == saddr  &&
14745                     qp->daddr == daddr  &&
14746 @@ -410,14 +395,14 @@
14747         }
14748         read_unlock(&ipfrag_lock);
14749  
14750 -       return ip_frag_create(iph, user);
14751 +       return ip_frag_create(net, iph, user);
14752  }
14753  
14754  /* Is the fragment too far ahead to be part of ipq? */
14755  static inline int ip_frag_too_far(struct ipq *qp)
14756  {
14757         struct inet_peer *peer = qp->peer;
14758 -       unsigned int max = sysctl_ipfrag_max_dist;
14759 +       unsigned int max = qp->net->sysctl_ipfrag_max_dist;
14760         unsigned int start, end;
14761  
14762         int rc;
14763 @@ -442,7 +427,7 @@
14764  {
14765         struct sk_buff *fp;
14766  
14767 -       if (!mod_timer(&qp->timer, jiffies + sysctl_ipfrag_time)) {
14768 +       if (!mod_timer(&qp->timer, jiffies + qp->net->sysctl_ipfrag_time)) {
14769                 atomic_inc(&qp->refcnt);
14770                 return -ETIMEDOUT;
14771         }
14772 @@ -450,7 +435,7 @@
14773         fp = qp->fragments;
14774         do {
14775                 struct sk_buff *xp = fp->next;
14776 -               frag_kfree_skb(fp, NULL);
14777 +               frag_kfree_skb(qp->net, fp, NULL);
14778                 fp = xp;
14779         } while (fp);
14780  
14781 @@ -466,6 +451,7 @@
14782  /* Add new segment to existing queue. */
14783  static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
14784  {
14785 +       struct net *net = qp->net;
14786         struct sk_buff *prev, *next;
14787         int flags, offset;
14788         int ihl, end;
14789 @@ -576,7 +562,7 @@
14790                                 qp->fragments = next;
14791  
14792                         qp->meat -= free_it->len;
14793 -                       frag_kfree_skb(free_it, NULL);
14794 +                       frag_kfree_skb(net, free_it, NULL);
14795                 }
14796         }
14797  
14798 @@ -594,12 +580,12 @@
14799         skb->dev = NULL;
14800         qp->stamp = skb->tstamp;
14801         qp->meat += skb->len;
14802 -       atomic_add(skb->truesize, &ip_frag_mem);
14803 +       atomic_add(skb->truesize, &net->ip_frag_mem);
14804         if (offset == 0)
14805                 qp->last_in |= FIRST_IN;
14806  
14807         write_lock(&ipfrag_lock);
14808 -       list_move_tail(&qp->lru_list, &ipq_lru_list);
14809 +       list_move_tail(&qp->lru_list, &net->ipq_lru_list);
14810         write_unlock(&ipfrag_lock);
14811  
14812         return;
14813 @@ -613,6 +599,7 @@
14814  
14815  static struct sk_buff *ip_frag_reasm(struct ipq *qp, struct net_device *dev)
14816  {
14817 +       struct net *net = qp->net;
14818         struct iphdr *iph;
14819         struct sk_buff *fp, *head = qp->fragments;
14820         int len;
14821 @@ -654,12 +641,12 @@
14822                 head->len -= clone->len;
14823                 clone->csum = 0;
14824                 clone->ip_summed = head->ip_summed;
14825 -               atomic_add(clone->truesize, &ip_frag_mem);
14826 +               atomic_add(clone->truesize, &net->ip_frag_mem);
14827         }
14828  
14829         skb_shinfo(head)->frag_list = head->next;
14830         skb_push(head, head->data - skb_network_header(head));
14831 -       atomic_sub(head->truesize, &ip_frag_mem);
14832 +       atomic_sub(head->truesize, &net->ip_frag_mem);
14833  
14834         for (fp=head->next; fp; fp = fp->next) {
14835                 head->data_len += fp->len;
14836 @@ -669,7 +656,7 @@
14837                 else if (head->ip_summed == CHECKSUM_COMPLETE)
14838                         head->csum = csum_add(head->csum, fp->csum);
14839                 head->truesize += fp->truesize;
14840 -               atomic_sub(fp->truesize, &ip_frag_mem);
14841 +               atomic_sub(fp->truesize, &net->ip_frag_mem);
14842         }
14843  
14844         head->next = NULL;
14845 @@ -700,19 +687,20 @@
14846  /* Process an incoming IP datagram fragment. */
14847  struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user)
14848  {
14849 +       struct net *net = skb->dev->nd_net;
14850         struct ipq *qp;
14851         struct net_device *dev;
14852  
14853         IP_INC_STATS_BH(IPSTATS_MIB_REASMREQDS);
14854  
14855         /* Start by cleaning up the memory. */
14856 -       if (atomic_read(&ip_frag_mem) > sysctl_ipfrag_high_thresh)
14857 -               ip_evictor();
14858 +       if (atomic_read(&net->ip_frag_mem) > net->sysctl_ipfrag_high_thresh)
14859 +               ip_evictor(net);
14860  
14861         dev = skb->dev;
14862  
14863         /* Lookup (or create) queue header */
14864 -       if ((qp = ip_find(ip_hdr(skb), user)) != NULL) {
14865 +       if ((qp = ip_find(net, ip_hdr(skb), user)) != NULL) {
14866                 struct sk_buff *ret = NULL;
14867  
14868                 spin_lock(&qp->lock);
14869 @@ -733,15 +721,70 @@
14870         return NULL;
14871  }
14872  
14873 -void __init ipfrag_init(void)
14874 +static int ipfrag_net_init(struct net *net)
14875  {
14876 -       ipfrag_hash_rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^
14877 +       struct timer_list *secret_timer;
14878 +       int i;
14879 +
14880 +       /* Fragment cache limits. We will commit 256K at one time. Should we
14881 +        * cross that limit we will prune down to 192K. This should cope with
14882 +        * even the most extreme cases without allowing an attacker to measurably
14883 +        * harm machine performance.
14884 +        */
14885 +       net->sysctl_ipfrag_high_thresh = 256*1024;
14886 +       net->sysctl_ipfrag_low_thresh = 192*1024;
14887 +       net->sysctl_ipfrag_max_dist = 64;
14888 +
14889 +       /* Important NOTE! Fragment queue must be destroyed before MSL expires.
14890 +        * RFC791 is wrong proposing to prolongate timer each fragment arrival by TTL.
14891 +        */
14892 +       net->sysctl_ipfrag_time = IP_FRAG_TIME;
14893 +
14894 +       net->sysctl_ipfrag_secret_interval = 10 * 60 * HZ;
14895 +
14896 +       net->ipq_hash = kzalloc(sizeof(*net->ipq_hash)*IPQ_HASHSZ, GFP_KERNEL);
14897 +       if (!net->ipq_hash)
14898 +               return -ENOMEM;
14899 +
14900 +       for (i = 0; i < IPQ_HASHSZ; i++)
14901 +               INIT_HLIST_HEAD(&net->ipq_hash[i]);
14902 +       INIT_LIST_HEAD(&net->ipq_lru_list);
14903 +       net->ip_frag_nqueues = 0;
14904 +       atomic_set(&net->ip_frag_mem, 0);
14905 +
14906 +
14907 +       net->ipfrag_hash_rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^
14908                                  (jiffies ^ (jiffies >> 6)));
14909  
14910 -       init_timer(&ipfrag_secret_timer);
14911 -       ipfrag_secret_timer.function = ipfrag_secret_rebuild;
14912 -       ipfrag_secret_timer.expires = jiffies + sysctl_ipfrag_secret_interval;
14913 -       add_timer(&ipfrag_secret_timer);
14914 +       secret_timer = &net->ipfrag_secret_timer;
14915 +       init_timer(secret_timer);
14916 +       secret_timer->function = ipfrag_secret_rebuild;
14917 +       secret_timer->expires = jiffies + net->sysctl_ipfrag_secret_interval;
14918 +       secret_timer->data = (unsigned long)net;
14919 +       add_timer(secret_timer);
14920 +
14921 +       return 0;
14922 +}
14923 +
14924 +static void ipfrag_net_exit(struct net *net)
14925 +{
14926 +       del_timer(&net->ipfrag_secret_timer);
14927 +
14928 +       net->sysctl_ipfrag_low_thresh = 0;
14929 +       while (atomic_read(&net->ip_frag_mem))
14930 +               ip_evictor(net);
14931 +
14932 +       kfree(net->ipq_hash);
14933 +}
14934 +
14935 +static struct pernet_operations ipfrag_net_ops = {
14936 +       .init = ipfrag_net_init,
14937 +       .exit = ipfrag_net_exit,
14938 +};
14939 +
14940 +void ipfrag_init(void)
14941 +{
14942 +       register_pernet_subsys(&ipfrag_net_ops);
14943  }
14944  
14945  EXPORT_SYMBOL(ip_defrag);
14946 diff -Nurb linux-2.6.22-try2/net/ipv4/ip_gre.c linux-2.6.22-try2-netns/net/ipv4/ip_gre.c
14947 --- linux-2.6.22-try2/net/ipv4/ip_gre.c 2007-12-19 13:37:57.000000000 -0500
14948 +++ linux-2.6.22-try2-netns/net/ipv4/ip_gre.c   2007-12-19 22:49:20.000000000 -0500
14949 @@ -262,7 +262,7 @@
14950                 int i;
14951                 for (i=1; i<100; i++) {
14952                         sprintf(name, "gre%d", i);
14953 -                       if (__dev_get_by_name(name) == NULL)
14954 +                       if (__dev_get_by_name(&init_net, name) == NULL)
14955                                 break;
14956                 }
14957                 if (i==100)
14958 @@ -397,6 +397,9 @@
14959         struct flowi fl;
14960         struct rtable *rt;
14961  
14962 +       if (skb->dev->nd_net != &init_net)
14963 +               return;
14964 +
14965         if (p[1] != htons(ETH_P_IP))
14966                 return;
14967  
14968 @@ -475,6 +478,7 @@
14969  
14970         /* Try to guess incoming interface */
14971         memset(&fl, 0, sizeof(fl));
14972 +       fl.fl_net = &init_net;
14973         fl.fl4_dst = eiph->saddr;
14974         fl.fl4_tos = RT_TOS(eiph->tos);
14975         fl.proto = IPPROTO_GRE;
14976 @@ -559,6 +563,10 @@
14977         struct ip_tunnel *tunnel;
14978         int    offset = 4;
14979  
14980 +       if (skb->dev->nd_net != &init_net) {
14981 +               kfree_skb(skb);
14982 +               return 0;
14983 +       }
14984         if (!pskb_may_pull(skb, 16))
14985                 goto drop_nolock;
14986  
14987 @@ -740,7 +748,8 @@
14988         }
14989  
14990         {
14991 -               struct flowi fl = { .oif = tunnel->parms.link,
14992 +               struct flowi fl = { .fl_net = &init_net,
14993 +                                   .oif = tunnel->parms.link,
14994                                     .nl_u = { .ip4_u =
14995                                               { .daddr = dst,
14996                                                 .saddr = tiph->saddr,
14997 @@ -1095,7 +1104,8 @@
14998         struct ip_tunnel *t = netdev_priv(dev);
14999  
15000         if (MULTICAST(t->parms.iph.daddr)) {
15001 -               struct flowi fl = { .oif = t->parms.link,
15002 +               struct flowi fl = { .fl_net = &init_net,
15003 +                                   .oif = t->parms.link,
15004                                     .nl_u = { .ip4_u =
15005                                               { .daddr = t->parms.iph.daddr,
15006                                                 .saddr = t->parms.iph.saddr,
15007 @@ -1118,7 +1128,7 @@
15008  {
15009         struct ip_tunnel *t = netdev_priv(dev);
15010         if (MULTICAST(t->parms.iph.daddr) && t->mlink) {
15011 -               struct in_device *in_dev = inetdev_by_index(t->mlink);
15012 +               struct in_device *in_dev = inetdev_by_index(&init_net, t->mlink);
15013                 if (in_dev) {
15014                         ip_mc_dec_group(in_dev, t->parms.iph.daddr);
15015                         in_dev_put(in_dev);
15016 @@ -1168,7 +1178,8 @@
15017         /* Guess output device to choose reasonable mtu and hard_header_len */
15018  
15019         if (iph->daddr) {
15020 -               struct flowi fl = { .oif = tunnel->parms.link,
15021 +               struct flowi fl = { .fl_net = &init_net,
15022 +                                   .oif = tunnel->parms.link,
15023                                     .nl_u = { .ip4_u =
15024                                               { .daddr = iph->daddr,
15025                                                 .saddr = iph->saddr,
15026 @@ -1195,7 +1206,7 @@
15027         }
15028  
15029         if (!tdev && tunnel->parms.link)
15030 -               tdev = __dev_get_by_index(tunnel->parms.link);
15031 +               tdev = __dev_get_by_index(&init_net, tunnel->parms.link);
15032  
15033         if (tdev) {
15034                 hlen = tdev->hard_header_len;
15035 diff -Nurb linux-2.6.22-try2/net/ipv4/ip_input.c linux-2.6.22-try2-netns/net/ipv4/ip_input.c
15036 --- linux-2.6.22-try2/net/ipv4/ip_input.c       2007-12-19 13:37:57.000000000 -0500
15037 +++ linux-2.6.22-try2-netns/net/ipv4/ip_input.c 2007-12-19 22:49:20.000000000 -0500
15038 @@ -280,6 +280,10 @@
15039         struct iphdr *iph;
15040         struct net_device *dev = skb->dev;
15041  
15042 +
15043 +       if (skb->dev->nd_net != &init_net)
15044 +               goto drop;
15045 +
15046         /* It looks as overkill, because not all
15047            IP options require packet mangling.
15048            But it is the easiest for now, especially taking
15049 diff -Nurb linux-2.6.22-try2/net/ipv4/ip_options.c linux-2.6.22-try2-netns/net/ipv4/ip_options.c
15050 --- linux-2.6.22-try2/net/ipv4/ip_options.c     2007-12-19 13:37:57.000000000 -0500
15051 +++ linux-2.6.22-try2-netns/net/ipv4/ip_options.c       2007-12-19 22:49:20.000000000 -0500
15052 @@ -151,7 +151,7 @@
15053                                                 __be32 addr;
15054  
15055                                                 memcpy(&addr, sptr+soffset-1, 4);
15056 -                                               if (inet_addr_type(addr) != RTN_LOCAL) {
15057 +                                               if (inet_addr_type(&init_net, addr) != RTN_LOCAL) {
15058                                                         dopt->ts_needtime = 1;
15059                                                         soffset += 8;
15060                                                 }
15061 @@ -400,7 +400,7 @@
15062                                         {
15063                                                 __be32 addr;
15064                                                 memcpy(&addr, &optptr[optptr[2]-1], 4);
15065 -                                               if (inet_addr_type(addr) == RTN_UNICAST)
15066 +                                               if (inet_addr_type(&init_net, addr) == RTN_UNICAST)
15067                                                         break;
15068                                                 if (skb)
15069                                                         timeptr = (__be32*)&optptr[optptr[2]+3];
15070 diff -Nurb linux-2.6.22-try2/net/ipv4/ip_output.c linux-2.6.22-try2-netns/net/ipv4/ip_output.c
15071 --- linux-2.6.22-try2/net/ipv4/ip_output.c      2007-12-19 15:29:23.000000000 -0500
15072 +++ linux-2.6.22-try2-netns/net/ipv4/ip_output.c        2007-12-19 22:49:20.000000000 -0500
15073 @@ -83,8 +83,6 @@
15074  #include <linux/netlink.h>
15075  #include <linux/tcp.h>
15076  
15077 -int sysctl_ip_default_ttl __read_mostly = IPDEFTTL;
15078 -
15079  /* Generate a checksum for an outgoing IP datagram. */
15080  __inline__ void ip_send_check(struct iphdr *iph)
15081  {
15082 @@ -317,7 +315,8 @@
15083                         daddr = opt->faddr;
15084  
15085                 {
15086 -                       struct flowi fl = { .oif = sk->sk_bound_dev_if,
15087 +                       struct flowi fl = { .fl_net = sk->sk_net,
15088 +                                           .oif = sk->sk_bound_dev_if,
15089                                             .nl_u = { .ip4_u =
15090                                                       { .daddr = daddr,
15091                                                         .saddr = inet->saddr,
15092 @@ -1352,7 +1351,8 @@
15093         }
15094  
15095         {
15096 -               struct flowi fl = { .oif = arg->bound_dev_if,
15097 +               struct flowi fl = { .fl_net = sk->sk_net,
15098 +                                   .oif = arg->bound_dev_if,
15099                                     .nl_u = { .ip4_u =
15100                                               { .daddr = daddr,
15101                                                 .saddr = rt->rt_spec_dst,
15102 diff -Nurb linux-2.6.22-try2/net/ipv4/ip_sockglue.c linux-2.6.22-try2-netns/net/ipv4/ip_sockglue.c
15103 --- linux-2.6.22-try2/net/ipv4/ip_sockglue.c    2007-12-19 13:37:57.000000000 -0500
15104 +++ linux-2.6.22-try2-netns/net/ipv4/ip_sockglue.c      2007-12-19 22:49:20.000000000 -0500
15105 @@ -411,6 +411,7 @@
15106  static int do_ip_setsockopt(struct sock *sk, int level,
15107                             int optname, char __user *optval, int optlen)
15108  {
15109 +       struct net *net = sk->sk_net;
15110         struct inet_sock *inet = inet_sk(sk);
15111         int val=0,err;
15112  
15113 @@ -596,13 +597,13 @@
15114                                 err = 0;
15115                                 break;
15116                         }
15117 -                       dev = ip_dev_find(mreq.imr_address.s_addr);
15118 +                       dev = ip_dev_find(net, mreq.imr_address.s_addr);
15119                         if (dev) {
15120                                 mreq.imr_ifindex = dev->ifindex;
15121                                 dev_put(dev);
15122                         }
15123                 } else
15124 -                       dev = __dev_get_by_index(mreq.imr_ifindex);
15125 +                       dev = __dev_get_by_index(net, mreq.imr_ifindex);
15126  
15127  
15128                 err = -EADDRNOTAVAIL;
15129 @@ -956,6 +957,7 @@
15130  static int do_ip_getsockopt(struct sock *sk, int level, int optname,
15131                             char __user *optval, int __user *optlen)
15132  {
15133 +       struct net *net = sk->sk_net;
15134         struct inet_sock *inet = inet_sk(sk);
15135         int val;
15136         int len;
15137 @@ -1023,7 +1025,7 @@
15138                 break;
15139         case IP_TTL:
15140                 val = (inet->uc_ttl == -1 ?
15141 -                      sysctl_ip_default_ttl :
15142 +                      net->sysctl_ip_default_ttl :
15143                        inet->uc_ttl);
15144                 break;
15145         case IP_HDRINCL:
15146 diff -Nurb linux-2.6.22-try2/net/ipv4/ipcomp.c linux-2.6.22-try2-netns/net/ipv4/ipcomp.c
15147 --- linux-2.6.22-try2/net/ipv4/ipcomp.c 2007-12-19 15:29:23.000000000 -0500
15148 +++ linux-2.6.22-try2-netns/net/ipv4/ipcomp.c   2007-12-19 22:49:20.000000000 -0500
15149 @@ -175,6 +175,9 @@
15150         struct ip_comp_hdr *ipch = (struct ip_comp_hdr *)(skb->data+(iph->ihl<<2));
15151         struct xfrm_state *x;
15152  
15153 +       if (skb->dev->nd_net != &init_net)
15154 +               return;
15155 +
15156         if (icmp_hdr(skb)->type != ICMP_DEST_UNREACH ||
15157             icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
15158                 return;
15159 diff -Nurb linux-2.6.22-try2/net/ipv4/ipconfig.c linux-2.6.22-try2-netns/net/ipv4/ipconfig.c
15160 --- linux-2.6.22-try2/net/ipv4/ipconfig.c       2007-12-19 13:37:58.000000000 -0500
15161 +++ linux-2.6.22-try2-netns/net/ipv4/ipconfig.c 2007-12-19 22:49:20.000000000 -0500
15162 @@ -59,6 +59,7 @@
15163  #include <net/ip.h>
15164  #include <net/ipconfig.h>
15165  #include <net/route.h>
15166 +#include <net/net_namespace.h>
15167  
15168  #include <asm/uaccess.h>
15169  #include <net/checksum.h>
15170 @@ -184,16 +185,18 @@
15171         struct ic_device *d, **last;
15172         struct net_device *dev;
15173         unsigned short oflags;
15174 +       struct net_device *lo;
15175  
15176         last = &ic_first_dev;
15177         rtnl_lock();
15178  
15179         /* bring loopback device up first */
15180 -       if (dev_change_flags(&loopback_dev, loopback_dev.flags | IFF_UP) < 0)
15181 -               printk(KERN_ERR "IP-Config: Failed to open %s\n", loopback_dev.name);
15182 +       lo = &init_net.loopback_dev;
15183 +       if (dev_change_flags(lo, lo->flags | IFF_UP) < 0)
15184 +               printk(KERN_ERR "IP-Config: Failed to open %s\n", lo->name);
15185  
15186 -       for_each_netdev(dev) {
15187 -               if (dev == &loopback_dev)
15188 +       for_each_netdev(&init_net, dev) {
15189 +               if (dev == lo)
15190                         continue;
15191                 if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
15192                     (!(dev->flags & IFF_LOOPBACK) &&
15193 @@ -283,7 +286,7 @@
15194  
15195         mm_segment_t oldfs = get_fs();
15196         set_fs(get_ds());
15197 -       res = devinet_ioctl(cmd, (struct ifreq __user *) arg);
15198 +       res = devinet_ioctl(&init_net, cmd, (struct ifreq __user *) arg);
15199         set_fs(oldfs);
15200         return res;
15201  }
15202 @@ -294,7 +297,7 @@
15203  
15204         mm_segment_t oldfs = get_fs();
15205         set_fs(get_ds());
15206 -       res = ip_rt_ioctl(cmd, (void __user *) arg);
15207 +       res = ip_rt_ioctl(&init_net, cmd, (void __user *) arg);
15208         set_fs(oldfs);
15209         return res;
15210  }
15211 @@ -425,6 +428,9 @@
15212         unsigned char *sha, *tha;               /* s for "source", t for "target" */
15213         struct ic_device *d;
15214  
15215 +       if (dev->nd_net != &init_net)
15216 +               goto drop;
15217 +
15218         if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
15219                 return NET_RX_DROP;
15220  
15221 @@ -834,6 +840,9 @@
15222         struct ic_device *d;
15223         int len, ext_len;
15224  
15225 +       if (dev->nd_net != &init_net)
15226 +               goto drop;
15227 +
15228         /* Perform verifications before taking the lock.  */
15229         if (skb->pkt_type == PACKET_OTHERHOST)
15230                 goto drop;
15231 @@ -1253,7 +1262,7 @@
15232         __be32 addr;
15233  
15234  #ifdef CONFIG_PROC_FS
15235 -       proc_net_fops_create("pnp", S_IRUGO, &pnp_seq_fops);
15236 +       proc_net_fops_create(&init_net, "pnp", S_IRUGO, &pnp_seq_fops);
15237  #endif /* CONFIG_PROC_FS */
15238  
15239         if (!ic_enable)
15240 diff -Nurb linux-2.6.22-try2/net/ipv4/ipip.c linux-2.6.22-try2-netns/net/ipv4/ipip.c
15241 --- linux-2.6.22-try2/net/ipv4/ipip.c   2007-12-19 13:37:58.000000000 -0500
15242 +++ linux-2.6.22-try2-netns/net/ipv4/ipip.c     2007-12-19 22:49:20.000000000 -0500
15243 @@ -225,7 +225,7 @@
15244                 int i;
15245                 for (i=1; i<100; i++) {
15246                         sprintf(name, "tunl%d", i);
15247 -                       if (__dev_get_by_name(name) == NULL)
15248 +                       if (__dev_get_by_name(&init_net, name) == NULL)
15249                                 break;
15250                 }
15251                 if (i==100)
15252 @@ -403,6 +403,7 @@
15253  
15254         /* Try to guess incoming interface */
15255         memset(&fl, 0, sizeof(fl));
15256 +       fl.fl_net = &init_net;
15257         fl.fl4_daddr = eiph->saddr;
15258         fl.fl4_tos = RT_TOS(eiph->tos);
15259         fl.proto = IPPROTO_IPIP;
15260 @@ -542,7 +543,8 @@
15261         }
15262  
15263         {
15264 -               struct flowi fl = { .oif = tunnel->parms.link,
15265 +               struct flowi fl = { .fl_net = &init_net,
15266 +                                   .oif = tunnel->parms.link,
15267                                     .nl_u = { .ip4_u =
15268                                               { .daddr = dst,
15269                                                 .saddr = tiph->saddr,
15270 @@ -806,7 +808,8 @@
15271         memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
15272  
15273         if (iph->daddr) {
15274 -               struct flowi fl = { .oif = tunnel->parms.link,
15275 +               struct flowi fl = { .fl_net = &init_net,
15276 +                                   .oif = tunnel->parms.link,
15277                                     .nl_u = { .ip4_u =
15278                                               { .daddr = iph->daddr,
15279                                                 .saddr = iph->saddr,
15280 @@ -821,7 +824,7 @@
15281         }
15282  
15283         if (!tdev && tunnel->parms.link)
15284 -               tdev = __dev_get_by_index(tunnel->parms.link);
15285 +               tdev = __dev_get_by_index(&init_net, tunnel->parms.link);
15286  
15287         if (tdev) {
15288                 dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
15289 diff -Nurb linux-2.6.22-try2/net/ipv4/ipmr.c linux-2.6.22-try2-netns/net/ipv4/ipmr.c
15290 --- linux-2.6.22-try2/net/ipv4/ipmr.c   2007-12-19 13:37:58.000000000 -0500
15291 +++ linux-2.6.22-try2-netns/net/ipv4/ipmr.c     2007-12-19 22:49:20.000000000 -0500
15292 @@ -62,6 +62,7 @@
15293  #include <linux/netfilter_ipv4.h>
15294  #include <net/ipip.h>
15295  #include <net/checksum.h>
15296 +#include <net/net_namespace.h>
15297  #include <net/netlink.h>
15298  
15299  #if defined(CONFIG_IP_PIMSM_V1) || defined(CONFIG_IP_PIMSM_V2)
15300 @@ -124,7 +125,7 @@
15301  {
15302         struct net_device  *dev;
15303  
15304 -       dev = __dev_get_by_name("tunl0");
15305 +       dev = __dev_get_by_name(&init_net, "tunl0");
15306  
15307         if (dev) {
15308                 int err;
15309 @@ -148,7 +149,7 @@
15310  
15311                 dev = NULL;
15312  
15313 -               if (err == 0 && (dev = __dev_get_by_name(p.name)) != NULL) {
15314 +               if (err == 0 && (dev = __dev_get_by_name(&init_net, p.name)) != NULL) {
15315                         dev->flags |= IFF_MULTICAST;
15316  
15317                         in_dev = __in_dev_get_rtnl(dev);
15318 @@ -320,7 +321,7 @@
15319                         e->error = -ETIMEDOUT;
15320                         memset(&e->msg, 0, sizeof(e->msg));
15321  
15322 -                       rtnl_unicast(skb, NETLINK_CB(skb).pid);
15323 +                       rtnl_unicast(skb, &init_net, NETLINK_CB(skb).pid);
15324                 } else
15325                         kfree_skb(skb);
15326         }
15327 @@ -422,7 +423,7 @@
15328                         return -ENOBUFS;
15329                 break;
15330         case 0:
15331 -               dev = ip_dev_find(vifc->vifc_lcl_addr.s_addr);
15332 +               dev = ip_dev_find(&init_net, vifc->vifc_lcl_addr.s_addr);
15333                 if (!dev)
15334                         return -EADDRNOTAVAIL;
15335                 dev_put(dev);
15336 @@ -532,7 +533,7 @@
15337                                 memset(&e->msg, 0, sizeof(e->msg));
15338                         }
15339  
15340 -                       rtnl_unicast(skb, NETLINK_CB(skb).pid);
15341 +                       rtnl_unicast(skb, &init_net, NETLINK_CB(skb).pid);
15342                 } else
15343                         ip_mr_forward(skb, c, 0);
15344         }
15345 @@ -848,7 +849,7 @@
15346  {
15347         rtnl_lock();
15348         if (sk == mroute_socket) {
15349 -               IPV4_DEVCONF_ALL(MC_FORWARDING)--;
15350 +               IPV4_DEVCONF_ALL(sk->sk_net, MC_FORWARDING)--;
15351  
15352                 write_lock_bh(&mrt_lock);
15353                 mroute_socket=NULL;
15354 @@ -897,7 +898,7 @@
15355                         mroute_socket=sk;
15356                         write_unlock_bh(&mrt_lock);
15357  
15358 -                       IPV4_DEVCONF_ALL(MC_FORWARDING)++;
15359 +                       IPV4_DEVCONF_ALL(sk->sk_net, MC_FORWARDING)++;
15360                 }
15361                 rtnl_unlock();
15362                 return ret;
15363 @@ -1082,13 +1083,18 @@
15364  
15365  static int ipmr_device_event(struct notifier_block *this, unsigned long event, void *ptr)
15366  {
15367 +       struct net_device *dev = ptr;
15368         struct vif_device *v;
15369         int ct;
15370 +
15371 +       if (dev->nd_net != &init_net)
15372 +               return NOTIFY_DONE;
15373 +
15374         if (event != NETDEV_UNREGISTER)
15375                 return NOTIFY_DONE;
15376         v=&vif_table[0];
15377         for (ct=0;ct<maxvif;ct++,v++) {
15378 -               if (v->dev==ptr)
15379 +               if (v->dev==dev)
15380                         vif_delete(ct);
15381         }
15382         return NOTIFY_DONE;
15383 @@ -1171,7 +1177,8 @@
15384  #endif
15385  
15386         if (vif->flags&VIFF_TUNNEL) {
15387 -               struct flowi fl = { .oif = vif->link,
15388 +               struct flowi fl = { .fl_net = &init_net,
15389 +                                   .oif = vif->link,
15390                                     .nl_u = { .ip4_u =
15391                                               { .daddr = vif->remote,
15392                                                 .saddr = vif->local,
15393 @@ -1181,7 +1188,8 @@
15394                         goto out_free;
15395                 encap = sizeof(struct iphdr);
15396         } else {
15397 -               struct flowi fl = { .oif = vif->link,
15398 +               struct flowi fl = { .fl_net = &init_net,
15399 +                                   .oif = vif->link,
15400                                     .nl_u = { .ip4_u =
15401                                               { .daddr = iph->daddr,
15402                                                 .tos = RT_TOS(iph->tos) } },
15403 @@ -1498,6 +1506,10 @@
15404         struct iphdr   *encap;
15405         struct net_device  *reg_dev = NULL;
15406  
15407 +       if (skb->dev->nd_net != &init_net) {
15408 +               kfree_skb(skb);
15409 +               return 0;
15410 +       }
15411         if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap)))
15412                 goto drop;
15413  
15414 @@ -1922,7 +1934,7 @@
15415         ipmr_expire_timer.function=ipmr_expire_process;
15416         register_netdevice_notifier(&ip_mr_notifier);
15417  #ifdef CONFIG_PROC_FS
15418 -       proc_net_fops_create("ip_mr_vif", 0, &ipmr_vif_fops);
15419 -       proc_net_fops_create("ip_mr_cache", 0, &ipmr_mfc_fops);
15420 +       proc_net_fops_create(&init_net, "ip_mr_vif", 0, &ipmr_vif_fops);
15421 +       proc_net_fops_create(&init_net, "ip_mr_cache", 0, &ipmr_mfc_fops);
15422  #endif
15423  }
15424 diff -Nurb linux-2.6.22-try2/net/ipv4/ipvs/ip_vs_app.c linux-2.6.22-try2-netns/net/ipv4/ipvs/ip_vs_app.c
15425 --- linux-2.6.22-try2/net/ipv4/ipvs/ip_vs_app.c 2007-12-19 13:37:58.000000000 -0500
15426 +++ linux-2.6.22-try2-netns/net/ipv4/ipvs/ip_vs_app.c   2007-12-19 22:49:20.000000000 -0500
15427 @@ -32,6 +32,7 @@
15428  #include <linux/proc_fs.h>
15429  #include <linux/seq_file.h>
15430  #include <linux/mutex.h>
15431 +#include <net/net_namespace.h>
15432  
15433  #include <net/ip_vs.h>
15434  
15435 @@ -616,12 +617,12 @@
15436  int ip_vs_app_init(void)
15437  {
15438         /* we will replace it with proc_net_ipvs_create() soon */
15439 -       proc_net_fops_create("ip_vs_app", 0, &ip_vs_app_fops);
15440 +       proc_net_fops_create(&init_net, "ip_vs_app", 0, &ip_vs_app_fops);
15441         return 0;
15442  }
15443  
15444  
15445  void ip_vs_app_cleanup(void)
15446  {
15447 -       proc_net_remove("ip_vs_app");
15448 +       proc_net_remove(&init_net, "ip_vs_app");
15449  }
15450 diff -Nurb linux-2.6.22-try2/net/ipv4/ipvs/ip_vs_conn.c linux-2.6.22-try2-netns/net/ipv4/ipvs/ip_vs_conn.c
15451 --- linux-2.6.22-try2/net/ipv4/ipvs/ip_vs_conn.c        2007-12-19 13:37:58.000000000 -0500
15452 +++ linux-2.6.22-try2-netns/net/ipv4/ipvs/ip_vs_conn.c  2007-12-19 22:49:20.000000000 -0500
15453 @@ -34,6 +34,7 @@
15454  #include <linux/seq_file.h>
15455  #include <linux/jhash.h>
15456  #include <linux/random.h>
15457 +#include <net/net_namespace.h>
15458  
15459  #include <net/ip_vs.h>
15460  
15461 @@ -922,7 +923,7 @@
15462                 rwlock_init(&__ip_vs_conntbl_lock_array[idx].l);
15463         }
15464  
15465 -       proc_net_fops_create("ip_vs_conn", 0, &ip_vs_conn_fops);
15466 +       proc_net_fops_create(&init_net, "ip_vs_conn", 0, &ip_vs_conn_fops);
15467  
15468         /* calculate the random value for connection hash */
15469         get_random_bytes(&ip_vs_conn_rnd, sizeof(ip_vs_conn_rnd));
15470 @@ -938,6 +939,6 @@
15471  
15472         /* Release the empty cache */
15473         kmem_cache_destroy(ip_vs_conn_cachep);
15474 -       proc_net_remove("ip_vs_conn");
15475 +       proc_net_remove(&init_net, "ip_vs_conn");
15476         vfree(ip_vs_conn_tab);
15477  }
15478 diff -Nurb linux-2.6.22-try2/net/ipv4/ipvs/ip_vs_core.c linux-2.6.22-try2-netns/net/ipv4/ipvs/ip_vs_core.c
15479 --- linux-2.6.22-try2/net/ipv4/ipvs/ip_vs_core.c        2007-12-19 13:37:58.000000000 -0500
15480 +++ linux-2.6.22-try2-netns/net/ipv4/ipvs/ip_vs_core.c  2007-12-19 22:49:20.000000000 -0500
15481 @@ -460,7 +460,7 @@
15482            and the destination is RTN_UNICAST (and not local), then create
15483            a cache_bypass connection entry */
15484         if (sysctl_ip_vs_cache_bypass && svc->fwmark
15485 -           && (inet_addr_type(iph->daddr) == RTN_UNICAST)) {
15486 +           && (inet_addr_type(&init_net, iph->daddr) == RTN_UNICAST)) {
15487                 int ret, cs;
15488                 struct ip_vs_conn *cp;
15489  
15490 @@ -530,6 +530,10 @@
15491                                        const struct net_device *out,
15492                                        int (*okfn)(struct sk_buff *))
15493  {
15494 +       /* Only filter packets in the initial network namespace */
15495 +       if ((in?in:out)->nd_net != &init_net)
15496 +               return NF_ACCEPT;
15497 +
15498         if (!((*pskb)->ipvs_property))
15499                 return NF_ACCEPT;
15500         /* The packet was sent from IPVS, exit this chain */
15501 @@ -734,6 +738,10 @@
15502         struct ip_vs_conn *cp;
15503         int ihl;
15504  
15505 +       /* Only filter packets in the initial network namespace */
15506 +       if ((in?in:out)->nd_net != &init_net)
15507 +               return NF_ACCEPT;
15508 +
15509         EnterFunction(11);
15510  
15511         if (skb->ipvs_property)
15512 @@ -818,7 +826,7 @@
15513          * if it came from this machine itself.  So re-compute
15514          * the routing information.
15515          */
15516 -       if (ip_route_me_harder(pskb, RTN_LOCAL) != 0)
15517 +       if (ip_route_me_harder(&init_net, pskb, RTN_LOCAL) != 0)
15518                 goto drop;
15519         skb = *pskb;
15520  
15521 @@ -956,12 +964,16 @@
15522         int ret, restart;
15523         int ihl;
15524  
15525 +       /* Only filter packets in the initial network namespace */
15526 +       if ((in?in:out)->nd_net != &init_net)
15527 +               return NF_ACCEPT;
15528 +
15529         /*
15530          *      Big tappo: only PACKET_HOST (neither loopback nor mcasts)
15531          *      ... don't know why 1st test DOES NOT include 2nd (?)
15532          */
15533         if (unlikely(skb->pkt_type != PACKET_HOST
15534 -                    || skb->dev == &loopback_dev || skb->sk)) {
15535 +                    || skb->dev == &init_net.loopback_dev || skb->sk)) {
15536                 IP_VS_DBG(12, "packet type=%d proto=%d daddr=%d.%d.%d.%d ignored\n",
15537                           skb->pkt_type,
15538                           ip_hdr(skb)->protocol,
15539 @@ -1062,6 +1074,10 @@
15540  {
15541         int r;
15542  
15543 +       /* Only filter packets in the initial network namespace */
15544 +       if ((in?in:out)->nd_net != &init_net)
15545 +               return NF_ACCEPT;
15546 +
15547         if (ip_hdr(*pskb)->protocol != IPPROTO_ICMP)
15548                 return NF_ACCEPT;
15549  
15550 diff -Nurb linux-2.6.22-try2/net/ipv4/ipvs/ip_vs_ctl.c linux-2.6.22-try2-netns/net/ipv4/ipvs/ip_vs_ctl.c
15551 --- linux-2.6.22-try2/net/ipv4/ipvs/ip_vs_ctl.c 2007-12-19 13:37:58.000000000 -0500
15552 +++ linux-2.6.22-try2-netns/net/ipv4/ipvs/ip_vs_ctl.c   2007-12-19 22:49:20.000000000 -0500
15553 @@ -39,6 +39,7 @@
15554  #include <net/ip.h>
15555  #include <net/route.h>
15556  #include <net/sock.h>
15557 +#include <net/net_namespace.h>
15558  
15559  #include <asm/uaccess.h>
15560  
15561 @@ -679,7 +680,7 @@
15562         conn_flags = udest->conn_flags | IP_VS_CONN_F_INACTIVE;
15563  
15564         /* check if local node and update the flags */
15565 -       if (inet_addr_type(udest->addr) == RTN_LOCAL) {
15566 +       if (inet_addr_type(&init_net, udest->addr) == RTN_LOCAL) {
15567                 conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK)
15568                         | IP_VS_CONN_F_LOCALNODE;
15569         }
15570 @@ -731,7 +732,7 @@
15571  
15572         EnterFunction(2);
15573  
15574 -       atype = inet_addr_type(udest->addr);
15575 +       atype = inet_addr_type(&init_net, udest->addr);
15576         if (atype != RTN_LOCAL && atype != RTN_UNICAST)
15577                 return -EINVAL;
15578  
15579 @@ -1932,6 +1933,9 @@
15580         struct ip_vs_service *svc;
15581         struct ip_vs_dest_user *udest;
15582  
15583 +       if (sk->sk_net != &init_net)
15584 +               return -ENOPROTOOPT;
15585 +
15586         if (!capable(CAP_NET_ADMIN))
15587                 return -EPERM;
15588  
15589 @@ -2196,6 +2200,9 @@
15590         unsigned char arg[128];
15591         int ret = 0;
15592  
15593 +       if (sk->sk_net != &init_net)
15594 +               return -ENOPROTOOPT;
15595 +
15596         if (!capable(CAP_NET_ADMIN))
15597                 return -EPERM;
15598  
15599 @@ -2356,8 +2363,8 @@
15600                 return ret;
15601         }
15602  
15603 -       proc_net_fops_create("ip_vs", 0, &ip_vs_info_fops);
15604 -       proc_net_fops_create("ip_vs_stats",0, &ip_vs_stats_fops);
15605 +       proc_net_fops_create(&init_net, "ip_vs", 0, &ip_vs_info_fops);
15606 +       proc_net_fops_create(&init_net, "ip_vs_stats",0, &ip_vs_stats_fops);
15607  
15608         sysctl_header = register_sysctl_table(vs_root_table);
15609  
15610 @@ -2390,8 +2397,8 @@
15611         cancel_work_sync(&defense_work.work);
15612         ip_vs_kill_estimator(&ip_vs_stats);
15613         unregister_sysctl_table(sysctl_header);
15614 -       proc_net_remove("ip_vs_stats");
15615 -       proc_net_remove("ip_vs");
15616 +       proc_net_remove(&init_net, "ip_vs_stats");
15617 +       proc_net_remove(&init_net, "ip_vs");
15618         nf_unregister_sockopt(&ip_vs_sockopts);
15619         LeaveFunction(2);
15620  }
15621 diff -Nurb linux-2.6.22-try2/net/ipv4/ipvs/ip_vs_lblcr.c linux-2.6.22-try2-netns/net/ipv4/ipvs/ip_vs_lblcr.c
15622 --- linux-2.6.22-try2/net/ipv4/ipvs/ip_vs_lblcr.c       2007-12-19 13:37:58.000000000 -0500
15623 +++ linux-2.6.22-try2-netns/net/ipv4/ipvs/ip_vs_lblcr.c 2007-12-19 22:49:20.000000000 -0500
15624 @@ -843,7 +843,7 @@
15625         INIT_LIST_HEAD(&ip_vs_lblcr_scheduler.n_list);
15626         sysctl_header = register_sysctl_table(lblcr_root_table);
15627  #ifdef CONFIG_IP_VS_LBLCR_DEBUG
15628 -       proc_net_create("ip_vs_lblcr", 0, ip_vs_lblcr_getinfo);
15629 +       proc_net_create(&init_net, "ip_vs_lblcr", 0, ip_vs_lblcr_getinfo);
15630  #endif
15631         return register_ip_vs_scheduler(&ip_vs_lblcr_scheduler);
15632  }
15633 @@ -852,7 +852,7 @@
15634  static void __exit ip_vs_lblcr_cleanup(void)
15635  {
15636  #ifdef CONFIG_IP_VS_LBLCR_DEBUG
15637 -       proc_net_remove("ip_vs_lblcr");
15638 +       proc_net_remove(&init_net, "ip_vs_lblcr");
15639  #endif
15640         unregister_sysctl_table(sysctl_header);
15641         unregister_ip_vs_scheduler(&ip_vs_lblcr_scheduler);
15642 diff -Nurb linux-2.6.22-try2/net/ipv4/ipvs/ip_vs_sync.c linux-2.6.22-try2-netns/net/ipv4/ipvs/ip_vs_sync.c
15643 --- linux-2.6.22-try2/net/ipv4/ipvs/ip_vs_sync.c        2007-12-19 13:37:58.000000000 -0500
15644 +++ linux-2.6.22-try2-netns/net/ipv4/ipvs/ip_vs_sync.c  2007-12-19 22:49:20.000000000 -0500
15645 @@ -387,7 +387,7 @@
15646         struct net_device *dev;
15647         struct inet_sock *inet = inet_sk(sk);
15648  
15649 -       if ((dev = __dev_get_by_name(ifname)) == NULL)
15650 +       if ((dev = __dev_get_by_name(&init_net, ifname)) == NULL)
15651                 return -ENODEV;
15652  
15653         if (sk->sk_bound_dev_if && dev->ifindex != sk->sk_bound_dev_if)
15654 @@ -412,7 +412,7 @@
15655         int num;
15656  
15657         if (sync_state == IP_VS_STATE_MASTER) {
15658 -               if ((dev = __dev_get_by_name(ip_vs_master_mcast_ifn)) == NULL)
15659 +               if ((dev = __dev_get_by_name(&init_net, ip_vs_master_mcast_ifn)) == NULL)
15660                         return -ENODEV;
15661  
15662                 num = (dev->mtu - sizeof(struct iphdr) -
15663 @@ -423,7 +423,7 @@
15664                 IP_VS_DBG(7, "setting the maximum length of sync sending "
15665                           "message %d.\n", sync_send_mesg_maxlen);
15666         } else if (sync_state == IP_VS_STATE_BACKUP) {
15667 -               if ((dev = __dev_get_by_name(ip_vs_backup_mcast_ifn)) == NULL)
15668 +               if ((dev = __dev_get_by_name(&init_net, ip_vs_backup_mcast_ifn)) == NULL)
15669                         return -ENODEV;
15670  
15671                 sync_recv_mesg_maxlen = dev->mtu -
15672 @@ -451,7 +451,7 @@
15673         memset(&mreq, 0, sizeof(mreq));
15674         memcpy(&mreq.imr_multiaddr, addr, sizeof(struct in_addr));
15675  
15676 -       if ((dev = __dev_get_by_name(ifname)) == NULL)
15677 +       if ((dev = __dev_get_by_name(&init_net, ifname)) == NULL)
15678                 return -ENODEV;
15679         if (sk->sk_bound_dev_if && dev->ifindex != sk->sk_bound_dev_if)
15680                 return -EINVAL;
15681 @@ -472,7 +472,7 @@
15682         __be32 addr;
15683         struct sockaddr_in sin;
15684  
15685 -       if ((dev = __dev_get_by_name(ifname)) == NULL)
15686 +       if ((dev = __dev_get_by_name(&init_net, ifname)) == NULL)
15687                 return -ENODEV;
15688  
15689         addr = inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE);
15690 diff -Nurb linux-2.6.22-try2/net/ipv4/ipvs/ip_vs_xmit.c linux-2.6.22-try2-netns/net/ipv4/ipvs/ip_vs_xmit.c
15691 --- linux-2.6.22-try2/net/ipv4/ipvs/ip_vs_xmit.c        2007-12-19 13:37:58.000000000 -0500
15692 +++ linux-2.6.22-try2-netns/net/ipv4/ipvs/ip_vs_xmit.c  2007-12-19 22:49:20.000000000 -0500
15693 @@ -70,6 +70,7 @@
15694                 if (!(rt = (struct rtable *)
15695                       __ip_vs_dst_check(dest, rtos, 0))) {
15696                         struct flowi fl = {
15697 +                               .fl_net = &init_net,
15698                                 .oif = 0,
15699                                 .nl_u = {
15700                                         .ip4_u = {
15701 @@ -93,6 +94,7 @@
15702                 spin_unlock(&dest->dst_lock);
15703         } else {
15704                 struct flowi fl = {
15705 +                       .fl_net = &init_net,
15706                         .oif = 0,
15707                         .nl_u = {
15708                                 .ip4_u = {
15709 @@ -160,6 +162,7 @@
15710         u8     tos = iph->tos;
15711         int    mtu;
15712         struct flowi fl = {
15713 +               .fl_net = &init_net,
15714                 .oif = 0,
15715                 .nl_u = {
15716                         .ip4_u = {
15717 diff -Nurb linux-2.6.22-try2/net/ipv4/netfilter/arp_tables.c linux-2.6.22-try2-netns/net/ipv4/netfilter/arp_tables.c
15718 --- linux-2.6.22-try2/net/ipv4/netfilter/arp_tables.c   2007-12-19 13:37:58.000000000 -0500
15719 +++ linux-2.6.22-try2-netns/net/ipv4/netfilter/arp_tables.c     2007-12-19 22:49:20.000000000 -0500
15720 @@ -19,6 +19,7 @@
15721  #include <linux/proc_fs.h>
15722  #include <linux/module.h>
15723  #include <linux/init.h>
15724 +#include <net/sock.h>
15725  
15726  #include <asm/uaccess.h>
15727  #include <linux/mutex.h>
15728 @@ -773,7 +774,7 @@
15729         int ret;
15730         struct arpt_table *t;
15731  
15732 -       t = xt_find_table_lock(NF_ARP, entries->name);
15733 +       t = xt_find_table_lock(&init_net, NF_ARP, entries->name);
15734         if (t && !IS_ERR(t)) {
15735                 struct xt_table_info *private = t->private;
15736                 duprintf("t->private->number = %u\n",
15737 @@ -843,7 +844,7 @@
15738  
15739         duprintf("arp_tables: Translated table\n");
15740  
15741 -       t = try_then_request_module(xt_find_table_lock(NF_ARP, tmp.name),
15742 +       t = try_then_request_module(xt_find_table_lock(&init_net, NF_ARP, tmp.name),
15743                                     "arptable_%s", tmp.name);
15744         if (!t || IS_ERR(t)) {
15745                 ret = t ? PTR_ERR(t) : -ENOENT;
15746 @@ -936,7 +937,7 @@
15747                 goto free;
15748         }
15749  
15750 -       t = xt_find_table_lock(NF_ARP, tmp.name);
15751 +       t = xt_find_table_lock(&init_net, NF_ARP, tmp.name);
15752         if (!t || IS_ERR(t)) {
15753                 ret = t ? PTR_ERR(t) : -ENOENT;
15754                 goto free;
15755 @@ -971,6 +972,9 @@
15756  {
15757         int ret;
15758  
15759 +       if (sk->sk_net != &init_net)
15760 +               return -ENOPROTOOPT;
15761 +
15762         if (!capable(CAP_NET_ADMIN))
15763                 return -EPERM;
15764  
15765 @@ -995,6 +999,9 @@
15766  {
15767         int ret;
15768  
15769 +       if (sk->sk_net != &init_net)
15770 +               return -ENOPROTOOPT;
15771 +
15772         if (!capable(CAP_NET_ADMIN))
15773                 return -EPERM;
15774  
15775 @@ -1016,7 +1023,7 @@
15776                 }
15777                 name[ARPT_TABLE_MAXNAMELEN-1] = '\0';
15778  
15779 -               t = try_then_request_module(xt_find_table_lock(NF_ARP, name),
15780 +               t = try_then_request_module(xt_find_table_lock(&init_net, NF_ARP, name),
15781                                             "arptable_%s", name);
15782                 if (t && !IS_ERR(t)) {
15783                         struct arpt_getinfo info;
15784 @@ -1116,7 +1123,7 @@
15785                 return ret;
15786         }
15787  
15788 -       ret = xt_register_table(table, &bootstrap, newinfo);
15789 +       ret = xt_register_table(&init_net, table, &bootstrap, newinfo);
15790         if (ret != 0) {
15791                 xt_free_table_info(newinfo);
15792                 return ret;
15793 diff -Nurb linux-2.6.22-try2/net/ipv4/netfilter/arptable_filter.c linux-2.6.22-try2-netns/net/ipv4/netfilter/arptable_filter.c
15794 --- linux-2.6.22-try2/net/ipv4/netfilter/arptable_filter.c      2007-12-19 13:37:58.000000000 -0500
15795 +++ linux-2.6.22-try2-netns/net/ipv4/netfilter/arptable_filter.c        2007-12-19 22:49:20.000000000 -0500
15796 @@ -61,6 +61,10 @@
15797                               const struct net_device *out,
15798                               int (*okfn)(struct sk_buff *))
15799  {
15800 +       /* Only filter packets in the initial network namespace */
15801 +       if ((in?in:out)->nd_net != &init_net)
15802 +               return NF_ACCEPT;
15803 +
15804         return arpt_do_table(pskb, hook, in, out, &packet_filter);
15805  }
15806  
15807 diff -Nurb linux-2.6.22-try2/net/ipv4/netfilter/ip_queue.c linux-2.6.22-try2-netns/net/ipv4/netfilter/ip_queue.c
15808 --- linux-2.6.22-try2/net/ipv4/netfilter/ip_queue.c     2007-12-19 13:37:58.000000000 -0500
15809 +++ linux-2.6.22-try2-netns/net/ipv4/netfilter/ip_queue.c       2007-12-19 22:49:20.000000000 -0500
15810 @@ -26,6 +26,7 @@
15811  #include <linux/mutex.h>
15812  #include <net/sock.h>
15813  #include <net/route.h>
15814 +#include <net/net_namespace.h>
15815  
15816  #define IPQ_QMAX_DEFAULT 1024
15817  #define IPQ_PROC_FS_NAME "ip_queue"
15818 @@ -556,6 +557,9 @@
15819  {
15820         struct net_device *dev = ptr;
15821  
15822 +       if (dev->nd_net != &init_net)
15823 +               return NOTIFY_DONE;
15824 +
15825         /* Drop any packets associated with the downed device */
15826         if (event == NETDEV_DOWN)
15827                 ipq_dev_drop(dev->ifindex);
15828 @@ -575,7 +579,7 @@
15829         if (event == NETLINK_URELEASE &&
15830             n->protocol == NETLINK_FIREWALL && n->pid) {
15831                 write_lock_bh(&queue_lock);
15832 -               if (n->pid == peer_pid)
15833 +               if ((n->net == &init_net) && (n->pid == peer_pid))
15834                         __ipq_reset();
15835                 write_unlock_bh(&queue_lock);
15836         }
15837 @@ -667,14 +671,14 @@
15838         struct proc_dir_entry *proc;
15839  
15840         netlink_register_notifier(&ipq_nl_notifier);
15841 -       ipqnl = netlink_kernel_create(NETLINK_FIREWALL, 0, ipq_rcv_sk,
15842 -                                     NULL, THIS_MODULE);
15843 +       ipqnl = netlink_kernel_create(&init_net, NETLINK_FIREWALL, 0,
15844 +                                     ipq_rcv_sk, NULL, THIS_MODULE);
15845         if (ipqnl == NULL) {
15846                 printk(KERN_ERR "ip_queue: failed to create netlink socket\n");
15847                 goto cleanup_netlink_notifier;
15848         }
15849  
15850 -       proc = proc_net_create(IPQ_PROC_FS_NAME, 0, ipq_get_info);
15851 +       proc = proc_net_create(&init_net, IPQ_PROC_FS_NAME, 0, ipq_get_info);
15852         if (proc)
15853                 proc->owner = THIS_MODULE;
15854         else {
15855 @@ -695,8 +699,7 @@
15856  cleanup_sysctl:
15857         unregister_sysctl_table(ipq_sysctl_header);
15858         unregister_netdevice_notifier(&ipq_dev_notifier);
15859 -       proc_net_remove(IPQ_PROC_FS_NAME);
15860 -
15861 +       proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
15862  cleanup_ipqnl:
15863         sock_release(ipqnl->sk_socket);
15864         mutex_lock(&ipqnl_mutex);
15865 @@ -715,7 +718,7 @@
15866  
15867         unregister_sysctl_table(ipq_sysctl_header);
15868         unregister_netdevice_notifier(&ipq_dev_notifier);
15869 -       proc_net_remove(IPQ_PROC_FS_NAME);
15870 +       proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
15871  
15872         sock_release(ipqnl->sk_socket);
15873         mutex_lock(&ipqnl_mutex);
15874 diff -Nurb linux-2.6.22-try2/net/ipv4/netfilter/ip_tables.c linux-2.6.22-try2-netns/net/ipv4/netfilter/ip_tables.c
15875 --- linux-2.6.22-try2/net/ipv4/netfilter/ip_tables.c    2007-12-19 13:37:58.000000000 -0500
15876 +++ linux-2.6.22-try2-netns/net/ipv4/netfilter/ip_tables.c      2007-12-19 22:49:20.000000000 -0500
15877 @@ -1039,7 +1039,7 @@
15878  }
15879  #endif
15880  
15881 -static int get_info(void __user *user, int *len, int compat)
15882 +static int get_info(struct net *net, void __user *user, int *len, int compat)
15883  {
15884         char name[IPT_TABLE_MAXNAMELEN];
15885         struct xt_table *t;
15886 @@ -1059,7 +1059,7 @@
15887         if (compat)
15888                 xt_compat_lock(AF_INET);
15889  #endif
15890 -       t = try_then_request_module(xt_find_table_lock(AF_INET, name),
15891 +       t = try_then_request_module(xt_find_table_lock(net, AF_INET, name),
15892                         "iptable_%s", name);
15893         if (t && !IS_ERR(t)) {
15894                 struct ipt_getinfo info;
15895 @@ -1099,7 +1099,7 @@
15896  }
15897  
15898  static int
15899 -get_entries(struct ipt_get_entries __user *uptr, int *len)
15900 +get_entries(struct net *net, struct ipt_get_entries __user *uptr, int *len)
15901  {
15902         int ret;
15903         struct ipt_get_entries get;
15904 @@ -1119,7 +1119,7 @@
15905                 return -EINVAL;
15906         }
15907  
15908 -       t = xt_find_table_lock(AF_INET, get.name);
15909 +       t = xt_find_table_lock(net, AF_INET, get.name);
15910         if (t && !IS_ERR(t)) {
15911                 struct xt_table_info *private = t->private;
15912                 duprintf("t->private->number = %u\n",
15913 @@ -1142,7 +1142,7 @@
15914  }
15915  
15916  static int
15917 -__do_replace(const char *name, unsigned int valid_hooks,
15918 +__do_replace(struct net *net, const char *name, unsigned int valid_hooks,
15919                 struct xt_table_info *newinfo, unsigned int num_counters,
15920                 void __user *counters_ptr)
15921  {
15922 @@ -1159,7 +1159,7 @@
15923                 goto out;
15924         }
15925  
15926 -       t = try_then_request_module(xt_find_table_lock(AF_INET, name),
15927 +       t = try_then_request_module(xt_find_table_lock(net, AF_INET, name),
15928                                     "iptable_%s", name);
15929         if (!t || IS_ERR(t)) {
15930                 ret = t ? PTR_ERR(t) : -ENOENT;
15931 @@ -1211,7 +1211,7 @@
15932  }
15933  
15934  static int
15935 -do_replace(void __user *user, unsigned int len)
15936 +do_replace(struct net *net, void __user *user, unsigned int len)
15937  {
15938         int ret;
15939         struct ipt_replace tmp;
15940 @@ -1252,7 +1252,7 @@
15941  
15942         duprintf("ip_tables: Translated table\n");
15943  
15944 -       ret = __do_replace(tmp.name, tmp.valid_hooks,
15945 +       ret = __do_replace(net, tmp.name, tmp.valid_hooks,
15946                               newinfo, tmp.num_counters,
15947                               tmp.counters);
15948         if (ret)
15949 @@ -1289,7 +1289,7 @@
15950  }
15951  
15952  static int
15953 -do_add_counters(void __user *user, unsigned int len, int compat)
15954 +do_add_counters(struct net *net, void __user *user, unsigned int len, int compat)
15955  {
15956         unsigned int i;
15957         struct xt_counters_info tmp;
15958 @@ -1341,7 +1341,7 @@
15959                 goto free;
15960         }
15961  
15962 -       t = xt_find_table_lock(AF_INET, name);
15963 +       t = xt_find_table_lock(net, AF_INET, name);
15964         if (!t || IS_ERR(t)) {
15965                 ret = t ? PTR_ERR(t) : -ENOENT;
15966                 goto free;
15967 @@ -1745,7 +1745,7 @@
15968  }
15969  
15970  static int
15971 -compat_do_replace(void __user *user, unsigned int len)
15972 +compat_do_replace(struct net *net, void __user *user, unsigned int len)
15973  {
15974         int ret;
15975         struct compat_ipt_replace tmp;
15976 @@ -1786,7 +1786,7 @@
15977  
15978         duprintf("compat_do_replace: Translated table\n");
15979  
15980 -       ret = __do_replace(tmp.name, tmp.valid_hooks,
15981 +       ret = __do_replace(net, tmp.name, tmp.valid_hooks,
15982                               newinfo, tmp.num_counters,
15983                               compat_ptr(tmp.counters));
15984         if (ret)
15985 @@ -1811,11 +1811,11 @@
15986  
15987         switch (cmd) {
15988         case IPT_SO_SET_REPLACE:
15989 -               ret = compat_do_replace(user, len);
15990 +               ret = compat_do_replace(sk->sk_net, user, len);
15991                 break;
15992  
15993         case IPT_SO_SET_ADD_COUNTERS:
15994 -               ret = do_add_counters(user, len, 1);
15995 +               ret = do_add_counters(sk->sk_net, user, len, 1);
15996                 break;
15997  
15998         default:
15999 @@ -1904,7 +1904,7 @@
16000  }
16001  
16002  static int
16003 -compat_get_entries(struct compat_ipt_get_entries __user *uptr, int *len)
16004 +compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr, int *len)
16005  {
16006         int ret;
16007         struct compat_ipt_get_entries get;
16008 @@ -1928,7 +1928,7 @@
16009         }
16010  
16011         xt_compat_lock(AF_INET);
16012 -       t = xt_find_table_lock(AF_INET, get.name);
16013 +       t = xt_find_table_lock(net, AF_INET, get.name);
16014         if (t && !IS_ERR(t)) {
16015                 struct xt_table_info *private = t->private;
16016                 struct xt_table_info info;
16017 @@ -1966,10 +1966,10 @@
16018  
16019         switch (cmd) {
16020         case IPT_SO_GET_INFO:
16021 -               ret = get_info(user, len, 1);
16022 +               ret = get_info(sk->sk_net, user, len, 1);
16023                 break;
16024         case IPT_SO_GET_ENTRIES:
16025 -               ret = compat_get_entries(user, len);
16026 +               ret = compat_get_entries(sk->sk_net, user, len);
16027                 break;
16028         default:
16029                 ret = do_ipt_get_ctl(sk, cmd, user, len);
16030 @@ -1988,11 +1988,11 @@
16031  
16032         switch (cmd) {
16033         case IPT_SO_SET_REPLACE:
16034 -               ret = do_replace(user, len);
16035 +               ret = do_replace(sk->sk_net, user, len);
16036                 break;
16037  
16038         case IPT_SO_SET_ADD_COUNTERS:
16039 -               ret = do_add_counters(user, len, 0);
16040 +               ret = do_add_counters(sk->sk_net, user, len, 0);
16041                 break;
16042  
16043         default:
16044 @@ -2013,11 +2013,11 @@
16045  
16046         switch (cmd) {
16047         case IPT_SO_GET_INFO:
16048 -               ret = get_info(user, len, 0);
16049 +               ret = get_info(sk->sk_net, user, len, 0);
16050                 break;
16051  
16052         case IPT_SO_GET_ENTRIES:
16053 -               ret = get_entries(user, len);
16054 +               ret = get_entries(sk->sk_net, user, len);
16055                 break;
16056  
16057         case IPT_SO_GET_REVISION_MATCH:
16058 @@ -2054,7 +2054,7 @@
16059         return ret;
16060  }
16061  
16062 -int ipt_register_table(struct xt_table *table, const struct ipt_replace *repl)
16063 +int ipt_register_table(struct net *net, struct xt_table *table, const struct ipt_replace *repl)
16064  {
16065         int ret;
16066         struct xt_table_info *newinfo;
16067 @@ -2082,7 +2082,7 @@
16068                 return ret;
16069         }
16070  
16071 -       ret = xt_register_table(table, &bootstrap, newinfo);
16072 +       ret = xt_register_table(net, table, &bootstrap, newinfo);
16073         if (ret != 0) {
16074                 xt_free_table_info(newinfo);
16075                 return ret;
16076 diff -Nurb linux-2.6.22-try2/net/ipv4/netfilter/ipt_CLUSTERIP.c linux-2.6.22-try2-netns/net/ipv4/netfilter/ipt_CLUSTERIP.c
16077 --- linux-2.6.22-try2/net/ipv4/netfilter/ipt_CLUSTERIP.c        2007-12-19 13:37:58.000000000 -0500
16078 +++ linux-2.6.22-try2-netns/net/ipv4/netfilter/ipt_CLUSTERIP.c  2007-12-19 22:49:20.000000000 -0500
16079 @@ -27,6 +27,7 @@
16080  #include <linux/netfilter_ipv4/ipt_CLUSTERIP.h>
16081  #include <net/netfilter/nf_conntrack.h>
16082  #include <net/checksum.h>
16083 +#include <net/net_namespace.h>
16084  
16085  #define CLUSTERIP_VERSION "0.8"
16086  
16087 @@ -427,7 +428,7 @@
16088                                 return 0;
16089                         }
16090  
16091 -                       dev = dev_get_by_name(e->ip.iniface);
16092 +                       dev = dev_get_by_name(&init_net, e->ip.iniface);
16093                         if (!dev) {
16094                                 printk(KERN_WARNING "CLUSTERIP: no such interface %s\n", e->ip.iniface);
16095                                 return 0;
16096 @@ -523,6 +524,10 @@
16097         struct arp_payload *payload;
16098         struct clusterip_config *c;
16099  
16100 +       /* Only filter packets in the initial network namespace */
16101 +       if ((in?in:out)->nd_net != &init_net)
16102 +               return NF_ACCEPT;
16103 +
16104         /* we don't care about non-ethernet and non-ipv4 ARP */
16105         if (arp->ar_hrd != htons(ARPHRD_ETHER)
16106             || arp->ar_pro != htons(ETH_P_IP)
16107 @@ -735,7 +740,7 @@
16108                 goto cleanup_target;
16109  
16110  #ifdef CONFIG_PROC_FS
16111 -       clusterip_procdir = proc_mkdir("ipt_CLUSTERIP", proc_net);
16112 +       clusterip_procdir = proc_mkdir("ipt_CLUSTERIP", init_net.proc_net);
16113         if (!clusterip_procdir) {
16114                 printk(KERN_ERR "CLUSTERIP: Unable to proc dir entry\n");
16115                 ret = -ENOMEM;
16116 diff -Nurb linux-2.6.22-try2/net/ipv4/netfilter/ipt_MASQUERADE.c linux-2.6.22-try2-netns/net/ipv4/netfilter/ipt_MASQUERADE.c
16117 --- linux-2.6.22-try2/net/ipv4/netfilter/ipt_MASQUERADE.c       2007-12-19 13:37:58.000000000 -0500
16118 +++ linux-2.6.22-try2-netns/net/ipv4/netfilter/ipt_MASQUERADE.c 2007-12-19 22:49:20.000000000 -0500
16119 @@ -131,6 +131,9 @@
16120  {
16121         struct net_device *dev = ptr;
16122  
16123 +       if (dev->nd_net != &init_net)
16124 +               return NOTIFY_DONE;
16125 +
16126         if (event == NETDEV_DOWN) {
16127                 /* Device was downed.  Search entire table for
16128                    conntracks which were associated with that device,
16129 diff -Nurb linux-2.6.22-try2/net/ipv4/netfilter/ipt_REJECT.c linux-2.6.22-try2-netns/net/ipv4/netfilter/ipt_REJECT.c
16130 --- linux-2.6.22-try2/net/ipv4/netfilter/ipt_REJECT.c   2007-12-19 13:37:58.000000000 -0500
16131 +++ linux-2.6.22-try2-netns/net/ipv4/netfilter/ipt_REJECT.c     2007-12-19 22:49:20.000000000 -0500
16132 @@ -137,7 +137,7 @@
16133            )
16134                 addr_type = RTN_LOCAL;
16135  
16136 -       if (ip_route_me_harder(&nskb, addr_type))
16137 +       if (ip_route_me_harder(&init_net, &nskb, addr_type))
16138                 goto free_nskb;
16139  
16140         nskb->ip_summed = CHECKSUM_NONE;
16141 diff -Nurb linux-2.6.22-try2/net/ipv4/netfilter/ipt_ULOG.c linux-2.6.22-try2-netns/net/ipv4/netfilter/ipt_ULOG.c
16142 --- linux-2.6.22-try2/net/ipv4/netfilter/ipt_ULOG.c     2007-12-19 13:37:58.000000000 -0500
16143 +++ linux-2.6.22-try2-netns/net/ipv4/netfilter/ipt_ULOG.c       2007-12-19 22:49:20.000000000 -0500
16144 @@ -419,7 +419,8 @@
16145         for (i = 0; i < ULOG_MAXNLGROUPS; i++)
16146                 setup_timer(&ulog_buffers[i].timer, ulog_timer, i);
16147  
16148 -       nflognl = netlink_kernel_create(NETLINK_NFLOG, ULOG_MAXNLGROUPS, NULL,
16149 +       nflognl = netlink_kernel_create(&init_net,
16150 +                                       NETLINK_NFLOG, ULOG_MAXNLGROUPS, NULL,
16151                                         NULL, THIS_MODULE);
16152         if (!nflognl)
16153                 return -ENOMEM;
16154 diff -Nurb linux-2.6.22-try2/net/ipv4/netfilter/ipt_addrtype.c linux-2.6.22-try2-netns/net/ipv4/netfilter/ipt_addrtype.c
16155 --- linux-2.6.22-try2/net/ipv4/netfilter/ipt_addrtype.c 2007-12-19 13:37:58.000000000 -0500
16156 +++ linux-2.6.22-try2-netns/net/ipv4/netfilter/ipt_addrtype.c   2007-12-19 22:49:20.000000000 -0500
16157 @@ -24,7 +24,7 @@
16158  
16159  static inline int match_type(__be32 addr, u_int16_t mask)
16160  {
16161 -       return !!(mask & (1 << inet_addr_type(addr)));
16162 +       return !!(mask & (1 << inet_addr_type(&init_net, addr)));
16163  }
16164  
16165  static int match(const struct sk_buff *skb,
16166 diff -Nurb linux-2.6.22-try2/net/ipv4/netfilter/ipt_recent.c linux-2.6.22-try2-netns/net/ipv4/netfilter/ipt_recent.c
16167 --- linux-2.6.22-try2/net/ipv4/netfilter/ipt_recent.c   2007-12-19 13:37:58.000000000 -0500
16168 +++ linux-2.6.22-try2-netns/net/ipv4/netfilter/ipt_recent.c     2007-12-19 22:49:20.000000000 -0500
16169 @@ -24,6 +24,7 @@
16170  #include <linux/bitops.h>
16171  #include <linux/skbuff.h>
16172  #include <linux/inet.h>
16173 +#include <net/net_namespace.h>
16174  
16175  #include <linux/netfilter/x_tables.h>
16176  #include <linux/netfilter_ipv4/ipt_recent.h>
16177 @@ -485,7 +486,7 @@
16178  #ifdef CONFIG_PROC_FS
16179         if (err)
16180                 return err;
16181 -       proc_dir = proc_mkdir("ipt_recent", proc_net);
16182 +       proc_dir = proc_mkdir("ipt_recent", init_net.proc_net);
16183         if (proc_dir == NULL) {
16184                 xt_unregister_match(&recent_match);
16185                 err = -ENOMEM;
16186 @@ -499,7 +500,7 @@
16187         BUG_ON(!list_empty(&tables));
16188         xt_unregister_match(&recent_match);
16189  #ifdef CONFIG_PROC_FS
16190 -       remove_proc_entry("ipt_recent", proc_net);
16191 +       remove_proc_entry("ipt_recent", init_net.proc_net);
16192  #endif
16193  }
16194  
16195 diff -Nurb linux-2.6.22-try2/net/ipv4/netfilter/iptable_filter.c linux-2.6.22-try2-netns/net/ipv4/netfilter/iptable_filter.c
16196 --- linux-2.6.22-try2/net/ipv4/netfilter/iptable_filter.c       2007-12-19 13:37:58.000000000 -0500
16197 +++ linux-2.6.22-try2-netns/net/ipv4/netfilter/iptable_filter.c 2007-12-19 22:49:20.000000000 -0500
16198 @@ -26,7 +26,7 @@
16199         struct ipt_replace repl;
16200         struct ipt_standard entries[3];
16201         struct ipt_error term;
16202 -} initial_table __initdata = {
16203 +} initial_table = {
16204         .repl = {
16205                 .name = "filter",
16206                 .valid_hooks = FILTER_VALID_HOOKS,
16207 @@ -51,7 +51,7 @@
16208         .term = IPT_ERROR_INIT,                 /* ERROR */
16209  };
16210  
16211 -static struct xt_table packet_filter = {
16212 +static struct xt_table ip_packet_filter_dflt = {
16213         .name           = "filter",
16214         .valid_hooks    = FILTER_VALID_HOOKS,
16215         .lock           = RW_LOCK_UNLOCKED,
16216 @@ -67,7 +67,9 @@
16217          const struct net_device *out,
16218          int (*okfn)(struct sk_buff *))
16219  {
16220 -       return ipt_do_table(pskb, hook, in, out, &packet_filter);
16221 +       struct net *net = (in?in:out)->nd_net;
16222 +
16223 +       return ipt_do_table(pskb, hook, in, out, net->ip_packet_filter);
16224  }
16225  
16226  static unsigned int
16227 @@ -77,6 +79,8 @@
16228                    const struct net_device *out,
16229                    int (*okfn)(struct sk_buff *))
16230  {
16231 +       struct net *net = (in?in:out)->nd_net;
16232 +
16233         /* root is playing with raw sockets. */
16234         if ((*pskb)->len < sizeof(struct iphdr)
16235             || ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
16236 @@ -86,7 +90,7 @@
16237                 return NF_ACCEPT;
16238         }
16239  
16240 -       return ipt_do_table(pskb, hook, in, out, &packet_filter);
16241 +       return ipt_do_table(pskb, hook, in, out, net->ip_packet_filter);
16242  }
16243  
16244  static struct nf_hook_ops ipt_ops[] = {
16245 @@ -117,6 +121,30 @@
16246  static int forward = NF_ACCEPT;
16247  module_param(forward, bool, 0000);
16248  
16249 +static int iptable_filter_net_init(struct net *net)
16250 +{
16251 +       /* Allocate the table */
16252 +       net->ip_packet_filter = kmemdup(&ip_packet_filter_dflt,
16253 +                                       sizeof(*net->ip_packet_filter),
16254 +                                       GFP_KERNEL);
16255 +       if (!net->ip_packet_filter)
16256 +               return -ENOMEM;
16257 +
16258 +       /* Register table */
16259 +       return ipt_register_table(net, net->ip_packet_filter, &initial_table.repl);
16260 +}
16261 +
16262 +static void iptable_filter_net_exit(struct net *net)
16263 +{
16264 +       ipt_unregister_table(net->ip_packet_filter);
16265 +       kfree(net->ip_packet_filter);
16266 +}
16267 +
16268 +static struct pernet_operations iptable_filter_net_ops = {
16269 +       .init = iptable_filter_net_init,
16270 +       .exit = iptable_filter_net_exit,
16271 +};
16272 +
16273  static int __init iptable_filter_init(void)
16274  {
16275         int ret;
16276 @@ -130,7 +158,7 @@
16277         initial_table.entries[1].target.verdict = -forward - 1;
16278  
16279         /* Register table */
16280 -       ret = ipt_register_table(&packet_filter, &initial_table.repl);
16281 +       ret = register_pernet_subsys(&iptable_filter_net_ops);
16282         if (ret < 0)
16283                 return ret;
16284  
16285 @@ -142,14 +170,14 @@
16286         return ret;
16287  
16288   cleanup_table:
16289 -       ipt_unregister_table(&packet_filter);
16290 +       unregister_pernet_subsys(&iptable_filter_net_ops);
16291         return ret;
16292  }
16293  
16294  static void __exit iptable_filter_fini(void)
16295  {
16296         nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops));
16297 -       ipt_unregister_table(&packet_filter);
16298 +       unregister_pernet_subsys(&iptable_filter_net_ops);
16299  }
16300  
16301  module_init(iptable_filter_init);
16302 diff -Nurb linux-2.6.22-try2/net/ipv4/netfilter/iptable_mangle.c linux-2.6.22-try2-netns/net/ipv4/netfilter/iptable_mangle.c
16303 --- linux-2.6.22-try2/net/ipv4/netfilter/iptable_mangle.c       2007-12-19 13:37:58.000000000 -0500
16304 +++ linux-2.6.22-try2-netns/net/ipv4/netfilter/iptable_mangle.c 2007-12-19 22:49:20.000000000 -0500
16305 @@ -80,6 +80,10 @@
16306          const struct net_device *out,
16307          int (*okfn)(struct sk_buff *))
16308  {
16309 +       /* Only filter packets in the initial network namespace */
16310 +       if ((in?in:out)->nd_net != &init_net)
16311 +               return NF_ACCEPT;
16312 +
16313         return ipt_do_table(pskb, hook, in, out, &packet_mangler);
16314  }
16315  
16316 @@ -96,6 +100,10 @@
16317         __be32 saddr, daddr;
16318         u_int32_t mark;
16319  
16320 +       /* Only filter packets in the initial network namespace */
16321 +       if ((in?in:out)->nd_net != &init_net)
16322 +               return NF_ACCEPT;
16323 +
16324         /* root is playing with raw sockets. */
16325         if ((*pskb)->len < sizeof(struct iphdr)
16326             || ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
16327 @@ -121,7 +129,7 @@
16328                     iph->daddr != daddr ||
16329                     (*pskb)->mark != mark ||
16330                     iph->tos != tos)
16331 -                       if (ip_route_me_harder(pskb, RTN_UNSPEC))
16332 +                       if (ip_route_me_harder(&init_net, pskb, RTN_UNSPEC))
16333                                 ret = NF_DROP;
16334         }
16335  
16336 @@ -171,7 +179,7 @@
16337         int ret;
16338  
16339         /* Register table */
16340 -       ret = ipt_register_table(&packet_mangler, &initial_table.repl);
16341 +       ret = ipt_register_table(&init_net, &packet_mangler, &initial_table.repl);
16342         if (ret < 0)
16343                 return ret;
16344  
16345 diff -Nurb linux-2.6.22-try2/net/ipv4/netfilter/iptable_raw.c linux-2.6.22-try2-netns/net/ipv4/netfilter/iptable_raw.c
16346 --- linux-2.6.22-try2/net/ipv4/netfilter/iptable_raw.c  2007-12-19 13:37:58.000000000 -0500
16347 +++ linux-2.6.22-try2-netns/net/ipv4/netfilter/iptable_raw.c    2007-12-19 22:49:20.000000000 -0500
16348 @@ -52,6 +52,10 @@
16349          const struct net_device *out,
16350          int (*okfn)(struct sk_buff *))
16351  {
16352 +       /* Only filter packets in the initial network namespace */
16353 +       if ((in?in:out)->nd_net != &init_net)
16354 +               return NF_ACCEPT;
16355 +
16356         return ipt_do_table(pskb, hook, in, out, &packet_raw);
16357  }
16358  
16359 @@ -96,7 +100,7 @@
16360         int ret;
16361  
16362         /* Register table */
16363 -       ret = ipt_register_table(&packet_raw, &initial_table.repl);
16364 +       ret = ipt_register_table(&init_net, &packet_raw, &initial_table.repl);
16365         if (ret < 0)
16366                 return ret;
16367  
16368 diff -Nurb linux-2.6.22-try2/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c linux-2.6.22-try2-netns/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
16369 --- linux-2.6.22-try2/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c    2007-12-19 13:37:58.000000000 -0500
16370 +++ linux-2.6.22-try2-netns/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c      2007-12-19 22:49:20.000000000 -0500
16371 @@ -120,6 +120,10 @@
16372                                  const struct net_device *out,
16373                                  int (*okfn)(struct sk_buff *))
16374  {
16375 +       /* Only filter packets in the initial network namespace */
16376 +       if ((in?in:out)->nd_net != &init_net)
16377 +               return NF_ACCEPT;
16378 +
16379         /* We've seen it coming out the other side: confirm it */
16380         return nf_conntrack_confirm(pskb);
16381  }
16382 @@ -135,6 +139,10 @@
16383         struct nf_conn_help *help;
16384         struct nf_conntrack_helper *helper;
16385  
16386 +       /* Only filter packets in the initial network namespace */
16387 +       if ((in?in:out)->nd_net != &init_net)
16388 +               return NF_ACCEPT;
16389 +
16390         /* This is where we call the helper: as the packet goes out. */
16391         ct = nf_ct_get(*pskb, &ctinfo);
16392         if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)
16393 @@ -157,6 +165,10 @@
16394                                           const struct net_device *out,
16395                                           int (*okfn)(struct sk_buff *))
16396  {
16397 +       /* Only filter packets in the initial network namespace */
16398 +       if ((in?in:out)->nd_net != &init_net)
16399 +               return NF_ACCEPT;
16400 +
16401         /* Previously seen (loopback)?  Ignore.  Do this before
16402            fragment check. */
16403         if ((*pskb)->nfct)
16404 @@ -180,6 +192,10 @@
16405                                       const struct net_device *out,
16406                                       int (*okfn)(struct sk_buff *))
16407  {
16408 +       /* Only filter packets in the initial network namespace */
16409 +       if ((in?in:out)->nd_net != &init_net)
16410 +               return NF_ACCEPT;
16411 +
16412         return nf_conntrack_in(PF_INET, hooknum, pskb);
16413  }
16414  
16415 @@ -189,6 +205,10 @@
16416                                          const struct net_device *out,
16417                                          int (*okfn)(struct sk_buff *))
16418  {
16419 +       /* Only filter packets in the initial network namespace */
16420 +       if ((in?in:out)->nd_net != &init_net)
16421 +               return NF_ACCEPT;
16422 +
16423         /* root is playing with raw sockets. */
16424         if ((*pskb)->len < sizeof(struct iphdr)
16425             || ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
16426 @@ -325,6 +345,9 @@
16427         struct nf_conntrack_tuple_hash *h;
16428         struct nf_conntrack_tuple tuple;
16429  
16430 +       if (sk->sk_net != &init_net)
16431 +               return -ENOPROTOOPT;
16432 +
16433         NF_CT_TUPLE_U_BLANK(&tuple);
16434         tuple.src.u3.ip = inet->rcv_saddr;
16435         tuple.src.u.tcp.port = inet->sport;
16436 diff -Nurb linux-2.6.22-try2/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c linux-2.6.22-try2-netns/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
16437 --- linux-2.6.22-try2/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c     2007-12-19 13:37:58.000000000 -0500
16438 +++ linux-2.6.22-try2-netns/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c       2007-12-19 22:49:20.000000000 -0500
16439 @@ -11,6 +11,7 @@
16440  #include <linux/proc_fs.h>
16441  #include <linux/seq_file.h>
16442  #include <linux/percpu.h>
16443 +#include <net/net_namespace.h>
16444  
16445  #include <linux/netfilter.h>
16446  #include <net/netfilter/nf_conntrack_core.h>
16447 @@ -378,16 +379,16 @@
16448  {
16449         struct proc_dir_entry *proc, *proc_exp, *proc_stat;
16450  
16451 -       proc = proc_net_fops_create("ip_conntrack", 0440, &ct_file_ops);
16452 +       proc = proc_net_fops_create(&init_net, "ip_conntrack", 0440, &ct_file_ops);
16453         if (!proc)
16454                 goto err1;
16455  
16456 -       proc_exp = proc_net_fops_create("ip_conntrack_expect", 0440,
16457 +       proc_exp = proc_net_fops_create(&init_net, "ip_conntrack_expect", 0440,
16458                                         &ip_exp_file_ops);
16459         if (!proc_exp)
16460                 goto err2;
16461  
16462 -       proc_stat = create_proc_entry("ip_conntrack", S_IRUGO, proc_net_stat);
16463 +       proc_stat = create_proc_entry("ip_conntrack", S_IRUGO, init_net.proc_net_stat);
16464         if (!proc_stat)
16465                 goto err3;
16466  
16467 @@ -397,16 +398,16 @@
16468         return 0;
16469  
16470  err3:
16471 -       proc_net_remove("ip_conntrack_expect");
16472 +       proc_net_remove(&init_net, "ip_conntrack_expect");
16473  err2:
16474 -       proc_net_remove("ip_conntrack");
16475 +       proc_net_remove(&init_net, "ip_conntrack");
16476  err1:
16477         return -ENOMEM;
16478  }
16479  
16480  void __exit nf_conntrack_ipv4_compat_fini(void)
16481  {
16482 -       remove_proc_entry("ip_conntrack", proc_net_stat);
16483 -       proc_net_remove("ip_conntrack_expect");
16484 -       proc_net_remove("ip_conntrack");
16485 +       remove_proc_entry("ip_conntrack", init_net.proc_net_stat);
16486 +       proc_net_remove(&init_net, "ip_conntrack_expect");
16487 +       proc_net_remove(&init_net, "ip_conntrack");
16488  }
16489 diff -Nurb linux-2.6.22-try2/net/ipv4/netfilter/nf_nat_rule.c linux-2.6.22-try2-netns/net/ipv4/netfilter/nf_nat_rule.c
16490 --- linux-2.6.22-try2/net/ipv4/netfilter/nf_nat_rule.c  2007-12-19 13:37:58.000000000 -0500
16491 +++ linux-2.6.22-try2-netns/net/ipv4/netfilter/nf_nat_rule.c    2007-12-19 22:49:20.000000000 -0500
16492 @@ -98,7 +98,10 @@
16493  static void warn_if_extra_mangle(__be32 dstip, __be32 srcip)
16494  {
16495         static int warned = 0;
16496 -       struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } };
16497 +       struct flowi fl = {
16498 +               .fl_net = &init_net,
16499 +               .nl_u = { .ip4_u = { .daddr = dstip } }
16500 +       };
16501         struct rtable *rt;
16502  
16503         if (ip_route_output_key(&rt, &fl) != 0)
16504 @@ -252,7 +255,7 @@
16505  {
16506         int ret;
16507  
16508 -       ret = ipt_register_table(&nat_table, &nat_initial_table.repl);
16509 +       ret = ipt_register_table(&init_net, &nat_table, &nat_initial_table.repl);
16510         if (ret != 0)
16511                 return ret;
16512         ret = xt_register_target(&ipt_snat_reg);
16513 diff -Nurb linux-2.6.22-try2/net/ipv4/netfilter/nf_nat_standalone.c linux-2.6.22-try2-netns/net/ipv4/netfilter/nf_nat_standalone.c
16514 --- linux-2.6.22-try2/net/ipv4/netfilter/nf_nat_standalone.c    2007-12-19 13:37:58.000000000 -0500
16515 +++ linux-2.6.22-try2-netns/net/ipv4/netfilter/nf_nat_standalone.c      2007-12-19 22:49:20.000000000 -0500
16516 @@ -83,6 +83,10 @@
16517         /* maniptype == SRC for postrouting. */
16518         enum nf_nat_manip_type maniptype = HOOK2MANIP(hooknum);
16519  
16520 +       /* Only filter packets in the initial network namespace */
16521 +       if ((in?in:out)->nd_net != &init_net)
16522 +               return NF_ACCEPT;
16523 +
16524         /* We never see fragments: conntrack defrags on pre-routing
16525            and local-out, and nf_nat_out protects post-routing. */
16526         NF_CT_ASSERT(!(ip_hdr(*pskb)->frag_off & htons(IP_MF | IP_OFFSET)));
16527 @@ -172,6 +176,10 @@
16528         unsigned int ret;
16529         __be32 daddr = ip_hdr(*pskb)->daddr;
16530  
16531 +       /* Only filter packets in the initial network namespace */
16532 +       if ((in?in:out)->nd_net != &init_net)
16533 +               return NF_ACCEPT;
16534 +
16535         ret = nf_nat_fn(hooknum, pskb, in, out, okfn);
16536         if (ret != NF_DROP && ret != NF_STOLEN &&
16537             daddr != ip_hdr(*pskb)->daddr) {
16538 @@ -194,6 +202,10 @@
16539  #endif
16540         unsigned int ret;
16541  
16542 +       /* Only filter packets in the initial network namespace */
16543 +       if ((in?in:out)->nd_net != &init_net)
16544 +               return NF_ACCEPT;
16545 +
16546         /* root is playing with raw sockets. */
16547         if ((*pskb)->len < sizeof(struct iphdr) ||
16548             ip_hdrlen(*pskb) < sizeof(struct iphdr))
16549 @@ -227,6 +239,10 @@
16550         enum ip_conntrack_info ctinfo;
16551         unsigned int ret;
16552  
16553 +       /* Only filter packets in the initial network namespace */
16554 +       if ((in?in:out)->nd_net != &init_net)
16555 +               return NF_ACCEPT;
16556 +
16557         /* root is playing with raw sockets. */
16558         if ((*pskb)->len < sizeof(struct iphdr) ||
16559             ip_hdrlen(*pskb) < sizeof(struct iphdr))
16560 @@ -239,7 +255,7 @@
16561  
16562                 if (ct->tuplehash[dir].tuple.dst.u3.ip !=
16563                     ct->tuplehash[!dir].tuple.src.u3.ip) {
16564 -                       if (ip_route_me_harder(pskb, RTN_UNSPEC))
16565 +                       if (ip_route_me_harder(&init_net, pskb, RTN_UNSPEC))
16566                                 ret = NF_DROP;
16567                 }
16568  #ifdef CONFIG_XFRM
16569 @@ -262,6 +278,10 @@
16570         struct nf_conn *ct;
16571         enum ip_conntrack_info ctinfo;
16572  
16573 +       /* Only filter packets in the initial network namespace */
16574 +       if ((in?in:out)->nd_net != &init_net)
16575 +               return NF_ACCEPT;
16576 +
16577         ct = nf_ct_get(*pskb, &ctinfo);
16578         if (ct && test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
16579                 DEBUGP("nf_nat_standalone: adjusting sequence number\n");
16580 diff -Nurb linux-2.6.22-try2/net/ipv4/netfilter.c linux-2.6.22-try2-netns/net/ipv4/netfilter.c
16581 --- linux-2.6.22-try2/net/ipv4/netfilter.c      2007-12-19 13:37:58.000000000 -0500
16582 +++ linux-2.6.22-try2-netns/net/ipv4/netfilter.c        2007-12-19 22:49:20.000000000 -0500
16583 @@ -8,7 +8,7 @@
16584  #include <net/ip.h>
16585  
16586  /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
16587 -int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type)
16588 +int ip_route_me_harder(struct net *net, struct sk_buff **pskb, unsigned addr_type)
16589  {
16590         const struct iphdr *iph = ip_hdr(*pskb);
16591         struct rtable *rt;
16592 @@ -17,7 +17,8 @@
16593         unsigned int hh_len;
16594         unsigned int type;
16595  
16596 -       type = inet_addr_type(iph->saddr);
16597 +       fl.fl_net = net;
16598 +       type = inet_addr_type(net, iph->saddr);
16599         if (addr_type == RTN_UNSPEC)
16600                 addr_type = type;
16601  
16602 @@ -155,12 +156,13 @@
16603         const struct ip_rt_info *rt_info = nf_info_reroute(info);
16604  
16605         if (info->hook == NF_IP_LOCAL_OUT) {
16606 +               struct net *net = (info->indev?info->indev:info->outdev)->nd_net;
16607                 const struct iphdr *iph = ip_hdr(*pskb);
16608  
16609                 if (!(iph->tos == rt_info->tos
16610                       && iph->daddr == rt_info->daddr
16611                       && iph->saddr == rt_info->saddr))
16612 -                       return ip_route_me_harder(pskb, RTN_UNSPEC);
16613 +                       return ip_route_me_harder(net, pskb, RTN_UNSPEC);
16614         }
16615         return 0;
16616  }
16617 diff -Nurb linux-2.6.22-try2/net/ipv4/proc.c linux-2.6.22-try2-netns/net/ipv4/proc.c
16618 --- linux-2.6.22-try2/net/ipv4/proc.c   2007-12-19 13:37:58.000000000 -0500
16619 +++ linux-2.6.22-try2-netns/net/ipv4/proc.c     2007-12-19 22:49:20.000000000 -0500
16620 @@ -44,6 +44,7 @@
16621  #include <linux/seq_file.h>
16622  #include <net/sock.h>
16623  #include <net/raw.h>
16624 +#include <net/net_namespace.h>
16625  
16626  static int fold_prot_inuse(struct proto *proto)
16627  {
16628 @@ -69,8 +70,9 @@
16629         seq_printf(seq, "UDP: inuse %d\n", fold_prot_inuse(&udp_prot));
16630         seq_printf(seq, "UDPLITE: inuse %d\n", fold_prot_inuse(&udplite_prot));
16631         seq_printf(seq, "RAW: inuse %d\n", fold_prot_inuse(&raw_prot));
16632 -       seq_printf(seq,  "FRAG: inuse %d memory %d\n", ip_frag_nqueues,
16633 -                  atomic_read(&ip_frag_mem));
16634 +       seq_printf(seq,  "FRAG: inuse %d memory %d\n", 
16635 +                  init_net.ip_frag_nqueues,
16636 +                  atomic_read(&init_net.ip_frag_mem));
16637         return 0;
16638  }
16639  
16640 @@ -260,7 +262,8 @@
16641                 seq_printf(seq, " %s", snmp4_ipstats_list[i].name);
16642  
16643         seq_printf(seq, "\nIp: %d %d",
16644 -                  IPV4_DEVCONF_ALL(FORWARDING) ? 1 : 2, sysctl_ip_default_ttl);
16645 +                  IPV4_DEVCONF_ALL(&init_net, FORWARDING) ? 1 : 2,
16646 +                  init_net.sysctl_ip_default_ttl);
16647  
16648         for (i = 0; snmp4_ipstats_list[i].name != NULL; i++)
16649                 seq_printf(seq, " %lu",
16650 @@ -380,20 +383,20 @@
16651  {
16652         int rc = 0;
16653  
16654 -       if (!proc_net_fops_create("netstat", S_IRUGO, &netstat_seq_fops))
16655 +       if (!proc_net_fops_create(&init_net, "netstat", S_IRUGO, &netstat_seq_fops))
16656                 goto out_netstat;
16657  
16658 -       if (!proc_net_fops_create("snmp", S_IRUGO, &snmp_seq_fops))
16659 +       if (!proc_net_fops_create(&init_net, "snmp", S_IRUGO, &snmp_seq_fops))
16660                 goto out_snmp;
16661  
16662 -       if (!proc_net_fops_create("sockstat", S_IRUGO, &sockstat_seq_fops))
16663 +       if (!proc_net_fops_create(&init_net, "sockstat", S_IRUGO, &sockstat_seq_fops))
16664                 goto out_sockstat;
16665  out:
16666         return rc;
16667  out_sockstat:
16668 -       proc_net_remove("snmp");
16669 +       proc_net_remove(&init_net, "snmp");
16670  out_snmp:
16671 -       proc_net_remove("netstat");
16672 +       proc_net_remove(&init_net, "netstat");
16673  out_netstat:
16674         rc = -ENOMEM;
16675         goto out;
16676 diff -Nurb linux-2.6.22-try2/net/ipv4/raw.c linux-2.6.22-try2-netns/net/ipv4/raw.c
16677 --- linux-2.6.22-try2/net/ipv4/raw.c    2007-12-19 13:37:58.000000000 -0500
16678 +++ linux-2.6.22-try2-netns/net/ipv4/raw.c      2007-12-19 23:30:30.000000000 -0500
16679 @@ -73,6 +73,7 @@
16680  #include <net/inet_common.h>
16681  #include <net/checksum.h>
16682  #include <net/xfrm.h>
16683 +#include <net/net_namespace.h>
16684  #include <linux/rtnetlink.h>
16685  #include <linux/proc_fs.h>
16686  #include <linux/seq_file.h>
16687 @@ -101,7 +102,7 @@
16688         write_unlock_bh(&raw_v4_lock);
16689  }
16690  
16691 -struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
16692 +struct sock *__raw_v4_lookup(struct net *net, struct sock *sk, unsigned short num,
16693                              __be32 raddr, __be32 laddr,
16694                              int dif, int tag)
16695  {
16696 @@ -110,6 +111,9 @@
16697         sk_for_each_from(sk, node) {
16698                 struct inet_sock *inet = inet_sk(sk);
16699  
16700 +               if (sk->sk_net != net)
16701 +                       continue;
16702 +
16703                 if (inet->num == num                                    &&
16704                     !(inet->daddr && inet->daddr != raddr)              &&
16705                     (!sk->sk_nx_info || tag == 1 || sk->sk_nid == tag)  &&
16706 @@ -152,6 +156,7 @@
16707   */
16708  int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
16709  {
16710 +       struct net *net = skb->dev->nd_net;
16711         struct sock *sk;
16712         struct hlist_head *head;
16713         int delivered = 0;
16714 @@ -160,7 +165,7 @@
16715         head = &raw_v4_htable[hash];
16716         if (hlist_empty(head))
16717                 goto out;
16718 -       sk = __raw_v4_lookup(__sk_head(head), iph->protocol,
16719 +       sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol,
16720                              iph->saddr, iph->daddr,
16721                              skb->dev->ifindex, skb->skb_tag);
16722  
16723 @@ -173,7 +178,7 @@
16724                         if (clone)
16725                                 raw_rcv(sk, clone);
16726                 }
16727 -               sk = __raw_v4_lookup(sk_next(sk), iph->protocol,
16728 +               sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol,
16729                                      iph->saddr, iph->daddr,
16730                                      skb->dev->ifindex, skb->skb_tag);
16731         }
16732 @@ -484,7 +489,8 @@
16733         }
16734  
16735         {
16736 -               struct flowi fl = { .oif = ipc.oif,
16737 +               struct flowi fl = { .fl_net = sk->sk_net,
16738 +                                   .oif = ipc.oif,
16739                                     .nl_u = { .ip4_u =
16740                                               { .daddr = daddr,
16741                                                 .saddr = saddr,
16742 @@ -574,7 +580,7 @@
16743         if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in))
16744                 goto out;
16745         v4_map_sock_addr(inet, addr, &nsa);
16746 -       chk_addr_ret = inet_addr_type(nsa.saddr);
16747 +       chk_addr_ret = inet_addr_type(sk->sk_net, nsa.saddr);
16748         ret = -EADDRNOTAVAIL;
16749         if (nsa.saddr && chk_addr_ret != RTN_LOCAL &&
16750             chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
16751 @@ -798,6 +804,7 @@
16752  
16753  #ifdef CONFIG_PROC_FS
16754  struct raw_iter_state {
16755 +       struct net *net;
16756         int bucket;
16757  };
16758  
16759 @@ -811,11 +818,14 @@
16760         for (state->bucket = 0; state->bucket < RAWV4_HTABLE_SIZE; ++state->bucket) {
16761                 struct hlist_node *node;
16762  
16763 -               sk_for_each(sk, node, &raw_v4_htable[state->bucket])
16764 +               sk_for_each(sk, node, &raw_v4_htable[state->bucket]) {
16765 +                       if (sk->sk_net != state->net)
16766 +                               continue;
16767                         if (sk->sk_family == PF_INET &&
16768                                 nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
16769                                 goto found;
16770         }
16771 +       }
16772         sk = NULL;
16773  found:
16774         return sk;
16775 @@ -830,7 +840,7 @@
16776  try_again:
16777                 ;
16778         } while (sk && (sk->sk_family != PF_INET ||
16779 -               !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
16780 +               !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT) || (sk->sk_net != state->net)));
16781  
16782         if (!sk && ++state->bucket < RAWV4_HTABLE_SIZE) {
16783                 sk = sk_head(&raw_v4_htable[state->bucket]);
16784 @@ -933,6 +943,7 @@
16785         seq = file->private_data;
16786         seq->private = s;
16787         memset(s, 0, sizeof(*s));
16788 +       s->net = get_net(PROC_NET(inode));
16789  out:
16790         return rc;
16791  out_kfree:
16792 @@ -940,23 +951,46 @@
16793         goto out;
16794  }
16795  
16796 +static int raw_seq_release(struct inode *inode, struct file *file)
16797 +{
16798 +       struct seq_file *seq = file->private_data;
16799 +       struct raw_iter_state *state = seq->private;
16800 +       put_net(state->net);
16801 +       return seq_release_private(inode, file);
16802 +}
16803 +
16804  static const struct file_operations raw_seq_fops = {
16805         .owner   = THIS_MODULE,
16806         .open    = raw_seq_open,
16807         .read    = seq_read,
16808         .llseek  = seq_lseek,
16809 -       .release = seq_release_private,
16810 +       .release = raw_seq_release,
16811  };
16812  
16813 -int __init raw_proc_init(void)
16814 +static int raw_proc_net_init(struct net *net)
16815  {
16816 -       if (!proc_net_fops_create("raw", S_IRUGO, &raw_seq_fops))
16817 +       if (!proc_net_fops_create(net, "raw", S_IRUGO, &raw_seq_fops))
16818                 return -ENOMEM;
16819         return 0;
16820  }
16821  
16822 +static void raw_proc_net_exit(struct net *net)
16823 +{
16824 +       proc_net_remove(net, "raw");
16825 +}
16826 +
16827 +static struct pernet_operations raw_proc_net_ops = {
16828 +       .init = raw_proc_net_init,
16829 +       .exit = raw_proc_net_exit,
16830 +};
16831 +
16832 +int __init raw_proc_init(void)
16833 +{
16834 +       return register_pernet_subsys(&raw_proc_net_ops);
16835 +}
16836 +
16837  void __init raw_proc_exit(void)
16838  {
16839 -       proc_net_remove("raw");
16840 +       unregister_pernet_subsys(&raw_proc_net_ops);
16841  }
16842  #endif /* CONFIG_PROC_FS */
16843 diff -Nurb linux-2.6.22-try2/net/ipv4/route.c linux-2.6.22-try2-netns/net/ipv4/route.c
16844 --- linux-2.6.22-try2/net/ipv4/route.c  2007-12-19 15:29:23.000000000 -0500
16845 +++ linux-2.6.22-try2-netns/net/ipv4/route.c    2007-12-19 22:49:20.000000000 -0500
16846 @@ -102,6 +102,7 @@
16847  #include <net/icmp.h>
16848  #include <net/xfrm.h>
16849  #include <net/netevent.h>
16850 +#include <net/net_namespace.h>
16851  #include <net/rtnetlink.h>
16852  #ifdef CONFIG_SYSCTL
16853  #include <linux/sysctl.h>
16854 @@ -265,6 +266,7 @@
16855  
16856  #ifdef CONFIG_PROC_FS
16857  struct rt_cache_iter_state {
16858 +       struct net *net;
16859         int bucket;
16860  };
16861  
16862 @@ -333,6 +335,7 @@
16863  
16864  static int rt_cache_seq_show(struct seq_file *seq, void *v)
16865  {
16866 +       struct rt_cache_iter_state *st = seq->private;
16867         if (v == SEQ_START_TOKEN)
16868                 seq_printf(seq, "%-127s\n",
16869                            "Iface\tDestination\tGateway \tFlags\t\tRefCnt\tUse\t"
16870 @@ -342,6 +345,9 @@
16871                 struct rtable *r = v;
16872                 char temp[256];
16873  
16874 +               if (r->fl.fl_net != st->net)
16875 +                       return 0;
16876 +
16877                 sprintf(temp, "%s\t%08lX\t%08lX\t%8X\t%d\t%u\t%d\t"
16878                               "%08lX\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X",
16879                         r->u.dst.dev ? r->u.dst.dev->name : "*",
16880 @@ -384,6 +390,7 @@
16881         seq          = file->private_data;
16882         seq->private = s;
16883         memset(s, 0, sizeof(*s));
16884 +       s->net = get_net(PROC_NET(inode));
16885  out:
16886         return rc;
16887  out_kfree:
16888 @@ -391,12 +398,20 @@
16889         goto out;
16890  }
16891  
16892 +static int rt_cache_seq_release(struct inode *inode, struct file *file)
16893 +{
16894 +       struct seq_file *seq = file->private_data;
16895 +       struct rt_cache_iter_state *st = seq->private;
16896 +       put_net(st->net);
16897 +       return seq_release_private(inode, file);
16898 +}
16899 +
16900  static const struct file_operations rt_cache_seq_fops = {
16901         .owner   = THIS_MODULE,
16902         .open    = rt_cache_seq_open,
16903         .read    = seq_read,
16904         .llseek  = seq_lseek,
16905 -       .release = seq_release_private,
16906 +       .release = rt_cache_seq_release,
16907  };
16908  
16909  
16910 @@ -562,13 +577,14 @@
16911  
16912  static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
16913  {
16914 -       return ((__force u32)((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) |
16915 +       return (((__force u32)((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) |
16916                 (fl1->nl_u.ip4_u.saddr ^ fl2->nl_u.ip4_u.saddr)) |
16917                 (fl1->mark ^ fl2->mark) |
16918                 (*(u16 *)&fl1->nl_u.ip4_u.tos ^
16919                  *(u16 *)&fl2->nl_u.ip4_u.tos) |
16920                 (fl1->oif ^ fl2->oif) |
16921 -               (fl1->iif ^ fl2->iif)) == 0;
16922 +               (fl1->iif ^ fl2->iif)) == 0) &&
16923 +               fl1->fl_net == fl2->fl_net;
16924  }
16925  
16926  /* This runs via a timer and thus is always in BH context. */
16927 @@ -963,7 +979,7 @@
16928         static DEFINE_SPINLOCK(rt_peer_lock);
16929         struct inet_peer *peer;
16930  
16931 -       peer = inet_getpeer(rt->rt_dst, create);
16932 +       peer = inet_getpeer(rt->fl.fl_net, rt->rt_dst, create);
16933  
16934         spin_lock_bh(&rt_peer_lock);
16935         if (rt->peer == NULL) {
16936 @@ -1056,7 +1072,7 @@
16937                 if (IN_DEV_SEC_REDIRECTS(in_dev) && ip_fib_check_default(new_gw, dev))
16938                         goto reject_redirect;
16939         } else {
16940 -               if (inet_addr_type(new_gw) != RTN_UNICAST)
16941 +               if (inet_addr_type(dev->nd_net, new_gw) != RTN_UNICAST)
16942                         goto reject_redirect;
16943         }
16944  
16945 @@ -1097,6 +1113,7 @@
16946  
16947                                 /* Copy all the information. */
16948                                 *rt = *rth;
16949 +                               hold_net(rt->fl.fl_net);
16950                                 INIT_RCU_HEAD(&rt->u.dst.rcu_head);
16951                                 rt->u.dst.__use         = 1;
16952                                 atomic_set(&rt->u.dst.__refcnt, 1);
16953 @@ -1315,7 +1332,7 @@
16954         __be32  daddr = iph->daddr;
16955         unsigned short est_mtu = 0;
16956  
16957 -       if (ipv4_config.no_pmtu_disc)
16958 +       if (init_net.sysctl_ipv4_no_pmtu_disc)
16959                 return 0;
16960  
16961         for (i = 0; i < 2; i++) {
16962 @@ -1397,6 +1414,7 @@
16963                 rt->idev = NULL;
16964                 in_dev_put(idev);
16965         }
16966 +       release_net(rt->fl.fl_net);
16967  }
16968  
16969  static void ipv4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
16970 @@ -1404,8 +1422,9 @@
16971  {
16972         struct rtable *rt = (struct rtable *) dst;
16973         struct in_device *idev = rt->idev;
16974 -       if (dev != &loopback_dev && idev && idev->dev == dev) {
16975 -               struct in_device *loopback_idev = in_dev_get(&loopback_dev);
16976 +       struct net *net = dev->nd_net;
16977 +       if (dev != &net->loopback_dev && idev && idev->dev == dev) {
16978 +               struct in_device *loopback_idev = in_dev_get(&net->loopback_dev);
16979                 if (loopback_idev) {
16980                         rt->idev = loopback_idev;
16981                         in_dev_put(idev);
16982 @@ -1492,7 +1511,7 @@
16983                 rt->u.dst.metrics[RTAX_MTU-1]= rt->u.dst.dev->mtu;
16984  
16985         if (rt->u.dst.metrics[RTAX_HOPLIMIT-1] == 0)
16986 -               rt->u.dst.metrics[RTAX_HOPLIMIT-1] = sysctl_ip_default_ttl;
16987 +               rt->u.dst.metrics[RTAX_HOPLIMIT-1] = init_net.sysctl_ip_default_ttl;
16988         if (rt->u.dst.metrics[RTAX_MTU-1] > IP_MAX_MTU)
16989                 rt->u.dst.metrics[RTAX_MTU-1] = IP_MAX_MTU;
16990         if (rt->u.dst.metrics[RTAX_ADVMSS-1] == 0)
16991 @@ -1513,6 +1532,7 @@
16992  static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
16993                                 u8 tos, struct net_device *dev, int our)
16994  {
16995 +       struct net *net = dev->nd_net;
16996         unsigned hash;
16997         struct rtable *rth;
16998         __be32 spec_dst;
16999 @@ -1546,6 +1566,7 @@
17000         rth->u.dst.flags= DST_HOST;
17001         if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
17002                 rth->u.dst.flags |= DST_NOPOLICY;
17003 +       rth->fl.fl_net  = hold_net(net);
17004         rth->fl.fl4_dst = daddr;
17005         rth->rt_dst     = daddr;
17006         rth->fl.fl4_tos = tos;
17007 @@ -1557,7 +1578,7 @@
17008  #endif
17009         rth->rt_iif     =
17010         rth->fl.iif     = dev->ifindex;
17011 -       rth->u.dst.dev  = &loopback_dev;
17012 +       rth->u.dst.dev  = &net->loopback_dev;
17013         dev_hold(rth->u.dst.dev);
17014         rth->idev       = in_dev_get(rth->u.dst.dev);
17015         rth->fl.oif     = 0;
17016 @@ -1686,6 +1707,7 @@
17017                 rth->u.dst.flags |= DST_NOPOLICY;
17018         if (IN_DEV_CONF_GET(out_dev, NOXFRM))
17019                 rth->u.dst.flags |= DST_NOXFRM;
17020 +       rth->fl.fl_net  = hold_net(in_dev->dev->nd_net);
17021         rth->fl.fl4_dst = daddr;
17022         rth->rt_dst     = daddr;
17023         rth->fl.fl4_tos = tos;
17024 @@ -1754,9 +1776,11 @@
17025  static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
17026                                u8 tos, struct net_device *dev)
17027  {
17028 +       struct net *net = dev->nd_net;
17029         struct fib_result res;
17030         struct in_device *in_dev = in_dev_get(dev);
17031 -       struct flowi fl = { .nl_u = { .ip4_u =
17032 +       struct flowi fl = { .fl_net = net,
17033 +                           .nl_u = { .ip4_u =
17034                                       { .daddr = daddr,
17035                                         .saddr = saddr,
17036                                         .tos = tos,
17037 @@ -1814,7 +1838,7 @@
17038         if (res.type == RTN_LOCAL) {
17039                 int result;
17040                 result = fib_validate_source(saddr, daddr, tos,
17041 -                                            loopback_dev.ifindex,
17042 +                                            net->loopback_dev.ifindex,
17043                                              dev, &spec_dst, &itag);
17044                 if (result < 0)
17045                         goto martian_source;
17046 @@ -1870,6 +1894,7 @@
17047         rth->u.dst.flags= DST_HOST;
17048         if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
17049                 rth->u.dst.flags |= DST_NOPOLICY;
17050 +       rth->fl.fl_net  = hold_net(net);
17051         rth->fl.fl4_dst = daddr;
17052         rth->rt_dst     = daddr;
17053         rth->fl.fl4_tos = tos;
17054 @@ -1881,7 +1906,7 @@
17055  #endif
17056         rth->rt_iif     =
17057         rth->fl.iif     = dev->ifindex;
17058 -       rth->u.dst.dev  = &loopback_dev;
17059 +       rth->u.dst.dev  = &net->loopback_dev;
17060         dev_hold(rth->u.dst.dev);
17061         rth->idev       = in_dev_get(rth->u.dst.dev);
17062         rth->rt_gateway = daddr;
17063 @@ -1939,6 +1964,7 @@
17064         struct rtable * rth;
17065         unsigned        hash;
17066         int iif = dev->ifindex;
17067 +       struct net *net = dev->nd_net;
17068  
17069         tos &= IPTOS_RT_MASK;
17070         hash = rt_hash(daddr, saddr, iif);
17071 @@ -1951,7 +1977,8 @@
17072                     rth->fl.iif == iif &&
17073                     rth->fl.oif == 0 &&
17074                     rth->fl.mark == skb->mark &&
17075 -                   rth->fl.fl4_tos == tos) {
17076 +                   rth->fl.fl4_tos == tos &&
17077 +                   rth->fl.fl_net == net) {
17078                         rth->u.dst.lastuse = jiffies;
17079                         dst_hold(&rth->u.dst);
17080                         rth->u.dst.__use++;
17081 @@ -2063,6 +2090,7 @@
17082         if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
17083                 rth->u.dst.flags |= DST_NOPOLICY;
17084  
17085 +       rth->fl.fl_net  = hold_net(oldflp->fl_net);
17086         rth->fl.fl4_dst = oldflp->fl4_dst;
17087         rth->fl.fl4_tos = tos;
17088         rth->fl.fl4_src = oldflp->fl4_src;
17089 @@ -2142,7 +2170,9 @@
17090  static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
17091  {
17092         u32 tos = RT_FL_TOS(oldflp);
17093 -       struct flowi fl = { .nl_u = { .ip4_u =
17094 +       struct net *net = oldflp->fl_net;
17095 +       struct flowi fl = { .fl_net = net,
17096 +                           .nl_u = { .ip4_u =
17097                                       { .daddr = oldflp->fl4_dst,
17098                                         .saddr = oldflp->fl4_src,
17099                                         .tos = tos & IPTOS_RT_MASK,
17100 @@ -2151,7 +2181,7 @@
17101                                                   RT_SCOPE_UNIVERSE),
17102                                       } },
17103                             .mark = oldflp->mark,
17104 -                           .iif = loopback_dev.ifindex,
17105 +                           .iif = net->loopback_dev.ifindex,
17106                             .oif = oldflp->oif };
17107         struct fib_result res;
17108         unsigned flags = 0;
17109 @@ -2173,7 +2203,7 @@
17110                         goto out;
17111  
17112                 /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
17113 -               dev_out = ip_dev_find(oldflp->fl4_src);
17114 +               dev_out = ip_dev_find(net, oldflp->fl4_src);
17115                 if (dev_out == NULL)
17116                         goto out;
17117  
17118 @@ -2212,7 +2242,7 @@
17119  
17120  
17121         if (oldflp->oif) {
17122 -               dev_out = dev_get_by_index(oldflp->oif);
17123 +               dev_out = dev_get_by_index(net, oldflp->oif);
17124                 err = -ENODEV;
17125                 if (dev_out == NULL)
17126                         goto out;
17127 @@ -2245,9 +2275,9 @@
17128                         fl.fl4_dst = fl.fl4_src = htonl(INADDR_LOOPBACK);
17129                 if (dev_out)
17130                         dev_put(dev_out);
17131 -               dev_out = &loopback_dev;
17132 +               dev_out = &net->loopback_dev;
17133                 dev_hold(dev_out);
17134 -               fl.oif = loopback_dev.ifindex;
17135 +               fl.oif = net->loopback_dev.ifindex;
17136                 res.type = RTN_LOCAL;
17137                 flags |= RTCF_LOCAL;
17138                 goto make_route;
17139 @@ -2292,7 +2322,7 @@
17140                         fl.fl4_src = fl.fl4_dst;
17141                 if (dev_out)
17142                         dev_put(dev_out);
17143 -               dev_out = &loopback_dev;
17144 +               dev_out = &net->loopback_dev;
17145                 dev_hold(dev_out);
17146                 fl.oif = dev_out->ifindex;
17147                 if (res.fi)
17148 @@ -2346,6 +2376,7 @@
17149                     rth->fl.iif == 0 &&
17150                     rth->fl.oif == flp->oif &&
17151                     rth->fl.mark == flp->mark &&
17152 +                   rth->fl.fl_net == flp->fl_net &&
17153                     !((rth->fl.fl4_tos ^ flp->fl4_tos) &
17154                             (IPTOS_RT_MASK | RTO_ONLINK))) {
17155                         rth->u.dst.lastuse = jiffies;
17156 @@ -2522,7 +2553,7 @@
17157                 __be32 dst = rt->rt_dst;
17158  
17159                 if (MULTICAST(dst) && !LOCAL_MCAST(dst) &&
17160 -                   IPV4_DEVCONF_ALL(MC_FORWARDING)) {
17161 +                   IPV4_DEVCONF_ALL(&init_net, MC_FORWARDING)) {
17162                         int err = ipmr_get_route(skb, r, nowait);
17163                         if (err <= 0) {
17164                                 if (!nowait) {
17165 @@ -2553,6 +2584,7 @@
17166  
17167  static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
17168  {
17169 +       struct net *net = in_skb->sk->sk_net;
17170         struct rtmsg *rtm;
17171         struct nlattr *tb[RTA_MAX+1];
17172         struct rtable *rt = NULL;
17173 @@ -2591,7 +2623,7 @@
17174         if (iif) {
17175                 struct net_device *dev;
17176  
17177 -               dev = __dev_get_by_index(iif);
17178 +               dev = __dev_get_by_index(net, iif);
17179                 if (dev == NULL) {
17180                         err = -ENODEV;
17181                         goto errout_free;
17182 @@ -2608,6 +2640,7 @@
17183                         err = -rt->u.dst.error;
17184         } else {
17185                 struct flowi fl = {
17186 +                       .fl_net = net,
17187                         .nl_u = {
17188                                 .ip4_u = {
17189                                         .daddr = dst,
17190 @@ -2632,7 +2665,7 @@
17191         if (err <= 0)
17192                 goto errout_free;
17193  
17194 -       err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
17195 +       err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid);
17196  errout:
17197         return err;
17198  
17199 @@ -2945,6 +2978,48 @@
17200  }
17201  __setup("rhash_entries=", set_rhash_entries);
17202  
17203 +
17204 +static void ip_rt_net_exit(struct net *net)
17205 +{
17206 +#ifdef CONFIG_PROC_FS
17207 +# ifdef CONFIG_NET_CLS_ROUTE
17208 +       proc_net_remove(net, "rt_acct");
17209 +# endif
17210 +       remove_proc_entry("rt_cache", net->proc_net_stat);
17211 +       proc_net_remove(net, "rt_cache");
17212 +#endif
17213 +       rt_run_flush(0);
17214 +}
17215 +
17216 +static int ip_rt_net_init(struct net *net)
17217 +{
17218 +       int error = -ENOMEM;
17219 +#ifdef CONFIG_PROC_FS
17220 +       struct proc_dir_entry *rtstat_pde;
17221 +       if (!proc_net_fops_create(net, "rt_cache", S_IRUGO, &rt_cache_seq_fops))
17222 +               goto out;
17223 +       if (!(rtstat_pde = create_proc_entry("rt_cache", S_IRUGO,
17224 +                       net->proc_net_stat)))
17225 +               goto out;
17226 +       rtstat_pde->proc_fops = &rt_cpu_seq_fops;
17227 +# ifdef CONFIG_NET_CLS_ROUTE
17228 +       if (!create_proc_read_entry("rt_acct", 0, net->proc_net,
17229 +                   ip_rt_acct_read, NULL))
17230 +               goto out;
17231 +# endif
17232 +#endif
17233 +       error = 0;
17234 +out:
17235 +       if (error)
17236 +               ip_rt_net_exit(net);
17237 +       return error;
17238 +}
17239 +
17240 +struct pernet_operations ip_rt_net_ops = {
17241 +       .init = ip_rt_net_init,
17242 +       .exit = ip_rt_net_exit,
17243 +};
17244
17245  int __init ip_rt_init(void)
17246  {
17247         int rc = 0;
17248 @@ -3008,20 +3083,7 @@
17249                 ip_rt_secret_interval;
17250         add_timer(&rt_secret_timer);
17251  
17252 -#ifdef CONFIG_PROC_FS
17253 -       {
17254 -       struct proc_dir_entry *rtstat_pde = NULL; /* keep gcc happy */
17255 -       if (!proc_net_fops_create("rt_cache", S_IRUGO, &rt_cache_seq_fops) ||
17256 -           !(rtstat_pde = create_proc_entry("rt_cache", S_IRUGO,
17257 -                                            proc_net_stat))) {
17258 -               return -ENOMEM;
17259 -       }
17260 -       rtstat_pde->proc_fops = &rt_cpu_seq_fops;
17261 -       }
17262 -#ifdef CONFIG_NET_CLS_ROUTE
17263 -       create_proc_read_entry("rt_acct", 0, proc_net, ip_rt_acct_read, NULL);
17264 -#endif
17265 -#endif
17266 +       register_pernet_subsys(&ip_rt_net_ops);
17267  #ifdef CONFIG_XFRM
17268         xfrm_init();
17269         xfrm4_init();
17270 diff -Nurb linux-2.6.22-try2/net/ipv4/syncookies.c linux-2.6.22-try2-netns/net/ipv4/syncookies.c
17271 --- linux-2.6.22-try2/net/ipv4/syncookies.c     2007-12-19 13:37:58.000000000 -0500
17272 +++ linux-2.6.22-try2-netns/net/ipv4/syncookies.c       2007-12-19 22:49:20.000000000 -0500
17273 @@ -253,7 +253,8 @@
17274          * no easy way to do this.
17275          */
17276         {
17277 -               struct flowi fl = { .nl_u = { .ip4_u =
17278 +               struct flowi fl = { .fl_net = &init_net,
17279 +                                   .nl_u = { .ip4_u =
17280                                               { .daddr = ((opt && opt->srr) ?
17281                                                           opt->faddr :
17282                                                           ireq->rmt_addr),
17283 diff -Nurb linux-2.6.22-try2/net/ipv4/sysctl_net_ipv4.c linux-2.6.22-try2-netns/net/ipv4/sysctl_net_ipv4.c
17284 --- linux-2.6.22-try2/net/ipv4/sysctl_net_ipv4.c        2007-12-19 13:37:58.000000000 -0500
17285 +++ linux-2.6.22-try2-netns/net/ipv4/sysctl_net_ipv4.c  2007-12-19 22:49:20.000000000 -0500
17286 @@ -29,21 +29,21 @@
17287  static int ip_local_port_range_max[] = { 65535, 65535 };
17288  #endif
17289  
17290 -struct ipv4_config ipv4_config;
17291 -
17292  #ifdef CONFIG_SYSCTL
17293  
17294  static
17295  int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
17296                         void __user *buffer, size_t *lenp, loff_t *ppos)
17297  {
17298 -       int val = IPV4_DEVCONF_ALL(FORWARDING);
17299 +       struct net *net = ctl->extra2;
17300 +       int *valp = ctl->data;
17301 +       int old = *valp;
17302         int ret;
17303  
17304         ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
17305  
17306 -       if (write && IPV4_DEVCONF_ALL(FORWARDING) != val)
17307 -               inet_forward_change();
17308 +       if (write && *valp != old)
17309 +               inet_forward_change(net);
17310  
17311         return ret;
17312  }
17313 @@ -53,6 +53,7 @@
17314                          void __user *oldval, size_t __user *oldlenp,
17315                          void __user *newval, size_t newlen)
17316  {
17317 +       struct net *net = table->extra2;
17318         int *valp = table->data;
17319         int new;
17320  
17321 @@ -85,7 +86,7 @@
17322         }
17323  
17324         *valp = new;
17325 -       inet_forward_change();
17326 +       inet_forward_change(net);
17327         return 1;
17328  }
17329  
17330 @@ -188,22 +189,6 @@
17331  
17332  ctl_table ipv4_table[] = {
17333         {
17334 -               .ctl_name       = NET_IPV4_TCP_TIMESTAMPS,
17335 -               .procname       = "tcp_timestamps",
17336 -               .data           = &sysctl_tcp_timestamps,
17337 -               .maxlen         = sizeof(int),
17338 -               .mode           = 0644,
17339 -               .proc_handler   = &proc_dointvec
17340 -       },
17341 -       {
17342 -               .ctl_name       = NET_IPV4_TCP_WINDOW_SCALING,
17343 -               .procname       = "tcp_window_scaling",
17344 -               .data           = &sysctl_tcp_window_scaling,
17345 -               .maxlen         = sizeof(int),
17346 -               .mode           = 0644,
17347 -               .proc_handler   = &proc_dointvec
17348 -       },
17349 -       {
17350                 .ctl_name       = NET_IPV4_TCP_SACK,
17351                 .procname       = "tcp_sack",
17352                 .data           = &sysctl_tcp_sack,
17353 @@ -220,40 +205,6 @@
17354                 .proc_handler   = &proc_dointvec
17355         },
17356         {
17357 -               .ctl_name       = NET_IPV4_FORWARD,
17358 -               .procname       = "ip_forward",
17359 -               .data           = &IPV4_DEVCONF_ALL(FORWARDING),
17360 -               .maxlen         = sizeof(int),
17361 -               .mode           = 0644,
17362 -               .proc_handler   = &ipv4_sysctl_forward,
17363 -               .strategy       = &ipv4_sysctl_forward_strategy
17364 -       },
17365 -       {
17366 -               .ctl_name       = NET_IPV4_DEFAULT_TTL,
17367 -               .procname       = "ip_default_ttl",
17368 -               .data           = &sysctl_ip_default_ttl,
17369 -               .maxlen         = sizeof(int),
17370 -               .mode           = 0644,
17371 -               .proc_handler   = &ipv4_doint_and_flush,
17372 -               .strategy       = &ipv4_doint_and_flush_strategy,
17373 -       },
17374 -       {
17375 -               .ctl_name       = NET_IPV4_NO_PMTU_DISC,
17376 -               .procname       = "ip_no_pmtu_disc",
17377 -               .data           = &ipv4_config.no_pmtu_disc,
17378 -               .maxlen         = sizeof(int),
17379 -               .mode           = 0644,
17380 -               .proc_handler   = &proc_dointvec
17381 -       },
17382 -       {
17383 -               .ctl_name       = NET_IPV4_NONLOCAL_BIND,
17384 -               .procname       = "ip_nonlocal_bind",
17385 -               .data           = &sysctl_ip_nonlocal_bind,
17386 -               .maxlen         = sizeof(int),
17387 -               .mode           = 0644,
17388 -               .proc_handler   = &proc_dointvec
17389 -       },
17390 -       {
17391                 .ctl_name       = NET_IPV4_TCP_SYN_RETRIES,
17392                 .procname       = "tcp_syn_retries",
17393                 .data           = &sysctl_tcp_syn_retries,
17394 @@ -286,39 +237,6 @@
17395                 .proc_handler   = &proc_dointvec
17396         },
17397         {
17398 -               .ctl_name       = NET_IPV4_IPFRAG_HIGH_THRESH,
17399 -               .procname       = "ipfrag_high_thresh",
17400 -               .data           = &sysctl_ipfrag_high_thresh,
17401 -               .maxlen         = sizeof(int),
17402 -               .mode           = 0644,
17403 -               .proc_handler   = &proc_dointvec
17404 -       },
17405 -       {
17406 -               .ctl_name       = NET_IPV4_IPFRAG_LOW_THRESH,
17407 -               .procname       = "ipfrag_low_thresh",
17408 -               .data           = &sysctl_ipfrag_low_thresh,
17409 -               .maxlen         = sizeof(int),
17410 -               .mode           = 0644,
17411 -               .proc_handler   = &proc_dointvec
17412 -       },
17413 -       {
17414 -               .ctl_name       = NET_IPV4_DYNADDR,
17415 -               .procname       = "ip_dynaddr",
17416 -               .data           = &sysctl_ip_dynaddr,
17417 -               .maxlen         = sizeof(int),
17418 -               .mode           = 0644,
17419 -               .proc_handler   = &proc_dointvec
17420 -       },
17421 -       {
17422 -               .ctl_name       = NET_IPV4_IPFRAG_TIME,
17423 -               .procname       = "ipfrag_time",
17424 -               .data           = &sysctl_ipfrag_time,
17425 -               .maxlen         = sizeof(int),
17426 -               .mode           = 0644,
17427 -               .proc_handler   = &proc_dointvec_jiffies,
17428 -               .strategy       = &sysctl_jiffies
17429 -       },
17430 -       {
17431                 .ctl_name       = NET_IPV4_TCP_KEEPALIVE_TIME,
17432                 .procname       = "tcp_keepalive_time",
17433                 .data           = &sysctl_tcp_keepalive_time,
17434 @@ -422,17 +340,6 @@
17435                 .proc_handler   = &proc_dointvec
17436         },
17437         {
17438 -               .ctl_name       = NET_IPV4_LOCAL_PORT_RANGE,
17439 -               .procname       = "ip_local_port_range",
17440 -               .data           = &sysctl_local_port_range,
17441 -               .maxlen         = sizeof(sysctl_local_port_range),
17442 -               .mode           = 0644,
17443 -               .proc_handler   = &proc_dointvec_minmax,
17444 -               .strategy       = &sysctl_intvec,
17445 -               .extra1         = ip_local_port_range_min,
17446 -               .extra2         = ip_local_port_range_max
17447 -       },
17448 -       {
17449                 .ctl_name       = NET_IPV4_ICMP_ECHO_IGNORE_ALL,
17450                 .procname       = "icmp_echo_ignore_all",
17451                 .data           = &sysctl_icmp_echo_ignore_all,
17452 @@ -534,50 +441,6 @@
17453                 .proc_handler   = &proc_dointvec
17454         },
17455         {
17456 -               .ctl_name       = NET_IPV4_INET_PEER_THRESHOLD,
17457 -               .procname       = "inet_peer_threshold",
17458 -               .data           = &inet_peer_threshold,
17459 -               .maxlen         = sizeof(int),
17460 -               .mode           = 0644,
17461 -               .proc_handler   = &proc_dointvec
17462 -       },
17463 -       {
17464 -               .ctl_name       = NET_IPV4_INET_PEER_MINTTL,
17465 -               .procname       = "inet_peer_minttl",
17466 -               .data           = &inet_peer_minttl,
17467 -               .maxlen         = sizeof(int),
17468 -               .mode           = 0644,
17469 -               .proc_handler   = &proc_dointvec_jiffies,
17470 -               .strategy       = &sysctl_jiffies
17471 -       },
17472 -       {
17473 -               .ctl_name       = NET_IPV4_INET_PEER_MAXTTL,
17474 -               .procname       = "inet_peer_maxttl",
17475 -               .data           = &inet_peer_maxttl,
17476 -               .maxlen         = sizeof(int),
17477 -               .mode           = 0644,
17478 -               .proc_handler   = &proc_dointvec_jiffies,
17479 -               .strategy       = &sysctl_jiffies
17480 -       },
17481 -       {
17482 -               .ctl_name       = NET_IPV4_INET_PEER_GC_MINTIME,
17483 -               .procname       = "inet_peer_gc_mintime",
17484 -               .data           = &inet_peer_gc_mintime,
17485 -               .maxlen         = sizeof(int),
17486 -               .mode           = 0644,
17487 -               .proc_handler   = &proc_dointvec_jiffies,
17488 -               .strategy       = &sysctl_jiffies
17489 -       },
17490 -       {
17491 -               .ctl_name       = NET_IPV4_INET_PEER_GC_MAXTIME,
17492 -               .procname       = "inet_peer_gc_maxtime",
17493 -               .data           = &inet_peer_gc_maxtime,
17494 -               .maxlen         = sizeof(int),
17495 -               .mode           = 0644,
17496 -               .proc_handler   = &proc_dointvec_jiffies,
17497 -               .strategy       = &sysctl_jiffies
17498 -       },
17499 -       {
17500                 .ctl_name       = NET_TCP_ORPHAN_RETRIES,
17501                 .procname       = "tcp_orphan_retries",
17502                 .data           = &sysctl_tcp_orphan_retries,
17503 @@ -706,24 +569,6 @@
17504                 .proc_handler   = &proc_dointvec
17505         },
17506         {
17507 -               .ctl_name       = NET_IPV4_IPFRAG_SECRET_INTERVAL,
17508 -               .procname       = "ipfrag_secret_interval",
17509 -               .data           = &sysctl_ipfrag_secret_interval,
17510 -               .maxlen         = sizeof(int),
17511 -               .mode           = 0644,
17512 -               .proc_handler   = &proc_dointvec_jiffies,
17513 -               .strategy       = &sysctl_jiffies
17514 -       },
17515 -       {
17516 -               .ctl_name       = NET_IPV4_IPFRAG_MAX_DIST,
17517 -               .procname       = "ipfrag_max_dist",
17518 -               .data           = &sysctl_ipfrag_max_dist,
17519 -               .maxlen         = sizeof(int),
17520 -               .mode           = 0644,
17521 -               .proc_handler   = &proc_dointvec_minmax,
17522 -               .extra1         = &zero
17523 -       },
17524 -       {
17525                 .ctl_name       = NET_TCP_NO_METRICS_SAVE,
17526                 .procname       = "tcp_no_metrics_save",
17527                 .data           = &sysctl_tcp_nometrics_save,
17528 @@ -865,6 +710,181 @@
17529         { .ctl_name = 0 }
17530  };
17531  
17532 -#endif /* CONFIG_SYSCTL */
17533 +struct ctl_table multi_ipv4_table[] = {
17534 +       {
17535 +               /* .data is filled in by devinet_net_init.
17536 +                * As a consequence this table entry must be the first
17537 +                * entry in multi_ipv4_table.
17538 +                */
17539 +               .ctl_name       = NET_IPV4_FORWARD,
17540 +               .procname       = "ip_forward",
17541 +               .data           = NULL,
17542 +               .extra2         = &init_net,
17543 +               .maxlen         = sizeof(int),
17544 +               .mode           = 0644,
17545 +               .proc_handler   = &ipv4_sysctl_forward,
17546 +               .strategy       = &ipv4_sysctl_forward_strategy
17547 +       },
17548 +       {
17549 +               .ctl_name       = NET_IPV4_DEFAULT_TTL,
17550 +               .procname       = "ip_default_ttl",
17551 +               .data           = &init_net.sysctl_ip_default_ttl,
17552 +               .maxlen         = sizeof(int),
17553 +               .mode           = 0644,
17554 +               .proc_handler   = &ipv4_doint_and_flush,
17555 +               .strategy       = &ipv4_doint_and_flush_strategy,
17556 +       },
17557 +       {
17558 +               .ctl_name       = NET_IPV4_NO_PMTU_DISC,
17559 +               .procname       = "ip_no_pmtu_disc",
17560 +               .data           = &init_net.sysctl_ipv4_no_pmtu_disc,
17561 +               .maxlen         = sizeof(int),
17562 +               .mode           = 0644,
17563 +               .proc_handler   = &proc_dointvec
17564 +       },
17565 +       {
17566 +               .ctl_name       = NET_IPV4_NONLOCAL_BIND,
17567 +               .procname       = "ip_nonlocal_bind",
17568 +               .data           = &init_net.sysctl_ip_nonlocal_bind,
17569 +               .maxlen         = sizeof(int),
17570 +               .mode           = 0644,
17571 +               .proc_handler   = &proc_dointvec
17572 +       },
17573 +       {
17574 +               .ctl_name       = NET_IPV4_LOCAL_PORT_RANGE,
17575 +               .procname       = "ip_local_port_range",
17576 +               .data           = &init_net.sysctl_local_port_range,
17577 +               .maxlen         = sizeof(init_net.sysctl_local_port_range),
17578 +               .mode           = 0644,
17579 +               .proc_handler   = &proc_dointvec_minmax,
17580 +               .strategy       = &sysctl_intvec,
17581 +               .extra1         = ip_local_port_range_min,
17582 +               .extra2         = ip_local_port_range_max
17583 +       },
17584 +       {
17585 +               .ctl_name       = NET_IPV4_IPFRAG_HIGH_THRESH,
17586 +               .procname       = "ipfrag_high_thresh",
17587 +               .data           = &init_net.sysctl_ipfrag_high_thresh,
17588 +               .maxlen         = sizeof(int),
17589 +               .mode           = 0644,
17590 +               .proc_handler   = &proc_dointvec
17591 +       },
17592 +       {
17593 +               .ctl_name       = NET_IPV4_IPFRAG_LOW_THRESH,
17594 +               .procname       = "ipfrag_low_thresh",
17595 +               .data           = &init_net.sysctl_ipfrag_low_thresh,
17596 +               .maxlen         = sizeof(int),
17597 +               .mode           = 0644,
17598 +               .proc_handler   = &proc_dointvec
17599 +       },
17600 +       {
17601 +               .ctl_name       = NET_IPV4_IPFRAG_TIME,
17602 +               .procname       = "ipfrag_time",
17603 +               .data           = &init_net.sysctl_ipfrag_time,
17604 +               .maxlen         = sizeof(int),
17605 +               .mode           = 0644,
17606 +               .proc_handler   = &proc_dointvec_jiffies,
17607 +               .strategy       = &sysctl_jiffies
17608 +       },
17609 +       {
17610 +               .ctl_name       = NET_IPV4_IPFRAG_SECRET_INTERVAL,
17611 +               .procname       = "ipfrag_secret_interval",
17612 +               .data           = &init_net.sysctl_ipfrag_secret_interval,
17613 +               .maxlen         = sizeof(int),
17614 +               .mode           = 0644,
17615 +               .proc_handler   = &proc_dointvec_jiffies,
17616 +               .strategy       = &sysctl_jiffies
17617 +       },
17618 +       {
17619 +               .ctl_name       = NET_IPV4_IPFRAG_MAX_DIST,
17620 +               .procname       = "ipfrag_max_dist",
17621 +               .data           = &init_net.sysctl_ipfrag_max_dist,
17622 +               .maxlen         = sizeof(int),
17623 +               .mode           = 0644,
17624 +               .proc_handler   = &proc_dointvec_minmax,
17625 +               .extra1         = &zero
17626 +       },
17627 +       {
17628 +               .ctl_name       = NET_IPV4_DYNADDR,
17629 +               .procname       = "ip_dynaddr",
17630 +               .data           = &init_net.sysctl_ip_dynaddr,
17631 +               .maxlen         = sizeof(int),
17632 +               .mode           = 0644,
17633 +               .proc_handler   = &proc_dointvec
17634 +       },
17635 +       {
17636 +               .ctl_name       = NET_IPV4_LOCAL_PORT_RANGE,
17637 +               .procname       = "ip_local_port_range",
17638 +               .data           = &init_net.sysctl_local_port_range,
17639 +               .maxlen         = sizeof(init_net.sysctl_local_port_range),
17640 +               .mode           = 0644,
17641 +               .proc_handler   = &proc_dointvec_minmax,
17642 +               .strategy       = &sysctl_intvec,
17643 +               .extra1         = ip_local_port_range_min,
17644 +               .extra2         = ip_local_port_range_max
17645 +       },
17646 +       {
17647 +               .ctl_name       = NET_IPV4_INET_PEER_THRESHOLD,
17648 +               .procname       = "inet_peer_threshold",
17649 +               .data           = &init_net.inet_peer_threshold,
17650 +               .maxlen         = sizeof(int),
17651 +               .mode           = 0644,
17652 +               .proc_handler   = &proc_dointvec
17653 +       },
17654 +       {
17655 +               .ctl_name       = NET_IPV4_INET_PEER_MINTTL,
17656 +               .procname       = "inet_peer_minttl",
17657 +               .data           = &init_net.inet_peer_minttl,
17658 +               .maxlen         = sizeof(int),
17659 +               .mode           = 0644,
17660 +               .proc_handler   = &proc_dointvec_jiffies,
17661 +               .strategy       = &sysctl_jiffies
17662 +       },
17663 +       {
17664 +               .ctl_name       = NET_IPV4_INET_PEER_MAXTTL,
17665 +               .procname       = "inet_peer_maxttl",
17666 +               .data           = &init_net.inet_peer_maxttl,
17667 +               .maxlen         = sizeof(int),
17668 +               .mode           = 0644,
17669 +               .proc_handler   = &proc_dointvec_jiffies,
17670 +               .strategy       = &sysctl_jiffies
17671 +       },
17672 +       {
17673 +               .ctl_name       = NET_IPV4_INET_PEER_GC_MINTIME,
17674 +               .procname       = "inet_peer_gc_mintime",
17675 +               .data           = &init_net.inet_peer_gc_mintime,
17676 +               .maxlen         = sizeof(int),
17677 +               .mode           = 0644,
17678 +               .proc_handler   = &proc_dointvec_jiffies,
17679 +               .strategy       = &sysctl_jiffies
17680 +       },
17681 +       {
17682 +               .ctl_name       = NET_IPV4_INET_PEER_GC_MAXTIME,
17683 +               .procname       = "inet_peer_gc_maxtime",
17684 +               .data           = &init_net.inet_peer_gc_maxtime,
17685 +               .maxlen         = sizeof(int),
17686 +               .mode           = 0644,
17687 +               .proc_handler   = &proc_dointvec_jiffies,
17688 +               .strategy       = &sysctl_jiffies
17689 +       },
17690 +       {
17691 +               .ctl_name       = NET_IPV4_TCP_TIMESTAMPS,
17692 +               .procname       = "tcp_timestamps",
17693 +               .data           = &init_net.sysctl_tcp_timestamps,
17694 +               .maxlen         = sizeof(int),
17695 +               .mode           = 0644,
17696 +               .proc_handler   = &proc_dointvec
17697 +
17698 +       },
17699 +       {
17700 +               .ctl_name       = NET_IPV4_TCP_WINDOW_SCALING,
17701 +               .procname       = "tcp_window_scaling",
17702 +               .data           = &init_net.sysctl_tcp_window_scaling,
17703 +               .maxlen         = sizeof(int),
17704 +               .mode           = 0644,
17705 +               .proc_handler   = &proc_dointvec
17706 +       },
17707 +       {}
17708 +};
17709  
17710 -EXPORT_SYMBOL(ipv4_config);
17711 +#endif /* CONFIG_SYSCTL */
17712 diff -Nurb linux-2.6.22-try2/net/ipv4/tcp.c linux-2.6.22-try2-netns/net/ipv4/tcp.c
17713 --- linux-2.6.22-try2/net/ipv4/tcp.c    2007-12-19 13:37:58.000000000 -0500
17714 +++ linux-2.6.22-try2-netns/net/ipv4/tcp.c      2007-12-19 22:49:20.000000000 -0500
17715 @@ -2409,6 +2409,23 @@
17716  }
17717  __setup("thash_entries=", set_thash_entries);
17718  
17719 +static int tcp_net_init(struct net *net)
17720 +{
17721 +       /*
17722 +        * This array holds the first and last local port number.
17723 +        */
17724 +       net->sysctl_local_port_range[0] = 32768;
17725 +       net->sysctl_local_port_range[1] = 61000;
17726 +
17727 +       net->sysctl_tcp_timestamps = 1;
17728 +       net->sysctl_tcp_window_scaling = 1;
17729 +       return 0;
17730 +}
17731 +
17732 +static struct pernet_operations tcp_net_ops = {
17733 +       .init = tcp_net_init,
17734 +};
17735 +
17736  void __init tcp_init(void)
17737  {
17738         struct sk_buff *skb = NULL;
17739 @@ -2502,6 +2519,8 @@
17740         sysctl_tcp_rmem[1] = 87380;
17741         sysctl_tcp_rmem[2] = max(87380, max_share);
17742  
17743 +       register_pernet_subsys(&tcp_net_ops);
17744 +
17745         printk(KERN_INFO "TCP: Hash tables configured "
17746                "(established %d bind %d)\n",
17747                tcp_hashinfo.ehash_size, tcp_hashinfo.bhash_size);
17748 diff -Nurb linux-2.6.22-try2/net/ipv4/tcp_input.c linux-2.6.22-try2-netns/net/ipv4/tcp_input.c
17749 --- linux-2.6.22-try2/net/ipv4/tcp_input.c      2007-12-19 13:37:58.000000000 -0500
17750 +++ linux-2.6.22-try2-netns/net/ipv4/tcp_input.c        2007-12-19 22:49:20.000000000 -0500
17751 @@ -72,8 +72,6 @@
17752  #include <asm/unaligned.h>
17753  #include <net/netdma.h>
17754  
17755 -int sysctl_tcp_timestamps __read_mostly = 1;
17756 -int sysctl_tcp_window_scaling __read_mostly = 1;
17757  int sysctl_tcp_sack __read_mostly = 1;
17758  int sysctl_tcp_fack __read_mostly = 1;
17759  int sysctl_tcp_reordering __read_mostly = TCP_FASTRETRANS_THRESH;
17760 @@ -2922,7 +2920,7 @@
17761                                         break;
17762                                 case TCPOPT_WINDOW:
17763                                         if (opsize==TCPOLEN_WINDOW && th->syn && !estab)
17764 -                                               if (sysctl_tcp_window_scaling) {
17765 +                                               if (init_net.sysctl_tcp_window_scaling) {
17766                                                         __u8 snd_wscale = *(__u8 *) ptr;
17767                                                         opt_rx->wscale_ok = 1;
17768                                                         if (snd_wscale > 14) {
17769 @@ -2938,7 +2936,7 @@
17770                                 case TCPOPT_TIMESTAMP:
17771                                         if (opsize==TCPOLEN_TIMESTAMP) {
17772                                                 if ((estab && opt_rx->tstamp_ok) ||
17773 -                                                   (!estab && sysctl_tcp_timestamps)) {
17774 +                                                   (!estab && init_net.sysctl_tcp_timestamps)) {
17775                                                         opt_rx->saw_tstamp = 1;
17776                                                         opt_rx->rcv_tsval = ntohl(get_unaligned((__be32 *)ptr));
17777                                                         opt_rx->rcv_tsecr = ntohl(get_unaligned((__be32 *)(ptr+4)));
17778 diff -Nurb linux-2.6.22-try2/net/ipv4/tcp_ipv4.c linux-2.6.22-try2-netns/net/ipv4/tcp_ipv4.c
17779 --- linux-2.6.22-try2/net/ipv4/tcp_ipv4.c       2007-12-19 15:29:23.000000000 -0500
17780 +++ linux-2.6.22-try2-netns/net/ipv4/tcp_ipv4.c 2007-12-19 23:33:32.000000000 -0500
17781 @@ -71,6 +71,7 @@
17782  #include <net/timewait_sock.h>
17783  #include <net/xfrm.h>
17784  #include <net/netdma.h>
17785 +#include <net/net_namespace.h>
17786  
17787  #include <linux/inet.h>
17788  #include <linux/ipv6.h>
17789 @@ -353,6 +354,7 @@
17790  
17791  void tcp_v4_err(struct sk_buff *skb, u32 info)
17792  {
17793 +       struct net *net = skb->dev->nd_net;
17794         struct iphdr *iph = (struct iphdr *)skb->data;
17795         struct tcphdr *th = (struct tcphdr *)(skb->data + (iph->ihl << 2));
17796         struct tcp_sock *tp;
17797 @@ -369,7 +371,7 @@
17798         }
17799  
17800         sk = inet_lookup(&tcp_hashinfo, iph->daddr, th->dest, iph->saddr,
17801 -                        th->source, inet_iif(skb));
17802 +                        th->source, inet_iif(skb), net);
17803         if (!sk) {
17804                 ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
17805                 return;
17806 @@ -1499,7 +1501,8 @@
17807                 return tcp_check_req(sk, skb, req, prev);
17808  
17809         nsk = inet_lookup_established(&tcp_hashinfo, iph->saddr, th->source,
17810 -                                     iph->daddr, th->dest, inet_iif(skb));
17811 +                                     iph->daddr, th->dest, inet_iif(skb),
17812 +                                     sk->sk_net);
17813  
17814         if (nsk) {
17815                 if (nsk->sk_state != TCP_TIME_WAIT) {
17816 @@ -1618,6 +1621,7 @@
17817  
17818  int tcp_v4_rcv(struct sk_buff *skb)
17819  {
17820 +       struct net *net = skb->dev->nd_net;
17821         const struct iphdr *iph;
17822         struct tcphdr *th;
17823         struct sock *sk;
17824 @@ -1657,7 +1661,7 @@
17825         TCP_SKB_CB(skb)->sacked  = 0;
17826  
17827         sk = __inet_lookup(&tcp_hashinfo, iph->saddr, th->source,
17828 -                          iph->daddr, th->dest, inet_iif(skb));
17829 +                          iph->daddr, th->dest, inet_iif(skb), net);
17830         if (!sk)
17831                 goto no_tcp_socket;
17832  
17833 @@ -1732,7 +1736,7 @@
17834         case TCP_TW_SYN: {
17835                 struct sock *sk2 = inet_lookup_listener(&tcp_hashinfo,
17836                                                         iph->daddr, th->dest,
17837 -                                                       inet_iif(skb));
17838 +                                                       inet_iif(skb), net);
17839                 if (sk2) {
17840                         inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row);
17841                         inet_twsk_put(inet_twsk(sk));
17842 @@ -1766,7 +1770,7 @@
17843         int release_it = 0;
17844  
17845         if (!rt || rt->rt_dst != inet->daddr) {
17846 -               peer = inet_getpeer(inet->daddr, 1);
17847 +               peer = inet_getpeer(sk->sk_net, inet->daddr, 1);
17848                 release_it = 1;
17849         } else {
17850                 if (!rt->peer)
17851 @@ -1791,7 +1795,7 @@
17852  
17853  int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw)
17854  {
17855 -       struct inet_peer *peer = inet_getpeer(tw->tw_daddr, 1);
17856 +       struct inet_peer *peer = inet_getpeer(tw->tw_net, tw->tw_daddr, 1);
17857  
17858         if (peer) {
17859                 const struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw);
17860 @@ -1980,7 +1984,8 @@
17861                                 if (req->sk &&
17862                                         !nx_check(req->sk->sk_nid, VS_WATCH_P | VS_IDENT))
17863                                         continue;
17864 -                               if (req->rsk_ops->family == st->family) {
17865 +                               if ((req->rsk_ops->family == st->family) &&
17866 +                                   (req->sk->sk_net == st->net)) {
17867                                         cur = req;
17868                                         goto out;
17869                                 }
17870 @@ -2004,6 +2009,8 @@
17871         }
17872  get_sk:
17873         sk_for_each_from(sk, node) {
17874 +               if (sk->sk_net != st->net)
17875 +                       continue;
17876                 vxdprintk(VXD_CBIT(net, 6), "sk: %p [#%d] (from %d)",
17877                         sk, sk->sk_nid, nx_current_nid());
17878                 if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
17879 @@ -2056,6 +2063,8 @@
17880  
17881                 read_lock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
17882                 sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
17883 +                       if (sk->sk_net != st->net)
17884 +                               continue;
17885                         vxdprintk(VXD_CBIT(net, 6),
17886                                 "sk,egf: %p [#%d] (from %d)",
17887                                 sk, sk->sk_nid, nx_current_nid());
17888 @@ -2069,6 +2078,8 @@
17889                 st->state = TCP_SEQ_STATE_TIME_WAIT;
17890                 inet_twsk_for_each(tw, node,
17891                                    &tcp_hashinfo.ehash[st->bucket].twchain) {
17892 +                       if (tw->tw_net != st->net)
17893 +                               continue;
17894                         vxdprintk(VXD_CBIT(net, 6),
17895                                 "tw: %p [#%d] (from %d)",
17896                                 tw, tw->tw_nid, nx_current_nid());
17897 @@ -2099,7 +2110,8 @@
17898                 tw = cur;
17899                 tw = tw_next(tw);
17900  get_tw:
17901 -               while (tw && (tw->tw_family != st->family ||
17902 +               while (tw && ((tw->tw_net != st->net) || 
17903 +                                       (tw->tw_family != st->family) ||
17904                         !nx_check(tw->tw_nid, VS_WATCH_P | VS_IDENT))) {
17905                         tw = tw_next(tw);
17906                 }
17907 @@ -2124,6 +2136,8 @@
17908                 vxdprintk(VXD_CBIT(net, 6),
17909                         "sk,egn: %p [#%d] (from %d)",
17910                         sk, sk->sk_nid, nx_current_nid());
17911 +               if (sk->sk_net != st->net)
17912 +                       continue;
17913                 if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
17914                         continue;
17915                 if (sk->sk_family == st->family)
17916 @@ -2253,6 +2267,7 @@
17917                 goto out_kfree;
17918         seq          = file->private_data;
17919         seq->private = s;
17920 +       s->net = get_net(PROC_NET(inode));
17921  out:
17922         return rc;
17923  out_kfree:
17924 @@ -2260,20 +2275,30 @@
17925         goto out;
17926  }
17927  
17928 -int tcp_proc_register(struct tcp_seq_afinfo *afinfo)
17929 +static int tcp_seq_release(struct inode *inode, struct file *file)
17930 +{
17931 +       struct seq_file *seq = file->private_data;
17932 +       struct tcp_iter_state *st = seq->private;
17933 +       put_net(st->net);
17934 +       return seq_release_private(inode, file);
17935 +}
17936 +
17937 +int tcp_proc_register(struct net *net, struct tcp_seq_afinfo *afinfo)
17938  {
17939         int rc = 0;
17940         struct proc_dir_entry *p;
17941  
17942         if (!afinfo)
17943                 return -EINVAL;
17944 +       if (net == &init_net) {
17945         afinfo->seq_fops->owner         = afinfo->owner;
17946         afinfo->seq_fops->open          = tcp_seq_open;
17947         afinfo->seq_fops->read          = seq_read;
17948         afinfo->seq_fops->llseek        = seq_lseek;
17949 -       afinfo->seq_fops->release       = seq_release_private;
17950 +               afinfo->seq_fops->release       = tcp_seq_release;
17951 +       }
17952  
17953 -       p = proc_net_fops_create(afinfo->name, S_IRUGO, afinfo->seq_fops);
17954 +       p = proc_net_fops_create(net, afinfo->name, S_IRUGO, afinfo->seq_fops);
17955         if (p)
17956                 p->data = afinfo;
17957         else
17958 @@ -2281,11 +2306,12 @@
17959         return rc;
17960  }
17961  
17962 -void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo)
17963 +void tcp_proc_unregister(struct net *net, struct tcp_seq_afinfo *afinfo)
17964  {
17965         if (!afinfo)
17966                 return;
17967 -       proc_net_remove(afinfo->name);
17968 +       proc_net_remove(net, afinfo->name);
17969 +       if (net == &init_net)
17970         memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops));
17971  }
17972  
17973 @@ -2430,14 +2456,29 @@
17974         .seq_fops       = &tcp4_seq_fops,
17975  };
17976  
17977 +static int tcp4_proc_net_init(struct net *net)
17978 +{
17979 +       return tcp_proc_register(net, &tcp4_seq_afinfo);
17980 +}
17981 +
17982 +static void tcp4_proc_net_exit(struct net *net)
17983 +{
17984 +       tcp_proc_unregister(net, &tcp4_seq_afinfo);
17985 +}
17986 +
17987 +static struct pernet_operations tcp4_proc_net_ops = {
17988 +       .init = tcp4_proc_net_init,
17989 +       .exit = tcp4_proc_net_exit,
17990 +};
17991 +
17992  int __init tcp4_proc_init(void)
17993  {
17994 -       return tcp_proc_register(&tcp4_seq_afinfo);
17995 +       return register_pernet_subsys(&tcp4_proc_net_ops);
17996  }
17997  
17998  void tcp4_proc_exit(void)
17999  {
18000 -       tcp_proc_unregister(&tcp4_seq_afinfo);
18001 +       unregister_pernet_subsys(&tcp4_proc_net_ops);
18002  }
18003  #endif /* CONFIG_PROC_FS */
18004  
18005 @@ -2499,6 +2540,5 @@
18006  EXPORT_SYMBOL(tcp_proc_register);
18007  EXPORT_SYMBOL(tcp_proc_unregister);
18008  #endif
18009 -EXPORT_SYMBOL(sysctl_local_port_range);
18010  EXPORT_SYMBOL(sysctl_tcp_low_latency);
18011  
18012 diff -Nurb linux-2.6.22-try2/net/ipv4/tcp_output.c linux-2.6.22-try2-netns/net/ipv4/tcp_output.c
18013 --- linux-2.6.22-try2/net/ipv4/tcp_output.c     2007-12-19 13:37:58.000000000 -0500
18014 +++ linux-2.6.22-try2-netns/net/ipv4/tcp_output.c       2007-12-19 22:49:20.000000000 -0500
18015 @@ -432,11 +432,11 @@
18016         sysctl_flags = 0;
18017         if (unlikely(tcb->flags & TCPCB_FLAG_SYN)) {
18018                 tcp_header_size = sizeof(struct tcphdr) + TCPOLEN_MSS;
18019 -               if (sysctl_tcp_timestamps) {
18020 +               if (sk->sk_net->sysctl_tcp_timestamps) {
18021                         tcp_header_size += TCPOLEN_TSTAMP_ALIGNED;
18022                         sysctl_flags |= SYSCTL_FLAG_TSTAMPS;
18023                 }
18024 -               if (sysctl_tcp_window_scaling) {
18025 +               if (sk->sk_net->sysctl_tcp_window_scaling) {
18026                         tcp_header_size += TCPOLEN_WSCALE_ALIGNED;
18027                         sysctl_flags |= SYSCTL_FLAG_WSCALE;
18028                 }
18029 @@ -2215,7 +2215,7 @@
18030          * See tcp_input.c:tcp_rcv_state_process case TCP_SYN_SENT.
18031          */
18032         tp->tcp_header_len = sizeof(struct tcphdr) +
18033 -               (sysctl_tcp_timestamps ? TCPOLEN_TSTAMP_ALIGNED : 0);
18034 +               (sk->sk_net->sysctl_tcp_timestamps ? TCPOLEN_TSTAMP_ALIGNED : 0);
18035  
18036  #ifdef CONFIG_TCP_MD5SIG
18037         if (tp->af_specific->md5_lookup(sk, sk) != NULL)
18038 @@ -2238,7 +2238,7 @@
18039                                   tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0),
18040                                   &tp->rcv_wnd,
18041                                   &tp->window_clamp,
18042 -                                 sysctl_tcp_window_scaling,
18043 +                                 sk->sk_net->sysctl_tcp_window_scaling,
18044                                   &rcv_wscale);
18045  
18046         tp->rx_opt.rcv_wscale = rcv_wscale;
18047 diff -Nurb linux-2.6.22-try2/net/ipv4/tcp_probe.c linux-2.6.22-try2-netns/net/ipv4/tcp_probe.c
18048 --- linux-2.6.22-try2/net/ipv4/tcp_probe.c      2007-12-19 13:37:58.000000000 -0500
18049 +++ linux-2.6.22-try2-netns/net/ipv4/tcp_probe.c        2007-12-19 22:49:20.000000000 -0500
18050 @@ -172,7 +172,7 @@
18051         if (IS_ERR(tcpw.fifo))
18052                 return PTR_ERR(tcpw.fifo);
18053  
18054 -       if (!proc_net_fops_create(procname, S_IRUSR, &tcpprobe_fops))
18055 +       if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &tcpprobe_fops))
18056                 goto err0;
18057  
18058         ret = register_jprobe(&tcp_probe);
18059 @@ -182,7 +182,7 @@
18060         pr_info("TCP watch registered (port=%d)\n", port);
18061         return 0;
18062   err1:
18063 -       proc_net_remove(procname);
18064 +       proc_net_remove(&init_net, procname);
18065   err0:
18066         kfifo_free(tcpw.fifo);
18067         return ret;
18068 @@ -192,7 +192,7 @@
18069  static __exit void tcpprobe_exit(void)
18070  {
18071         kfifo_free(tcpw.fifo);
18072 -       proc_net_remove(procname);
18073 +       proc_net_remove(&init_net, procname);
18074         unregister_jprobe(&tcp_probe);
18075  
18076  }
18077 diff -Nurb linux-2.6.22-try2/net/ipv4/tunnel4.c linux-2.6.22-try2-netns/net/ipv4/tunnel4.c
18078 --- linux-2.6.22-try2/net/ipv4/tunnel4.c        2007-12-19 13:37:58.000000000 -0500
18079 +++ linux-2.6.22-try2-netns/net/ipv4/tunnel4.c  2007-12-19 22:49:20.000000000 -0500
18080 @@ -75,6 +75,10 @@
18081  {
18082         struct xfrm_tunnel *handler;
18083  
18084 +       if (skb->dev->nd_net != &init_net) {
18085 +               kfree_skb(skb);
18086 +               return 0;
18087 +       }
18088         if (!pskb_may_pull(skb, sizeof(struct iphdr)))
18089                 goto drop;
18090  
18091 @@ -113,6 +117,9 @@
18092  {
18093         struct xfrm_tunnel *handler;
18094  
18095 +       if (skb->dev->nd_net != &init_net)
18096 +               return;
18097 +
18098         for (handler = tunnel4_handlers; handler; handler = handler->next)
18099                 if (!handler->err_handler(skb, info))
18100                         break;
18101 diff -Nurb linux-2.6.22-try2/net/ipv4/udp.c linux-2.6.22-try2-netns/net/ipv4/udp.c
18102 --- linux-2.6.22-try2/net/ipv4/udp.c    2007-12-19 13:37:58.000000000 -0500
18103 +++ linux-2.6.22-try2-netns/net/ipv4/udp.c      2007-12-19 23:34:00.000000000 -0500
18104 @@ -101,6 +101,7 @@
18105  #include <net/route.h>
18106  #include <net/checksum.h>
18107  #include <net/xfrm.h>
18108 +#include <net/net_namespace.h>
18109  #include "udp_impl.h"
18110  
18111  /*
18112 @@ -112,16 +113,17 @@
18113  struct hlist_head udp_hash[UDP_HTABLE_SIZE];
18114  DEFINE_RWLOCK(udp_hash_lock);
18115  
18116 -static int udp_port_rover;
18117 -
18118 -static inline int __udp_lib_lport_inuse(__u16 num, struct hlist_head udptable[])
18119 +static inline int __udp_lib_lport_inuse(struct net *net, __u16 num, struct hlist_head udptable[])
18120  {
18121         struct sock *sk;
18122         struct hlist_node *node;
18123  
18124 -       sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)])
18125 +       sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)]) {
18126 +               if (sk->sk_net != net)
18127 +                       continue;
18128                 if (sk->sk_hash == num)
18129                         return 1;
18130 +       }
18131         return 0;
18132  }
18133  
18134 @@ -148,9 +150,9 @@
18135         if (snum == 0) {
18136                 int best_size_so_far, best, result, i;
18137  
18138 -               if (*port_rover > sysctl_local_port_range[1] ||
18139 -                   *port_rover < sysctl_local_port_range[0])
18140 -                       *port_rover = sysctl_local_port_range[0];
18141 +               if (*port_rover > sk->sk_net->sysctl_local_port_range[1] ||
18142 +                   *port_rover < sk->sk_net->sysctl_local_port_range[0])
18143 +                       *port_rover = sk->sk_net->sysctl_local_port_range[0];
18144                 best_size_so_far = 32767;
18145                 best = result = *port_rover;
18146                 for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) {
18147 @@ -158,9 +160,9 @@
18148  
18149                         head = &udptable[result & (UDP_HTABLE_SIZE - 1)];
18150                         if (hlist_empty(head)) {
18151 -                               if (result > sysctl_local_port_range[1])
18152 -                                       result = sysctl_local_port_range[0] +
18153 -                                               ((result - sysctl_local_port_range[0]) &
18154 +                               if (result > sk->sk_net->sysctl_local_port_range[1])
18155 +                                       result = sk->sk_net->sysctl_local_port_range[0] +
18156 +                                               ((result - sk->sk_net->sysctl_local_port_range[0]) &
18157                                                  (UDP_HTABLE_SIZE - 1));
18158                                 goto gotit;
18159                         }
18160 @@ -177,11 +179,11 @@
18161                 result = best;
18162                 for (i = 0; i < (1 << 16) / UDP_HTABLE_SIZE;
18163                      i++, result += UDP_HTABLE_SIZE) {
18164 -                       if (result > sysctl_local_port_range[1])
18165 -                               result = sysctl_local_port_range[0]
18166 -                                       + ((result - sysctl_local_port_range[0]) &
18167 +                       if (result > sk->sk_net->sysctl_local_port_range[1])
18168 +                               result = sk->sk_net->sysctl_local_port_range[0]
18169 +                                       + ((result - sk->sk_net->sysctl_local_port_range[0]) &
18170                                            (UDP_HTABLE_SIZE - 1));
18171 -                       if (! __udp_lib_lport_inuse(result, udptable))
18172 +                       if (! __udp_lib_lport_inuse(sk->sk_net, result, udptable))
18173                                 break;
18174                 }
18175                 if (i >= (1 << 16) / UDP_HTABLE_SIZE)
18176 @@ -194,6 +196,7 @@
18177                 sk_for_each(sk2, node, head)
18178                         if (sk2->sk_hash == snum                             &&
18179                             sk2 != sk                                        &&
18180 +                           sk->sk_net == sk2->sk_net                        &&
18181                             (!sk2->sk_reuse        || !sk->sk_reuse)         &&
18182                             (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
18183                              || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
18184 @@ -216,7 +219,7 @@
18185  int udp_get_port(struct sock *sk, unsigned short snum,
18186                         int (*scmp)(const struct sock *, const struct sock *))
18187  {
18188 -       return  __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, scmp);
18189 +       return  __udp_lib_get_port(sk, snum, udp_hash, &sk->sk_net->udp_port_rover, scmp);
18190  }
18191  
18192  extern int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2);
18193 @@ -229,7 +232,8 @@
18194  /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
18195   * harder than this. -DaveM
18196   */
18197 -static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
18198 +static struct sock *__udp4_lib_lookup(struct net *net,
18199 +                                     __be32 saddr, __be16 sport,
18200                                       __be32 daddr, __be16 dport,
18201                                       int dif, struct hlist_head udptable[])
18202  {
18203 @@ -243,6 +247,9 @@
18204         sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
18205                 struct inet_sock *inet = inet_sk(sk);
18206  
18207 +               if (sk->sk_net != net)
18208 +                       continue;
18209 +
18210                 if (sk->sk_hash == hnum && !ipv6_only_sock(sk)) {
18211                         int score = (sk->sk_family == PF_INET ? 1 : 0);
18212  
18213 @@ -299,6 +306,9 @@
18214         sk_for_each_from(s, node) {
18215                 struct inet_sock *inet = inet_sk(s);
18216  
18217 +               if (s->sk_net != sk->sk_net)
18218 +                       continue;
18219 +
18220                 if (s->sk_hash != hnum                                  ||
18221                     (inet->daddr && inet->daddr != rmt_addr)            ||
18222                     (inet->dport != rmt_port && inet->dport)            ||
18223 @@ -328,6 +338,7 @@
18224  
18225  void __udp4_lib_err(struct sk_buff *skb, u32 info, struct hlist_head udptable[])
18226  {
18227 +       struct net *net = skb->dev->nd_net;
18228         struct inet_sock *inet;
18229         struct iphdr *iph = (struct iphdr*)skb->data;
18230         struct udphdr *uh = (struct udphdr*)(skb->data+(iph->ihl<<2));
18231 @@ -337,7 +348,7 @@
18232         int harderr;
18233         int err;
18234  
18235 -       sk = __udp4_lib_lookup(iph->daddr, uh->dest, iph->saddr, uh->source,
18236 +       sk = __udp4_lib_lookup(net, iph->daddr, uh->dest, iph->saddr, uh->source,
18237                                skb->dev->ifindex, udptable                  );
18238         if (sk == NULL) {
18239                 ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
18240 @@ -623,7 +634,8 @@
18241                 rt = (struct rtable*)sk_dst_check(sk, 0);
18242  
18243         if (rt == NULL) {
18244 -               struct flowi fl = { .oif = ipc.oif,
18245 +               struct flowi fl = { .fl_net = sk->sk_net,
18246 +                                   .oif = ipc.oif,
18247                                     .nl_u = { .ip4_u =
18248                                               { .daddr = faddr,
18249                                                 .saddr = saddr,
18250 @@ -1288,6 +1300,7 @@
18251  int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
18252                    int proto)
18253  {
18254 +       struct net *net = skb->dev->nd_net;
18255         struct sock *sk;
18256         struct udphdr *uh = udp_hdr(skb);
18257         unsigned short ulen;
18258 @@ -1322,7 +1335,7 @@
18259         udp_ping_of_death(skb, uh, saddr);
18260  #endif
18261  
18262 -       sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest,
18263 +       sk = __udp4_lib_lookup(net, saddr, uh->source, daddr, uh->dest,
18264                                skb->dev->ifindex, udptable        );
18265  
18266         if (sk != NULL) {
18267 @@ -1651,7 +1664,7 @@
18268                 sk = sk_next(sk);
18269  try_again:
18270                 ;
18271 -       } while (sk && (sk->sk_family != state->family ||
18272 +       } while (sk && ((sk->sk_net != state->net) || sk->sk_family != state->family ||
18273                 !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
18274  
18275         if (!sk && ++state->bucket < UDP_HTABLE_SIZE) {
18276 @@ -1717,6 +1730,7 @@
18277  
18278         seq          = file->private_data;
18279         seq->private = s;
18280 +       s->net       = get_net(PROC_NET(inode));
18281  out:
18282         return rc;
18283  out_kfree:
18284 @@ -1724,21 +1738,31 @@
18285         goto out;
18286  }
18287  
18288 +static int udp_seq_release(struct inode *inode, struct file *file)
18289 +{
18290 +       struct seq_file *seq = file->private_data;
18291 +       struct udp_iter_state *state = seq->private;
18292 +       put_net(state->net);
18293 +       return seq_release_private(inode, file);
18294 +}
18295 +
18296  /* ------------------------------------------------------------------------ */
18297 -int udp_proc_register(struct udp_seq_afinfo *afinfo)
18298 +int udp_proc_register(struct net *net, struct udp_seq_afinfo *afinfo)
18299  {
18300         struct proc_dir_entry *p;
18301         int rc = 0;
18302  
18303         if (!afinfo)
18304                 return -EINVAL;
18305 +       if (net == &init_net) {
18306         afinfo->seq_fops->owner         = afinfo->owner;
18307         afinfo->seq_fops->open          = udp_seq_open;
18308         afinfo->seq_fops->read          = seq_read;
18309         afinfo->seq_fops->llseek        = seq_lseek;
18310 -       afinfo->seq_fops->release       = seq_release_private;
18311 +               afinfo->seq_fops->release       = udp_seq_release;
18312 +       }
18313  
18314 -       p = proc_net_fops_create(afinfo->name, S_IRUGO, afinfo->seq_fops);
18315 +       p = proc_net_fops_create(net, afinfo->name, S_IRUGO, afinfo->seq_fops);
18316         if (p)
18317                 p->data = afinfo;
18318         else
18319 @@ -1746,11 +1770,12 @@
18320         return rc;
18321  }
18322  
18323 -void udp_proc_unregister(struct udp_seq_afinfo *afinfo)
18324 +void udp_proc_unregister(struct net *net, struct udp_seq_afinfo *afinfo)
18325  {
18326         if (!afinfo)
18327                 return;
18328 -       proc_net_remove(afinfo->name);
18329 +       proc_net_remove(net, afinfo->name);
18330 +       if (net == &init_net)
18331         memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops));
18332  }
18333  
18334 @@ -1803,14 +1828,30 @@
18335         .seq_fops       = &udp4_seq_fops,
18336  };
18337  
18338 +
18339 +static int udp4_proc_net_init(struct net *net)
18340 +{
18341 +       return udp_proc_register(net, &udp4_seq_afinfo);
18342 +}
18343 +
18344 +static void udp4_proc_net_exit(struct net *net)
18345 +{
18346 +       udp_proc_unregister(net, &udp4_seq_afinfo);
18347 +}
18348 +
18349 +static struct pernet_operations udp4_proc_net_ops = {
18350 +       .init = udp4_proc_net_init,
18351 +       .exit = udp4_proc_net_exit,
18352 +};
18353 +
18354  int __init udp4_proc_init(void)
18355  {
18356 -       return udp_proc_register(&udp4_seq_afinfo);
18357 +       return register_pernet_subsys(&udp4_proc_net_ops);
18358  }
18359  
18360  void udp4_proc_exit(void)
18361  {
18362 -       udp_proc_unregister(&udp4_seq_afinfo);
18363 +       unregister_pernet_subsys(&udp4_proc_net_ops);
18364  }
18365  #endif /* CONFIG_PROC_FS */
18366  
18367 diff -Nurb linux-2.6.22-try2/net/ipv4/udplite.c linux-2.6.22-try2-netns/net/ipv4/udplite.c
18368 --- linux-2.6.22-try2/net/ipv4/udplite.c        2007-12-19 13:37:58.000000000 -0500
18369 +++ linux-2.6.22-try2-netns/net/ipv4/udplite.c  2007-12-19 22:49:20.000000000 -0500
18370 @@ -31,11 +31,18 @@
18371  
18372  static int udplite_rcv(struct sk_buff *skb)
18373  {
18374 +       if (skb->dev->nd_net != &init_net) {
18375 +               kfree_skb(skb);
18376 +               return 0;
18377 +       }
18378         return __udp4_lib_rcv(skb, udplite_hash, IPPROTO_UDPLITE);
18379  }
18380  
18381  static void udplite_err(struct sk_buff *skb, u32 info)
18382  {
18383 +       if (skb->dev->nd_net != &init_net)
18384 +               return;
18385 +
18386         return __udp4_lib_err(skb, info, udplite_hash);
18387  }
18388  
18389 @@ -103,7 +110,7 @@
18390         inet_register_protosw(&udplite4_protosw);
18391  
18392  #ifdef CONFIG_PROC_FS
18393 -       if (udp_proc_register(&udplite4_seq_afinfo)) /* udplite4_proc_init() */
18394 +       if (udp_proc_register(&init_net, &udplite4_seq_afinfo)) /* udplite4_proc_init() */
18395                 printk(KERN_ERR "%s: Cannot register /proc!\n", __FUNCTION__);
18396  #endif
18397         return;
18398 diff -Nurb linux-2.6.22-try2/net/ipv4/xfrm4_input.c linux-2.6.22-try2-netns/net/ipv4/xfrm4_input.c
18399 --- linux-2.6.22-try2/net/ipv4/xfrm4_input.c    2007-12-19 13:37:58.000000000 -0500
18400 +++ linux-2.6.22-try2-netns/net/ipv4/xfrm4_input.c      2007-12-19 22:49:20.000000000 -0500
18401 @@ -18,6 +18,10 @@
18402  
18403  int xfrm4_rcv(struct sk_buff *skb)
18404  {
18405 +       if (skb->dev->nd_net != &init_net) {
18406 +               kfree_skb(skb);
18407 +               return 0;
18408 +       }
18409         return xfrm4_rcv_encap(skb, 0);
18410  }
18411  
18412 diff -Nurb linux-2.6.22-try2/net/ipv4/xfrm4_policy.c linux-2.6.22-try2-netns/net/ipv4/xfrm4_policy.c
18413 --- linux-2.6.22-try2/net/ipv4/xfrm4_policy.c   2007-12-19 13:37:58.000000000 -0500
18414 +++ linux-2.6.22-try2-netns/net/ipv4/xfrm4_policy.c     2007-12-19 22:49:20.000000000 -0500
18415 @@ -25,6 +25,7 @@
18416  {
18417         struct rtable *rt;
18418         struct flowi fl_tunnel = {
18419 +               .fl_net = &init_net,
18420                 .nl_u = {
18421                         .ip4_u = {
18422                                 .daddr = daddr->a4,
18423 @@ -73,6 +74,7 @@
18424         struct rtable *rt0 = (struct rtable*)(*dst_p);
18425         struct rtable *rt = rt0;
18426         struct flowi fl_tunnel = {
18427 +               .fl_net = &init_net,
18428                 .nl_u = {
18429                         .ip4_u = {
18430                                 .saddr = fl->fl4_src,
18431 @@ -213,6 +215,7 @@
18432         u8 *xprth = skb_network_header(skb) + iph->ihl * 4;
18433  
18434         memset(fl, 0, sizeof(struct flowi));
18435 +       fl->fl_net = &init_net;
18436         if (!(iph->frag_off & htons(IP_MF | IP_OFFSET))) {
18437                 switch (iph->protocol) {
18438                 case IPPROTO_UDP:
18439 @@ -306,7 +309,7 @@
18440  
18441         xdst = (struct xfrm_dst *)dst;
18442         if (xdst->u.rt.idev->dev == dev) {
18443 -               struct in_device *loopback_idev = in_dev_get(&loopback_dev);
18444 +               struct in_device *loopback_idev = in_dev_get(&init_net.loopback_dev);
18445                 BUG_ON(!loopback_idev);
18446  
18447                 do {
18448 diff -Nurb linux-2.6.22-try2/net/ipv4/xfrm4_state.c linux-2.6.22-try2-netns/net/ipv4/xfrm4_state.c
18449 --- linux-2.6.22-try2/net/ipv4/xfrm4_state.c    2007-12-19 13:37:58.000000000 -0500
18450 +++ linux-2.6.22-try2-netns/net/ipv4/xfrm4_state.c      2007-12-19 22:49:20.000000000 -0500
18451 @@ -16,7 +16,7 @@
18452  
18453  static int xfrm4_init_flags(struct xfrm_state *x)
18454  {
18455 -       if (ipv4_config.no_pmtu_disc)
18456 +       if (init_net.sysctl_ipv4_no_pmtu_disc)
18457                 x->props.flags |= XFRM_STATE_NOPMTUDISC;
18458         return 0;
18459  }
18460 diff -Nurb linux-2.6.22-try2/net/ipv6/addrconf.c linux-2.6.22-try2-netns/net/ipv6/addrconf.c
18461 --- linux-2.6.22-try2/net/ipv6/addrconf.c       2007-12-19 15:29:23.000000000 -0500
18462 +++ linux-2.6.22-try2-netns/net/ipv6/addrconf.c 2007-12-19 23:35:57.000000000 -0500
18463 @@ -73,6 +73,7 @@
18464  #include <net/tcp.h>
18465  #include <net/ip.h>
18466  #include <net/netlink.h>
18467 +#include <net/net_namespace.h>
18468  #include <net/pkt_sched.h>
18469  #include <linux/if_tunnel.h>
18470  #include <linux/rtnetlink.h>
18471 @@ -457,7 +458,7 @@
18472         struct inet6_dev *idev;
18473  
18474         read_lock(&dev_base_lock);
18475 -       for_each_netdev(dev) {
18476 +       for_each_netdev(&init_net, dev) {
18477                 rcu_read_lock();
18478                 idev = __in6_dev_get(dev);
18479                 if (idev) {
18480 @@ -920,7 +921,7 @@
18481         read_lock(&dev_base_lock);
18482         rcu_read_lock();
18483  
18484 -       for_each_netdev(dev) {
18485 +       for_each_netdev(&init_net, dev) {
18486                 struct inet6_dev *idev;
18487                 struct inet6_ifaddr *ifa;
18488  
18489 @@ -1882,7 +1883,7 @@
18490         if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq)))
18491                 goto err_exit;
18492  
18493 -       dev = __dev_get_by_index(ireq.ifr6_ifindex);
18494 +       dev = __dev_get_by_index(&init_net, ireq.ifr6_ifindex);
18495  
18496         err = -ENODEV;
18497         if (dev == NULL)
18498 @@ -1913,7 +1914,7 @@
18499  
18500                 if (err == 0) {
18501                         err = -ENOBUFS;
18502 -                       if ((dev = __dev_get_by_name(p.name)) == NULL)
18503 +                       if ((dev = __dev_get_by_name(&init_net, p.name)) == NULL)
18504                                 goto err_exit;
18505                         err = dev_open(dev);
18506                 }
18507 @@ -1943,7 +1944,7 @@
18508         if (!valid_lft || prefered_lft > valid_lft)
18509                 return -EINVAL;
18510  
18511 -       if ((dev = __dev_get_by_index(ifindex)) == NULL)
18512 +       if ((dev = __dev_get_by_index(&init_net, ifindex)) == NULL)
18513                 return -ENODEV;
18514  
18515         if ((idev = addrconf_add_dev(dev)) == NULL)
18516 @@ -1994,7 +1995,7 @@
18517         struct inet6_dev *idev;
18518         struct net_device *dev;
18519  
18520 -       if ((dev = __dev_get_by_index(ifindex)) == NULL)
18521 +       if ((dev = __dev_get_by_index(&init_net, ifindex)) == NULL)
18522                 return -ENODEV;
18523  
18524         if ((idev = __in6_dev_get(dev)) == NULL)
18525 @@ -2089,7 +2090,7 @@
18526                 return;
18527         }
18528  
18529 -       for_each_netdev(dev) {
18530 +       for_each_netdev(&init_net, dev) {
18531                 struct in_device * in_dev = __in_dev_get_rtnl(dev);
18532                 if (in_dev && (dev->flags & IFF_UP)) {
18533                         struct in_ifaddr * ifa;
18534 @@ -2245,12 +2246,12 @@
18535  
18536         /* first try to inherit the link-local address from the link device */
18537         if (idev->dev->iflink &&
18538 -           (link_dev = __dev_get_by_index(idev->dev->iflink))) {
18539 +           (link_dev = __dev_get_by_index(&init_net, idev->dev->iflink))) {
18540                 if (!ipv6_inherit_linklocal(idev, link_dev))
18541                         return;
18542         }
18543         /* then try to inherit it from any device */
18544 -       for_each_netdev(link_dev) {
18545 +       for_each_netdev(&init_net, link_dev) {
18546                 if (!ipv6_inherit_linklocal(idev, link_dev))
18547                         return;
18548         }
18549 @@ -2282,6 +2283,9 @@
18550         struct inet6_dev *idev = __in6_dev_get(dev);
18551         int run_pending = 0;
18552  
18553 +       if (dev->nd_net != &init_net)
18554 +               return NOTIFY_DONE;
18555 +
18556         switch(event) {
18557         case NETDEV_REGISTER:
18558                 if (!idev && dev->mtu >= IPV6_MIN_MTU) {
18559 @@ -2419,7 +2423,7 @@
18560  
18561         ASSERT_RTNL();
18562  
18563 -       if (dev == &loopback_dev && how == 1)
18564 +       if (dev == &init_net.loopback_dev && how == 1)
18565                 how = 0;
18566  
18567         rt6_ifdown(dev);
18568 @@ -2850,14 +2854,14 @@
18569  
18570  int __init if6_proc_init(void)
18571  {
18572 -       if (!proc_net_fops_create("if_inet6", S_IRUGO, &if6_fops))
18573 +       if (!proc_net_fops_create(&init_net, "if_inet6", S_IRUGO, &if6_fops))
18574                 return -ENOMEM;
18575         return 0;
18576  }
18577  
18578  void if6_proc_exit(void)
18579  {
18580 -       proc_net_remove("if_inet6");
18581 +       proc_net_remove(&init_net, "if_inet6");
18582  }
18583  #endif /* CONFIG_PROC_FS */
18584  
18585 @@ -3017,11 +3021,15 @@
18586  static int
18587  inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
18588  {
18589 +       struct net *net = skb->sk->sk_net;
18590         struct ifaddrmsg *ifm;
18591         struct nlattr *tb[IFA_MAX+1];
18592         struct in6_addr *pfx;
18593         int err;
18594  
18595 +       if (net != &init_net)
18596 +               return -EINVAL;
18597 +
18598         err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
18599         if (err < 0)
18600                 return err;
18601 @@ -3074,6 +3082,7 @@
18602  static int
18603  inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
18604  {
18605 +       struct net *net = skb->sk->sk_net;
18606         struct ifaddrmsg *ifm;
18607         struct nlattr *tb[IFA_MAX+1];
18608         struct in6_addr *pfx;
18609 @@ -3083,6 +3092,9 @@
18610         u8 ifa_flags;
18611         int err;
18612  
18613 +       if (net != &init_net)
18614 +               return -EINVAL;
18615 +
18616         err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
18617         if (err < 0)
18618                 return err;
18619 @@ -3103,7 +3115,7 @@
18620                 valid_lft = INFINITY_LIFE_TIME;
18621         }
18622  
18623 -       dev =  __dev_get_by_index(ifm->ifa_index);
18624 +       dev =  __dev_get_by_index(&init_net, ifm->ifa_index);
18625         if (dev == NULL)
18626                 return -ENODEV;
18627  
18628 @@ -3292,7 +3304,7 @@
18629         s_ip_idx = ip_idx = cb->args[1];
18630  
18631         idx = 0;
18632 -       for_each_netdev(dev) {
18633 +       for_each_netdev(&init_net, dev) {
18634                 if (idx < s_idx)
18635                         goto cont;
18636                 if (idx > s_idx)
18637 @@ -3367,26 +3379,42 @@
18638  
18639  static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
18640  {
18641 +       struct net *net = skb->sk->sk_net;
18642         enum addr_type_t type = UNICAST_ADDR;
18643 +
18644 +       if (net != &init_net)
18645 +               return 0;
18646 +
18647         return inet6_dump_addr(skb, cb, type);
18648  }
18649  
18650  static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb)
18651  {
18652 +       struct net *net = skb->sk->sk_net;
18653         enum addr_type_t type = MULTICAST_ADDR;
18654 +
18655 +       if (net != &init_net)
18656 +               return 0;
18657 +
18658         return inet6_dump_addr(skb, cb, type);
18659  }
18660  
18661  
18662  static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb)
18663  {
18664 +       struct net *net = skb->sk->sk_net;
18665         enum addr_type_t type = ANYCAST_ADDR;
18666 +
18667 +       if (net != &init_net)
18668 +               return 0;
18669 +
18670         return inet6_dump_addr(skb, cb, type);
18671  }
18672  
18673  static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
18674                              void *arg)
18675  {
18676 +       struct net *net = in_skb->sk->sk_net;
18677         struct ifaddrmsg *ifm;
18678         struct nlattr *tb[IFA_MAX+1];
18679         struct in6_addr *addr = NULL;
18680 @@ -3395,6 +3423,9 @@
18681         struct sk_buff *skb;
18682         int err;
18683  
18684 +       if (net != &init_net)
18685 +               return -EINVAL;
18686 +
18687         err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
18688         if (err < 0)
18689                 goto errout;
18690 @@ -3407,7 +3438,7 @@
18691  
18692         ifm = nlmsg_data(nlh);
18693         if (ifm->ifa_index)
18694 -               dev = __dev_get_by_index(ifm->ifa_index);
18695 +               dev = __dev_get_by_index(&init_net, ifm->ifa_index);
18696  
18697         if ((ifa = ipv6_get_ifaddr(addr, dev, 1)) == NULL) {
18698                 err = -EADDRNOTAVAIL;
18699 @@ -3427,7 +3458,7 @@
18700                 kfree_skb(skb);
18701                 goto errout_ifa;
18702         }
18703 -       err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
18704 +       err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
18705  errout_ifa:
18706         in6_ifa_put(ifa);
18707  errout:
18708 @@ -3450,10 +3481,10 @@
18709                 kfree_skb(skb);
18710                 goto errout;
18711         }
18712 -       err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
18713 +       err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
18714  errout:
18715         if (err < 0)
18716 -               rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
18717 +               rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err);
18718  }
18719  
18720  static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
18721 @@ -3612,19 +3643,22 @@
18722  
18723  static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
18724  {
18725 +       struct net *net = skb->sk->sk_net;
18726         int idx, err;
18727         int s_idx = cb->args[0];
18728         struct net_device *dev;
18729         struct inet6_dev *idev;
18730         struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL;
18731  
18732 +       if (net != &init_net)
18733 +               return 0;
18734         /* FIXME: maybe disable ipv6 on non v6 guests?
18735         if (skb->sk && skb->sk->sk_vx_info)
18736                 return skb->len;        */
18737  
18738         read_lock(&dev_base_lock);
18739         idx = 0;
18740 -       for_each_netdev(dev) {
18741 +       for_each_netdev(&init_net, dev) {
18742                 if (idx < s_idx)
18743                         goto cont;
18744                 if (!v6_dev_in_nx_info(dev, nxi))
18745 @@ -3661,10 +3695,10 @@
18746                 kfree_skb(skb);
18747                 goto errout;
18748         }
18749 -       err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
18750 +       err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
18751  errout:
18752         if (err < 0)
18753 -               rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
18754 +               rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err);
18755  }
18756  
18757  static inline size_t inet6_prefix_nlmsg_size(void)
18758 @@ -3730,10 +3764,10 @@
18759                 kfree_skb(skb);
18760                 goto errout;
18761         }
18762 -       err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
18763 +       err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
18764  errout:
18765         if (err < 0)
18766 -               rtnl_set_sk_err(RTNLGRP_IPV6_PREFIX, err);
18767 +               rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_PREFIX, err);
18768  }
18769  
18770  static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
18771 @@ -4244,16 +4278,16 @@
18772          * device and it being up should be removed.
18773          */
18774         rtnl_lock();
18775 -       if (!ipv6_add_dev(&loopback_dev))
18776 +       if (!ipv6_add_dev(&init_net.loopback_dev))
18777                 err = -ENOMEM;
18778         rtnl_unlock();
18779         if (err)
18780                 return err;
18781  
18782 -       ip6_null_entry.rt6i_idev = in6_dev_get(&loopback_dev);
18783 +       ip6_null_entry.rt6i_idev = in6_dev_get(&init_net.loopback_dev);
18784  #ifdef CONFIG_IPV6_MULTIPLE_TABLES
18785 -       ip6_prohibit_entry.rt6i_idev = in6_dev_get(&loopback_dev);
18786 -       ip6_blk_hole_entry.rt6i_idev = in6_dev_get(&loopback_dev);
18787 +       ip6_prohibit_entry.rt6i_idev = in6_dev_get(&init_net.loopback_dev);
18788 +       ip6_blk_hole_entry.rt6i_idev = in6_dev_get(&init_net.loopback_dev);
18789  #endif
18790  
18791         register_netdevice_notifier(&ipv6_dev_notf);
18792 @@ -4304,12 +4338,12 @@
18793          *      clean dev list.
18794          */
18795  
18796 -       for_each_netdev(dev) {
18797 +       for_each_netdev(&init_net, dev) {
18798                 if ((idev = __in6_dev_get(dev)) == NULL)
18799                         continue;
18800                 addrconf_ifdown(dev, 1);
18801         }
18802 -       addrconf_ifdown(&loopback_dev, 2);
18803 +       addrconf_ifdown(&init_net.loopback_dev, 2);
18804  
18805         /*
18806          *      Check hash table.
18807 @@ -4335,6 +4369,6 @@
18808         rtnl_unlock();
18809  
18810  #ifdef CONFIG_PROC_FS
18811 -       proc_net_remove("if_inet6");
18812 +       proc_net_remove(&init_net, "if_inet6");
18813  #endif
18814  }
18815 diff -Nurb linux-2.6.22-try2/net/ipv6/af_inet6.c linux-2.6.22-try2-netns/net/ipv6/af_inet6.c
18816 --- linux-2.6.22-try2/net/ipv6/af_inet6.c       2007-12-19 15:29:23.000000000 -0500
18817 +++ linux-2.6.22-try2-netns/net/ipv6/af_inet6.c 2007-12-19 22:49:20.000000000 -0500
18818 @@ -82,7 +82,7 @@
18819         return (struct ipv6_pinfo *)(((u8 *)sk) + offset);
18820  }
18821  
18822 -static int inet6_create(struct socket *sock, int protocol)
18823 +static int inet6_create(struct net *net, struct socket *sock, int protocol)
18824  {
18825         struct inet_sock *inet;
18826         struct ipv6_pinfo *np;
18827 @@ -95,6 +95,9 @@
18828         int try_loading_module = 0;
18829         int err;
18830  
18831 +       if (net != &init_net)
18832 +               return -EAFNOSUPPORT;
18833 +
18834         if (sock->type != SOCK_RAW &&
18835             sock->type != SOCK_DGRAM &&
18836             !inet_ehash_secret)
18837 @@ -163,7 +166,7 @@
18838         BUG_TRAP(answer_prot->slab != NULL);
18839  
18840         err = -ENOBUFS;
18841 -       sk = sk_alloc(PF_INET6, GFP_KERNEL, answer_prot, 1);
18842 +       sk = sk_alloc(net, PF_INET6, GFP_KERNEL, answer_prot, 1);
18843         if (sk == NULL)
18844                 goto out;
18845  
18846 @@ -206,7 +209,7 @@
18847         inet->mc_index  = 0;
18848         inet->mc_list   = NULL;
18849  
18850 -       if (ipv4_config.no_pmtu_disc)
18851 +       if (init_net.sysctl_ipv4_no_pmtu_disc)
18852                 inet->pmtudisc = IP_PMTUDISC_DONT;
18853         else
18854                 inet->pmtudisc = IP_PMTUDISC_WANT;
18855 @@ -287,7 +290,7 @@
18856         /* Check if the address belongs to the host. */
18857         if (addr_type == IPV6_ADDR_MAPPED) {
18858                 v4addr = addr->sin6_addr.s6_addr32[3];
18859 -               if (inet_addr_type(v4addr) != RTN_LOCAL) {
18860 +               if (inet_addr_type(&init_net, v4addr) != RTN_LOCAL) {
18861                         err = -EADDRNOTAVAIL;
18862                         goto out;
18863                 }
18864 @@ -313,7 +316,7 @@
18865                                         err = -EINVAL;
18866                                         goto out;
18867                                 }
18868 -                               dev = dev_get_by_index(sk->sk_bound_dev_if);
18869 +                               dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if);
18870                                 if (!dev) {
18871                                         err = -ENODEV;
18872                                         goto out;
18873 @@ -672,6 +675,7 @@
18874                 struct flowi fl;
18875  
18876                 memset(&fl, 0, sizeof(fl));
18877 +               fl.fl_net = &init_net;
18878                 fl.proto = sk->sk_protocol;
18879                 ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
18880                 ipv6_addr_copy(&fl.fl6_src, &np->saddr);
18881 diff -Nurb linux-2.6.22-try2/net/ipv6/anycast.c linux-2.6.22-try2-netns/net/ipv6/anycast.c
18882 --- linux-2.6.22-try2/net/ipv6/anycast.c        2007-12-19 13:37:58.000000000 -0500
18883 +++ linux-2.6.22-try2-netns/net/ipv6/anycast.c  2007-12-19 22:49:20.000000000 -0500
18884 @@ -32,6 +32,7 @@
18885  
18886  #include <net/sock.h>
18887  #include <net/snmp.h>
18888 +#include <net/net_namespace.h>
18889  
18890  #include <net/ipv6.h>
18891  #include <net/protocol.h>
18892 @@ -112,10 +113,10 @@
18893                 } else {
18894                         /* router, no matching interface: just pick one */
18895  
18896 -                       dev = dev_get_by_flags(IFF_UP, IFF_UP|IFF_LOOPBACK);
18897 +                       dev = dev_get_by_flags(&init_net, IFF_UP, IFF_UP|IFF_LOOPBACK);
18898                 }
18899         } else
18900 -               dev = dev_get_by_index(ifindex);
18901 +               dev = dev_get_by_index(&init_net, ifindex);
18902  
18903         if (dev == NULL) {
18904                 err = -ENODEV;
18905 @@ -196,7 +197,7 @@
18906  
18907         write_unlock_bh(&ipv6_sk_ac_lock);
18908  
18909 -       dev = dev_get_by_index(pac->acl_ifindex);
18910 +       dev = dev_get_by_index(&init_net, pac->acl_ifindex);
18911         if (dev) {
18912                 ipv6_dev_ac_dec(dev, &pac->acl_addr);
18913                 dev_put(dev);
18914 @@ -224,7 +225,7 @@
18915                 if (pac->acl_ifindex != prev_index) {
18916                         if (dev)
18917                                 dev_put(dev);
18918 -                       dev = dev_get_by_index(pac->acl_ifindex);
18919 +                       dev = dev_get_by_index(&init_net, pac->acl_ifindex);
18920                         prev_index = pac->acl_ifindex;
18921                 }
18922                 if (dev)
18923 @@ -429,7 +430,7 @@
18924         if (dev)
18925                 return ipv6_chk_acast_dev(dev, addr);
18926         read_lock(&dev_base_lock);
18927 -       for_each_netdev(dev)
18928 +       for_each_netdev(&init_net, dev)
18929                 if (ipv6_chk_acast_dev(dev, addr)) {
18930                         found = 1;
18931                         break;
18932 @@ -453,7 +454,7 @@
18933         struct ac6_iter_state *state = ac6_seq_private(seq);
18934  
18935         state->idev = NULL;
18936 -       for_each_netdev(state->dev) {
18937 +       for_each_netdev(&init_net, state->dev) {
18938                 struct inet6_dev *idev;
18939                 idev = in6_dev_get(state->dev);
18940                 if (!idev)
18941 @@ -579,7 +580,7 @@
18942  
18943  int __init ac6_proc_init(void)
18944  {
18945 -       if (!proc_net_fops_create("anycast6", S_IRUGO, &ac6_seq_fops))
18946 +       if (!proc_net_fops_create(&init_net, "anycast6", S_IRUGO, &ac6_seq_fops))
18947                 return -ENOMEM;
18948  
18949         return 0;
18950 @@ -587,7 +588,7 @@
18951  
18952  void ac6_proc_exit(void)
18953  {
18954 -       proc_net_remove("anycast6");
18955 +       proc_net_remove(&init_net, "anycast6");
18956  }
18957  #endif
18958  
18959 diff -Nurb linux-2.6.22-try2/net/ipv6/datagram.c linux-2.6.22-try2-netns/net/ipv6/datagram.c
18960 --- linux-2.6.22-try2/net/ipv6/datagram.c       2007-12-19 15:29:23.000000000 -0500
18961 +++ linux-2.6.22-try2-netns/net/ipv6/datagram.c 2007-12-19 22:49:20.000000000 -0500
18962 @@ -60,6 +60,7 @@
18963                 return -EAFNOSUPPORT;
18964  
18965         memset(&fl, 0, sizeof(fl));
18966 +       fl.fl_net = &init_net;
18967         if (np->sndflow) {
18968                 fl.fl6_flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK;
18969                 if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
18970 @@ -544,7 +545,7 @@
18971                                 if (!src_info->ipi6_ifindex)
18972                                         return -EINVAL;
18973                                 else {
18974 -                                       dev = dev_get_by_index(src_info->ipi6_ifindex);
18975 +                                       dev = dev_get_by_index(&init_net, src_info->ipi6_ifindex);
18976                                         if (!dev)
18977                                                 return -ENODEV;
18978                                 }
18979 diff -Nurb linux-2.6.22-try2/net/ipv6/fib6_rules.c linux-2.6.22-try2-netns/net/ipv6/fib6_rules.c
18980 --- linux-2.6.22-try2/net/ipv6/fib6_rules.c     2007-12-19 13:37:58.000000000 -0500
18981 +++ linux-2.6.22-try2-netns/net/ipv6/fib6_rules.c       2007-12-19 22:49:20.000000000 -0500
18982 @@ -244,7 +244,7 @@
18983         return -ENOBUFS;
18984  }
18985  
18986 -static u32 fib6_rule_default_pref(void)
18987 +static u32 fib6_rule_default_pref(struct fib_rules_ops *ops)
18988  {
18989         return 0x3FFF;
18990  }
18991 @@ -277,10 +277,10 @@
18992         list_add_tail(&local_rule.common.list, &fib6_rules);
18993         list_add_tail(&main_rule.common.list, &fib6_rules);
18994  
18995 -       fib_rules_register(&fib6_rules_ops);
18996 +       fib_rules_register(&init_net, &fib6_rules_ops);
18997  }
18998  
18999  void fib6_rules_cleanup(void)
19000  {
19001 -       fib_rules_unregister(&fib6_rules_ops);
19002 +       fib_rules_unregister(&init_net, &fib6_rules_ops);
19003  }
19004 diff -Nurb linux-2.6.22-try2/net/ipv6/icmp.c linux-2.6.22-try2-netns/net/ipv6/icmp.c
19005 --- linux-2.6.22-try2/net/ipv6/icmp.c   2007-12-19 15:29:23.000000000 -0500
19006 +++ linux-2.6.22-try2-netns/net/ipv6/icmp.c     2007-12-19 22:49:20.000000000 -0500
19007 @@ -377,6 +377,7 @@
19008         mip6_addr_swap(skb);
19009  
19010         memset(&fl, 0, sizeof(fl));
19011 +       fl.fl_net = &init_net;
19012         fl.proto = IPPROTO_ICMPV6;
19013         ipv6_addr_copy(&fl.fl6_dst, &hdr->saddr);
19014         if (saddr)
19015 @@ -495,6 +496,7 @@
19016         tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY;
19017  
19018         memset(&fl, 0, sizeof(fl));
19019 +       fl.fl_net = &init_net;
19020         fl.proto = IPPROTO_ICMPV6;
19021         ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr);
19022         if (saddr)
19023 diff -Nurb linux-2.6.22-try2/net/ipv6/inet6_connection_sock.c linux-2.6.22-try2-netns/net/ipv6/inet6_connection_sock.c
19024 --- linux-2.6.22-try2/net/ipv6/inet6_connection_sock.c  2007-12-19 13:37:58.000000000 -0500
19025 +++ linux-2.6.22-try2-netns/net/ipv6/inet6_connection_sock.c    2007-12-19 22:49:20.000000000 -0500
19026 @@ -149,6 +149,7 @@
19027         struct in6_addr *final_p = NULL, final;
19028  
19029         memset(&fl, 0, sizeof(fl));
19030 +       fl.fl_net = &init_net;
19031         fl.proto = sk->sk_protocol;
19032         ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
19033         ipv6_addr_copy(&fl.fl6_src, &np->saddr);
19034 diff -Nurb linux-2.6.22-try2/net/ipv6/inet6_hashtables.c linux-2.6.22-try2-netns/net/ipv6/inet6_hashtables.c
19035 --- linux-2.6.22-try2/net/ipv6/inet6_hashtables.c       2007-12-19 13:37:58.000000000 -0500
19036 +++ linux-2.6.22-try2-netns/net/ipv6/inet6_hashtables.c 2007-12-19 22:49:20.000000000 -0500
19037 @@ -61,7 +61,7 @@
19038                                            const __be16 sport,
19039                                            const struct in6_addr *daddr,
19040                                            const u16 hnum,
19041 -                                          const int dif)
19042 +                                          const int dif, struct net *net)
19043  {
19044         struct sock *sk;
19045         const struct hlist_node *node;
19046 @@ -105,7 +105,7 @@
19047  
19048  struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
19049                                    const struct in6_addr *daddr,
19050 -                                  const unsigned short hnum, const int dif)
19051 +                                  const unsigned short hnum, const int dif, struct net *net)
19052  {
19053         struct sock *sk;
19054         const struct hlist_node *node;
19055 @@ -113,7 +113,7 @@
19056         int score, hiscore = 0;
19057  
19058         read_lock(&hashinfo->lhash_lock);
19059 -       sk_for_each(sk, node, &hashinfo->listening_hash[inet_lhashfn(hnum)]) {
19060 +       sk_for_each(sk, node, &hashinfo->listening_hash[inet_lhashfn(net, hnum)]) {
19061                 if (inet_sk(sk)->num == hnum && sk->sk_family == PF_INET6) {
19062                         const struct ipv6_pinfo *np = inet6_sk(sk);
19063  
19064 @@ -152,12 +152,12 @@
19065  struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
19066                           const struct in6_addr *saddr, const __be16 sport,
19067                           const struct in6_addr *daddr, const __be16 dport,
19068 -                         const int dif)
19069 +                         const int dif, struct net *net)
19070  {
19071         struct sock *sk;
19072  
19073         local_bh_disable();
19074 -       sk = __inet6_lookup(hashinfo, saddr, sport, daddr, ntohs(dport), dif);
19075 +       sk = __inet6_lookup(hashinfo, saddr, sport, daddr, ntohs(dport), dif, net);
19076         local_bh_enable();
19077  
19078         return sk;
19079 @@ -251,6 +251,7 @@
19080  int inet6_hash_connect(struct inet_timewait_death_row *death_row,
19081                        struct sock *sk)
19082  {
19083 +       struct net *net = sk->sk_net;
19084         struct inet_hashinfo *hinfo = death_row->hashinfo;
19085         const unsigned short snum = inet_sk(sk)->num;
19086         struct inet_bind_hashbucket *head;
19087 @@ -258,8 +259,8 @@
19088         int ret;
19089  
19090         if (snum == 0) {
19091 -               const int low = sysctl_local_port_range[0];
19092 -               const int high = sysctl_local_port_range[1];
19093 +               const int low = sk->sk_net->sysctl_local_port_range[0];
19094 +               const int high = sk->sk_net->sysctl_local_port_range[1];
19095                 const int range = high - low;
19096                 int i, port;
19097                 static u32 hint;
19098 @@ -270,7 +271,7 @@
19099                 local_bh_disable();
19100                 for (i = 1; i <= range; i++) {
19101                         port = low + (i + offset) % range;
19102 -                       head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)];
19103 +                       head = &hinfo->bhash[inet_bhashfn(net, port, hinfo->bhash_size)];
19104                         spin_lock(&head->lock);
19105  
19106                         /* Does not bother with rcv_saddr checks,
19107 @@ -278,7 +279,7 @@
19108                          * unique enough.
19109                          */
19110                         inet_bind_bucket_for_each(tb, node, &head->chain) {
19111 -                               if (tb->port == port) {
19112 +                               if ((tb->port == port) && (tb->net == net)) {
19113                                         BUG_TRAP(!hlist_empty(&tb->owners));
19114                                         if (tb->fastreuse >= 0)
19115                                                 goto next_port;
19116 @@ -291,7 +292,7 @@
19117                         }
19118  
19119                         tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
19120 -                                                    head, port);
19121 +                                                    head, net, port);
19122                         if (!tb) {
19123                                 spin_unlock(&head->lock);
19124                                 break;
19125 @@ -326,7 +327,7 @@
19126                 goto out;
19127         }
19128  
19129 -       head = &hinfo->bhash[inet_bhashfn(snum, hinfo->bhash_size)];
19130 +       head = &hinfo->bhash[inet_bhashfn(net, snum, hinfo->bhash_size)];
19131         tb   = inet_csk(sk)->icsk_bind_hash;
19132         spin_lock_bh(&head->lock);
19133  
19134 diff -Nurb linux-2.6.22-try2/net/ipv6/ip6_fib.c linux-2.6.22-try2-netns/net/ipv6/ip6_fib.c
19135 --- linux-2.6.22-try2/net/ipv6/ip6_fib.c        2007-12-19 13:37:58.000000000 -0500
19136 +++ linux-2.6.22-try2-netns/net/ipv6/ip6_fib.c  2007-12-19 22:49:20.000000000 -0500
19137 @@ -361,6 +361,7 @@
19138  
19139  static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
19140  {
19141 +       struct net *net = skb->sk->sk_net;
19142         unsigned int h, s_h;
19143         unsigned int e = 0, s_e;
19144         struct rt6_rtnl_dump_arg arg;
19145 @@ -369,6 +370,9 @@
19146         struct hlist_node *node;
19147         int res = 0;
19148  
19149 +       if (net != &init_net)
19150 +               return 0;
19151 +
19152         s_h = cb->args[0];
19153         s_e = cb->args[1];
19154  
19155 @@ -1311,6 +1315,11 @@
19156  
19157  static int fib6_clean_node(struct fib6_walker_t *w)
19158  {
19159 +       struct nl_info info = {
19160 +               .nlh = NULL,
19161 +               .pid = 0,
19162 +               .net = &init_net,
19163 +       };
19164         int res;
19165         struct rt6_info *rt;
19166         struct fib6_cleaner_t *c = (struct fib6_cleaner_t*)w;
19167 @@ -1319,7 +1328,7 @@
19168                 res = c->func(rt, c->arg);
19169                 if (res < 0) {
19170                         w->leaf = rt;
19171 -                       res = fib6_del(rt, NULL);
19172 +                       res = fib6_del(rt, &info);
19173                         if (res) {
19174  #if RT6_DEBUG >= 2
19175                                 printk(KERN_DEBUG "fib6_clean_node: del failed: rt=%p@%p err=%d\n", rt, rt->rt6i_node, res);
19176 diff -Nurb linux-2.6.22-try2/net/ipv6/ip6_flowlabel.c linux-2.6.22-try2-netns/net/ipv6/ip6_flowlabel.c
19177 --- linux-2.6.22-try2/net/ipv6/ip6_flowlabel.c  2007-12-19 13:37:58.000000000 -0500
19178 +++ linux-2.6.22-try2-netns/net/ipv6/ip6_flowlabel.c    2007-12-19 22:49:20.000000000 -0500
19179 @@ -22,6 +22,7 @@
19180  #include <linux/seq_file.h>
19181  
19182  #include <net/sock.h>
19183 +#include <net/net_namespace.h>
19184  
19185  #include <net/ipv6.h>
19186  #include <net/ndisc.h>
19187 @@ -309,6 +310,7 @@
19188  
19189                 msg.msg_controllen = olen;
19190                 msg.msg_control = (void*)(fl->opt+1);
19191 +               flowi.fl_net = &init_net;
19192                 flowi.oif = 0;
19193  
19194                 err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk, &junk);
19195 @@ -690,7 +692,7 @@
19196  void ip6_flowlabel_init(void)
19197  {
19198  #ifdef CONFIG_PROC_FS
19199 -       proc_net_fops_create("ip6_flowlabel", S_IRUGO, &ip6fl_seq_fops);
19200 +       proc_net_fops_create(&init_net, "ip6_flowlabel", S_IRUGO, &ip6fl_seq_fops);
19201  #endif
19202  }
19203  
19204 @@ -698,6 +700,6 @@
19205  {
19206         del_timer(&ip6_fl_gc_timer);
19207  #ifdef CONFIG_PROC_FS
19208 -       proc_net_remove("ip6_flowlabel");
19209 +       proc_net_remove(&init_net, "ip6_flowlabel");
19210  #endif
19211  }
19212 diff -Nurb linux-2.6.22-try2/net/ipv6/ip6_input.c linux-2.6.22-try2-netns/net/ipv6/ip6_input.c
19213 --- linux-2.6.22-try2/net/ipv6/ip6_input.c      2007-12-19 13:37:58.000000000 -0500
19214 +++ linux-2.6.22-try2-netns/net/ipv6/ip6_input.c        2007-12-19 22:49:20.000000000 -0500
19215 @@ -61,6 +61,11 @@
19216         u32             pkt_len;
19217         struct inet6_dev *idev;
19218  
19219 +       if (dev->nd_net != &init_net) {
19220 +               kfree_skb(skb);
19221 +               return 0;
19222 +       }
19223 +
19224         if (skb->pkt_type == PACKET_OTHERHOST) {
19225                 kfree_skb(skb);
19226                 return 0;
19227 diff -Nurb linux-2.6.22-try2/net/ipv6/ip6_output.c linux-2.6.22-try2-netns/net/ipv6/ip6_output.c
19228 --- linux-2.6.22-try2/net/ipv6/ip6_output.c     2007-12-19 15:29:23.000000000 -0500
19229 +++ linux-2.6.22-try2-netns/net/ipv6/ip6_output.c       2007-12-19 22:49:20.000000000 -0500
19230 @@ -423,7 +423,7 @@
19231  
19232         /* XXX: idev->cnf.proxy_ndp? */
19233         if (ipv6_devconf.proxy_ndp &&
19234 -           pneigh_lookup(&nd_tbl, &hdr->daddr, skb->dev, 0)) {
19235 +           pneigh_lookup(&nd_tbl, &init_net, &hdr->daddr, skb->dev, 0)) {
19236                 int proxied = ip6_forward_proxy_check(skb);
19237                 if (proxied > 0)
19238                         return ip6_input(skb);
19239 diff -Nurb linux-2.6.22-try2/net/ipv6/ip6_tunnel.c linux-2.6.22-try2-netns/net/ipv6/ip6_tunnel.c
19240 --- linux-2.6.22-try2/net/ipv6/ip6_tunnel.c     2007-12-19 13:37:58.000000000 -0500
19241 +++ linux-2.6.22-try2-netns/net/ipv6/ip6_tunnel.c       2007-12-19 22:49:20.000000000 -0500
19242 @@ -235,7 +235,7 @@
19243                 int i;
19244                 for (i = 1; i < IP6_TNL_MAX; i++) {
19245                         sprintf(name, "ip6tnl%d", i);
19246 -                       if (__dev_get_by_name(name) == NULL)
19247 +                       if (__dev_get_by_name(&init_net, name) == NULL)
19248                                 break;
19249                 }
19250                 if (i == IP6_TNL_MAX)
19251 @@ -651,7 +651,7 @@
19252                 struct net_device *ldev = NULL;
19253  
19254                 if (p->link)
19255 -                       ldev = dev_get_by_index(p->link);
19256 +                       ldev = dev_get_by_index(&init_net, p->link);
19257  
19258                 if ((ipv6_addr_is_multicast(&p->laddr) ||
19259                      likely(ipv6_chk_addr(&p->laddr, ldev, 0))) &&
19260 @@ -787,7 +787,7 @@
19261                 struct net_device *ldev = NULL;
19262  
19263                 if (p->link)
19264 -                       ldev = dev_get_by_index(p->link);
19265 +                       ldev = dev_get_by_index(&init_net, p->link);
19266  
19267                 if (unlikely(!ipv6_chk_addr(&p->laddr, ldev, 0)))
19268                         printk(KERN_WARNING
19269 diff -Nurb linux-2.6.22-try2/net/ipv6/ipv6_sockglue.c linux-2.6.22-try2-netns/net/ipv6/ipv6_sockglue.c
19270 --- linux-2.6.22-try2/net/ipv6/ipv6_sockglue.c  2007-12-19 15:29:23.000000000 -0500
19271 +++ linux-2.6.22-try2-netns/net/ipv6/ipv6_sockglue.c    2007-12-19 22:49:20.000000000 -0500
19272 @@ -463,6 +463,7 @@
19273                 struct flowi fl;
19274                 int junk;
19275  
19276 +               fl.fl_net = &init_net;
19277                 fl.fl6_flowlabel = 0;
19278                 fl.oif = sk->sk_bound_dev_if;
19279  
19280 @@ -547,7 +548,7 @@
19281                 if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != val)
19282                         goto e_inval;
19283  
19284 -               if (__dev_get_by_index(val) == NULL) {
19285 +               if (__dev_get_by_index(&init_net, val) == NULL) {
19286                         retv = -ENODEV;
19287                         break;
19288                 }
19289 diff -Nurb linux-2.6.22-try2/net/ipv6/mcast.c linux-2.6.22-try2-netns/net/ipv6/mcast.c
19290 --- linux-2.6.22-try2/net/ipv6/mcast.c  2007-12-19 13:37:58.000000000 -0500
19291 +++ linux-2.6.22-try2-netns/net/ipv6/mcast.c    2007-12-19 22:49:20.000000000 -0500
19292 @@ -51,6 +51,7 @@
19293  
19294  #include <net/sock.h>
19295  #include <net/snmp.h>
19296 +#include <net/net_namespace.h>
19297  
19298  #include <net/ipv6.h>
19299  #include <net/protocol.h>
19300 @@ -214,7 +215,7 @@
19301                         dst_release(&rt->u.dst);
19302                 }
19303         } else
19304 -               dev = dev_get_by_index(ifindex);
19305 +               dev = dev_get_by_index(&init_net, ifindex);
19306  
19307         if (dev == NULL) {
19308                 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
19309 @@ -265,7 +266,7 @@
19310                         *lnk = mc_lst->next;
19311                         write_unlock_bh(&ipv6_sk_mc_lock);
19312  
19313 -                       if ((dev = dev_get_by_index(mc_lst->ifindex)) != NULL) {
19314 +                       if ((dev = dev_get_by_index(&init_net, mc_lst->ifindex)) != NULL) {
19315                                 struct inet6_dev *idev = in6_dev_get(dev);
19316  
19317                                 (void) ip6_mc_leave_src(sk, mc_lst, idev);
19318 @@ -300,7 +301,7 @@
19319                         dst_release(&rt->u.dst);
19320                 }
19321         } else
19322 -               dev = dev_get_by_index(ifindex);
19323 +               dev = dev_get_by_index(&init_net, ifindex);
19324  
19325         if (!dev)
19326                 return NULL;
19327 @@ -331,7 +332,7 @@
19328                 np->ipv6_mc_list = mc_lst->next;
19329                 write_unlock_bh(&ipv6_sk_mc_lock);
19330  
19331 -               dev = dev_get_by_index(mc_lst->ifindex);
19332 +               dev = dev_get_by_index(&init_net, mc_lst->ifindex);
19333                 if (dev) {
19334                         struct inet6_dev *idev = in6_dev_get(dev);
19335  
19336 @@ -2332,7 +2333,7 @@
19337         struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
19338  
19339         state->idev = NULL;
19340 -       for_each_netdev(state->dev) {
19341 +       for_each_netdev(&init_net, state->dev) {
19342                 struct inet6_dev *idev;
19343                 idev = in6_dev_get(state->dev);
19344                 if (!idev)
19345 @@ -2476,7 +2477,7 @@
19346  
19347         state->idev = NULL;
19348         state->im = NULL;
19349 -       for_each_netdev(state->dev) {
19350 +       for_each_netdev(&init_net, state->dev) {
19351                 struct inet6_dev *idev;
19352                 idev = in6_dev_get(state->dev);
19353                 if (unlikely(idev == NULL))
19354 @@ -2658,8 +2659,8 @@
19355         np->hop_limit = 1;
19356  
19357  #ifdef CONFIG_PROC_FS
19358 -       proc_net_fops_create("igmp6", S_IRUGO, &igmp6_mc_seq_fops);
19359 -       proc_net_fops_create("mcfilter6", S_IRUGO, &igmp6_mcf_seq_fops);
19360 +       proc_net_fops_create(&init_net, "igmp6", S_IRUGO, &igmp6_mc_seq_fops);
19361 +       proc_net_fops_create(&init_net, "mcfilter6", S_IRUGO, &igmp6_mcf_seq_fops);
19362  #endif
19363  
19364         return 0;
19365 @@ -2671,7 +2672,7 @@
19366         igmp6_socket = NULL; /* for safety */
19367  
19368  #ifdef CONFIG_PROC_FS
19369 -       proc_net_remove("mcfilter6");
19370 -       proc_net_remove("igmp6");
19371 +       proc_net_remove(&init_net, "mcfilter6");
19372 +       proc_net_remove(&init_net, "igmp6");
19373  #endif
19374  }
19375 diff -Nurb linux-2.6.22-try2/net/ipv6/ndisc.c linux-2.6.22-try2-netns/net/ipv6/ndisc.c
19376 --- linux-2.6.22-try2/net/ipv6/ndisc.c  2007-12-19 13:37:58.000000000 -0500
19377 +++ linux-2.6.22-try2-netns/net/ipv6/ndisc.c    2007-12-19 22:49:20.000000000 -0500
19378 @@ -418,6 +418,7 @@
19379                             int oif)
19380  {
19381         memset(fl, 0, sizeof(*fl));
19382 +       fl->fl_net = &init_net;
19383         ipv6_addr_copy(&fl->fl6_src, saddr);
19384         ipv6_addr_copy(&fl->fl6_dst, daddr);
19385         fl->proto               = IPPROTO_ICMPV6;
19386 @@ -760,7 +761,7 @@
19387                 if (ipv6_chk_acast_addr(dev, &msg->target) ||
19388                     (idev->cnf.forwarding &&
19389                      (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) &&
19390 -                    (pneigh = pneigh_lookup(&nd_tbl,
19391 +                    (pneigh = pneigh_lookup(&nd_tbl, &init_net,
19392                                              &msg->target, dev, 0)) != NULL)) {
19393                         if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
19394                             skb->pkt_type != PACKET_HOST &&
19395 @@ -901,7 +902,7 @@
19396                  */
19397                 if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
19398                     ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp &&
19399 -                   pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) {
19400 +                   pneigh_lookup(&nd_tbl, &init_net, &msg->target, dev, 0)) {
19401                         /* XXX: idev->cnf.prixy_ndp */
19402                         goto out;
19403                 }
19404 @@ -1525,6 +1526,9 @@
19405  {
19406         struct net_device *dev = ptr;
19407  
19408 +       if (dev->nd_net != &init_net)
19409 +               return NOTIFY_DONE;
19410 +
19411         switch (event) {
19412         case NETDEV_CHANGEADDR:
19413                 neigh_changeaddr(&nd_tbl, dev);
19414 diff -Nurb linux-2.6.22-try2/net/ipv6/netfilter/ip6_queue.c linux-2.6.22-try2-netns/net/ipv6/netfilter/ip6_queue.c
19415 --- linux-2.6.22-try2/net/ipv6/netfilter/ip6_queue.c    2007-12-19 13:37:58.000000000 -0500
19416 +++ linux-2.6.22-try2-netns/net/ipv6/netfilter/ip6_queue.c      2007-12-19 22:49:20.000000000 -0500
19417 @@ -24,6 +24,7 @@
19418  #include <linux/sysctl.h>
19419  #include <linux/proc_fs.h>
19420  #include <linux/mutex.h>
19421 +#include <net/net_namespace.h>
19422  #include <net/sock.h>
19423  #include <net/ipv6.h>
19424  #include <net/ip6_route.h>
19425 @@ -546,6 +547,9 @@
19426  {
19427         struct net_device *dev = ptr;
19428  
19429 +       if (dev->nd_net != &init_net)
19430 +               return NOTIFY_DONE;
19431 +
19432         /* Drop any packets associated with the downed device */
19433         if (event == NETDEV_DOWN)
19434                 ipq_dev_drop(dev->ifindex);
19435 @@ -565,7 +569,7 @@
19436         if (event == NETLINK_URELEASE &&
19437             n->protocol == NETLINK_IP6_FW && n->pid) {
19438                 write_lock_bh(&queue_lock);
19439 -               if (n->pid == peer_pid)
19440 +               if ((n->net == &init_net) && (n->pid == peer_pid))
19441                         __ipq_reset();
19442                 write_unlock_bh(&queue_lock);
19443         }
19444 @@ -657,14 +661,14 @@
19445         struct proc_dir_entry *proc;
19446  
19447         netlink_register_notifier(&ipq_nl_notifier);
19448 -       ipqnl = netlink_kernel_create(NETLINK_IP6_FW, 0, ipq_rcv_sk, NULL,
19449 -                                     THIS_MODULE);
19450 +       ipqnl = netlink_kernel_create(&init_net, NETLINK_IP6_FW, 0, ipq_rcv_sk,
19451 +                                       NULL, THIS_MODULE);
19452         if (ipqnl == NULL) {
19453                 printk(KERN_ERR "ip6_queue: failed to create netlink socket\n");
19454                 goto cleanup_netlink_notifier;
19455         }
19456  
19457 -       proc = proc_net_create(IPQ_PROC_FS_NAME, 0, ipq_get_info);
19458 +       proc = proc_net_create(&init_net, IPQ_PROC_FS_NAME, 0, ipq_get_info);
19459         if (proc)
19460                 proc->owner = THIS_MODULE;
19461         else {
19462 @@ -685,7 +689,7 @@
19463  cleanup_sysctl:
19464         unregister_sysctl_table(ipq_sysctl_header);
19465         unregister_netdevice_notifier(&ipq_dev_notifier);
19466 -       proc_net_remove(IPQ_PROC_FS_NAME);
19467 +       proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
19468  
19469  cleanup_ipqnl:
19470         sock_release(ipqnl->sk_socket);
19471 @@ -705,7 +709,7 @@
19472  
19473         unregister_sysctl_table(ipq_sysctl_header);
19474         unregister_netdevice_notifier(&ipq_dev_notifier);
19475 -       proc_net_remove(IPQ_PROC_FS_NAME);
19476 +       proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
19477  
19478         sock_release(ipqnl->sk_socket);
19479         mutex_lock(&ipqnl_mutex);
19480 diff -Nurb linux-2.6.22-try2/net/ipv6/netfilter/ip6_tables.c linux-2.6.22-try2-netns/net/ipv6/netfilter/ip6_tables.c
19481 --- linux-2.6.22-try2/net/ipv6/netfilter/ip6_tables.c   2007-12-19 13:37:58.000000000 -0500
19482 +++ linux-2.6.22-try2-netns/net/ipv6/netfilter/ip6_tables.c     2007-12-19 22:49:20.000000000 -0500
19483 @@ -906,7 +906,7 @@
19484         int ret;
19485         struct xt_table *t;
19486  
19487 -       t = xt_find_table_lock(AF_INET6, entries->name);
19488 +       t = xt_find_table_lock(&init_net, AF_INET6, entries->name);
19489         if (t && !IS_ERR(t)) {
19490                 struct xt_table_info *private = t->private;
19491                 duprintf("t->private->number = %u\n", private->number);
19492 @@ -972,7 +972,7 @@
19493  
19494         duprintf("ip_tables: Translated table\n");
19495  
19496 -       t = try_then_request_module(xt_find_table_lock(AF_INET6, tmp.name),
19497 +       t = try_then_request_module(xt_find_table_lock(&init_net, AF_INET6, tmp.name),
19498                                     "ip6table_%s", tmp.name);
19499         if (!t || IS_ERR(t)) {
19500                 ret = t ? PTR_ERR(t) : -ENOENT;
19501 @@ -1073,7 +1073,7 @@
19502                 goto free;
19503         }
19504  
19505 -       t = xt_find_table_lock(AF_INET6, tmp.name);
19506 +       t = xt_find_table_lock(&init_net, AF_INET6, tmp.name);
19507         if (!t || IS_ERR(t)) {
19508                 ret = t ? PTR_ERR(t) : -ENOENT;
19509                 goto free;
19510 @@ -1109,6 +1109,9 @@
19511  {
19512         int ret;
19513  
19514 +       if (sk->sk_net != &init_net)
19515 +               return -ENOPROTOOPT;
19516 +
19517         if (!capable(CAP_NET_ADMIN))
19518                 return -EPERM;
19519  
19520 @@ -1134,6 +1137,9 @@
19521  {
19522         int ret;
19523  
19524 +       if (sk->sk_net != &init_net)
19525 +               return -ENOPROTOOPT;
19526 +
19527         if (!capable(CAP_NET_ADMIN))
19528                 return -EPERM;
19529  
19530 @@ -1155,7 +1161,7 @@
19531                 }
19532                 name[IP6T_TABLE_MAXNAMELEN-1] = '\0';
19533  
19534 -               t = try_then_request_module(xt_find_table_lock(AF_INET6, name),
19535 +               t = try_then_request_module(xt_find_table_lock(&init_net, AF_INET6, name),
19536                                             "ip6table_%s", name);
19537                 if (t && !IS_ERR(t)) {
19538                         struct ip6t_getinfo info;
19539 @@ -1259,7 +1265,7 @@
19540                 return ret;
19541         }
19542  
19543 -       ret = xt_register_table(table, &bootstrap, newinfo);
19544 +       ret = xt_register_table(&init_net, table, &bootstrap, newinfo);
19545         if (ret != 0) {
19546                 xt_free_table_info(newinfo);
19547                 return ret;
19548 diff -Nurb linux-2.6.22-try2/net/ipv6/netfilter/ip6t_REJECT.c linux-2.6.22-try2-netns/net/ipv6/netfilter/ip6t_REJECT.c
19549 --- linux-2.6.22-try2/net/ipv6/netfilter/ip6t_REJECT.c  2007-12-19 13:37:58.000000000 -0500
19550 +++ linux-2.6.22-try2-netns/net/ipv6/netfilter/ip6t_REJECT.c    2007-12-19 22:49:20.000000000 -0500
19551 @@ -92,6 +92,7 @@
19552         }
19553  
19554         memset(&fl, 0, sizeof(fl));
19555 +       fl.fl_net = &init_net;
19556         fl.proto = IPPROTO_TCP;
19557         ipv6_addr_copy(&fl.fl6_src, &oip6h->daddr);
19558         ipv6_addr_copy(&fl.fl6_dst, &oip6h->saddr);
19559 @@ -172,7 +173,7 @@
19560  send_unreach(struct sk_buff *skb_in, unsigned char code, unsigned int hooknum)
19561  {
19562         if (hooknum == NF_IP6_LOCAL_OUT && skb_in->dev == NULL)
19563 -               skb_in->dev = &loopback_dev;
19564 +               skb_in->dev = &init_net.loopback_dev;
19565  
19566         icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL);
19567  }
19568 diff -Nurb linux-2.6.22-try2/net/ipv6/netfilter/ip6table_filter.c linux-2.6.22-try2-netns/net/ipv6/netfilter/ip6table_filter.c
19569 --- linux-2.6.22-try2/net/ipv6/netfilter/ip6table_filter.c      2007-12-19 13:37:58.000000000 -0500
19570 +++ linux-2.6.22-try2-netns/net/ipv6/netfilter/ip6table_filter.c        2007-12-19 22:49:20.000000000 -0500
19571 @@ -65,6 +65,10 @@
19572          const struct net_device *out,
19573          int (*okfn)(struct sk_buff *))
19574  {
19575 +       /* Only filter packets in the initial network namespace */
19576 +       if ((in?in:out)->nd_net != &init_net)
19577 +               return NF_ACCEPT;
19578 +
19579         return ip6t_do_table(pskb, hook, in, out, &packet_filter);
19580  }
19581  
19582 @@ -75,6 +79,10 @@
19583                    const struct net_device *out,
19584                    int (*okfn)(struct sk_buff *))
19585  {
19586 +       /* Only filter packets in the initial network namespace */
19587 +       if ((in?in:out)->nd_net != &init_net)
19588 +               return NF_ACCEPT;
19589 +
19590  #if 0
19591         /* root is playing with raw sockets. */
19592         if ((*pskb)->len < sizeof(struct iphdr)
19593 diff -Nurb linux-2.6.22-try2/net/ipv6/netfilter/ip6table_mangle.c linux-2.6.22-try2-netns/net/ipv6/netfilter/ip6table_mangle.c
19594 --- linux-2.6.22-try2/net/ipv6/netfilter/ip6table_mangle.c      2007-12-19 13:37:58.000000000 -0500
19595 +++ linux-2.6.22-try2-netns/net/ipv6/netfilter/ip6table_mangle.c        2007-12-19 22:49:20.000000000 -0500
19596 @@ -79,6 +79,10 @@
19597          const struct net_device *out,
19598          int (*okfn)(struct sk_buff *))
19599  {
19600 +       /* Only filter packets in the initial network namespace */
19601 +       if ((in?in:out)->nd_net != &init_net)
19602 +               return NF_ACCEPT;
19603 +
19604         return ip6t_do_table(pskb, hook, in, out, &packet_mangler);
19605  }
19606  
19607 @@ -95,6 +99,10 @@
19608         u_int8_t hop_limit;
19609         u_int32_t flowlabel, mark;
19610  
19611 +       /* Only filter packets in the initial network namespace */
19612 +       if ((in?in:out)->nd_net != &init_net)
19613 +               return NF_ACCEPT;
19614 +
19615  #if 0
19616         /* root is playing with raw sockets. */
19617         if ((*pskb)->len < sizeof(struct iphdr)
19618 diff -Nurb linux-2.6.22-try2/net/ipv6/netfilter/ip6table_raw.c linux-2.6.22-try2-netns/net/ipv6/netfilter/ip6table_raw.c
19619 --- linux-2.6.22-try2/net/ipv6/netfilter/ip6table_raw.c 2007-12-19 13:37:58.000000000 -0500
19620 +++ linux-2.6.22-try2-netns/net/ipv6/netfilter/ip6table_raw.c   2007-12-19 22:49:20.000000000 -0500
19621 @@ -57,6 +57,10 @@
19622          const struct net_device *out,
19623          int (*okfn)(struct sk_buff *))
19624  {
19625 +       /* Only filter packets in the initial network namespace */
19626 +       if ((in?in:out)->nd_net != &init_net)
19627 +               return NF_ACCEPT;
19628 +
19629         return ip6t_do_table(pskb, hook, in, out, &packet_raw);
19630  }
19631  
19632 diff -Nurb linux-2.6.22-try2/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c linux-2.6.22-try2-netns/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
19633 --- linux-2.6.22-try2/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c    2007-12-19 13:37:58.000000000 -0500
19634 +++ linux-2.6.22-try2-netns/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c      2007-12-19 22:49:20.000000000 -0500
19635 @@ -167,6 +167,10 @@
19636         unsigned char pnum = ipv6_hdr(*pskb)->nexthdr;
19637  
19638  
19639 +       /* Only filter packets in the initial network namespace */
19640 +       if ((in?in:out)->nd_net != &init_net)
19641 +               return NF_ACCEPT;
19642 +
19643         /* This is where we call the helper: as the packet goes out. */
19644         ct = nf_ct_get(*pskb, &ctinfo);
19645         if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)
19646 @@ -203,6 +207,10 @@
19647  {
19648         struct sk_buff *reasm;
19649  
19650 +       /* Only filter packets in the initial network namespace */
19651 +       if ((in?in:out)->nd_net != &init_net)
19652 +               return NF_ACCEPT;
19653 +
19654         /* Previously seen (loopback)?  */
19655         if ((*pskb)->nfct)
19656                 return NF_ACCEPT;
19657 @@ -231,6 +239,10 @@
19658  {
19659         struct sk_buff *reasm = (*pskb)->nfct_reasm;
19660  
19661 +       /* Only filter packets in the initial network namespace */
19662 +       if ((in?in:out)->nd_net != &init_net)
19663 +               return NF_ACCEPT;
19664 +
19665         /* This packet is fragmented and has reassembled packet. */
19666         if (reasm) {
19667                 /* Reassembled packet isn't parsed yet ? */
19668 @@ -256,6 +268,10 @@
19669                                          const struct net_device *out,
19670                                          int (*okfn)(struct sk_buff *))
19671  {
19672 +       /* Only filter packets in the initial network namespace */
19673 +       if ((in?in:out)->nd_net != &init_net)
19674 +               return NF_ACCEPT;
19675 +
19676         /* root is playing with raw sockets. */
19677         if ((*pskb)->len < sizeof(struct ipv6hdr)) {
19678                 if (net_ratelimit())
19679 diff -Nurb linux-2.6.22-try2/net/ipv6/netfilter.c linux-2.6.22-try2-netns/net/ipv6/netfilter.c
19680 --- linux-2.6.22-try2/net/ipv6/netfilter.c      2007-12-19 13:37:58.000000000 -0500
19681 +++ linux-2.6.22-try2-netns/net/ipv6/netfilter.c        2007-12-19 22:49:20.000000000 -0500
19682 @@ -14,6 +14,7 @@
19683         struct ipv6hdr *iph = ipv6_hdr(skb);
19684         struct dst_entry *dst;
19685         struct flowi fl = {
19686 +               .fl_net = &init_net,
19687                 .oif = skb->sk ? skb->sk->sk_bound_dev_if : 0,
19688                 .mark = skb->mark,
19689                 .nl_u =
19690 diff -Nurb linux-2.6.22-try2/net/ipv6/proc.c linux-2.6.22-try2-netns/net/ipv6/proc.c
19691 --- linux-2.6.22-try2/net/ipv6/proc.c   2007-12-19 13:37:58.000000000 -0500
19692 +++ linux-2.6.22-try2-netns/net/ipv6/proc.c     2007-12-19 22:49:20.000000000 -0500
19693 @@ -28,6 +28,7 @@
19694  #include <net/tcp.h>
19695  #include <net/transp_v6.h>
19696  #include <net/ipv6.h>
19697 +#include <net/net_namespace.h>
19698  
19699  static struct proc_dir_entry *proc_net_devsnmp6;
19700  
19701 @@ -231,22 +232,22 @@
19702  {
19703         int rc = 0;
19704  
19705 -       if (!proc_net_fops_create("snmp6", S_IRUGO, &snmp6_seq_fops))
19706 +       if (!proc_net_fops_create(&init_net, "snmp6", S_IRUGO, &snmp6_seq_fops))
19707                 goto proc_snmp6_fail;
19708  
19709 -       proc_net_devsnmp6 = proc_mkdir("dev_snmp6", proc_net);
19710 +       proc_net_devsnmp6 = proc_mkdir("dev_snmp6", init_net.proc_net);
19711         if (!proc_net_devsnmp6)
19712                 goto proc_dev_snmp6_fail;
19713  
19714 -       if (!proc_net_fops_create("sockstat6", S_IRUGO, &sockstat6_seq_fops))
19715 +       if (!proc_net_fops_create(&init_net, "sockstat6", S_IRUGO, &sockstat6_seq_fops))
19716                 goto proc_sockstat6_fail;
19717  out:
19718         return rc;
19719  
19720  proc_sockstat6_fail:
19721 -       proc_net_remove("dev_snmp6");
19722 +       proc_net_remove(&init_net, "dev_snmp6");
19723  proc_dev_snmp6_fail:
19724 -       proc_net_remove("snmp6");
19725 +       proc_net_remove(&init_net, "snmp6");
19726  proc_snmp6_fail:
19727         rc = -ENOMEM;
19728         goto out;
19729 @@ -254,8 +255,8 @@
19730  
19731  void ipv6_misc_proc_exit(void)
19732  {
19733 -       proc_net_remove("sockstat6");
19734 -       proc_net_remove("dev_snmp6");
19735 -       proc_net_remove("snmp6");
19736 +       proc_net_remove(&init_net, "sockstat6");
19737 +       proc_net_remove(&init_net, "dev_snmp6");
19738 +       proc_net_remove(&init_net, "snmp6");
19739  }
19740  
19741 diff -Nurb linux-2.6.22-try2/net/ipv6/raw.c linux-2.6.22-try2-netns/net/ipv6/raw.c
19742 --- linux-2.6.22-try2/net/ipv6/raw.c    2007-12-19 15:29:23.000000000 -0500
19743 +++ linux-2.6.22-try2-netns/net/ipv6/raw.c      2007-12-19 22:49:20.000000000 -0500
19744 @@ -49,6 +49,7 @@
19745  #include <net/udp.h>
19746  #include <net/inet_common.h>
19747  #include <net/tcp_states.h>
19748 +#include <net/net_namespace.h>
19749  #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
19750  #include <net/mip6.h>
19751  #endif
19752 @@ -282,7 +283,7 @@
19753                         if (!sk->sk_bound_dev_if)
19754                                 goto out;
19755  
19756 -                       dev = dev_get_by_index(sk->sk_bound_dev_if);
19757 +                       dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if);
19758                         if (!dev) {
19759                                 err = -ENODEV;
19760                                 goto out;
19761 @@ -728,6 +729,7 @@
19762          *      Get and verify the address.
19763          */
19764         memset(&fl, 0, sizeof(fl));
19765 +       fl.fl_net = &init_net;
19766  
19767         if (sin6) {
19768                 if (addr_len < SIN6_LEN_RFC2133)
19769 @@ -1315,13 +1317,13 @@
19770  
19771  int __init raw6_proc_init(void)
19772  {
19773 -       if (!proc_net_fops_create("raw6", S_IRUGO, &raw6_seq_fops))
19774 +       if (!proc_net_fops_create(&init_net, "raw6", S_IRUGO, &raw6_seq_fops))
19775                 return -ENOMEM;
19776         return 0;
19777  }
19778  
19779  void raw6_proc_exit(void)
19780  {
19781 -       proc_net_remove("raw6");
19782 +       proc_net_remove(&init_net, "raw6");
19783  }
19784  #endif /* CONFIG_PROC_FS */
19785 diff -Nurb linux-2.6.22-try2/net/ipv6/reassembly.c linux-2.6.22-try2-netns/net/ipv6/reassembly.c
19786 --- linux-2.6.22-try2/net/ipv6/reassembly.c     2007-12-19 13:37:58.000000000 -0500
19787 +++ linux-2.6.22-try2-netns/net/ipv6/reassembly.c       2007-12-19 22:49:20.000000000 -0500
19788 @@ -301,7 +301,7 @@
19789  
19790         fq_kill(fq);
19791  
19792 -       dev = dev_get_by_index(fq->iif);
19793 +       dev = dev_get_by_index(&init_net, fq->iif);
19794         if (!dev)
19795                 goto out;
19796  
19797 diff -Nurb linux-2.6.22-try2/net/ipv6/route.c linux-2.6.22-try2-netns/net/ipv6/route.c
19798 --- linux-2.6.22-try2/net/ipv6/route.c  2007-12-19 13:37:58.000000000 -0500
19799 +++ linux-2.6.22-try2-netns/net/ipv6/route.c    2007-12-19 22:49:20.000000000 -0500
19800 @@ -56,6 +56,7 @@
19801  #include <net/xfrm.h>
19802  #include <net/netevent.h>
19803  #include <net/netlink.h>
19804 +#include <net/net_namespace.h>
19805  
19806  #include <asm/uaccess.h>
19807  
19808 @@ -137,7 +138,7 @@
19809                 .dst = {
19810                         .__refcnt       = ATOMIC_INIT(1),
19811                         .__use          = 1,
19812 -                       .dev            = &loopback_dev,
19813 +                       .dev            = NULL,
19814                         .obsolete       = -1,
19815                         .error          = -ENETUNREACH,
19816                         .metrics        = { [RTAX_HOPLIMIT - 1] = 255, },
19817 @@ -163,7 +164,7 @@
19818                 .dst = {
19819                         .__refcnt       = ATOMIC_INIT(1),
19820                         .__use          = 1,
19821 -                       .dev            = &loopback_dev,
19822 +                       .dev            = NULL,
19823                         .obsolete       = -1,
19824                         .error          = -EACCES,
19825                         .metrics        = { [RTAX_HOPLIMIT - 1] = 255, },
19826 @@ -183,7 +184,7 @@
19827                 .dst = {
19828                         .__refcnt       = ATOMIC_INIT(1),
19829                         .__use          = 1,
19830 -                       .dev            = &loopback_dev,
19831 +                       .dev            = NULL,
19832                         .obsolete       = -1,
19833                         .error          = -EINVAL,
19834                         .metrics        = { [RTAX_HOPLIMIT - 1] = 255, },
19835 @@ -223,8 +224,8 @@
19836         struct rt6_info *rt = (struct rt6_info *)dst;
19837         struct inet6_dev *idev = rt->rt6i_idev;
19838  
19839 -       if (dev != &loopback_dev && idev != NULL && idev->dev == dev) {
19840 -               struct inet6_dev *loopback_idev = in6_dev_get(&loopback_dev);
19841 +       if (dev != &init_net.loopback_dev && idev != NULL && idev->dev == dev) {
19842 +               struct inet6_dev *loopback_idev = in6_dev_get(&init_net.loopback_dev);
19843                 if (loopback_idev != NULL) {
19844                         rt->rt6i_idev = loopback_idev;
19845                         in6_dev_put(idev);
19846 @@ -564,6 +565,7 @@
19847                             int oif, int strict)
19848  {
19849         struct flowi fl = {
19850 +               .fl_net = &init_net,
19851                 .oif = oif,
19852                 .nl_u = {
19853                         .ip6_u = {
19854 @@ -611,7 +613,12 @@
19855  
19856  int ip6_ins_rt(struct rt6_info *rt)
19857  {
19858 -       return __ip6_ins_rt(rt, NULL);
19859 +       struct nl_info info = {
19860 +               .nlh = NULL,
19861 +               .pid = 0,
19862 +               .net = &init_net,
19863 +       };
19864 +       return __ip6_ins_rt(rt, &info);
19865  }
19866  
19867  static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *daddr,
19868 @@ -742,6 +749,7 @@
19869         struct ipv6hdr *iph = ipv6_hdr(skb);
19870         int flags = RT6_LOOKUP_F_HAS_SADDR;
19871         struct flowi fl = {
19872 +               .fl_net = &init_net,
19873                 .iif = skb->dev->ifindex,
19874                 .nl_u = {
19875                         .ip6_u = {
19876 @@ -1129,7 +1137,7 @@
19877  #endif
19878         if (cfg->fc_ifindex) {
19879                 err = -ENODEV;
19880 -               dev = dev_get_by_index(cfg->fc_ifindex);
19881 +               dev = dev_get_by_index(&init_net, cfg->fc_ifindex);
19882                 if (!dev)
19883                         goto out;
19884                 idev = in6_dev_get(dev);
19885 @@ -1187,12 +1195,12 @@
19886         if ((cfg->fc_flags & RTF_REJECT) ||
19887             (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) {
19888                 /* hold loopback dev/idev if we haven't done so. */
19889 -               if (dev != &loopback_dev) {
19890 +               if (dev != &init_net.loopback_dev) {
19891                         if (dev) {
19892                                 dev_put(dev);
19893                                 in6_dev_put(idev);
19894                         }
19895 -                       dev = &loopback_dev;
19896 +                       dev = &init_net.loopback_dev;
19897                         dev_hold(dev);
19898                         idev = in6_dev_get(dev);
19899                         if (!idev) {
19900 @@ -1333,7 +1341,12 @@
19901  
19902  int ip6_del_rt(struct rt6_info *rt)
19903  {
19904 -       return __ip6_del_rt(rt, NULL);
19905 +       struct nl_info info = {
19906 +               .nlh = NULL,
19907 +               .pid = 0,
19908 +               .net = &init_net,
19909 +       };
19910 +       return __ip6_del_rt(rt, &info);
19911  }
19912  
19913  static int ip6_route_del(struct fib6_config *cfg)
19914 @@ -1444,6 +1457,7 @@
19915         int flags = RT6_LOOKUP_F_HAS_SADDR;
19916         struct ip6rd_flowi rdfl = {
19917                 .fl = {
19918 +                       .fl_net = &init_net,
19919                         .oif = dev->ifindex,
19920                         .nl_u = {
19921                                 .ip6_u = {
19922 @@ -1896,13 +1910,13 @@
19923         if (rt == NULL)
19924                 return ERR_PTR(-ENOMEM);
19925  
19926 -       dev_hold(&loopback_dev);
19927 +       dev_hold(&init_net.loopback_dev);
19928         in6_dev_hold(idev);
19929  
19930         rt->u.dst.flags = DST_HOST;
19931         rt->u.dst.input = ip6_input;
19932         rt->u.dst.output = ip6_output;
19933 -       rt->rt6i_dev = &loopback_dev;
19934 +       rt->rt6i_dev = &init_net.loopback_dev;
19935         rt->rt6i_idev = idev;
19936         rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev);
19937         rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst));
19938 @@ -2033,6 +2047,7 @@
19939  
19940         cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
19941         cfg->fc_nlinfo.nlh = nlh;
19942 +       cfg->fc_nlinfo.net = skb->sk->sk_net;
19943  
19944         if (tb[RTA_GATEWAY]) {
19945                 nla_memcpy(&cfg->fc_gateway, tb[RTA_GATEWAY], 16);
19946 @@ -2078,9 +2093,13 @@
19947  
19948  static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
19949  {
19950 +       struct net *net = skb->sk->sk_net;
19951         struct fib6_config cfg;
19952         int err;
19953  
19954 +       if (net != &init_net)
19955 +               return -EINVAL;
19956 +
19957         err = rtm_to_fib6_config(skb, nlh, &cfg);
19958         if (err < 0)
19959                 return err;
19960 @@ -2090,9 +2109,13 @@
19961  
19962  static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
19963  {
19964 +       struct net *net = skb->sk->sk_net;
19965         struct fib6_config cfg;
19966         int err;
19967  
19968 +       if (net != &init_net)
19969 +               return -EINVAL;
19970 +
19971         err = rtm_to_fib6_config(skb, nlh, &cfg);
19972         if (err < 0)
19973                 return err;
19974 @@ -2227,6 +2250,7 @@
19975  
19976  static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
19977  {
19978 +       struct net *net = in_skb->sk->sk_net;
19979         struct nlattr *tb[RTA_MAX+1];
19980         struct rt6_info *rt;
19981         struct sk_buff *skb;
19982 @@ -2234,12 +2258,16 @@
19983         struct flowi fl;
19984         int err, iif = 0;
19985  
19986 +       if (net != &init_net)
19987 +               return -EINVAL;
19988 +
19989         err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
19990         if (err < 0)
19991                 goto errout;
19992  
19993         err = -EINVAL;
19994         memset(&fl, 0, sizeof(fl));
19995 +       fl.fl_net = &init_net;
19996  
19997         if (tb[RTA_SRC]) {
19998                 if (nla_len(tb[RTA_SRC]) < sizeof(struct in6_addr))
19999 @@ -2263,7 +2291,7 @@
20000  
20001         if (iif) {
20002                 struct net_device *dev;
20003 -               dev = __dev_get_by_index(iif);
20004 +               dev = __dev_get_by_index(&init_net, iif);
20005                 if (!dev) {
20006                         err = -ENODEV;
20007                         goto errout;
20008 @@ -2293,7 +2321,7 @@
20009                 goto errout;
20010         }
20011  
20012 -       err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
20013 +       err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
20014  errout:
20015         return err;
20016  }
20017 @@ -2301,17 +2329,10 @@
20018  void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
20019  {
20020         struct sk_buff *skb;
20021 -       u32 pid = 0, seq = 0;
20022 -       struct nlmsghdr *nlh = NULL;
20023 +       u32 pid = info->pid, seq = info->nlh ? info->nlh->nlmsg_seq : 0;
20024 +       struct nlmsghdr *nlh = info->nlh;
20025         int err = -ENOBUFS;
20026  
20027 -       if (info) {
20028 -               pid = info->pid;
20029 -               nlh = info->nlh;
20030 -               if (nlh)
20031 -                       seq = nlh->nlmsg_seq;
20032 -       }
20033 -
20034         skb = nlmsg_new(rt6_nlmsg_size(), gfp_any());
20035         if (skb == NULL)
20036                 goto errout;
20037 @@ -2323,10 +2344,10 @@
20038                 kfree_skb(skb);
20039                 goto errout;
20040         }
20041 -       err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any());
20042 +       err = rtnl_notify(skb, &init_net, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any());
20043  errout:
20044         if (err < 0)
20045 -               rtnl_set_sk_err(RTNLGRP_IPV6_ROUTE, err);
20046 +               rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_ROUTE, err);
20047  }
20048  
20049  /*
20050 @@ -2558,13 +2579,19 @@
20051                                   SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
20052         ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops.kmem_cachep;
20053  
20054 +       /* Perform the initialization we can't perform at compile time */
20055 +       ip6_null_entry.u.dst.dev = &init_net.loopback_dev;
20056 +#ifdef CONFIG_IPV6_MULTIPLE_TABLES
20057 +       ip6_prohibit_entry.u.dst.dev = &init_net.loopback_dev;
20058 +       ip6_blk_hole_entry.u.dst.dev = &init_net.loopback_dev;
20059 +#endif 
20060         fib6_init();
20061  #ifdef         CONFIG_PROC_FS
20062 -       p = proc_net_create("ipv6_route", 0, rt6_proc_info);
20063 +       p = proc_net_create(&init_net, "ipv6_route", 0, rt6_proc_info);
20064         if (p)
20065                 p->owner = THIS_MODULE;
20066  
20067 -       proc_net_fops_create("rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
20068 +       proc_net_fops_create(&init_net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
20069  #endif
20070  #ifdef CONFIG_XFRM
20071         xfrm6_init();
20072 @@ -2584,8 +2611,8 @@
20073         fib6_rules_cleanup();
20074  #endif
20075  #ifdef CONFIG_PROC_FS
20076 -       proc_net_remove("ipv6_route");
20077 -       proc_net_remove("rt6_stats");
20078 +       proc_net_remove(&init_net, "ipv6_route");
20079 +       proc_net_remove(&init_net, "rt6_stats");
20080  #endif
20081  #ifdef CONFIG_XFRM
20082         xfrm6_fini();
20083 diff -Nurb linux-2.6.22-try2/net/ipv6/sit.c linux-2.6.22-try2-netns/net/ipv6/sit.c
20084 --- linux-2.6.22-try2/net/ipv6/sit.c    2007-12-19 13:37:58.000000000 -0500
20085 +++ linux-2.6.22-try2-netns/net/ipv6/sit.c      2007-12-19 22:49:20.000000000 -0500
20086 @@ -167,7 +167,7 @@
20087                 int i;
20088                 for (i=1; i<100; i++) {
20089                         sprintf(name, "sit%d", i);
20090 -                       if (__dev_get_by_name(name) == NULL)
20091 +                       if (__dev_get_by_name(&init_net, name) == NULL)
20092                                 break;
20093                 }
20094                 if (i==100)
20095 @@ -283,6 +283,9 @@
20096         struct sk_buff *skb2;
20097         struct rt6_info *rt6i;
20098  
20099 +       if (skb->dev->nd_net != &init_net)
20100 +               return;
20101 +
20102         if (len < hlen + sizeof(struct ipv6hdr))
20103                 return;
20104         iph6 = (struct ipv6hdr*)(dp + hlen);
20105 @@ -369,6 +372,10 @@
20106         struct iphdr *iph;
20107         struct ip_tunnel *tunnel;
20108  
20109 +       if (skb->dev->nd_net != &init_net) {
20110 +               kfree_skb(skb);
20111 +               return 0;
20112 +       }
20113         if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
20114                 goto out;
20115  
20116 @@ -474,7 +481,8 @@
20117         }
20118  
20119         {
20120 -               struct flowi fl = { .nl_u = { .ip4_u =
20121 +               struct flowi fl = { .fl_net = &init_net,
20122 +                                   .nl_u = { .ip4_u =
20123                                               { .daddr = dst,
20124                                                 .saddr = tiph->saddr,
20125                                                 .tos = RT_TOS(tos) } },
20126 @@ -745,7 +753,8 @@
20127         memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
20128  
20129         if (iph->daddr) {
20130 -               struct flowi fl = { .nl_u = { .ip4_u =
20131 +               struct flowi fl = { .fl_net = &init_net,
20132 +                                   .nl_u = { .ip4_u =
20133                                               { .daddr = iph->daddr,
20134                                                 .saddr = iph->saddr,
20135                                                 .tos = RT_TOS(iph->tos) } },
20136 @@ -760,7 +769,7 @@
20137         }
20138  
20139         if (!tdev && tunnel->parms.link)
20140 -               tdev = __dev_get_by_index(tunnel->parms.link);
20141 +               tdev = __dev_get_by_index(&init_net, tunnel->parms.link);
20142  
20143         if (tdev) {
20144                 dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
20145 diff -Nurb linux-2.6.22-try2/net/ipv6/tcp_ipv6.c linux-2.6.22-try2-netns/net/ipv6/tcp_ipv6.c
20146 --- linux-2.6.22-try2/net/ipv6/tcp_ipv6.c       2007-12-19 13:37:58.000000000 -0500
20147 +++ linux-2.6.22-try2-netns/net/ipv6/tcp_ipv6.c 2007-12-19 22:49:20.000000000 -0500
20148 @@ -143,6 +143,7 @@
20149                 return(-EAFNOSUPPORT);
20150  
20151         memset(&fl, 0, sizeof(fl));
20152 +       fl.fl_net = &init_net;
20153  
20154         if (np->sndflow) {
20155                 fl.fl6_flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK;
20156 @@ -330,6 +331,7 @@
20157  static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
20158                 int type, int code, int offset, __be32 info)
20159  {
20160 +       struct net *net = skb->dev->nd_net;
20161         struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
20162         const struct tcphdr *th = (struct tcphdr *)(skb->data+offset);
20163         struct ipv6_pinfo *np;
20164 @@ -339,7 +341,7 @@
20165         __u32 seq;
20166  
20167         sk = inet6_lookup(&tcp_hashinfo, &hdr->daddr, th->dest, &hdr->saddr,
20168 -                         th->source, skb->dev->ifindex);
20169 +                         th->source, skb->dev->ifindex, net);
20170  
20171         if (sk == NULL) {
20172                 ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
20173 @@ -388,6 +390,7 @@
20174                            for now.
20175                          */
20176                         memset(&fl, 0, sizeof(fl));
20177 +                       fl.fl_net = &init_net;
20178                         fl.proto = IPPROTO_TCP;
20179                         ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
20180                         ipv6_addr_copy(&fl.fl6_src, &np->saddr);
20181 @@ -481,6 +484,7 @@
20182         int err = -1;
20183  
20184         memset(&fl, 0, sizeof(fl));
20185 +       fl.fl_net = &init_net;
20186         fl.proto = IPPROTO_TCP;
20187         ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr);
20188         ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);
20189 @@ -1066,6 +1070,7 @@
20190         buff->csum = csum_partial((char *)t1, sizeof(*t1), 0);
20191  
20192         memset(&fl, 0, sizeof(fl));
20193 +       fl.fl_net = &init_net;
20194         ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr);
20195         ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr);
20196  
20197 @@ -1167,6 +1172,7 @@
20198         buff->csum = csum_partial((char *)t1, tot_len, 0);
20199  
20200         memset(&fl, 0, sizeof(fl));
20201 +       fl.fl_net = &init_net;
20202         ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr);
20203         ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr);
20204  
20205 @@ -1224,7 +1230,8 @@
20206  
20207         nsk = __inet6_lookup_established(&tcp_hashinfo, &ipv6_hdr(skb)->saddr,
20208                                          th->source, &ipv6_hdr(skb)->daddr,
20209 -                                        ntohs(th->dest), inet6_iif(skb));
20210 +                                        ntohs(th->dest), inet6_iif(skb),
20211 +                                        sk->sk_net);
20212  
20213         if (nsk) {
20214                 if (nsk->sk_state != TCP_TIME_WAIT) {
20215 @@ -1414,6 +1421,7 @@
20216                 struct flowi fl;
20217  
20218                 memset(&fl, 0, sizeof(fl));
20219 +               fl.fl_net = &init_net;
20220                 fl.proto = IPPROTO_TCP;
20221                 ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr);
20222                 if (opt && opt->srcrt) {
20223 @@ -1700,6 +1708,7 @@
20224  static int tcp_v6_rcv(struct sk_buff **pskb)
20225  {
20226         struct sk_buff *skb = *pskb;
20227 +       struct net *net = skb->dev->nd_net;
20228         struct tcphdr *th;
20229         struct sock *sk;
20230         int ret;
20231 @@ -1736,7 +1745,7 @@
20232  
20233         sk = __inet6_lookup(&tcp_hashinfo, &ipv6_hdr(skb)->saddr, th->source,
20234                             &ipv6_hdr(skb)->daddr, ntohs(th->dest),
20235 -                           inet6_iif(skb));
20236 +                           inet6_iif(skb), net);
20237  
20238         if (!sk)
20239                 goto no_tcp_socket;
20240 @@ -1816,7 +1825,8 @@
20241  
20242                 sk2 = inet6_lookup_listener(&tcp_hashinfo,
20243                                             &ipv6_hdr(skb)->daddr,
20244 -                                           ntohs(th->dest), inet6_iif(skb));
20245 +                                           ntohs(th->dest), inet6_iif(skb),
20246 +                                           net);
20247                 if (sk2 != NULL) {
20248                         struct inet_timewait_sock *tw = inet_twsk(sk);
20249                         inet_twsk_deschedule(tw, &tcp_death_row);
20250 @@ -2121,12 +2131,12 @@
20251  
20252  int __init tcp6_proc_init(void)
20253  {
20254 -       return tcp_proc_register(&tcp6_seq_afinfo);
20255 +       return tcp_proc_register(&init_net, &tcp6_seq_afinfo);
20256  }
20257  
20258  void tcp6_proc_exit(void)
20259  {
20260 -       tcp_proc_unregister(&tcp6_seq_afinfo);
20261 +       tcp_proc_unregister(&init_net, &tcp6_seq_afinfo);
20262  }
20263  #endif
20264  
20265 diff -Nurb linux-2.6.22-try2/net/ipv6/udp.c linux-2.6.22-try2-netns/net/ipv6/udp.c
20266 --- linux-2.6.22-try2/net/ipv6/udp.c    2007-12-19 13:37:58.000000000 -0500
20267 +++ linux-2.6.22-try2-netns/net/ipv6/udp.c      2007-12-19 22:49:20.000000000 -0500
20268 @@ -657,6 +657,7 @@
20269         ulen += sizeof(struct udphdr);
20270  
20271         memset(&fl, 0, sizeof(fl));
20272 +       fl.fl_net = &init_net;
20273  
20274         if (sin6) {
20275                 if (sin6->sin6_port == 0)
20276 @@ -967,11 +968,11 @@
20277  
20278  int __init udp6_proc_init(void)
20279  {
20280 -       return udp_proc_register(&udp6_seq_afinfo);
20281 +       return udp_proc_register(&init_net, &udp6_seq_afinfo);
20282  }
20283  
20284  void udp6_proc_exit(void) {
20285 -       udp_proc_unregister(&udp6_seq_afinfo);
20286 +       udp_proc_unregister(&init_net, &udp6_seq_afinfo);
20287  }
20288  #endif /* CONFIG_PROC_FS */
20289  
20290 diff -Nurb linux-2.6.22-try2/net/ipv6/udplite.c linux-2.6.22-try2-netns/net/ipv6/udplite.c
20291 --- linux-2.6.22-try2/net/ipv6/udplite.c        2007-12-19 13:37:58.000000000 -0500
20292 +++ linux-2.6.22-try2-netns/net/ipv6/udplite.c  2007-12-19 22:49:20.000000000 -0500
20293 @@ -95,11 +95,11 @@
20294  
20295  int __init udplite6_proc_init(void)
20296  {
20297 -       return udp_proc_register(&udplite6_seq_afinfo);
20298 +       return udp_proc_register(&init_net, &udplite6_seq_afinfo);
20299  }
20300  
20301  void udplite6_proc_exit(void)
20302  {
20303 -       udp_proc_unregister(&udplite6_seq_afinfo);
20304 +       udp_proc_unregister(&init_net, &udplite6_seq_afinfo);
20305  }
20306  #endif
20307 diff -Nurb linux-2.6.22-try2/net/ipv6/xfrm6_policy.c linux-2.6.22-try2-netns/net/ipv6/xfrm6_policy.c
20308 --- linux-2.6.22-try2/net/ipv6/xfrm6_policy.c   2007-12-19 15:29:23.000000000 -0500
20309 +++ linux-2.6.22-try2-netns/net/ipv6/xfrm6_policy.c     2007-12-19 22:49:20.000000000 -0500
20310 @@ -40,6 +40,7 @@
20311  {
20312         struct rt6_info *rt;
20313         struct flowi fl_tunnel = {
20314 +               .fl_net = &init_net,
20315                 .nl_u = {
20316                         .ip6_u = {
20317                                 .daddr = *(struct in6_addr *)&daddr->a6,
20318 @@ -132,6 +133,7 @@
20319         struct rt6_info *rt0 = (struct rt6_info*)(*dst_p);
20320         struct rt6_info *rt  = rt0;
20321         struct flowi fl_tunnel = {
20322 +               .fl_net = &init_net,
20323                 .nl_u = {
20324                         .ip6_u = {
20325                                 .saddr = fl->fl6_src,
20326 @@ -278,6 +280,7 @@
20327         u8 nexthdr = nh[IP6CB(skb)->nhoff];
20328  
20329         memset(fl, 0, sizeof(struct flowi));
20330 +       fl->fl_net = &init_net;
20331         ipv6_addr_copy(&fl->fl6_dst, &hdr->daddr);
20332         ipv6_addr_copy(&fl->fl6_src, &hdr->saddr);
20333  
20334 @@ -375,7 +378,7 @@
20335  
20336         xdst = (struct xfrm_dst *)dst;
20337         if (xdst->u.rt6.rt6i_idev->dev == dev) {
20338 -               struct inet6_dev *loopback_idev = in6_dev_get(&loopback_dev);
20339 +               struct inet6_dev *loopback_idev = in6_dev_get(&init_net.loopback_dev);
20340                 BUG_ON(!loopback_idev);
20341  
20342                 do {
20343 diff -Nurb linux-2.6.22-try2/net/ipx/af_ipx.c linux-2.6.22-try2-netns/net/ipx/af_ipx.c
20344 --- linux-2.6.22-try2/net/ipx/af_ipx.c  2007-12-19 13:37:58.000000000 -0500
20345 +++ linux-2.6.22-try2-netns/net/ipx/af_ipx.c    2007-12-19 22:49:20.000000000 -0500
20346 @@ -347,6 +347,9 @@
20347         struct net_device *dev = ptr;
20348         struct ipx_interface *i, *tmp;
20349  
20350 +       if (dev->nd_net != &init_net)
20351 +               return NOTIFY_DONE;
20352 +
20353         if (event != NETDEV_DOWN && event != NETDEV_UP)
20354                 goto out;
20355  
20356 @@ -986,7 +989,7 @@
20357         if (intrfc)
20358                 ipxitf_put(intrfc);
20359  
20360 -       dev = dev_get_by_name(idef->ipx_device);
20361 +       dev = dev_get_by_name(&init_net, idef->ipx_device);
20362         rc = -ENODEV;
20363         if (!dev)
20364                 goto out;
20365 @@ -1094,7 +1097,7 @@
20366         if (!dlink_type)
20367                 goto out;
20368  
20369 -       dev = __dev_get_by_name(idef->ipx_device);
20370 +       dev = __dev_get_by_name(&init_net, idef->ipx_device);
20371         rc = -ENODEV;
20372         if (!dev)
20373                 goto out;
20374 @@ -1189,7 +1192,7 @@
20375                 if (copy_from_user(&ifr, arg, sizeof(ifr)))
20376                         break;
20377                 sipx = (struct sockaddr_ipx *)&ifr.ifr_addr;
20378 -               dev  = __dev_get_by_name(ifr.ifr_name);
20379 +               dev  = __dev_get_by_name(&init_net, ifr.ifr_name);
20380                 rc   = -ENODEV;
20381                 if (!dev)
20382                         break;
20383 @@ -1360,11 +1363,14 @@
20384         .obj_size = sizeof(struct ipx_sock),
20385  };
20386  
20387 -static int ipx_create(struct socket *sock, int protocol)
20388 +static int ipx_create(struct net *net, struct socket *sock, int protocol)
20389  {
20390         int rc = -ESOCKTNOSUPPORT;
20391         struct sock *sk;
20392  
20393 +       if (net != &init_net)
20394 +               return -EAFNOSUPPORT;
20395 +
20396         /*
20397          * SPX support is not anymore in the kernel sources. If you want to
20398          * ressurrect it, completing it and making it understand shared skbs,
20399 @@ -1375,7 +1381,7 @@
20400                 goto out;
20401  
20402         rc = -ENOMEM;
20403 -       sk = sk_alloc(PF_IPX, GFP_KERNEL, &ipx_proto, 1);
20404 +       sk = sk_alloc(net, PF_IPX, GFP_KERNEL, &ipx_proto, 1);
20405         if (!sk)
20406                 goto out;
20407  #ifdef IPX_REFCNT_DEBUG
20408 @@ -1644,6 +1650,9 @@
20409         u16 ipx_pktsize;
20410         int rc = 0;
20411  
20412 +       if (dev->nd_net != &init_net)
20413 +               goto drop;
20414 +
20415         /* Not ours */
20416         if (skb->pkt_type == PACKET_OTHERHOST)
20417                 goto drop;
20418 diff -Nurb linux-2.6.22-try2/net/ipx/ipx_proc.c linux-2.6.22-try2-netns/net/ipx/ipx_proc.c
20419 --- linux-2.6.22-try2/net/ipx/ipx_proc.c        2007-12-19 13:37:58.000000000 -0500
20420 +++ linux-2.6.22-try2-netns/net/ipx/ipx_proc.c  2007-12-19 22:49:20.000000000 -0500
20421 @@ -9,6 +9,7 @@
20422  #include <linux/proc_fs.h>
20423  #include <linux/spinlock.h>
20424  #include <linux/seq_file.h>
20425 +#include <net/net_namespace.h>
20426  #include <net/tcp_states.h>
20427  #include <net/ipx.h>
20428  
20429 @@ -353,7 +354,7 @@
20430         struct proc_dir_entry *p;
20431         int rc = -ENOMEM;
20432  
20433 -       ipx_proc_dir = proc_mkdir("ipx", proc_net);
20434 +       ipx_proc_dir = proc_mkdir("ipx", init_net.proc_net);
20435  
20436         if (!ipx_proc_dir)
20437                 goto out;
20438 @@ -381,7 +382,7 @@
20439  out_route:
20440         remove_proc_entry("interface", ipx_proc_dir);
20441  out_interface:
20442 -       remove_proc_entry("ipx", proc_net);
20443 +       remove_proc_entry("ipx", init_net.proc_net);
20444         goto out;
20445  }
20446  
20447 @@ -390,7 +391,7 @@
20448         remove_proc_entry("interface", ipx_proc_dir);
20449         remove_proc_entry("route", ipx_proc_dir);
20450         remove_proc_entry("socket", ipx_proc_dir);
20451 -       remove_proc_entry("ipx", proc_net);
20452 +       remove_proc_entry("ipx", init_net.proc_net);
20453  }
20454  
20455  #else /* CONFIG_PROC_FS */
20456 diff -Nurb linux-2.6.22-try2/net/irda/af_irda.c linux-2.6.22-try2-netns/net/irda/af_irda.c
20457 --- linux-2.6.22-try2/net/irda/af_irda.c        2007-12-19 13:37:58.000000000 -0500
20458 +++ linux-2.6.22-try2-netns/net/irda/af_irda.c  2007-12-19 22:49:20.000000000 -0500
20459 @@ -60,7 +60,7 @@
20460  
20461  #include <net/irda/af_irda.h>
20462  
20463 -static int irda_create(struct socket *sock, int protocol);
20464 +static int irda_create(struct net *net, struct socket *sock, int protocol);
20465  
20466  static const struct proto_ops irda_stream_ops;
20467  static const struct proto_ops irda_seqpacket_ops;
20468 @@ -831,7 +831,7 @@
20469  
20470         IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
20471  
20472 -       err = irda_create(newsock, sk->sk_protocol);
20473 +       err = irda_create(sk->sk_net, newsock, sk->sk_protocol);
20474         if (err)
20475                 return err;
20476  
20477 @@ -1057,13 +1057,16 @@
20478   *    Create IrDA socket
20479   *
20480   */
20481 -static int irda_create(struct socket *sock, int protocol)
20482 +static int irda_create(struct net *net, struct socket *sock, int protocol)
20483  {
20484         struct sock *sk;
20485         struct irda_sock *self;
20486  
20487         IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
20488  
20489 +       if (net != &init_net)
20490 +               return -EAFNOSUPPORT;
20491 +
20492         /* Check for valid socket type */
20493         switch (sock->type) {
20494         case SOCK_STREAM:     /* For TTP connections with SAR disabled */
20495 @@ -1075,7 +1078,7 @@
20496         }
20497  
20498         /* Allocate networking socket */
20499 -       sk = sk_alloc(PF_IRDA, GFP_ATOMIC, &irda_proto, 1);
20500 +       sk = sk_alloc(net, PF_IRDA, GFP_ATOMIC, &irda_proto, 1);
20501         if (sk == NULL)
20502                 return -ENOMEM;
20503  
20504 diff -Nurb linux-2.6.22-try2/net/irda/irlap_frame.c linux-2.6.22-try2-netns/net/irda/irlap_frame.c
20505 --- linux-2.6.22-try2/net/irda/irlap_frame.c    2007-12-19 13:37:59.000000000 -0500
20506 +++ linux-2.6.22-try2-netns/net/irda/irlap_frame.c      2007-12-19 22:49:20.000000000 -0500
20507 @@ -1319,6 +1319,9 @@
20508         int command;
20509         __u8 control;
20510  
20511 +       if (dev->nd_net != &init_net)
20512 +               goto out;
20513 +
20514         /* FIXME: should we get our own field? */
20515         self = (struct irlap_cb *) dev->atalk_ptr;
20516  
20517 diff -Nurb linux-2.6.22-try2/net/irda/irproc.c linux-2.6.22-try2-netns/net/irda/irproc.c
20518 --- linux-2.6.22-try2/net/irda/irproc.c 2007-12-19 13:37:59.000000000 -0500
20519 +++ linux-2.6.22-try2-netns/net/irda/irproc.c   2007-12-19 22:49:20.000000000 -0500
20520 @@ -28,6 +28,7 @@
20521  #include <linux/seq_file.h>
20522  #include <linux/module.h>
20523  #include <linux/init.h>
20524 +#include <net/net_namespace.h>
20525  
20526  #include <net/irda/irda.h>
20527  #include <net/irda/irlap.h>
20528 @@ -66,7 +67,7 @@
20529         int i;
20530         struct proc_dir_entry *d;
20531  
20532 -       proc_irda = proc_mkdir("irda", proc_net);
20533 +       proc_irda = proc_mkdir("irda", init_net.proc_net);
20534         if (proc_irda == NULL)
20535                 return;
20536         proc_irda->owner = THIS_MODULE;
20537 @@ -92,7 +93,7 @@
20538                 for (i=0; i<ARRAY_SIZE(irda_dirs); i++)
20539                         remove_proc_entry(irda_dirs[i].name, proc_irda);
20540  
20541 -               remove_proc_entry("irda", proc_net);
20542 +               remove_proc_entry("irda", init_net.proc_net);
20543                 proc_irda = NULL;
20544         }
20545  }
20546 diff -Nurb linux-2.6.22-try2/net/key/af_key.c linux-2.6.22-try2-netns/net/key/af_key.c
20547 --- linux-2.6.22-try2/net/key/af_key.c  2007-12-19 13:37:59.000000000 -0500
20548 +++ linux-2.6.22-try2-netns/net/key/af_key.c    2007-12-19 22:49:20.000000000 -0500
20549 @@ -28,6 +28,7 @@
20550  #include <linux/init.h>
20551  #include <net/xfrm.h>
20552  #include <linux/audit.h>
20553 +#include <net/net_namespace.h>
20554  
20555  #include <net/sock.h>
20556  
20557 @@ -136,11 +137,14 @@
20558         .obj_size = sizeof(struct pfkey_sock),
20559  };
20560  
20561 -static int pfkey_create(struct socket *sock, int protocol)
20562 +static int pfkey_create(struct net *net, struct socket *sock, int protocol)
20563  {
20564         struct sock *sk;
20565         int err;
20566  
20567 +       if (net != &init_net)
20568 +               return -EAFNOSUPPORT;
20569 +
20570         if (!capable(CAP_NET_ADMIN))
20571                 return -EPERM;
20572         if (sock->type != SOCK_RAW)
20573 @@ -149,7 +153,7 @@
20574                 return -EPROTONOSUPPORT;
20575  
20576         err = -ENOMEM;
20577 -       sk = sk_alloc(PF_KEY, GFP_KERNEL, &key_proto, 1);
20578 +       sk = sk_alloc(net, PF_KEY, GFP_KERNEL, &key_proto, 1);
20579         if (sk == NULL)
20580                 goto out;
20581  
20582 @@ -3781,7 +3785,7 @@
20583  static void __exit ipsec_pfkey_exit(void)
20584  {
20585         xfrm_unregister_km(&pfkeyv2_mgr);
20586 -       remove_proc_entry("net/pfkey", NULL);
20587 +       remove_proc_entry("pfkey", init_net.proc_net);
20588         sock_unregister(PF_KEY);
20589         proto_unregister(&key_proto);
20590  }
20591 @@ -3798,7 +3802,7 @@
20592                 goto out_unregister_key_proto;
20593  #ifdef CONFIG_PROC_FS
20594         err = -ENOMEM;
20595 -       if (create_proc_read_entry("net/pfkey", 0, NULL, pfkey_read_proc, NULL) == NULL)
20596 +       if (create_proc_read_entry("pfkey", 0, init_net.proc_net, pfkey_read_proc, NULL) == NULL)
20597                 goto out_sock_unregister;
20598  #endif
20599         err = xfrm_register_km(&pfkeyv2_mgr);
20600 diff -Nurb linux-2.6.22-try2/net/llc/af_llc.c linux-2.6.22-try2-netns/net/llc/af_llc.c
20601 --- linux-2.6.22-try2/net/llc/af_llc.c  2007-12-19 13:37:59.000000000 -0500
20602 +++ linux-2.6.22-try2-netns/net/llc/af_llc.c    2007-12-19 22:49:20.000000000 -0500
20603 @@ -150,14 +150,17 @@
20604   *     socket type we have available.
20605   *     Returns 0 upon success, negative upon failure.
20606   */
20607 -static int llc_ui_create(struct socket *sock, int protocol)
20608 +static int llc_ui_create(struct net *net, struct socket *sock, int protocol)
20609  {
20610         struct sock *sk;
20611         int rc = -ESOCKTNOSUPPORT;
20612  
20613 +       if (net != &init_net)
20614 +               return -EAFNOSUPPORT;
20615 +
20616         if (likely(sock->type == SOCK_DGRAM || sock->type == SOCK_STREAM)) {
20617                 rc = -ENOMEM;
20618 -               sk = llc_sk_alloc(PF_LLC, GFP_KERNEL, &llc_proto);
20619 +               sk = llc_sk_alloc(net, PF_LLC, GFP_KERNEL, &llc_proto);
20620                 if (sk) {
20621                         rc = 0;
20622                         llc_ui_sk_init(sock, sk);
20623 @@ -249,7 +252,7 @@
20624         if (!sock_flag(sk, SOCK_ZAPPED))
20625                 goto out;
20626         rc = -ENODEV;
20627 -       llc->dev = dev_getfirstbyhwtype(addr->sllc_arphrd);
20628 +       llc->dev = dev_getfirstbyhwtype(&init_net, addr->sllc_arphrd);
20629         if (!llc->dev)
20630                 goto out;
20631         rc = -EUSERS;
20632 @@ -300,7 +303,7 @@
20633                 goto out;
20634         rc = -ENODEV;
20635         rtnl_lock();
20636 -       llc->dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_mac);
20637 +       llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd, addr->sllc_mac);
20638         rtnl_unlock();
20639         if (!llc->dev)
20640                 goto out;
20641 diff -Nurb linux-2.6.22-try2/net/llc/llc_conn.c linux-2.6.22-try2-netns/net/llc/llc_conn.c
20642 --- linux-2.6.22-try2/net/llc/llc_conn.c        2007-12-19 13:37:59.000000000 -0500
20643 +++ linux-2.6.22-try2-netns/net/llc/llc_conn.c  2007-12-19 22:49:20.000000000 -0500
20644 @@ -700,7 +700,7 @@
20645                                              struct llc_addr *saddr,
20646                                              struct llc_addr *daddr)
20647  {
20648 -       struct sock *newsk = llc_sk_alloc(sk->sk_family, GFP_ATOMIC,
20649 +       struct sock *newsk = llc_sk_alloc(sk->sk_net, sk->sk_family, GFP_ATOMIC,
20650                                           sk->sk_prot);
20651         struct llc_sock *newllc, *llc = llc_sk(sk);
20652  
20653 @@ -867,9 +867,9 @@
20654   *     Allocates a LLC sock and initializes it. Returns the new LLC sock
20655   *     or %NULL if there's no memory available for one
20656   */
20657 -struct sock *llc_sk_alloc(int family, gfp_t priority, struct proto *prot)
20658 +struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority, struct proto *prot)
20659  {
20660 -       struct sock *sk = sk_alloc(family, priority, prot, 1);
20661 +       struct sock *sk = sk_alloc(net, family, priority, prot, 1);
20662  
20663         if (!sk)
20664                 goto out;
20665 diff -Nurb linux-2.6.22-try2/net/llc/llc_core.c linux-2.6.22-try2-netns/net/llc/llc_core.c
20666 --- linux-2.6.22-try2/net/llc/llc_core.c        2007-12-19 13:37:59.000000000 -0500
20667 +++ linux-2.6.22-try2-netns/net/llc/llc_core.c  2007-12-19 22:49:20.000000000 -0500
20668 @@ -19,6 +19,7 @@
20669  #include <linux/slab.h>
20670  #include <linux/string.h>
20671  #include <linux/init.h>
20672 +#include <net/net_namespace.h>
20673  #include <net/llc.h>
20674  
20675  LIST_HEAD(llc_sap_list);
20676 @@ -162,7 +163,7 @@
20677  {
20678         struct net_device *dev;
20679  
20680 -       dev = first_net_device();
20681 +       dev = first_net_device(&init_net);
20682         if (dev != NULL)
20683                 dev = next_net_device(dev);
20684  
20685 diff -Nurb linux-2.6.22-try2/net/llc/llc_input.c linux-2.6.22-try2-netns/net/llc/llc_input.c
20686 --- linux-2.6.22-try2/net/llc/llc_input.c       2007-12-19 13:37:59.000000000 -0500
20687 +++ linux-2.6.22-try2-netns/net/llc/llc_input.c 2007-12-19 22:49:20.000000000 -0500
20688 @@ -12,6 +12,7 @@
20689   * See the GNU General Public License for more details.
20690   */
20691  #include <linux/netdevice.h>
20692 +#include <net/net_namespace.h>
20693  #include <net/llc.h>
20694  #include <net/llc_pdu.h>
20695  #include <net/llc_sap.h>
20696 @@ -145,6 +146,9 @@
20697         int (*rcv)(struct sk_buff *, struct net_device *,
20698                    struct packet_type *, struct net_device *);
20699  
20700 +       if (dev->nd_net != &init_net)
20701 +               goto drop;
20702 +
20703         /*
20704          * When the interface is in promisc. mode, drop all the crap that it
20705          * receives, do not try to analyse it.
20706 diff -Nurb linux-2.6.22-try2/net/llc/llc_proc.c linux-2.6.22-try2-netns/net/llc/llc_proc.c
20707 --- linux-2.6.22-try2/net/llc/llc_proc.c        2007-12-19 13:37:59.000000000 -0500
20708 +++ linux-2.6.22-try2-netns/net/llc/llc_proc.c  2007-12-19 22:49:20.000000000 -0500
20709 @@ -18,6 +18,7 @@
20710  #include <linux/errno.h>
20711  #include <linux/seq_file.h>
20712  #include <net/sock.h>
20713 +#include <net/net_namespace.h>
20714  #include <net/llc.h>
20715  #include <net/llc_c_ac.h>
20716  #include <net/llc_c_ev.h>
20717 @@ -231,7 +232,7 @@
20718         int rc = -ENOMEM;
20719         struct proc_dir_entry *p;
20720  
20721 -       llc_proc_dir = proc_mkdir("llc", proc_net);
20722 +       llc_proc_dir = proc_mkdir("llc", init_net.proc_net);
20723         if (!llc_proc_dir)
20724                 goto out;
20725         llc_proc_dir->owner = THIS_MODULE;
20726 @@ -254,7 +255,7 @@
20727  out_core:
20728         remove_proc_entry("socket", llc_proc_dir);
20729  out_socket:
20730 -       remove_proc_entry("llc", proc_net);
20731 +       remove_proc_entry("llc", init_net.proc_net);
20732         goto out;
20733  }
20734  
20735 @@ -262,5 +263,5 @@
20736  {
20737         remove_proc_entry("socket", llc_proc_dir);
20738         remove_proc_entry("core", llc_proc_dir);
20739 -       remove_proc_entry("llc", proc_net);
20740 +       remove_proc_entry("llc", init_net.proc_net);
20741  }
20742 diff -Nurb linux-2.6.22-try2/net/netfilter/core.c linux-2.6.22-try2-netns/net/netfilter/core.c
20743 --- linux-2.6.22-try2/net/netfilter/core.c      2007-12-19 15:29:23.000000000 -0500
20744 +++ linux-2.6.22-try2-netns/net/netfilter/core.c        2007-12-19 22:49:20.000000000 -0500
20745 @@ -20,6 +20,7 @@
20746  #include <linux/proc_fs.h>
20747  #include <linux/mutex.h>
20748  #include <net/sock.h>
20749 +#include <net/net_namespace.h>
20750  
20751  #include "nf_internals.h"
20752  
20753 @@ -280,8 +281,28 @@
20754  #endif /* CONFIG_NF_CONNTRACK */
20755  
20756  #ifdef CONFIG_PROC_FS
20757 -struct proc_dir_entry *proc_net_netfilter;
20758 -EXPORT_SYMBOL(proc_net_netfilter);
20759 +static int netfilter_proc_init(struct net * net)
20760 +{
20761 +       int error = -ENOMEM;
20762 +       net->proc_net_netfilter = proc_mkdir("netfilter", net->proc_net);
20763 +
20764 +       if (net->proc_net_netfilter) {
20765 +               net->proc_net_netfilter->data = net;
20766 +               error = 0;
20767 +       }
20768 +       return error;
20769 +}
20770 +
20771 +static void netfilter_proc_exit(struct net *net)
20772 +{
20773 +       remove_proc_entry("netfilter", net->proc_net);
20774 +}
20775 +
20776 +static struct pernet_operations netfilter_proc_ops = {
20777 +       .init = netfilter_proc_init,
20778 +       .exit = netfilter_proc_exit,
20779 +};
20780 +
20781  #endif
20782  
20783  void __init netfilter_init(void)
20784 @@ -293,8 +314,7 @@
20785         }
20786  
20787  #ifdef CONFIG_PROC_FS
20788 -       proc_net_netfilter = proc_mkdir("netfilter", proc_net);
20789 -       if (!proc_net_netfilter)
20790 +       if (register_pernet_subsys(&netfilter_proc_ops) < 0)
20791                 panic("cannot create netfilter proc entry");
20792  #endif
20793  
20794 diff -Nurb linux-2.6.22-try2/net/netfilter/nf_conntrack_h323_main.c linux-2.6.22-try2-netns/net/netfilter/nf_conntrack_h323_main.c
20795 --- linux-2.6.22-try2/net/netfilter/nf_conntrack_h323_main.c    2007-12-19 13:37:59.000000000 -0500
20796 +++ linux-2.6.22-try2-netns/net/netfilter/nf_conntrack_h323_main.c      2007-12-19 22:49:20.000000000 -0500
20797 @@ -724,6 +724,8 @@
20798  
20799         memset(&fl1, 0, sizeof(fl1));
20800         memset(&fl2, 0, sizeof(fl2));
20801 +       fl1.fl_net = &init_net;
20802 +       fl2.fl_net = &init_net;
20803  
20804         switch (family) {
20805         case AF_INET: {
20806 diff -Nurb linux-2.6.22-try2/net/netfilter/nf_conntrack_standalone.c linux-2.6.22-try2-netns/net/netfilter/nf_conntrack_standalone.c
20807 --- linux-2.6.22-try2/net/netfilter/nf_conntrack_standalone.c   2007-12-19 13:37:59.000000000 -0500
20808 +++ linux-2.6.22-try2-netns/net/netfilter/nf_conntrack_standalone.c     2007-12-19 22:49:20.000000000 -0500
20809 @@ -14,6 +14,7 @@
20810  #include <linux/seq_file.h>
20811  #include <linux/percpu.h>
20812  #include <linux/netdevice.h>
20813 +#include <net/net_namespace.h>
20814  #ifdef CONFIG_SYSCTL
20815  #include <linux/sysctl.h>
20816  #endif
20817 @@ -419,14 +420,14 @@
20818                 return ret;
20819  
20820  #ifdef CONFIG_PROC_FS
20821 -       proc = proc_net_fops_create("nf_conntrack", 0440, &ct_file_ops);
20822 +       proc = proc_net_fops_create(&init_net, "nf_conntrack", 0440, &ct_file_ops);
20823         if (!proc) goto cleanup_init;
20824  
20825 -       proc_exp = proc_net_fops_create("nf_conntrack_expect", 0440,
20826 +       proc_exp = proc_net_fops_create(&init_net, "nf_conntrack_expect", 0440,
20827                                         &exp_file_ops);
20828         if (!proc_exp) goto cleanup_proc;
20829  
20830 -       proc_stat = create_proc_entry("nf_conntrack", S_IRUGO, proc_net_stat);
20831 +       proc_stat = create_proc_entry("nf_conntrack", S_IRUGO, init_net.proc_net_stat);
20832         if (!proc_stat)
20833                 goto cleanup_proc_exp;
20834  
20835 @@ -447,11 +448,11 @@
20836   cleanup_proc_stat:
20837  #endif
20838  #ifdef CONFIG_PROC_FS
20839 -       remove_proc_entry("nf_conntrack", proc_net_stat);
20840 +       remove_proc_entry("nf_conntrack", init_net.proc_net_stat);
20841   cleanup_proc_exp:
20842 -       proc_net_remove("nf_conntrack_expect");
20843 +       proc_net_remove(&init_net, "nf_conntrack_expect");
20844   cleanup_proc:
20845 -       proc_net_remove("nf_conntrack");
20846 +       proc_net_remove(&init_net, "nf_conntrack");
20847   cleanup_init:
20848  #endif /* CNFIG_PROC_FS */
20849         nf_conntrack_cleanup();
20850 @@ -464,9 +465,9 @@
20851         unregister_sysctl_table(nf_ct_sysctl_header);
20852  #endif
20853  #ifdef CONFIG_PROC_FS
20854 -       remove_proc_entry("nf_conntrack", proc_net_stat);
20855 -       proc_net_remove("nf_conntrack_expect");
20856 -       proc_net_remove("nf_conntrack");
20857 +       remove_proc_entry("nf_conntrack", init_net.proc_net_stat);
20858 +       proc_net_remove(&init_net, "nf_conntrack_expect");
20859 +       proc_net_remove(&init_net, "nf_conntrack");
20860  #endif /* CNFIG_PROC_FS */
20861         nf_conntrack_cleanup();
20862  }
20863 diff -Nurb linux-2.6.22-try2/net/netfilter/nf_log.c linux-2.6.22-try2-netns/net/netfilter/nf_log.c
20864 --- linux-2.6.22-try2/net/netfilter/nf_log.c    2007-12-19 13:37:59.000000000 -0500
20865 +++ linux-2.6.22-try2-netns/net/netfilter/nf_log.c      2007-12-19 22:49:20.000000000 -0500
20866 @@ -168,7 +168,8 @@
20867  #ifdef CONFIG_PROC_FS
20868         struct proc_dir_entry *pde;
20869  
20870 -       pde = create_proc_entry("nf_log", S_IRUGO, proc_net_netfilter);
20871 +       pde = create_proc_entry("nf_log", S_IRUGO,
20872 +               init_net.proc_net_netfilter);
20873         if (!pde)
20874                 return -1;
20875  
20876 diff -Nurb linux-2.6.22-try2/net/netfilter/nf_queue.c linux-2.6.22-try2-netns/net/netfilter/nf_queue.c
20877 --- linux-2.6.22-try2/net/netfilter/nf_queue.c  2007-12-19 13:37:59.000000000 -0500
20878 +++ linux-2.6.22-try2-netns/net/netfilter/nf_queue.c    2007-12-19 22:49:20.000000000 -0500
20879 @@ -346,7 +346,7 @@
20880  #ifdef CONFIG_PROC_FS
20881         struct proc_dir_entry *pde;
20882  
20883 -       pde = create_proc_entry("nf_queue", S_IRUGO, proc_net_netfilter);
20884 +       pde = create_proc_entry("nf_queue", S_IRUGO, init_net.proc_net_netfilter);
20885         if (!pde)
20886                 return -1;
20887         pde->proc_fops = &nfqueue_file_ops;
20888 diff -Nurb linux-2.6.22-try2/net/netfilter/nfnetlink.c linux-2.6.22-try2-netns/net/netfilter/nfnetlink.c
20889 --- linux-2.6.22-try2/net/netfilter/nfnetlink.c 2007-12-19 13:37:59.000000000 -0500
20890 +++ linux-2.6.22-try2-netns/net/netfilter/nfnetlink.c   2007-12-19 22:49:20.000000000 -0500
20891 @@ -264,7 +264,7 @@
20892  {
20893         printk("Netfilter messages via NETLINK v%s.\n", nfversion);
20894  
20895 -       nfnl = netlink_kernel_create(NETLINK_NETFILTER, NFNLGRP_MAX,
20896 +       nfnl = netlink_kernel_create(&init_net, NETLINK_NETFILTER, NFNLGRP_MAX,
20897                                      nfnetlink_rcv, NULL, THIS_MODULE);
20898         if (!nfnl) {
20899                 printk(KERN_ERR "cannot initialize nfnetlink!\n");
20900 diff -Nurb linux-2.6.22-try2/net/netfilter/nfnetlink_log.c linux-2.6.22-try2-netns/net/netfilter/nfnetlink_log.c
20901 --- linux-2.6.22-try2/net/netfilter/nfnetlink_log.c     2007-12-19 13:37:59.000000000 -0500
20902 +++ linux-2.6.22-try2-netns/net/netfilter/nfnetlink_log.c       2007-12-19 22:49:20.000000000 -0500
20903 @@ -705,7 +705,8 @@
20904  
20905                         hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) {
20906                                 UDEBUG("node = %p\n", inst);
20907 -                               if (n->pid == inst->peer_pid)
20908 +                               if ((n->net == &init_net) && 
20909 +                                   (n->pid == inst->peer_pid))
20910                                         __instance_destroy(inst);
20911                         }
20912                 }
20913 @@ -1023,7 +1024,7 @@
20914  
20915  #ifdef CONFIG_PROC_FS
20916         proc_nful = create_proc_entry("nfnetlink_log", 0440,
20917 -                                     proc_net_netfilter);
20918 +                                     init_net.proc_net_netfilter);
20919         if (!proc_nful)
20920                 goto cleanup_subsys;
20921         proc_nful->proc_fops = &nful_file_ops;
20922 @@ -1043,7 +1044,7 @@
20923  {
20924         nf_log_unregister(&nfulnl_logger);
20925  #ifdef CONFIG_PROC_FS
20926 -       remove_proc_entry("nfnetlink_log", proc_net_netfilter);
20927 +       remove_proc_entry("nfnetlink_log", init_net.proc_net_netfilter);
20928  #endif
20929         nfnetlink_subsys_unregister(&nfulnl_subsys);
20930         netlink_unregister_notifier(&nfulnl_rtnl_notifier);
20931 diff -Nurb linux-2.6.22-try2/net/netfilter/nfnetlink_queue.c linux-2.6.22-try2-netns/net/netfilter/nfnetlink_queue.c
20932 --- linux-2.6.22-try2/net/netfilter/nfnetlink_queue.c   2007-12-19 13:37:59.000000000 -0500
20933 +++ linux-2.6.22-try2-netns/net/netfilter/nfnetlink_queue.c     2007-12-19 22:49:20.000000000 -0500
20934 @@ -734,6 +734,9 @@
20935  {
20936         struct net_device *dev = ptr;
20937  
20938 +       if (dev->nd_net != &init_net)
20939 +               return NOTIFY_DONE;
20940 +
20941         /* Drop any packets associated with the downed device */
20942         if (event == NETDEV_DOWN)
20943                 nfqnl_dev_drop(dev->ifindex);
20944 @@ -762,7 +765,8 @@
20945                         struct hlist_head *head = &instance_table[i];
20946  
20947                         hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) {
20948 -                               if (n->pid == inst->peer_pid)
20949 +                               if ((n->net == &init_net) && 
20950 +                                   (n->pid == inst->peer_pid))
20951                                         __instance_destroy(inst);
20952                         }
20953                 }
20954 @@ -1106,7 +1110,7 @@
20955  
20956  #ifdef CONFIG_PROC_FS
20957         proc_nfqueue = create_proc_entry("nfnetlink_queue", 0440,
20958 -                                        proc_net_netfilter);
20959 +                                        init_net.proc_net_netfilter);
20960         if (!proc_nfqueue)
20961                 goto cleanup_subsys;
20962         proc_nfqueue->proc_fops = &nfqnl_file_ops;
20963 @@ -1129,7 +1133,7 @@
20964         nf_unregister_queue_handlers(&nfqh);
20965         unregister_netdevice_notifier(&nfqnl_dev_notifier);
20966  #ifdef CONFIG_PROC_FS
20967 -       remove_proc_entry("nfnetlink_queue", proc_net_netfilter);
20968 +       remove_proc_entry("nfnetlink_queue", init_net.proc_net_netfilter);
20969  #endif
20970         nfnetlink_subsys_unregister(&nfqnl_subsys);
20971         netlink_unregister_notifier(&nfqnl_rtnl_notifier);
20972 diff -Nurb linux-2.6.22-try2/net/netfilter/x_tables.c linux-2.6.22-try2-netns/net/netfilter/x_tables.c
20973 --- linux-2.6.22-try2/net/netfilter/x_tables.c  2007-12-19 13:37:59.000000000 -0500
20974 +++ linux-2.6.22-try2-netns/net/netfilter/x_tables.c    2007-12-19 22:49:20.000000000 -0500
20975 @@ -22,6 +22,7 @@
20976  #include <linux/vmalloc.h>
20977  #include <linux/mutex.h>
20978  #include <linux/mm.h>
20979 +#include <net/net_namespace.h>
20980  
20981  #include <linux/netfilter/x_tables.h>
20982  #include <linux/netfilter_arp.h>
20983 @@ -37,11 +38,16 @@
20984         struct mutex mutex;
20985         struct list_head match;
20986         struct list_head target;
20987 -       struct list_head tables;
20988         struct mutex compat_mutex;
20989  };
20990  
20991 -static struct xt_af *xt;
20992 +
20993 +struct xt_af_pernet {
20994 +       struct list_head tables;
20995 +};
20996 +
20997 +static struct xt_af * xt;
20998 +
20999  
21000  #ifdef DEBUG_IP_FIREWALL_USER
21001  #define duprintf(format, args...) printk(format , ## args)
21002 @@ -286,9 +292,9 @@
21003                 return 1;
21004         }
21005         if (target == 1)
21006 -               have_rev = target_revfn(af, name, revision, &best);
21007 +               have_rev = target_revfn( af, name, revision, &best);
21008         else
21009 -               have_rev = match_revfn(af, name, revision, &best);
21010 +               have_rev = match_revfn( af, name, revision, &best);
21011         mutex_unlock(&xt[af].mutex);
21012  
21013         /* Nothing at all?  Return 0 to try loading module. */
21014 @@ -533,14 +539,14 @@
21015  EXPORT_SYMBOL(xt_free_table_info);
21016  
21017  /* Find table by name, grabs mutex & ref.  Returns ERR_PTR() on error. */
21018 -struct xt_table *xt_find_table_lock(int af, const char *name)
21019 +struct xt_table *xt_find_table_lock(struct net *net, int af, const char *name)
21020  {
21021         struct xt_table *t;
21022  
21023         if (mutex_lock_interruptible(&xt[af].mutex) != 0)
21024                 return ERR_PTR(-EINTR);
21025  
21026 -       list_for_each_entry(t, &xt[af].tables, list)
21027 +       list_for_each_entry(t, &net->xtn[af].tables, list)
21028                 if (strcmp(t->name, name) == 0 && try_module_get(t->me))
21029                         return t;
21030         mutex_unlock(&xt[af].mutex);
21031 @@ -596,7 +602,7 @@
21032  }
21033  EXPORT_SYMBOL_GPL(xt_replace_table);
21034  
21035 -int xt_register_table(struct xt_table *table,
21036 +int xt_register_table(struct net *net, struct xt_table *table,
21037                       struct xt_table_info *bootstrap,
21038                       struct xt_table_info *newinfo)
21039  {
21040 @@ -609,7 +615,7 @@
21041                 return ret;
21042  
21043         /* Don't autoload: we'd eat our tail... */
21044 -       list_for_each_entry(t, &xt[table->af].tables, list) {
21045 +       list_for_each_entry(t, &net->xtn[table->af].tables, list) {
21046                 if (strcmp(t->name, table->name) == 0) {
21047                         ret = -EEXIST;
21048                         goto unlock;
21049 @@ -628,7 +634,7 @@
21050         /* save number of initial entries */
21051         private->initial_entries = private->number;
21052  
21053 -       list_add(&table->list, &xt[table->af].tables);
21054 +       list_add(&table->list, &net->xtn[table->af].tables);
21055  
21056         ret = 0;
21057   unlock:
21058 @@ -666,7 +672,7 @@
21059         return pos ? NULL : head;
21060  }
21061  
21062 -static struct list_head *type2list(u_int16_t af, u_int16_t type)
21063 +static struct list_head *type2list(struct net *net, u_int16_t af, u_int16_t type)
21064  {
21065         struct list_head *list;
21066  
21067 @@ -678,7 +684,7 @@
21068                 list = &xt[af].match;
21069                 break;
21070         case TABLE:
21071 -               list = &xt[af].tables;
21072 +               list = &net->xtn[af].tables;
21073                 break;
21074         default:
21075                 list = NULL;
21076 @@ -691,6 +697,7 @@
21077  static void *xt_tgt_seq_start(struct seq_file *seq, loff_t *pos)
21078  {
21079         struct proc_dir_entry *pde = (struct proc_dir_entry *) seq->private;
21080 +       struct net *net = PDE_NET(pde);
21081         u_int16_t af = (unsigned long)pde->data & 0xffff;
21082         u_int16_t type = (unsigned long)pde->data >> 16;
21083         struct list_head *list;
21084 @@ -698,7 +705,7 @@
21085         if (af >= NPROTO)
21086                 return NULL;
21087  
21088 -       list = type2list(af, type);
21089 +       list = type2list(net, af, type);
21090         if (!list)
21091                 return NULL;
21092  
21093 @@ -711,6 +718,7 @@
21094  static void *xt_tgt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
21095  {
21096         struct proc_dir_entry *pde = seq->private;
21097 +       struct net *net = PDE_NET(pde);
21098         u_int16_t af = (unsigned long)pde->data & 0xffff;
21099         u_int16_t type = (unsigned long)pde->data >> 16;
21100         struct list_head *list;
21101 @@ -718,7 +726,7 @@
21102         if (af >= NPROTO)
21103                 return NULL;
21104  
21105 -       list = type2list(af, type);
21106 +       list = type2list(net, af, type);
21107         if (!list)
21108                 return NULL;
21109  
21110 @@ -759,6 +767,7 @@
21111         if (!ret) {
21112                 struct seq_file *seq = file->private_data;
21113                 struct proc_dir_entry *pde = PDE(inode);
21114 +               get_net(PROC_NET(inode));
21115  
21116                 seq->private = pde;
21117         }
21118 @@ -766,12 +775,18 @@
21119         return ret;
21120  }
21121  
21122 +static int xt_tgt_release(struct inode *inode, struct file *file)
21123 +{
21124 +       put_net(PROC_NET(inode));
21125 +       return seq_release(inode, file);
21126 +}
21127 +
21128  static const struct file_operations xt_file_ops = {
21129         .owner   = THIS_MODULE,
21130         .open    = xt_tgt_open,
21131         .read    = seq_read,
21132         .llseek  = seq_lseek,
21133 -       .release = seq_release,
21134 +       .release = xt_tgt_release,
21135  };
21136  
21137  #define FORMAT_TABLES  "_tables_names"
21138 @@ -794,7 +809,7 @@
21139  #ifdef CONFIG_PROC_FS
21140         strlcpy(buf, xt_prefix[af], sizeof(buf));
21141         strlcat(buf, FORMAT_TABLES, sizeof(buf));
21142 -       proc = proc_net_fops_create(buf, 0440, &xt_file_ops);
21143 +       proc = proc_net_fops_create(&init_net, buf, 0440, &xt_file_ops);
21144         if (!proc)
21145                 goto out;
21146         proc->data = (void *) ((unsigned long) af | (TABLE << 16));
21147 @@ -802,14 +817,14 @@
21148  
21149         strlcpy(buf, xt_prefix[af], sizeof(buf));
21150         strlcat(buf, FORMAT_MATCHES, sizeof(buf));
21151 -       proc = proc_net_fops_create(buf, 0440, &xt_file_ops);
21152 +       proc = proc_net_fops_create(&init_net, buf, 0440, &xt_file_ops);
21153         if (!proc)
21154                 goto out_remove_tables;
21155         proc->data = (void *) ((unsigned long) af | (MATCH << 16));
21156  
21157         strlcpy(buf, xt_prefix[af], sizeof(buf));
21158         strlcat(buf, FORMAT_TARGETS, sizeof(buf));
21159 -       proc = proc_net_fops_create(buf, 0440, &xt_file_ops);
21160 +       proc = proc_net_fops_create(&init_net, buf, 0440, &xt_file_ops);
21161         if (!proc)
21162                 goto out_remove_matches;
21163         proc->data = (void *) ((unsigned long) af | (TARGET << 16));
21164 @@ -821,12 +836,12 @@
21165  out_remove_matches:
21166         strlcpy(buf, xt_prefix[af], sizeof(buf));
21167         strlcat(buf, FORMAT_MATCHES, sizeof(buf));
21168 -       proc_net_remove(buf);
21169 +       proc_net_remove(&init_net, buf);
21170  
21171  out_remove_tables:
21172         strlcpy(buf, xt_prefix[af], sizeof(buf));
21173         strlcat(buf, FORMAT_TABLES, sizeof(buf));
21174 -       proc_net_remove(buf);
21175 +       proc_net_remove(&init_net, buf);
21176  out:
21177         return -1;
21178  #endif
21179 @@ -840,19 +855,42 @@
21180  
21181         strlcpy(buf, xt_prefix[af], sizeof(buf));
21182         strlcat(buf, FORMAT_TABLES, sizeof(buf));
21183 -       proc_net_remove(buf);
21184 +       proc_net_remove(&init_net, buf);
21185  
21186         strlcpy(buf, xt_prefix[af], sizeof(buf));
21187         strlcat(buf, FORMAT_TARGETS, sizeof(buf));
21188 -       proc_net_remove(buf);
21189 +       proc_net_remove(&init_net, buf);
21190  
21191         strlcpy(buf, xt_prefix[af], sizeof(buf));
21192         strlcat(buf, FORMAT_MATCHES, sizeof(buf));
21193 -       proc_net_remove(buf);
21194 +       proc_net_remove(&init_net, buf);
21195  #endif /*CONFIG_PROC_FS*/
21196  }
21197  EXPORT_SYMBOL_GPL(xt_proto_fini);
21198  
21199 +static int xt_net_init(struct net *net)
21200 +{
21201 +       int i;
21202 +
21203 +       net->xtn = kmalloc(sizeof(struct xt_af_pernet) * NPROTO, GFP_KERNEL);
21204 +       if (!net->xtn)
21205 +               return -ENOMEM;
21206 +
21207 +       for (i = 0; i < NPROTO; i++) {
21208 +               INIT_LIST_HEAD(&net->xtn[i].tables);
21209 +       }
21210 +       return 0;
21211 +}
21212 +
21213 +static void xt_net_exit(struct net *net)
21214 +{
21215 +       kfree(net->xtn);
21216 +}
21217 +
21218 +static struct pernet_operations xt_net_ops = {
21219 +       .init = xt_net_init,
21220 +       .exit = xt_net_exit,
21221 +};
21222  
21223  static int __init xt_init(void)
21224  {
21225 @@ -869,13 +907,13 @@
21226  #endif
21227                 INIT_LIST_HEAD(&xt[i].target);
21228                 INIT_LIST_HEAD(&xt[i].match);
21229 -               INIT_LIST_HEAD(&xt[i].tables);
21230         }
21231 -       return 0;
21232 +       return register_pernet_subsys(&xt_net_ops);
21233  }
21234  
21235  static void __exit xt_fini(void)
21236  {
21237 +       unregister_pernet_subsys(&xt_net_ops);
21238         kfree(xt);
21239  }
21240  
21241 diff -Nurb linux-2.6.22-try2/net/netfilter/xt_hashlimit.c linux-2.6.22-try2-netns/net/netfilter/xt_hashlimit.c
21242 --- linux-2.6.22-try2/net/netfilter/xt_hashlimit.c      2007-12-19 13:37:59.000000000 -0500
21243 +++ linux-2.6.22-try2-netns/net/netfilter/xt_hashlimit.c        2007-12-19 22:49:20.000000000 -0500
21244 @@ -21,6 +21,7 @@
21245  #include <linux/in.h>
21246  #include <linux/ip.h>
21247  #include <linux/ipv6.h>
21248 +#include <net/net_namespace.h>
21249  
21250  #include <linux/netfilter/x_tables.h>
21251  #include <linux/netfilter_ipv4/ip_tables.h>
21252 @@ -736,13 +737,13 @@
21253                 printk(KERN_ERR "xt_hashlimit: unable to create slab cache\n");
21254                 goto err2;
21255         }
21256 -       hashlimit_procdir4 = proc_mkdir("ipt_hashlimit", proc_net);
21257 +       hashlimit_procdir4 = proc_mkdir("ipt_hashlimit", init_net.proc_net);
21258         if (!hashlimit_procdir4) {
21259                 printk(KERN_ERR "xt_hashlimit: unable to create proc dir "
21260                                 "entry\n");
21261                 goto err3;
21262         }
21263 -       hashlimit_procdir6 = proc_mkdir("ip6t_hashlimit", proc_net);
21264 +       hashlimit_procdir6 = proc_mkdir("ip6t_hashlimit", init_net.proc_net);
21265         if (!hashlimit_procdir6) {
21266                 printk(KERN_ERR "xt_hashlimit: unable to create proc dir "
21267                                 "entry\n");
21268 @@ -750,7 +751,7 @@
21269         }
21270         return 0;
21271  err4:
21272 -       remove_proc_entry("ipt_hashlimit", proc_net);
21273 +       remove_proc_entry("ipt_hashlimit", init_net.proc_net);
21274  err3:
21275         kmem_cache_destroy(hashlimit_cachep);
21276  err2:
21277 @@ -762,8 +763,8 @@
21278  
21279  static void __exit xt_hashlimit_fini(void)
21280  {
21281 -       remove_proc_entry("ipt_hashlimit", proc_net);
21282 -       remove_proc_entry("ip6t_hashlimit", proc_net);
21283 +       remove_proc_entry("ipt_hashlimit", init_net.proc_net);
21284 +       remove_proc_entry("ip6t_hashlimit", init_net.proc_net);
21285         kmem_cache_destroy(hashlimit_cachep);
21286         xt_unregister_matches(xt_hashlimit, ARRAY_SIZE(xt_hashlimit));
21287  }
21288 diff -Nurb linux-2.6.22-try2/net/netlink/af_netlink.c linux-2.6.22-try2-netns/net/netlink/af_netlink.c
21289 --- linux-2.6.22-try2/net/netlink/af_netlink.c  2007-12-19 13:37:59.000000000 -0500
21290 +++ linux-2.6.22-try2-netns/net/netlink/af_netlink.c    2007-12-19 22:49:20.000000000 -0500
21291 @@ -63,6 +63,7 @@
21292  #include <net/sock.h>
21293  #include <net/scm.h>
21294  #include <net/netlink.h>
21295 +#include <net/net_namespace.h>
21296  
21297  #define NLGRPSZ(x)     (ALIGN(x, sizeof(unsigned long) * 8) / 8)
21298  
21299 @@ -212,7 +213,7 @@
21300                 wake_up(&nl_table_wait);
21301  }
21302  
21303 -static __inline__ struct sock *netlink_lookup(int protocol, u32 pid)
21304 +static __inline__ struct sock *netlink_lookup(struct net *net, int protocol, u32 pid)
21305  {
21306         struct nl_pid_hash *hash = &nl_table[protocol].hash;
21307         struct hlist_head *head;
21308 @@ -222,7 +223,7 @@
21309         read_lock(&nl_table_lock);
21310         head = nl_pid_hashfn(hash, pid);
21311         sk_for_each(sk, node, head) {
21312 -               if (nlk_sk(sk)->pid == pid) {
21313 +               if ((sk->sk_net == net) && (nlk_sk(sk)->pid == pid)) {
21314                         sock_hold(sk);
21315                         goto found;
21316                 }
21317 @@ -327,7 +328,7 @@
21318          * makes sure updates are visible before bind or setsockopt return. */
21319  }
21320  
21321 -static int netlink_insert(struct sock *sk, u32 pid)
21322 +static int netlink_insert(struct sock *sk, struct net *net, u32 pid)
21323  {
21324         struct nl_pid_hash *hash = &nl_table[sk->sk_protocol].hash;
21325         struct hlist_head *head;
21326 @@ -340,7 +341,7 @@
21327         head = nl_pid_hashfn(hash, pid);
21328         len = 0;
21329         sk_for_each(osk, node, head) {
21330 -               if (nlk_sk(osk)->pid == pid)
21331 +               if ((osk->sk_net == net) && (nlk_sk(osk)->pid == pid))
21332                         break;
21333                 len++;
21334         }
21335 @@ -383,15 +384,15 @@
21336         .obj_size = sizeof(struct netlink_sock),
21337  };
21338  
21339 -static int __netlink_create(struct socket *sock, struct mutex *cb_mutex,
21340 -                           int protocol)
21341 +static int __netlink_create(struct net *net, struct socket *sock,
21342 +                           struct mutex *cb_mutex, int protocol)
21343  {
21344         struct sock *sk;
21345         struct netlink_sock *nlk;
21346  
21347         sock->ops = &netlink_ops;
21348  
21349 -       sk = sk_alloc(PF_NETLINK, GFP_KERNEL, &netlink_proto, 1);
21350 +       sk = sk_alloc(net, PF_NETLINK, GFP_KERNEL, &netlink_proto, 1);
21351         if (!sk)
21352                 return -ENOMEM;
21353  
21354 @@ -411,7 +412,7 @@
21355         return 0;
21356  }
21357  
21358 -static int netlink_create(struct socket *sock, int protocol)
21359 +static int netlink_create(struct net *net, struct socket *sock, int protocol)
21360  {
21361         struct module *module = NULL;
21362         struct mutex *cb_mutex;
21363 @@ -440,7 +441,7 @@
21364         cb_mutex = nl_table[protocol].cb_mutex;
21365         netlink_unlock_table();
21366  
21367 -       if ((err = __netlink_create(sock, cb_mutex, protocol)) < 0)
21368 +       if ((err = __netlink_create(net, sock, cb_mutex, protocol)) < 0)
21369                 goto out_module;
21370  
21371         nlk = nlk_sk(sock->sk);
21372 @@ -477,6 +478,7 @@
21373  
21374         if (nlk->pid && !nlk->subscriptions) {
21375                 struct netlink_notify n = {
21376 +                                               .net = sk->sk_net,
21377                                                 .protocol = sk->sk_protocol,
21378                                                 .pid = nlk->pid,
21379                                           };
21380 @@ -505,6 +507,7 @@
21381  static int netlink_autobind(struct socket *sock)
21382  {
21383         struct sock *sk = sock->sk;
21384 +       struct net *net = sk->sk_net;
21385         struct nl_pid_hash *hash = &nl_table[sk->sk_protocol].hash;
21386         struct hlist_head *head;
21387         struct sock *osk;
21388 @@ -518,6 +521,8 @@
21389         netlink_table_grab();
21390         head = nl_pid_hashfn(hash, pid);
21391         sk_for_each(osk, node, head) {
21392 +               if ((osk->sk_net != net))
21393 +                       continue;
21394                 if (nlk_sk(osk)->pid == pid) {
21395                         /* Bind collision, search negative pid values. */
21396                         pid = rover--;
21397 @@ -529,7 +534,7 @@
21398         }
21399         netlink_table_ungrab();
21400  
21401 -       err = netlink_insert(sk, pid);
21402 +       err = netlink_insert(sk, net, pid);
21403         if (err == -EADDRINUSE)
21404                 goto retry;
21405  
21406 @@ -583,6 +588,7 @@
21407  static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
21408  {
21409         struct sock *sk = sock->sk;
21410 +       struct net *net = sk->sk_net;
21411         struct netlink_sock *nlk = nlk_sk(sk);
21412         struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
21413         int err;
21414 @@ -606,7 +612,7 @@
21415                         return -EINVAL;
21416         } else {
21417                 err = nladdr->nl_pid ?
21418 -                       netlink_insert(sk, nladdr->nl_pid) :
21419 +                       netlink_insert(sk, net, nladdr->nl_pid) :
21420                         netlink_autobind(sock);
21421                 if (err)
21422                         return err;
21423 @@ -690,10 +696,12 @@
21424  static struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid)
21425  {
21426         int protocol = ssk->sk_protocol;
21427 +       struct net *net;
21428         struct sock *sock;
21429         struct netlink_sock *nlk;
21430  
21431 -       sock = netlink_lookup(protocol, pid);
21432 +       net = ssk->sk_net;
21433 +       sock = netlink_lookup(net, protocol, pid);
21434         if (!sock)
21435                 return ERR_PTR(-ECONNREFUSED);
21436  
21437 @@ -866,6 +874,7 @@
21438  
21439  struct netlink_broadcast_data {
21440         struct sock *exclude_sk;
21441 +       struct net *net;
21442         u32 pid;
21443         u32 group;
21444         int failure;
21445 @@ -888,6 +897,9 @@
21446             !test_bit(p->group - 1, nlk->groups))
21447                 goto out;
21448  
21449 +       if ((sk->sk_net != p->net))
21450 +               goto out;
21451 +
21452         if (p->failure) {
21453                 netlink_overrun(sk);
21454                 goto out;
21455 @@ -926,6 +938,7 @@
21456  int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid,
21457                       u32 group, gfp_t allocation)
21458  {
21459 +       struct net *net = ssk->sk_net;
21460         struct netlink_broadcast_data info;
21461         struct hlist_node *node;
21462         struct sock *sk;
21463 @@ -933,6 +946,7 @@
21464         skb = netlink_trim(skb, allocation);
21465  
21466         info.exclude_sk = ssk;
21467 +       info.net = net;
21468         info.pid = pid;
21469         info.group = group;
21470         info.failure = 0;
21471 @@ -981,6 +995,9 @@
21472         if (sk == p->exclude_sk)
21473                 goto out;
21474  
21475 +       if (sk->sk_net != p->exclude_sk->sk_net)
21476 +               goto out;
21477 +
21478         if (nlk->pid == p->pid || p->group - 1 >= nlk->ngroups ||
21479             !test_bit(p->group - 1, nlk->groups))
21480                 goto out;
21481 @@ -1276,7 +1293,7 @@
21482   */
21483  
21484  struct sock *
21485 -netlink_kernel_create(int unit, unsigned int groups,
21486 +netlink_kernel_create(struct net *net, int unit, unsigned int groups,
21487                       void (*input)(struct sock *sk, int len),
21488                       struct mutex *cb_mutex, struct module *module)
21489  {
21490 @@ -1293,7 +1310,7 @@
21491         if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
21492                 return NULL;
21493  
21494 -       if (__netlink_create(sock, cb_mutex, unit) < 0)
21495 +       if (__netlink_create(net, sock, cb_mutex, unit) < 0)
21496                 goto out_sock_release;
21497  
21498         if (groups < 32)
21499 @@ -1308,18 +1325,20 @@
21500         if (input)
21501                 nlk_sk(sk)->data_ready = input;
21502  
21503 -       if (netlink_insert(sk, 0))
21504 +       if (netlink_insert(sk, net, 0))
21505                 goto out_sock_release;
21506  
21507         nlk = nlk_sk(sk);
21508         nlk->flags |= NETLINK_KERNEL_SOCKET;
21509  
21510         netlink_table_grab();
21511 +       if (!nl_table[unit].registered) {
21512         nl_table[unit].groups = groups;
21513         nl_table[unit].listeners = listeners;
21514         nl_table[unit].cb_mutex = cb_mutex;
21515         nl_table[unit].module = module;
21516         nl_table[unit].registered = 1;
21517 +       }
21518         netlink_table_ungrab();
21519  
21520         return sk;
21521 @@ -1420,7 +1439,7 @@
21522         atomic_inc(&skb->users);
21523         cb->skb = skb;
21524  
21525 -       sk = netlink_lookup(ssk->sk_protocol, NETLINK_CB(skb).pid);
21526 +       sk = netlink_lookup(ssk->sk_net, ssk->sk_protocol, NETLINK_CB(skb).pid);
21527         if (sk == NULL) {
21528                 netlink_destroy_callback(cb);
21529                 return -ECONNREFUSED;
21530 @@ -1462,7 +1481,8 @@
21531         if (!skb) {
21532                 struct sock *sk;
21533  
21534 -               sk = netlink_lookup(in_skb->sk->sk_protocol,
21535 +               sk = netlink_lookup(in_skb->sk->sk_net,
21536 +                                   in_skb->sk->sk_protocol,
21537                                     NETLINK_CB(in_skb).pid);
21538                 if (sk) {
21539                         sk->sk_err = ENOBUFS;
21540 @@ -1613,6 +1633,7 @@
21541  
21542  #ifdef CONFIG_PROC_FS
21543  struct nl_seq_iter {
21544 +       struct net *net;
21545         int link;
21546         int hash_idx;
21547  };
21548 @@ -1630,6 +1651,8 @@
21549  
21550                 for (j = 0; j <= hash->mask; j++) {
21551                         sk_for_each(s, node, &hash->table[j]) {
21552 +                               if (iter->net != s->sk_net)
21553 +                                       continue;
21554                                 if (off == pos) {
21555                                         iter->link = i;
21556                                         iter->hash_idx = j;
21557 @@ -1659,11 +1682,14 @@
21558         if (v == SEQ_START_TOKEN)
21559                 return netlink_seq_socket_idx(seq, 0);
21560  
21561 -       s = sk_next(v);
21562 +       iter = seq->private;
21563 +       s = v;
21564 +       do {
21565 +               s = sk_next(s);
21566 +       } while (s && (iter->net != s->sk_net));
21567         if (s)
21568                 return s;
21569  
21570 -       iter = seq->private;
21571         i = iter->link;
21572         j = iter->hash_idx + 1;
21573  
21574 @@ -1672,6 +1698,8 @@
21575  
21576                 for (; j <= hash->mask; j++) {
21577                         s = sk_head(&hash->table[j]);
21578 +                       while (s && (iter->net != s->sk_net))
21579 +                               s = sk_next(s);
21580                         if (s) {
21581                                 iter->link = i;
21582                                 iter->hash_idx = j;
21583 @@ -1742,15 +1770,24 @@
21584  
21585         seq = file->private_data;
21586         seq->private = iter;
21587 +       iter->net = get_net(PROC_NET(inode));
21588         return 0;
21589  }
21590  
21591 +static int netlink_seq_release(struct inode *inode, struct file *file)
21592 +{
21593 +       struct seq_file *seq = file->private_data;
21594 +       struct nl_seq_iter *iter = seq->private;
21595 +       put_net(iter->net);
21596 +       return seq_release_private(inode, file);
21597 +}
21598 +
21599  static const struct file_operations netlink_seq_fops = {
21600         .owner          = THIS_MODULE,
21601         .open           = netlink_seq_open,
21602         .read           = seq_read,
21603         .llseek         = seq_lseek,
21604 -       .release        = seq_release_private,
21605 +       .release        = netlink_seq_release,
21606  };
21607  
21608  #endif
21609 @@ -1792,6 +1829,27 @@
21610         .owner  = THIS_MODULE,  /* for consistency 8) */
21611  };
21612  
21613 +static int netlink_net_init(struct net *net)
21614 +{
21615 +#ifdef CONFIG_PROC_FS
21616 +       if (!proc_net_fops_create(net, "netlink", 0, &netlink_seq_fops))
21617 +               return -ENOMEM;
21618 +#endif
21619 +       return 0;
21620 +}
21621 +
21622 +static void netlink_net_exit(struct net *net)
21623 +{
21624 +#ifdef CONFIG_PROC_FS
21625 +       proc_net_remove(net, "netlink");
21626 +#endif
21627 +}
21628 +
21629 +static struct pernet_operations netlink_net_ops = {
21630 +       .init = netlink_net_init,
21631 +       .exit = netlink_net_exit,
21632 +};
21633 +
21634  static int __init netlink_proto_init(void)
21635  {
21636         struct sk_buff *dummy_skb;
21637 @@ -1837,9 +1895,7 @@
21638         }
21639  
21640         sock_register(&netlink_family_ops);
21641 -#ifdef CONFIG_PROC_FS
21642 -       proc_net_fops_create("netlink", 0, &netlink_seq_fops);
21643 -#endif
21644 +       register_pernet_subsys(&netlink_net_ops);
21645         /* The netlink device handler may be needed early. */
21646         rtnetlink_init();
21647  out:
21648 diff -Nurb linux-2.6.22-try2/net/netlink/genetlink.c linux-2.6.22-try2-netns/net/netlink/genetlink.c
21649 --- linux-2.6.22-try2/net/netlink/genetlink.c   2007-12-19 13:37:59.000000000 -0500
21650 +++ linux-2.6.22-try2-netns/net/netlink/genetlink.c     2007-12-19 22:49:20.000000000 -0500
21651 @@ -557,8 +557,9 @@
21652                 goto errout_register;
21653  
21654         netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV);
21655 -       genl_sock = netlink_kernel_create(NETLINK_GENERIC, GENL_MAX_ID,
21656 -                                         genl_rcv, NULL, THIS_MODULE);
21657 +       genl_sock = netlink_kernel_create(&init_net, NETLINK_GENERIC,
21658 +                                         GENL_MAX_ID, genl_rcv, NULL,
21659 +                                         THIS_MODULE);
21660         if (genl_sock == NULL)
21661                 panic("GENL: Cannot initialize generic netlink\n");
21662  
21663 diff -Nurb linux-2.6.22-try2/net/netrom/af_netrom.c linux-2.6.22-try2-netns/net/netrom/af_netrom.c
21664 --- linux-2.6.22-try2/net/netrom/af_netrom.c    2007-12-19 13:37:59.000000000 -0500
21665 +++ linux-2.6.22-try2-netns/net/netrom/af_netrom.c      2007-12-19 22:49:20.000000000 -0500
21666 @@ -41,6 +41,7 @@
21667  #include <net/ip.h>
21668  #include <net/tcp_states.h>
21669  #include <net/arp.h>
21670 +#include <net/net_namespace.h>
21671  #include <linux/init.h>
21672  
21673  static int nr_ndevs = 4;
21674 @@ -105,6 +106,9 @@
21675  {
21676         struct net_device *dev = (struct net_device *)ptr;
21677  
21678 +       if (dev->nd_net != &init_net)
21679 +               return NOTIFY_DONE;
21680 +
21681         if (event != NETDEV_DOWN)
21682                 return NOTIFY_DONE;
21683  
21684 @@ -408,15 +412,18 @@
21685         .obj_size = sizeof(struct nr_sock),
21686  };
21687  
21688 -static int nr_create(struct socket *sock, int protocol)
21689 +static int nr_create(struct net *net, struct socket *sock, int protocol)
21690  {
21691         struct sock *sk;
21692         struct nr_sock *nr;
21693  
21694 +       if (net != &init_net)
21695 +               return -EAFNOSUPPORT;
21696 +
21697         if (sock->type != SOCK_SEQPACKET || protocol != 0)
21698                 return -ESOCKTNOSUPPORT;
21699  
21700 -       if ((sk = sk_alloc(PF_NETROM, GFP_ATOMIC, &nr_proto, 1)) == NULL)
21701 +       if ((sk = sk_alloc(net, PF_NETROM, GFP_ATOMIC, &nr_proto, 1)) == NULL)
21702                 return -ENOMEM;
21703  
21704         nr = nr_sk(sk);
21705 @@ -458,7 +465,7 @@
21706         if (osk->sk_type != SOCK_SEQPACKET)
21707                 return NULL;
21708  
21709 -       if ((sk = sk_alloc(PF_NETROM, GFP_ATOMIC, osk->sk_prot, 1)) == NULL)
21710 +       if ((sk = sk_alloc(osk->sk_net, PF_NETROM, GFP_ATOMIC, osk->sk_prot, 1)) == NULL)
21711                 return NULL;
21712  
21713         nr = nr_sk(sk);
21714 @@ -1447,9 +1454,9 @@
21715  
21716         nr_loopback_init();
21717  
21718 -       proc_net_fops_create("nr", S_IRUGO, &nr_info_fops);
21719 -       proc_net_fops_create("nr_neigh", S_IRUGO, &nr_neigh_fops);
21720 -       proc_net_fops_create("nr_nodes", S_IRUGO, &nr_nodes_fops);
21721 +       proc_net_fops_create(&init_net, "nr", S_IRUGO, &nr_info_fops);
21722 +       proc_net_fops_create(&init_net, "nr_neigh", S_IRUGO, &nr_neigh_fops);
21723 +       proc_net_fops_create(&init_net, "nr_nodes", S_IRUGO, &nr_nodes_fops);
21724  out:
21725         return rc;
21726  fail:
21727 @@ -1477,9 +1484,9 @@
21728  {
21729         int i;
21730  
21731 -       proc_net_remove("nr");
21732 -       proc_net_remove("nr_neigh");
21733 -       proc_net_remove("nr_nodes");
21734 +       proc_net_remove(&init_net, "nr");
21735 +       proc_net_remove(&init_net, "nr_neigh");
21736 +       proc_net_remove(&init_net, "nr_nodes");
21737         nr_loopback_clear();
21738  
21739         nr_rt_free();
21740 diff -Nurb linux-2.6.22-try2/net/netrom/nr_route.c linux-2.6.22-try2-netns/net/netrom/nr_route.c
21741 --- linux-2.6.22-try2/net/netrom/nr_route.c     2007-12-19 13:37:59.000000000 -0500
21742 +++ linux-2.6.22-try2-netns/net/netrom/nr_route.c       2007-12-19 22:49:20.000000000 -0500
21743 @@ -580,7 +580,7 @@
21744  {
21745         struct net_device *dev;
21746  
21747 -       if ((dev = dev_get_by_name(devname)) == NULL)
21748 +       if ((dev = dev_get_by_name(&init_net, devname)) == NULL)
21749                 return NULL;
21750  
21751         if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25)
21752 @@ -598,7 +598,7 @@
21753         struct net_device *dev, *first = NULL;
21754  
21755         read_lock(&dev_base_lock);
21756 -       for_each_netdev(dev) {
21757 +       for_each_netdev(&init_net, dev) {
21758                 if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM)
21759                         if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
21760                                 first = dev;
21761 @@ -618,7 +618,7 @@
21762         struct net_device *dev;
21763  
21764         read_lock(&dev_base_lock);
21765 -       for_each_netdev(dev) {
21766 +       for_each_netdev(&init_net, dev) {
21767                 if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM && ax25cmp(addr, (ax25_address *)dev->dev_addr) == 0) {
21768                         dev_hold(dev);
21769                         goto out;
21770 diff -Nurb linux-2.6.22-try2/net/packet/af_packet.c linux-2.6.22-try2-netns/net/packet/af_packet.c
21771 --- linux-2.6.22-try2/net/packet/af_packet.c    2007-12-19 13:37:59.000000000 -0500
21772 +++ linux-2.6.22-try2-netns/net/packet/af_packet.c      2007-12-19 22:49:20.000000000 -0500
21773 @@ -65,6 +65,7 @@
21774  #include <net/protocol.h>
21775  #include <linux/skbuff.h>
21776  #include <net/sock.h>
21777 +#include <net/net_namespace.h>
21778  #include <linux/errno.h>
21779  #include <linux/timer.h>
21780  #include <asm/system.h>
21781 @@ -135,10 +136,6 @@
21782     packet classifier depends on it.
21783   */
21784  
21785 -/* List of all packet sockets. */
21786 -static HLIST_HEAD(packet_sklist);
21787 -static DEFINE_RWLOCK(packet_sklist_lock);
21788 -
21789  static atomic_t packet_socks_nr;
21790  
21791  
21792 @@ -273,6 +270,9 @@
21793         if (skb->pkt_type == PACKET_LOOPBACK)
21794                 goto out;
21795  
21796 +       if (dev->nd_net != sk->sk_net)
21797 +               goto out;
21798 +
21799         if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
21800                 goto oom;
21801  
21802 @@ -344,7 +344,7 @@
21803          */
21804  
21805         saddr->spkt_device[13] = 0;
21806 -       dev = dev_get_by_name(saddr->spkt_device);
21807 +       dev = dev_get_by_name(sk->sk_net, saddr->spkt_device);
21808         err = -ENODEV;
21809         if (dev == NULL)
21810                 goto out_unlock;
21811 @@ -462,6 +462,9 @@
21812         sk = pt->af_packet_priv;
21813         po = pkt_sk(sk);
21814  
21815 +       if (dev->nd_net != sk->sk_net)
21816 +               goto drop;
21817 +
21818         skb->dev = dev;
21819  
21820         if (dev->hard_header) {
21821 @@ -578,6 +581,9 @@
21822         sk = pt->af_packet_priv;
21823         po = pkt_sk(sk);
21824  
21825 +       if (dev->nd_net != sk->sk_net)
21826 +               goto drop;
21827 +
21828         if (dev->hard_header) {
21829                 if (sk->sk_type != SOCK_DGRAM)
21830                         skb_push(skb, skb->data - skb_mac_header(skb));
21831 @@ -738,7 +744,7 @@
21832         }
21833  
21834  
21835 -       dev = dev_get_by_index(ifindex);
21836 +       dev = dev_get_by_index(sk->sk_net, ifindex);
21837         err = -ENXIO;
21838         if (dev == NULL)
21839                 goto out_unlock;
21840 @@ -811,15 +817,17 @@
21841  {
21842         struct sock *sk = sock->sk;
21843         struct packet_sock *po;
21844 +       struct net *net;
21845  
21846         if (!sk)
21847                 return 0;
21848  
21849 +       net = sk->sk_net;
21850         po = pkt_sk(sk);
21851  
21852 -       write_lock_bh(&packet_sklist_lock);
21853 +       write_lock_bh(&net->packet_sklist_lock);
21854         sk_del_node_init(sk);
21855 -       write_unlock_bh(&packet_sklist_lock);
21856 +       write_unlock_bh(&net->packet_sklist_lock);
21857  
21858         /*
21859          *      Unhook packet receive handler.
21860 @@ -933,7 +941,7 @@
21861                 return -EINVAL;
21862         strlcpy(name,uaddr->sa_data,sizeof(name));
21863  
21864 -       dev = dev_get_by_name(name);
21865 +       dev = dev_get_by_name(sk->sk_net, name);
21866         if (dev) {
21867                 err = packet_do_bind(sk, dev, pkt_sk(sk)->num);
21868                 dev_put(dev);
21869 @@ -960,7 +968,7 @@
21870  
21871         if (sll->sll_ifindex) {
21872                 err = -ENODEV;
21873 -               dev = dev_get_by_index(sll->sll_ifindex);
21874 +               dev = dev_get_by_index(sk->sk_net, sll->sll_ifindex);
21875                 if (dev == NULL)
21876                         goto out;
21877         }
21878 @@ -982,7 +990,7 @@
21879   *     Create a packet of type SOCK_PACKET.
21880   */
21881  
21882 -static int packet_create(struct socket *sock, int protocol)
21883 +static int packet_create(struct net *net, struct socket *sock, int protocol)
21884  {
21885         struct sock *sk;
21886         struct packet_sock *po;
21887 @@ -998,7 +1006,7 @@
21888         sock->state = SS_UNCONNECTED;
21889  
21890         err = -ENOBUFS;
21891 -       sk = sk_alloc(PF_PACKET, GFP_KERNEL, &packet_proto, 1);
21892 +       sk = sk_alloc(net, PF_PACKET, GFP_KERNEL, &packet_proto, 1);
21893         if (sk == NULL)
21894                 goto out;
21895  
21896 @@ -1034,9 +1042,9 @@
21897                 po->running = 1;
21898         }
21899  
21900 -       write_lock_bh(&packet_sklist_lock);
21901 -       sk_add_node(sk, &packet_sklist);
21902 -       write_unlock_bh(&packet_sklist_lock);
21903 +       write_lock_bh(&net->packet_sklist_lock);
21904 +       sk_add_node(sk, &net->packet_sklist);
21905 +       write_unlock_bh(&net->packet_sklist_lock);
21906         return(0);
21907  out:
21908         return err;
21909 @@ -1154,7 +1162,7 @@
21910                 return -EOPNOTSUPP;
21911  
21912         uaddr->sa_family = AF_PACKET;
21913 -       dev = dev_get_by_index(pkt_sk(sk)->ifindex);
21914 +       dev = dev_get_by_index(sk->sk_net, pkt_sk(sk)->ifindex);
21915         if (dev) {
21916                 strlcpy(uaddr->sa_data, dev->name, 15);
21917                 dev_put(dev);
21918 @@ -1179,7 +1187,7 @@
21919         sll->sll_family = AF_PACKET;
21920         sll->sll_ifindex = po->ifindex;
21921         sll->sll_protocol = po->num;
21922 -       dev = dev_get_by_index(po->ifindex);
21923 +       dev = dev_get_by_index(sk->sk_net, po->ifindex);
21924         if (dev) {
21925                 sll->sll_hatype = dev->type;
21926                 sll->sll_halen = dev->addr_len;
21927 @@ -1231,7 +1239,7 @@
21928         rtnl_lock();
21929  
21930         err = -ENODEV;
21931 -       dev = __dev_get_by_index(mreq->mr_ifindex);
21932 +       dev = __dev_get_by_index(sk->sk_net, mreq->mr_ifindex);
21933         if (!dev)
21934                 goto done;
21935  
21936 @@ -1285,7 +1293,7 @@
21937                         if (--ml->count == 0) {
21938                                 struct net_device *dev;
21939                                 *mlp = ml->next;
21940 -                               dev = dev_get_by_index(ml->ifindex);
21941 +                               dev = dev_get_by_index(sk->sk_net, ml->ifindex);
21942                                 if (dev) {
21943                                         packet_dev_mc(dev, ml, -1);
21944                                         dev_put(dev);
21945 @@ -1313,7 +1321,7 @@
21946                 struct net_device *dev;
21947  
21948                 po->mclist = ml->next;
21949 -               if ((dev = dev_get_by_index(ml->ifindex)) != NULL) {
21950 +               if ((dev = dev_get_by_index(sk->sk_net, ml->ifindex)) != NULL) {
21951                         packet_dev_mc(dev, ml, -1);
21952                         dev_put(dev);
21953                 }
21954 @@ -1469,9 +1477,10 @@
21955         struct sock *sk;
21956         struct hlist_node *node;
21957         struct net_device *dev = data;
21958 +       struct net *net = dev->nd_net;
21959  
21960 -       read_lock(&packet_sklist_lock);
21961 -       sk_for_each(sk, node, &packet_sklist) {
21962 +       read_lock(&net->packet_sklist_lock);
21963 +       sk_for_each(sk, node, &net->packet_sklist) {
21964                 struct packet_sock *po = pkt_sk(sk);
21965  
21966                 switch (msg) {
21967 @@ -1510,7 +1519,7 @@
21968                         break;
21969                 }
21970         }
21971 -       read_unlock(&packet_sklist_lock);
21972 +       read_unlock(&net->packet_sklist_lock);
21973         return NOTIFY_DONE;
21974  }
21975  
21976 @@ -1878,12 +1887,12 @@
21977  };
21978  
21979  #ifdef CONFIG_PROC_FS
21980 -static inline struct sock *packet_seq_idx(loff_t off)
21981 +static inline struct sock *packet_seq_idx(struct net *net, loff_t off)
21982  {
21983         struct sock *s;
21984         struct hlist_node *node;
21985  
21986 -       sk_for_each(s, node, &packet_sklist) {
21987 +       sk_for_each(s, node, &net->packet_sklist) {
21988                 if (!off--)
21989                         return s;
21990         }
21991 @@ -1892,21 +1901,24 @@
21992  
21993  static void *packet_seq_start(struct seq_file *seq, loff_t *pos)
21994  {
21995 -       read_lock(&packet_sklist_lock);
21996 -       return *pos ? packet_seq_idx(*pos - 1) : SEQ_START_TOKEN;
21997 +       struct net *net = seq->private;
21998 +       read_lock(&net->packet_sklist_lock);
21999 +       return *pos ? packet_seq_idx(net, *pos - 1) : SEQ_START_TOKEN;
22000  }
22001  
22002  static void *packet_seq_next(struct seq_file *seq, void *v, loff_t *pos)
22003  {
22004 +       struct net *net = seq->private;
22005         ++*pos;
22006         return  (v == SEQ_START_TOKEN)
22007 -               ? sk_head(&packet_sklist)
22008 +               ? sk_head(&net->packet_sklist)
22009                 : sk_next((struct sock*)v) ;
22010  }
22011  
22012  static void packet_seq_stop(struct seq_file *seq, void *v)
22013  {
22014 -       read_unlock(&packet_sklist_lock);
22015 +       struct net *net = seq->private;
22016 +       read_unlock(&net->packet_sklist_lock);
22017  }
22018  
22019  static int packet_seq_show(struct seq_file *seq, void *v)
22020 @@ -1942,7 +1954,22 @@
22021  
22022  static int packet_seq_open(struct inode *inode, struct file *file)
22023  {
22024 -       return seq_open(file, &packet_seq_ops);
22025 +       struct seq_file *seq;
22026 +       int res;
22027 +       res = seq_open(file, &packet_seq_ops);
22028 +       if (!res) {
22029 +               seq = file->private_data;
22030 +               seq->private = get_net(PROC_NET(inode));
22031 +       }
22032 +       return res;
22033 +}
22034 +
22035 +static int packet_seq_release(struct inode *inode, struct file *file)
22036 +{
22037 +       struct seq_file *seq=  file->private_data;
22038 +       struct net *net = seq->private;
22039 +       put_net(net);
22040 +       return seq_release(inode, file);
22041  }
22042  
22043  static const struct file_operations packet_seq_fops = {
22044 @@ -1950,15 +1977,37 @@
22045         .open           = packet_seq_open,
22046         .read           = seq_read,
22047         .llseek         = seq_lseek,
22048 -       .release        = seq_release,
22049 +       .release        = packet_seq_release,
22050  };
22051  
22052  #endif
22053  
22054 +static int packet_net_init(struct net *net)
22055 +{
22056 +       rwlock_init(&net->packet_sklist_lock);
22057 +       INIT_HLIST_HEAD(&net->packet_sklist);
22058 +
22059 +       if (!proc_net_fops_create(net, "packet", 0, &packet_seq_fops))
22060 +               return -ENOMEM;
22061 +
22062 +       return 0;
22063 +}
22064 +
22065 +static void packet_net_exit(struct net *net)
22066 +{
22067 +       proc_net_remove(net, "packet");
22068 +}
22069 +
22070 +static struct pernet_operations packet_net_ops = {
22071 +       .init = packet_net_init,
22072 +       .exit = packet_net_exit,
22073 +};
22074 +
22075 +
22076  static void __exit packet_exit(void)
22077  {
22078 -       proc_net_remove("packet");
22079         unregister_netdevice_notifier(&packet_netdev_notifier);
22080 +       unregister_pernet_subsys(&packet_net_ops);
22081         sock_unregister(PF_PACKET);
22082         proto_unregister(&packet_proto);
22083  }
22084 @@ -1971,8 +2020,8 @@
22085                 goto out;
22086  
22087         sock_register(&packet_family_ops);
22088 +       register_pernet_subsys(&packet_net_ops);
22089         register_netdevice_notifier(&packet_netdev_notifier);
22090 -       proc_net_fops_create("packet", 0, &packet_seq_fops);
22091  out:
22092         return rc;
22093  }
22094 diff -Nurb linux-2.6.22-try2/net/rose/af_rose.c linux-2.6.22-try2-netns/net/rose/af_rose.c
22095 --- linux-2.6.22-try2/net/rose/af_rose.c        2007-12-19 13:37:59.000000000 -0500
22096 +++ linux-2.6.22-try2-netns/net/rose/af_rose.c  2007-12-19 22:49:20.000000000 -0500
22097 @@ -45,6 +45,7 @@
22098  #include <net/tcp_states.h>
22099  #include <net/ip.h>
22100  #include <net/arp.h>
22101 +#include <net/net_namespace.h>
22102  
22103  static int rose_ndevs = 10;
22104  
22105 @@ -196,6 +197,9 @@
22106  {
22107         struct net_device *dev = (struct net_device *)ptr;
22108  
22109 +       if (dev->nd_net != &init_net)
22110 +               return NOTIFY_DONE;
22111 +
22112         if (event != NETDEV_DOWN)
22113                 return NOTIFY_DONE;
22114  
22115 @@ -498,15 +502,18 @@
22116         .obj_size = sizeof(struct rose_sock),
22117  };
22118  
22119 -static int rose_create(struct socket *sock, int protocol)
22120 +static int rose_create(struct net *net, struct socket *sock, int protocol)
22121  {
22122         struct sock *sk;
22123         struct rose_sock *rose;
22124  
22125 +       if (net != &init_net)
22126 +               return -EAFNOSUPPORT;
22127 +
22128         if (sock->type != SOCK_SEQPACKET || protocol != 0)
22129                 return -ESOCKTNOSUPPORT;
22130  
22131 -       if ((sk = sk_alloc(PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL)
22132 +       if ((sk = sk_alloc(net, PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL)
22133                 return -ENOMEM;
22134  
22135         rose = rose_sk(sk);
22136 @@ -544,7 +551,7 @@
22137         if (osk->sk_type != SOCK_SEQPACKET)
22138                 return NULL;
22139  
22140 -       if ((sk = sk_alloc(PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL)
22141 +       if ((sk = sk_alloc(osk->sk_net, PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL)
22142                 return NULL;
22143  
22144         rose = rose_sk(sk);
22145 @@ -1576,10 +1583,10 @@
22146  
22147         rose_add_loopback_neigh();
22148  
22149 -       proc_net_fops_create("rose", S_IRUGO, &rose_info_fops);
22150 -       proc_net_fops_create("rose_neigh", S_IRUGO, &rose_neigh_fops);
22151 -       proc_net_fops_create("rose_nodes", S_IRUGO, &rose_nodes_fops);
22152 -       proc_net_fops_create("rose_routes", S_IRUGO, &rose_routes_fops);
22153 +       proc_net_fops_create(&init_net, "rose", S_IRUGO, &rose_info_fops);
22154 +       proc_net_fops_create(&init_net, "rose_neigh", S_IRUGO, &rose_neigh_fops);
22155 +       proc_net_fops_create(&init_net, "rose_nodes", S_IRUGO, &rose_nodes_fops);
22156 +       proc_net_fops_create(&init_net, "rose_routes", S_IRUGO, &rose_routes_fops);
22157  out:
22158         return rc;
22159  fail:
22160 @@ -1606,10 +1613,10 @@
22161  {
22162         int i;
22163  
22164 -       proc_net_remove("rose");
22165 -       proc_net_remove("rose_neigh");
22166 -       proc_net_remove("rose_nodes");
22167 -       proc_net_remove("rose_routes");
22168 +       proc_net_remove(&init_net, "rose");
22169 +       proc_net_remove(&init_net, "rose_neigh");
22170 +       proc_net_remove(&init_net, "rose_nodes");
22171 +       proc_net_remove(&init_net, "rose_routes");
22172         rose_loopback_clear();
22173  
22174         rose_rt_free();
22175 diff -Nurb linux-2.6.22-try2/net/rose/rose_route.c linux-2.6.22-try2-netns/net/rose/rose_route.c
22176 --- linux-2.6.22-try2/net/rose/rose_route.c     2007-12-19 13:37:59.000000000 -0500
22177 +++ linux-2.6.22-try2-netns/net/rose/rose_route.c       2007-12-19 22:49:20.000000000 -0500
22178 @@ -583,7 +583,7 @@
22179  {
22180         struct net_device *dev;
22181  
22182 -       if ((dev = dev_get_by_name(devname)) == NULL)
22183 +       if ((dev = dev_get_by_name(&init_net, devname)) == NULL)
22184                 return NULL;
22185  
22186         if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25)
22187 @@ -601,7 +601,7 @@
22188         struct net_device *dev, *first = NULL;
22189  
22190         read_lock(&dev_base_lock);
22191 -       for_each_netdev(dev) {
22192 +       for_each_netdev(&init_net, dev) {
22193                 if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE)
22194                         if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
22195                                 first = dev;
22196 @@ -619,7 +619,7 @@
22197         struct net_device *dev;
22198  
22199         read_lock(&dev_base_lock);
22200 -       for_each_netdev(dev) {
22201 +       for_each_netdev(&init_net, dev) {
22202                 if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0) {
22203                         dev_hold(dev);
22204                         goto out;
22205 @@ -636,7 +636,7 @@
22206         struct net_device *dev;
22207  
22208         read_lock(&dev_base_lock);
22209 -       for_each_netdev(dev) {
22210 +       for_each_netdev(&init_net, dev) {
22211                 if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0)
22212                         goto out;
22213         }
22214 diff -Nurb linux-2.6.22-try2/net/rxrpc/af_rxrpc.c linux-2.6.22-try2-netns/net/rxrpc/af_rxrpc.c
22215 --- linux-2.6.22-try2/net/rxrpc/af_rxrpc.c      2007-12-19 13:37:59.000000000 -0500
22216 +++ linux-2.6.22-try2-netns/net/rxrpc/af_rxrpc.c        2007-12-19 22:49:20.000000000 -0500
22217 @@ -14,6 +14,7 @@
22218  #include <linux/skbuff.h>
22219  #include <linux/poll.h>
22220  #include <linux/proc_fs.h>
22221 +#include <net/net_namespace.h>
22222  #include <net/sock.h>
22223  #include <net/af_rxrpc.h>
22224  #include "ar-internal.h"
22225 @@ -605,13 +606,16 @@
22226  /*
22227   * create an RxRPC socket
22228   */
22229 -static int rxrpc_create(struct socket *sock, int protocol)
22230 +static int rxrpc_create(struct net *net, struct socket *sock, int protocol)
22231  {
22232         struct rxrpc_sock *rx;
22233         struct sock *sk;
22234  
22235         _enter("%p,%d", sock, protocol);
22236  
22237 +       if (net != &init_net)
22238 +               return -EAFNOSUPPORT;
22239 +
22240         /* we support transport protocol UDP only */
22241         if (protocol != PF_INET)
22242                 return -EPROTONOSUPPORT;
22243 @@ -622,7 +626,7 @@
22244         sock->ops = &rxrpc_rpc_ops;
22245         sock->state = SS_UNCONNECTED;
22246  
22247 -       sk = sk_alloc(PF_RXRPC, GFP_KERNEL, &rxrpc_proto, 1);
22248 +       sk = sk_alloc(net, PF_RXRPC, GFP_KERNEL, &rxrpc_proto, 1);
22249         if (!sk)
22250                 return -ENOMEM;
22251  
22252 @@ -829,8 +833,8 @@
22253         }
22254  
22255  #ifdef CONFIG_PROC_FS
22256 -       proc_net_fops_create("rxrpc_calls", 0, &rxrpc_call_seq_fops);
22257 -       proc_net_fops_create("rxrpc_conns", 0, &rxrpc_connection_seq_fops);
22258 +       proc_net_fops_create(&init_net, "rxrpc_calls", 0, &rxrpc_call_seq_fops);
22259 +       proc_net_fops_create(&init_net, "rxrpc_conns", 0, &rxrpc_connection_seq_fops);
22260  #endif
22261         return 0;
22262  
22263 @@ -868,8 +872,8 @@
22264  
22265         _debug("flush scheduled work");
22266         flush_workqueue(rxrpc_workqueue);
22267 -       proc_net_remove("rxrpc_conns");
22268 -       proc_net_remove("rxrpc_calls");
22269 +       proc_net_remove(&init_net, "rxrpc_conns");
22270 +       proc_net_remove(&init_net, "rxrpc_calls");
22271         destroy_workqueue(rxrpc_workqueue);
22272         kmem_cache_destroy(rxrpc_call_jar);
22273         _leave("");
22274 diff -Nurb linux-2.6.22-try2/net/sched/act_api.c linux-2.6.22-try2-netns/net/sched/act_api.c
22275 --- linux-2.6.22-try2/net/sched/act_api.c       2007-12-19 13:37:59.000000000 -0500
22276 +++ linux-2.6.22-try2-netns/net/sched/act_api.c 2007-12-19 22:49:20.000000000 -0500
22277 @@ -27,6 +27,7 @@
22278  #include <linux/skbuff.h>
22279  #include <linux/init.h>
22280  #include <linux/kmod.h>
22281 +#include <net/net_namespace.h>
22282  #include <net/sock.h>
22283  #include <net/sch_generic.h>
22284  #include <net/act_api.h>
22285 @@ -675,7 +676,7 @@
22286                 return -EINVAL;
22287         }
22288  
22289 -       return rtnl_unicast(skb, pid);
22290 +       return rtnl_unicast(skb, &init_net, pid);
22291  }
22292  
22293  static struct tc_action *
22294 @@ -796,7 +797,7 @@
22295         nlh->nlmsg_flags |= NLM_F_ROOT;
22296         module_put(a->ops->owner);
22297         kfree(a);
22298 -       err = rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
22299 +       err = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
22300         if (err > 0)
22301                 return 0;
22302  
22303 @@ -859,7 +860,7 @@
22304  
22305                 /* now do the delete */
22306                 tcf_action_destroy(head, 0);
22307 -               ret = rtnetlink_send(skb, pid, RTNLGRP_TC,
22308 +               ret = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC,
22309                                      n->nlmsg_flags&NLM_F_ECHO);
22310                 if (ret > 0)
22311                         return 0;
22312 @@ -903,7 +904,7 @@
22313         nlh->nlmsg_len = skb_tail_pointer(skb) - b;
22314         NETLINK_CB(skb).dst_group = RTNLGRP_TC;
22315  
22316 -       err = rtnetlink_send(skb, pid, RTNLGRP_TC, flags&NLM_F_ECHO);
22317 +       err = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, flags&NLM_F_ECHO);
22318         if (err > 0)
22319                 err = 0;
22320         return err;
22321 @@ -941,10 +942,14 @@
22322  
22323  static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
22324  {
22325 +       struct net *net = skb->sk->sk_net;
22326         struct rtattr **tca = arg;
22327         u32 pid = skb ? NETLINK_CB(skb).pid : 0;
22328         int ret = 0, ovr = 0;
22329  
22330 +       if (net != &init_net)
22331 +               return -EINVAL;
22332 +
22333         if (tca[TCA_ACT_TAB-1] == NULL) {
22334                 printk("tc_ctl_action: received NO action attribs\n");
22335                 return -EINVAL;
22336 @@ -1014,6 +1019,7 @@
22337  static int
22338  tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
22339  {
22340 +       struct net *net = skb->sk->sk_net;
22341         struct nlmsghdr *nlh;
22342         unsigned char *b = skb_tail_pointer(skb);
22343         struct rtattr *x;
22344 @@ -1023,6 +1029,9 @@
22345         struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh);
22346         struct rtattr *kind = find_dump_kind(cb->nlh);
22347  
22348 +       if (net != &init_net)
22349 +               return 0;
22350 +
22351         if (kind == NULL) {
22352                 printk("tc_dump_action: action bad kind\n");
22353                 return 0;
22354 diff -Nurb linux-2.6.22-try2/net/sched/act_mirred.c linux-2.6.22-try2-netns/net/sched/act_mirred.c
22355 --- linux-2.6.22-try2/net/sched/act_mirred.c    2007-12-19 13:37:59.000000000 -0500
22356 +++ linux-2.6.22-try2-netns/net/sched/act_mirred.c      2007-12-19 22:49:20.000000000 -0500
22357 @@ -85,7 +85,7 @@
22358         parm = RTA_DATA(tb[TCA_MIRRED_PARMS-1]);
22359  
22360         if (parm->ifindex) {
22361 -               dev = __dev_get_by_index(parm->ifindex);
22362 +               dev = __dev_get_by_index(&init_net, parm->ifindex);
22363                 if (dev == NULL)
22364                         return -ENODEV;
22365                 switch (dev->type) {
22366 diff -Nurb linux-2.6.22-try2/net/sched/cls_api.c linux-2.6.22-try2-netns/net/sched/cls_api.c
22367 --- linux-2.6.22-try2/net/sched/cls_api.c       2007-12-19 13:37:59.000000000 -0500
22368 +++ linux-2.6.22-try2-netns/net/sched/cls_api.c 2007-12-19 22:49:20.000000000 -0500
22369 @@ -129,6 +129,7 @@
22370  
22371  static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
22372  {
22373 +       struct net *net = skb->sk->sk_net;
22374         struct rtattr **tca;
22375         struct tcmsg *t;
22376         u32 protocol;
22377 @@ -145,6 +146,9 @@
22378         unsigned long fh;
22379         int err;
22380  
22381 +       if (net != &init_net)
22382 +               return -EINVAL;
22383 +
22384  replay:
22385         tca = arg;
22386         t = NLMSG_DATA(n);
22387 @@ -164,7 +168,7 @@
22388         /* Find head of filter chain. */
22389  
22390         /* Find link */
22391 -       if ((dev = __dev_get_by_index(t->tcm_ifindex)) == NULL)
22392 +       if ((dev = __dev_get_by_index(&init_net, t->tcm_ifindex)) == NULL)
22393                 return -ENODEV;
22394  
22395         /* Find qdisc */
22396 @@ -365,7 +369,7 @@
22397                 return -EINVAL;
22398         }
22399  
22400 -       return rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
22401 +       return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
22402  }
22403  
22404  struct tcf_dump_args
22405 @@ -385,6 +389,7 @@
22406  
22407  static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
22408  {
22409 +       struct net *net = skb->sk->sk_net;
22410         int t;
22411         int s_t;
22412         struct net_device *dev;
22413 @@ -395,9 +400,12 @@
22414         struct Qdisc_class_ops *cops;
22415         struct tcf_dump_args arg;
22416  
22417 +       if (net != &init_net)
22418 +               return 0;
22419 +
22420         if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm)))
22421                 return skb->len;
22422 -       if ((dev = dev_get_by_index(tcm->tcm_ifindex)) == NULL)
22423 +       if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
22424                 return skb->len;
22425  
22426         if (!tcm->tcm_parent)
22427 diff -Nurb linux-2.6.22-try2/net/sched/em_meta.c linux-2.6.22-try2-netns/net/sched/em_meta.c
22428 --- linux-2.6.22-try2/net/sched/em_meta.c       2007-12-19 13:37:59.000000000 -0500
22429 +++ linux-2.6.22-try2-netns/net/sched/em_meta.c 2007-12-19 22:49:20.000000000 -0500
22430 @@ -291,7 +291,7 @@
22431          } else  {
22432                 struct net_device *dev;
22433  
22434 -               dev = dev_get_by_index(skb->sk->sk_bound_dev_if);
22435 +               dev = dev_get_by_index(&init_net, skb->sk->sk_bound_dev_if);
22436                 *err = var_dev(dev, dst);
22437                 if (dev)
22438                         dev_put(dev);
22439 diff -Nurb linux-2.6.22-try2/net/sched/sch_api.c linux-2.6.22-try2-netns/net/sched/sch_api.c
22440 --- linux-2.6.22-try2/net/sched/sch_api.c       2007-12-19 13:37:59.000000000 -0500
22441 +++ linux-2.6.22-try2-netns/net/sched/sch_api.c 2007-12-19 22:49:20.000000000 -0500
22442 @@ -35,6 +35,7 @@
22443  #include <linux/bitops.h>
22444  #include <linux/hrtimer.h>
22445  
22446 +#include <net/net_namespace.h>
22447  #include <net/netlink.h>
22448  #include <net/sock.h>
22449  #include <net/pkt_sched.h>
22450 @@ -609,6 +610,7 @@
22451  
22452  static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
22453  {
22454 +       struct net *net = skb->sk->sk_net;
22455         struct tcmsg *tcm = NLMSG_DATA(n);
22456         struct rtattr **tca = arg;
22457         struct net_device *dev;
22458 @@ -617,7 +619,10 @@
22459         struct Qdisc *p = NULL;
22460         int err;
22461  
22462 -       if ((dev = __dev_get_by_index(tcm->tcm_ifindex)) == NULL)
22463 +       if (net != &init_net)
22464 +               return -EINVAL;
22465 +
22466 +       if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
22467                 return -ENODEV;
22468  
22469         if (clid) {
22470 @@ -670,6 +675,7 @@
22471  
22472  static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
22473  {
22474 +       struct net *net = skb->sk->sk_net;
22475         struct tcmsg *tcm;
22476         struct rtattr **tca;
22477         struct net_device *dev;
22478 @@ -677,6 +683,9 @@
22479         struct Qdisc *q, *p;
22480         int err;
22481  
22482 +       if (net != &init_net)
22483 +               return -EINVAL;
22484 +
22485  replay:
22486         /* Reinit, just in case something touches this. */
22487         tcm = NLMSG_DATA(n);
22488 @@ -684,7 +693,7 @@
22489         clid = tcm->tcm_parent;
22490         q = p = NULL;
22491  
22492 -       if ((dev = __dev_get_by_index(tcm->tcm_ifindex)) == NULL)
22493 +       if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
22494                 return -ENODEV;
22495  
22496         if (clid) {
22497 @@ -873,7 +882,7 @@
22498         }
22499  
22500         if (skb->len)
22501 -               return rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
22502 +               return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
22503  
22504  err_out:
22505         kfree_skb(skb);
22506 @@ -882,16 +891,20 @@
22507  
22508  static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
22509  {
22510 +       struct net *net = skb->sk->sk_net;
22511         int idx, q_idx;
22512         int s_idx, s_q_idx;
22513         struct net_device *dev;
22514         struct Qdisc *q;
22515  
22516 +       if (net != &init_net)
22517 +               return 0;
22518 +
22519         s_idx = cb->args[0];
22520         s_q_idx = q_idx = cb->args[1];
22521         read_lock(&dev_base_lock);
22522         idx = 0;
22523 -       for_each_netdev(dev) {
22524 +       for_each_netdev(&init_net, dev) {
22525                 if (idx < s_idx)
22526                         goto cont;
22527                 if (idx > s_idx)
22528 @@ -930,6 +943,7 @@
22529  
22530  static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
22531  {
22532 +       struct net *net = skb->sk->sk_net;
22533         struct tcmsg *tcm = NLMSG_DATA(n);
22534         struct rtattr **tca = arg;
22535         struct net_device *dev;
22536 @@ -942,7 +956,10 @@
22537         u32 qid = TC_H_MAJ(clid);
22538         int err;
22539  
22540 -       if ((dev = __dev_get_by_index(tcm->tcm_ifindex)) == NULL)
22541 +       if (net != &init_net)
22542 +               return -EINVAL;
22543 +
22544 +       if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
22545                 return -ENODEV;
22546  
22547         /*
22548 @@ -1096,7 +1113,7 @@
22549                 return -EINVAL;
22550         }
22551  
22552 -       return rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
22553 +       return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
22554  }
22555  
22556  struct qdisc_dump_args
22557 @@ -1116,6 +1133,7 @@
22558  
22559  static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
22560  {
22561 +       struct net *net = skb->sk->sk_net;
22562         int t;
22563         int s_t;
22564         struct net_device *dev;
22565 @@ -1123,9 +1141,12 @@
22566         struct tcmsg *tcm = (struct tcmsg*)NLMSG_DATA(cb->nlh);
22567         struct qdisc_dump_args arg;
22568  
22569 +       if (net != &init_net)
22570 +               return 0;
22571 +
22572         if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm)))
22573                 return 0;
22574 -       if ((dev = dev_get_by_index(tcm->tcm_ifindex)) == NULL)
22575 +       if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
22576                 return 0;
22577  
22578         s_t = cb->args[0];
22579 @@ -1252,7 +1273,7 @@
22580  {
22581         register_qdisc(&pfifo_qdisc_ops);
22582         register_qdisc(&bfifo_qdisc_ops);
22583 -       proc_net_fops_create("psched", 0, &psched_fops);
22584 +       proc_net_fops_create(&init_net, "psched", 0, &psched_fops);
22585  
22586         rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL);
22587         rtnl_register(PF_UNSPEC, RTM_DELQDISC, tc_get_qdisc, NULL);
22588 diff -Nurb linux-2.6.22-try2/net/sched/sch_ingress.c linux-2.6.22-try2-netns/net/sched/sch_ingress.c
22589 --- linux-2.6.22-try2/net/sched/sch_ingress.c   2007-12-19 13:37:59.000000000 -0500
22590 +++ linux-2.6.22-try2-netns/net/sched/sch_ingress.c     2007-12-19 22:49:20.000000000 -0500
22591 @@ -243,6 +243,10 @@
22592         struct net_device *dev = skb->dev;
22593         int fwres=NF_ACCEPT;
22594  
22595 +       /* Only filter packets in the initial network namespace */
22596 +       if ((indev?indev:outdev)->nd_net != &init_net)
22597 +               return NF_ACCEPT;
22598 +
22599         DPRINTK("ing_hook: skb %s dev=%s len=%u\n",
22600                 skb->sk ? "(owned)" : "(unowned)",
22601                 skb->dev ? (*pskb)->dev->name : "(no dev)",
22602 diff -Nurb linux-2.6.22-try2/net/sctp/input.c linux-2.6.22-try2-netns/net/sctp/input.c
22603 --- linux-2.6.22-try2/net/sctp/input.c  2007-12-19 13:37:59.000000000 -0500
22604 +++ linux-2.6.22-try2-netns/net/sctp/input.c    2007-12-19 22:49:20.000000000 -0500
22605 @@ -126,6 +126,10 @@
22606         int family;
22607         struct sctp_af *af;
22608  
22609 +       if (skb->dev->nd_net != &init_net) {
22610 +               kfree_skb(skb);
22611 +               return 0;
22612 +       }
22613         if (skb->pkt_type!=PACKET_HOST)
22614                 goto discard_it;
22615  
22616 @@ -509,6 +513,9 @@
22617         sk_buff_data_t saveip, savesctp;
22618         int err;
22619  
22620 +       if (skb->dev->nd_net != &init_net)
22621 +               return;
22622 +
22623         if (skb->len < ihlen + 8) {
22624                 ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
22625                 return;
22626 diff -Nurb linux-2.6.22-try2/net/sctp/ipv6.c linux-2.6.22-try2-netns/net/sctp/ipv6.c
22627 --- linux-2.6.22-try2/net/sctp/ipv6.c   2007-12-19 13:37:59.000000000 -0500
22628 +++ linux-2.6.22-try2-netns/net/sctp/ipv6.c     2007-12-19 22:49:20.000000000 -0500
22629 @@ -189,6 +189,7 @@
22630  
22631         memset(&fl, 0, sizeof(fl));
22632  
22633 +       fl.fl_net = &init_net;
22634         fl.proto = sk->sk_protocol;
22635  
22636         /* Fill in the dest address from the route entry passed with the skb
22637 @@ -230,6 +231,7 @@
22638         struct flowi fl;
22639  
22640         memset(&fl, 0, sizeof(fl));
22641 +       fl.fl_net = &init_net;
22642         ipv6_addr_copy(&fl.fl6_dst, &daddr->v6.sin6_addr);
22643         if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
22644                 fl.oif = daddr->v6.sin6_scope_id;
22645 @@ -619,7 +621,7 @@
22646         struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
22647         struct sctp6_sock *newsctp6sk;
22648  
22649 -       newsk = sk_alloc(PF_INET6, GFP_KERNEL, sk->sk_prot, 1);
22650 +       newsk = sk_alloc(sk->sk_net, PF_INET6, GFP_KERNEL, sk->sk_prot, 1);
22651         if (!newsk)
22652                 goto out;
22653  
22654 @@ -664,7 +666,7 @@
22655         newinet->mc_index = 0;
22656         newinet->mc_list = NULL;
22657  
22658 -       if (ipv4_config.no_pmtu_disc)
22659 +       if (init_net.sysctl_ipv4_no_pmtu_disc)
22660                 newinet->pmtudisc = IP_PMTUDISC_DONT;
22661         else
22662                 newinet->pmtudisc = IP_PMTUDISC_WANT;
22663 @@ -841,7 +843,7 @@
22664                 if (type & IPV6_ADDR_LINKLOCAL) {
22665                         if (!addr->v6.sin6_scope_id)
22666                                 return 0;
22667 -                       dev = dev_get_by_index(addr->v6.sin6_scope_id);
22668 +                       dev = dev_get_by_index(&init_net, addr->v6.sin6_scope_id);
22669                         if (!dev)
22670                                 return 0;
22671                         if (!ipv6_chk_addr(&addr->v6.sin6_addr, dev, 0)) {
22672 @@ -872,7 +874,7 @@
22673                 if (type & IPV6_ADDR_LINKLOCAL) {
22674                         if (!addr->v6.sin6_scope_id)
22675                                 return 0;
22676 -                       dev = dev_get_by_index(addr->v6.sin6_scope_id);
22677 +                       dev = dev_get_by_index(&init_net, addr->v6.sin6_scope_id);
22678                         if (!dev)
22679                                 return 0;
22680                         if (!ipv6_chk_addr(&addr->v6.sin6_addr, dev, 0)) {
22681 diff -Nurb linux-2.6.22-try2/net/sctp/protocol.c linux-2.6.22-try2-netns/net/sctp/protocol.c
22682 --- linux-2.6.22-try2/net/sctp/protocol.c       2007-12-19 13:37:59.000000000 -0500
22683 +++ linux-2.6.22-try2-netns/net/sctp/protocol.c 2007-12-19 22:49:20.000000000 -0500
22684 @@ -59,6 +59,7 @@
22685  #include <net/addrconf.h>
22686  #include <net/inet_common.h>
22687  #include <net/inet_ecn.h>
22688 +#include <net/net_namespace.h>
22689  
22690  /* Global data structures. */
22691  struct sctp_globals sctp_globals __read_mostly;
22692 @@ -93,7 +94,7 @@
22693  {
22694         if (!proc_net_sctp) {
22695                 struct proc_dir_entry *ent;
22696 -               ent = proc_mkdir("net/sctp", NULL);
22697 +               ent = proc_mkdir("sctp", init_net.proc_net);
22698                 if (ent) {
22699                         ent->owner = THIS_MODULE;
22700                         proc_net_sctp = ent;
22701 @@ -126,7 +127,7 @@
22702  
22703         if (proc_net_sctp) {
22704                 proc_net_sctp = NULL;
22705 -               remove_proc_entry("net/sctp", NULL);
22706 +               remove_proc_entry("sctp", init_net.proc_net);
22707         }
22708  }
22709  
22710 @@ -170,7 +171,7 @@
22711         struct sctp_af *af;
22712  
22713         read_lock(&dev_base_lock);
22714 -       for_each_netdev(dev) {
22715 +       for_each_netdev(&init_net, dev) {
22716                 __list_for_each(pos, &sctp_address_families) {
22717                         af = list_entry(pos, struct sctp_af, list);
22718                         af->copy_addrlist(&sctp_local_addr_list, dev);
22719 @@ -354,13 +355,13 @@
22720  /* Should this be available for binding?   */
22721  static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
22722  {
22723 -       int ret = inet_addr_type(addr->v4.sin_addr.s_addr);
22724 +       int ret = inet_addr_type(&init_net, addr->v4.sin_addr.s_addr);
22725  
22726  
22727         if (addr->v4.sin_addr.s_addr != INADDR_ANY &&
22728            ret != RTN_LOCAL &&
22729            !sp->inet.freebind &&
22730 -          !sysctl_ip_nonlocal_bind)
22731 +          !init_net.sysctl_ip_nonlocal_bind)
22732                 return 0;
22733  
22734         return 1;
22735 @@ -423,6 +424,7 @@
22736         union sctp_addr dst_saddr;
22737  
22738         memset(&fl, 0x0, sizeof(struct flowi));
22739 +       fl.fl_net = &init_net;
22740         fl.fl4_dst  = daddr->v4.sin_addr.s_addr;
22741         fl.proto = IPPROTO_SCTP;
22742         if (asoc) {
22743 @@ -539,7 +541,7 @@
22744  {
22745         struct inet_sock *inet = inet_sk(sk);
22746         struct inet_sock *newinet;
22747 -       struct sock *newsk = sk_alloc(PF_INET, GFP_KERNEL, sk->sk_prot, 1);
22748 +       struct sock *newsk = sk_alloc(sk->sk_net, PF_INET, GFP_KERNEL, sk->sk_prot, 1);
22749  
22750         if (!newsk)
22751                 goto out;
22752 @@ -1122,7 +1124,7 @@
22753         }
22754  
22755         spin_lock_init(&sctp_port_alloc_lock);
22756 -       sctp_port_rover = sysctl_local_port_range[0] - 1;
22757 +       sctp_port_rover = init_net.sysctl_local_port_range[0] - 1;
22758  
22759         printk(KERN_INFO "SCTP: Hash tables configured "
22760                          "(established %d bind %d)\n",
22761 diff -Nurb linux-2.6.22-try2/net/sctp/socket.c linux-2.6.22-try2-netns/net/sctp/socket.c
22762 --- linux-2.6.22-try2/net/sctp/socket.c 2007-12-19 13:37:59.000000000 -0500
22763 +++ linux-2.6.22-try2-netns/net/sctp/socket.c   2007-12-19 22:49:20.000000000 -0500
22764 @@ -5021,8 +5021,8 @@
22765                  * already in the hash table; if not, we use that; if
22766                  * it is, we try next.
22767                  */
22768 -               int low = sysctl_local_port_range[0];
22769 -               int high = sysctl_local_port_range[1];
22770 +               int low = sk->sk_net->sysctl_local_port_range[0];
22771 +               int high = sk->sk_net->sysctl_local_port_range[1];
22772                 int remaining = (high - low) + 1;
22773                 int rover;
22774                 int index;
22775 diff -Nurb linux-2.6.22-try2/net/socket.c linux-2.6.22-try2-netns/net/socket.c
22776 --- linux-2.6.22-try2/net/socket.c      2007-12-19 13:37:59.000000000 -0500
22777 +++ linux-2.6.22-try2-netns/net/socket.c        2007-12-19 22:49:20.000000000 -0500
22778 @@ -84,6 +84,7 @@
22779  #include <linux/kmod.h>
22780  #include <linux/audit.h>
22781  #include <linux/wireless.h>
22782 +#include <linux/nsproxy.h>
22783  
22784  #include <asm/uaccess.h>
22785  #include <asm/unistd.h>
22786 @@ -821,9 +822,9 @@
22787   */
22788  
22789  static DEFINE_MUTEX(br_ioctl_mutex);
22790 -static int (*br_ioctl_hook) (unsigned int cmd, void __user *arg) = NULL;
22791 +static int (*br_ioctl_hook) (struct net *, unsigned int cmd, void __user *arg) = NULL;
22792  
22793 -void brioctl_set(int (*hook) (unsigned int, void __user *))
22794 +void brioctl_set(int (*hook) (struct net *, unsigned int, void __user *))
22795  {
22796         mutex_lock(&br_ioctl_mutex);
22797         br_ioctl_hook = hook;
22798 @@ -833,9 +834,9 @@
22799  EXPORT_SYMBOL(brioctl_set);
22800  
22801  static DEFINE_MUTEX(vlan_ioctl_mutex);
22802 -static int (*vlan_ioctl_hook) (void __user *arg);
22803 +static int (*vlan_ioctl_hook) (struct net *, void __user *arg);
22804  
22805 -void vlan_ioctl_set(int (*hook) (void __user *))
22806 +void vlan_ioctl_set(int (*hook) (struct net *, void __user *))
22807  {
22808         mutex_lock(&vlan_ioctl_mutex);
22809         vlan_ioctl_hook = hook;
22810 @@ -864,16 +865,20 @@
22811  static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
22812  {
22813         struct socket *sock;
22814 +       struct sock *sk;
22815         void __user *argp = (void __user *)arg;
22816         int pid, err;
22817 +       struct net *net;
22818  
22819         sock = file->private_data;
22820 +       sk = sock->sk;
22821 +       net = sk->sk_net;
22822         if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
22823 -               err = dev_ioctl(cmd, argp);
22824 +               err = dev_ioctl(net, cmd, argp);
22825         } else
22826  #ifdef CONFIG_WIRELESS_EXT
22827         if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
22828 -               err = dev_ioctl(cmd, argp);
22829 +               err = dev_ioctl(net, cmd, argp);
22830         } else
22831  #endif                         /* CONFIG_WIRELESS_EXT */
22832                 switch (cmd) {
22833 @@ -899,7 +904,7 @@
22834  
22835                         mutex_lock(&br_ioctl_mutex);
22836                         if (br_ioctl_hook)
22837 -                               err = br_ioctl_hook(cmd, argp);
22838 +                               err = br_ioctl_hook(net, cmd, argp);
22839                         mutex_unlock(&br_ioctl_mutex);
22840                         break;
22841                 case SIOCGIFVLAN:
22842 @@ -910,7 +915,7 @@
22843  
22844                         mutex_lock(&vlan_ioctl_mutex);
22845                         if (vlan_ioctl_hook)
22846 -                               err = vlan_ioctl_hook(argp);
22847 +                               err = vlan_ioctl_hook(net, argp);
22848                         mutex_unlock(&vlan_ioctl_mutex);
22849                         break;
22850                 case SIOCADDDLCI:
22851 @@ -933,7 +938,7 @@
22852                          * to the NIC driver.
22853                          */
22854                         if (err == -ENOIOCTLCMD)
22855 -                               err = dev_ioctl(cmd, argp);
22856 +                               err = dev_ioctl(net, cmd, argp);
22857                         break;
22858                 }
22859         return err;
22860 @@ -1102,7 +1107,7 @@
22861         return 0;
22862  }
22863  
22864 -static int __sock_create(int family, int type, int protocol,
22865 +static int __sock_create(struct net *net, int family, int type, int protocol,
22866                          struct socket **res, int kern)
22867  {
22868         int err;
22869 @@ -1185,7 +1190,7 @@
22870         /* Now protected by module ref count */
22871         rcu_read_unlock();
22872  
22873 -       err = pf->create(sock, protocol);
22874 +       err = pf->create(net, sock, protocol);
22875         if (err < 0)
22876                 goto out_module_put;
22877  
22878 @@ -1224,12 +1229,12 @@
22879  
22880  int sock_create(int family, int type, int protocol, struct socket **res)
22881  {
22882 -       return __sock_create(family, type, protocol, res, 0);
22883 +       return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);
22884  }
22885  
22886  int sock_create_kern(int family, int type, int protocol, struct socket **res)
22887  {
22888 -       return __sock_create(family, type, protocol, res, 1);
22889 +       return __sock_create(&init_net, family, type, protocol, res, 1);
22890  }
22891  
22892  asmlinkage long sys_socket(int family, int type, int protocol)
22893 @@ -1389,8 +1394,6 @@
22894   *     ready for listening.
22895   */
22896  
22897 -int sysctl_somaxconn __read_mostly = SOMAXCONN;
22898 -
22899  asmlinkage long sys_listen(int fd, int backlog)
22900  {
22901         struct socket *sock;
22902 @@ -1398,8 +1401,9 @@
22903  
22904         sock = sockfd_lookup_light(fd, &err, &fput_needed);
22905         if (sock) {
22906 -               if ((unsigned)backlog > sysctl_somaxconn)
22907 -                       backlog = sysctl_somaxconn;
22908 +               struct net *net = sock->sk->sk_net;
22909 +               if ((unsigned)backlog > net->sysctl_somaxconn)
22910 +                       backlog = net->sysctl_somaxconn;
22911  
22912                 err = security_socket_listen(sock, backlog);
22913                 if (!err)
22914 @@ -2189,6 +2193,16 @@
22915         printk(KERN_INFO "NET: Unregistered protocol family %d\n", family);
22916  }
22917  
22918 +static int sock_pernet_init(struct net *net)
22919 +{
22920 +       net->sysctl_somaxconn = SOMAXCONN;
22921 +       return 0;
22922 +}
22923 +
22924 +static struct pernet_operations sock_net_ops = {
22925 +       .init = sock_pernet_init,
22926 +};
22927 +
22928  static int __init sock_init(void)
22929  {
22930         /*
22931 @@ -2217,6 +2231,8 @@
22932         netfilter_init();
22933  #endif
22934  
22935 +       register_pernet_subsys(&sock_net_ops);
22936 +
22937         return 0;
22938  }
22939  
22940 diff -Nurb linux-2.6.22-try2/net/sunrpc/stats.c linux-2.6.22-try2-netns/net/sunrpc/stats.c
22941 --- linux-2.6.22-try2/net/sunrpc/stats.c        2007-12-19 13:37:59.000000000 -0500
22942 +++ linux-2.6.22-try2-netns/net/sunrpc/stats.c  2007-12-19 22:49:20.000000000 -0500
22943 @@ -21,6 +21,7 @@
22944  #include <linux/sunrpc/clnt.h>
22945  #include <linux/sunrpc/svcsock.h>
22946  #include <linux/sunrpc/metrics.h>
22947 +#include <net/net_namespace.h>
22948  
22949  #define RPCDBG_FACILITY        RPCDBG_MISC
22950  
22951 @@ -265,7 +266,7 @@
22952         dprintk("RPC:       registering /proc/net/rpc\n");
22953         if (!proc_net_rpc) {
22954                 struct proc_dir_entry *ent;
22955 -               ent = proc_mkdir("rpc", proc_net);
22956 +               ent = proc_mkdir("rpc", init_net.proc_net);
22957                 if (ent) {
22958                         ent->owner = THIS_MODULE;
22959                         proc_net_rpc = ent;
22960 @@ -279,7 +280,7 @@
22961         dprintk("RPC:       unregistering /proc/net/rpc\n");
22962         if (proc_net_rpc) {
22963                 proc_net_rpc = NULL;
22964 -               remove_proc_entry("net/rpc", NULL);
22965 +               remove_proc_entry("rpc", init_net.proc_net);
22966         }
22967  }
22968  
22969 diff -Nurb linux-2.6.22-try2/net/sysctl_net.c linux-2.6.22-try2-netns/net/sysctl_net.c
22970 --- linux-2.6.22-try2/net/sysctl_net.c  2007-12-19 13:37:59.000000000 -0500
22971 +++ linux-2.6.22-try2-netns/net/sysctl_net.c    2007-12-19 22:49:20.000000000 -0500
22972 @@ -54,3 +54,31 @@
22973  #endif
22974         { 0 },
22975  };
22976 +
22977 +struct ctl_table multi_net_table[] = {
22978 +       {
22979 +               .ctl_name       = NET_CORE,
22980 +               .procname       = "core",
22981 +               .mode           = 0555,
22982 +               .child          = multi_core_table,
22983 +       },
22984 +#ifdef CONFIG_INET
22985 +       {
22986 +               .ctl_name       = NET_IPV4,
22987 +               .procname       = "ipv4",
22988 +               .mode           = 0555,
22989 +               .child          = multi_ipv4_table,
22990 +       },
22991 +#endif
22992 +       {},
22993 +};
22994 +
22995 +struct ctl_table net_root_table[] = {
22996 +       {
22997 +               .ctl_name       = CTL_NET,
22998 +               .procname       = "net",
22999 +               .mode           = 0555,
23000 +               .child          = multi_net_table,
23001 +       },
23002 +       {},
23003 +};
23004 diff -Nurb linux-2.6.22-try2/net/tipc/eth_media.c linux-2.6.22-try2-netns/net/tipc/eth_media.c
23005 --- linux-2.6.22-try2/net/tipc/eth_media.c      2007-12-19 15:29:23.000000000 -0500
23006 +++ linux-2.6.22-try2-netns/net/tipc/eth_media.c        2007-12-19 22:49:20.000000000 -0500
23007 @@ -38,6 +38,7 @@
23008  #include <net/tipc/tipc_bearer.h>
23009  #include <net/tipc/tipc_msg.h>
23010  #include <linux/netdevice.h>
23011 +#include <net/net_namespace.h>
23012  
23013  #define MAX_ETH_BEARERS                2
23014  #define ETH_LINK_PRIORITY      TIPC_DEF_LINK_PRI
23015 @@ -100,6 +101,11 @@
23016         struct eth_bearer *eb_ptr = (struct eth_bearer *)pt->af_packet_priv;
23017         u32 size;
23018  
23019 +       if (dev->nd_net != &init_net) {
23020 +               kfree_skb(buf);
23021 +               return 0;
23022 +       }
23023 +
23024         if (likely(eb_ptr->bearer)) {
23025                 if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
23026                         size = msg_size((struct tipc_msg *)buf->data);
23027 @@ -129,7 +135,7 @@
23028  
23029         /* Find device with specified name */
23030  
23031 -       for_each_netdev(pdev){
23032 +       for_each_netdev(&init_net, pdev){
23033                 if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) {
23034                         dev = pdev;
23035                         break;
23036 @@ -192,6 +198,9 @@
23037         struct eth_bearer *eb_ptr = &eth_bearers[0];
23038         struct eth_bearer *stop = &eth_bearers[MAX_ETH_BEARERS];
23039  
23040 +       if (dev->nd_net != &init_net)
23041 +               return NOTIFY_DONE;
23042 +
23043         while ((eb_ptr->dev != dev)) {
23044                 if (++eb_ptr == stop)
23045                         return NOTIFY_DONE;     /* couldn't find device */
23046 diff -Nurb linux-2.6.22-try2/net/tipc/socket.c linux-2.6.22-try2-netns/net/tipc/socket.c
23047 --- linux-2.6.22-try2/net/tipc/socket.c 2007-12-19 15:29:23.000000000 -0500
23048 +++ linux-2.6.22-try2-netns/net/tipc/socket.c   2007-12-19 22:49:20.000000000 -0500
23049 @@ -162,13 +162,16 @@
23050   *
23051   * Returns 0 on success, errno otherwise
23052   */
23053 -static int tipc_create(struct socket *sock, int protocol)
23054 +static int tipc_create(struct net *net, struct socket *sock, int protocol)
23055  {
23056         struct tipc_sock *tsock;
23057         struct tipc_port *port;
23058         struct sock *sk;
23059         u32 ref;
23060  
23061 +       if (net != &init_net)
23062 +               return -EAFNOSUPPORT;
23063 +
23064         if (unlikely(protocol != 0))
23065                 return -EPROTONOSUPPORT;
23066  
23067 @@ -198,7 +201,7 @@
23068                 return -EPROTOTYPE;
23069         }
23070  
23071 -       sk = sk_alloc(AF_TIPC, GFP_KERNEL, &tipc_proto, 1);
23072 +       sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto, 1);
23073         if (!sk) {
23074                 tipc_deleteport(ref);
23075                 return -ENOMEM;
23076 @@ -1372,7 +1375,7 @@
23077         }
23078         buf = skb_peek(&sock->sk->sk_receive_queue);
23079  
23080 -       res = tipc_create(newsock, 0);
23081 +       res = tipc_create(sock->sk->sk_net, newsock, 0);
23082         if (!res) {
23083                 struct tipc_sock *new_tsock = tipc_sk(newsock->sk);
23084                 struct tipc_portid id;
23085 diff -Nurb linux-2.6.22-try2/net/unix/af_unix.c linux-2.6.22-try2-netns/net/unix/af_unix.c
23086 --- linux-2.6.22-try2/net/unix/af_unix.c        2007-12-19 13:37:59.000000000 -0500
23087 +++ linux-2.6.22-try2-netns/net/unix/af_unix.c  2007-12-19 23:38:14.000000000 -0500
23088 @@ -117,8 +117,8 @@
23089  #include <linux/security.h>
23090  #include <linux/vs_context.h>
23091  #include <linux/vs_limit.h>
23092 +#include <net/net_namespace.h>
23093  
23094 -int sysctl_unix_max_dgram_qlen __read_mostly = 10;
23095  
23096  struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
23097  DEFINE_SPINLOCK(unix_table_lock);
23098 @@ -245,7 +245,8 @@
23099         spin_unlock(&unix_table_lock);
23100  }
23101  
23102 -static struct sock *__unix_find_socket_byname(struct sockaddr_un *sunname,
23103 +static struct sock *__unix_find_socket_byname(struct net *net,
23104 +                                             struct sockaddr_un *sunname,
23105                                               int len, int type, unsigned hash)
23106  {
23107         struct sock *s;
23108 @@ -254,7 +255,7 @@
23109         sk_for_each(s, node, &unix_socket_table[hash ^ type]) {
23110                 struct unix_sock *u = unix_sk(s);
23111  
23112 -               if (!nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT))
23113 +               if (!nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT) || (s->sk_net != net))
23114                         continue;
23115                 if (u->addr->len == len &&
23116                     !memcmp(u->addr->name, sunname, len))
23117 @@ -265,21 +266,22 @@
23118         return s;
23119  }
23120  
23121 -static inline struct sock *unix_find_socket_byname(struct sockaddr_un *sunname,
23122 +static inline struct sock *unix_find_socket_byname(struct net *net,
23123 +                                                  struct sockaddr_un *sunname,
23124                                                    int len, int type,
23125                                                    unsigned hash)
23126  {
23127         struct sock *s;
23128  
23129         spin_lock(&unix_table_lock);
23130 -       s = __unix_find_socket_byname(sunname, len, type, hash);
23131 +       s = __unix_find_socket_byname(net, sunname, len, type, hash);
23132         if (s)
23133                 sock_hold(s);
23134         spin_unlock(&unix_table_lock);
23135         return s;
23136  }
23137  
23138 -static struct sock *unix_find_socket_byinode(struct inode *i)
23139 +static struct sock *unix_find_socket_byinode(struct net *net, struct inode *i)
23140  {
23141         struct sock *s;
23142         struct hlist_node *node;
23143 @@ -289,6 +291,9 @@
23144                     &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
23145                 struct dentry *dentry = unix_sk(s)->dentry;
23146  
23147 +               if (s->sk_net != net)
23148 +                       continue;
23149 +
23150                 if(dentry && dentry->d_inode == i)
23151                 {
23152                         sock_hold(s);
23153 @@ -571,7 +576,7 @@
23154   */
23155  static struct lock_class_key af_unix_sk_receive_queue_lock_key;
23156  
23157 -static struct sock * unix_create1(struct socket *sock)
23158 +static struct sock * unix_create1(struct net *net, struct socket *sock)
23159  {
23160         struct sock *sk = NULL;
23161         struct unix_sock *u;
23162 @@ -579,7 +584,7 @@
23163         if (atomic_read(&unix_nr_socks) >= 2*get_max_files())
23164                 goto out;
23165  
23166 -       sk = sk_alloc(PF_UNIX, GFP_KERNEL, &unix_proto, 1);
23167 +       sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto, 1);
23168         if (!sk)
23169                 goto out;
23170  
23171 @@ -590,7 +595,7 @@
23172                                 &af_unix_sk_receive_queue_lock_key);
23173  
23174         sk->sk_write_space      = unix_write_space;
23175 -       sk->sk_max_ack_backlog  = sysctl_unix_max_dgram_qlen;
23176 +       sk->sk_max_ack_backlog  = net->sysctl_unix_max_dgram_qlen;
23177         sk->sk_destruct         = unix_sock_destructor;
23178         u         = unix_sk(sk);
23179         u->dentry = NULL;
23180 @@ -604,7 +609,7 @@
23181         return sk;
23182  }
23183  
23184 -static int unix_create(struct socket *sock, int protocol)
23185 +static int unix_create(struct net *net, struct socket *sock, int protocol)
23186  {
23187         if (protocol && protocol != PF_UNIX)
23188                 return -EPROTONOSUPPORT;
23189 @@ -631,7 +636,7 @@
23190                 return -ESOCKTNOSUPPORT;
23191         }
23192  
23193 -       return unix_create1(sock) ? 0 : -ENOMEM;
23194 +       return unix_create1(net, sock) ? 0 : -ENOMEM;
23195  }
23196  
23197  static int unix_release(struct socket *sock)
23198 @@ -649,6 +654,7 @@
23199  static int unix_autobind(struct socket *sock)
23200  {
23201         struct sock *sk = sock->sk;
23202 +       struct net *net = sk->sk_net;
23203         struct unix_sock *u = unix_sk(sk);
23204         static u32 ordernum = 1;
23205         struct unix_address * addr;
23206 @@ -675,7 +681,7 @@
23207         spin_lock(&unix_table_lock);
23208         ordernum = (ordernum+1)&0xFFFFF;
23209  
23210 -       if (__unix_find_socket_byname(addr->name, addr->len, sock->type,
23211 +       if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type,
23212                                       addr->hash)) {
23213                 spin_unlock(&unix_table_lock);
23214                 /* Sanity yield. It is unusual case, but yet... */
23215 @@ -695,7 +701,8 @@
23216         return err;
23217  }
23218  
23219 -static struct sock *unix_find_other(struct sockaddr_un *sunname, int len,
23220 +static struct sock *unix_find_other(struct net *net,
23221 +                                   struct sockaddr_un *sunname, int len,
23222                                     int type, unsigned hash, int *error)
23223  {
23224         struct sock *u;
23225 @@ -713,7 +720,7 @@
23226                 err = -ECONNREFUSED;
23227                 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
23228                         goto put_fail;
23229 -               u=unix_find_socket_byinode(nd.dentry->d_inode);
23230 +               u=unix_find_socket_byinode(net, nd.dentry->d_inode);
23231                 if (!u)
23232                         goto put_fail;
23233  
23234 @@ -729,7 +736,7 @@
23235                 }
23236         } else {
23237                 err = -ECONNREFUSED;
23238 -               u=unix_find_socket_byname(sunname, len, type, hash);
23239 +               u=unix_find_socket_byname(net, sunname, len, type, hash);
23240                 if (u) {
23241                         struct dentry *dentry;
23242                         dentry = unix_sk(u)->dentry;
23243 @@ -751,6 +758,7 @@
23244  static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
23245  {
23246         struct sock *sk = sock->sk;
23247 +       struct net *net = sk->sk_net;
23248         struct unix_sock *u = unix_sk(sk);
23249         struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
23250         struct dentry * dentry = NULL;
23251 @@ -825,7 +833,7 @@
23252  
23253         if (!sunaddr->sun_path[0]) {
23254                 err = -EADDRINUSE;
23255 -               if (__unix_find_socket_byname(sunaddr, addr_len,
23256 +               if (__unix_find_socket_byname(net, sunaddr, addr_len,
23257                                               sk->sk_type, hash)) {
23258                         unix_release_addr(addr);
23259                         goto out_unlock;
23260 @@ -891,6 +899,7 @@
23261                               int alen, int flags)
23262  {
23263         struct sock *sk = sock->sk;
23264 +       struct net *net = sk->sk_net;
23265         struct sockaddr_un *sunaddr=(struct sockaddr_un*)addr;
23266         struct sock *other;
23267         unsigned hash;
23268 @@ -907,7 +916,7 @@
23269                         goto out;
23270  
23271  restart:
23272 -               other=unix_find_other(sunaddr, alen, sock->type, hash, &err);
23273 +               other=unix_find_other(net, sunaddr, alen, sock->type, hash, &err);
23274                 if (!other)
23275                         goto out;
23276  
23277 @@ -987,6 +996,7 @@
23278  {
23279         struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
23280         struct sock *sk = sock->sk;
23281 +       struct net *net = sk->sk_net;
23282         struct unix_sock *u = unix_sk(sk), *newu, *otheru;
23283         struct sock *newsk = NULL;
23284         struct sock *other = NULL;
23285 @@ -1015,7 +1025,7 @@
23286         err = -ENOMEM;
23287  
23288         /* create new sock for complete connection */
23289 -       newsk = unix_create1(NULL);
23290 +       newsk = unix_create1(sk->sk_net, NULL);
23291         if (newsk == NULL)
23292                 goto out;
23293  
23294 @@ -1026,7 +1036,7 @@
23295  
23296  restart:
23297         /*  Find listening sock. */
23298 -       other = unix_find_other(sunaddr, addr_len, sk->sk_type, hash, &err);
23299 +       other = unix_find_other(net, sunaddr, addr_len, sk->sk_type, hash, &err);
23300         if (!other)
23301                 goto out;
23302  
23303 @@ -1305,6 +1315,7 @@
23304  {
23305         struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
23306         struct sock *sk = sock->sk;
23307 +       struct net *net = sk->sk_net;
23308         struct unix_sock *u = unix_sk(sk);
23309         struct sockaddr_un *sunaddr=msg->msg_name;
23310         struct sock *other = NULL;
23311 @@ -1368,7 +1379,7 @@
23312                 if (sunaddr == NULL)
23313                         goto out_free;
23314  
23315 -               other = unix_find_other(sunaddr, namelen, sk->sk_type,
23316 +               other = unix_find_other(net, sunaddr, namelen, sk->sk_type,
23317                                         hash, &err);
23318                 if (other==NULL)
23319                         goto out_free;
23320 @@ -1974,12 +1985,18 @@
23321  
23322  
23323  #ifdef CONFIG_PROC_FS
23324 -static struct sock *unix_seq_idx(int *iter, loff_t pos)
23325 +struct unix_iter_state {
23326 +       struct net *net;
23327 +       int i;
23328 +};
23329 +static struct sock *unix_seq_idx(struct unix_iter_state *iter, loff_t pos)
23330  {
23331         loff_t off = 0;
23332         struct sock *s;
23333  
23334 -       for (s = first_unix_socket(iter); s; s = next_unix_socket(iter, s)) {
23335 +       for (s = first_unix_socket(&iter->i); s; s = next_unix_socket(&iter->i, s)) {
23336 +               if (s->sk_net != iter->net)
23337 +                       continue;
23338                 if (off == pos)
23339                         return s;
23340                 ++off;
23341 @@ -1990,17 +2007,24 @@
23342  
23343  static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
23344  {
23345 +       struct unix_iter_state *iter = seq->private;
23346         spin_lock(&unix_table_lock);
23347 -       return *pos ? unix_seq_idx(seq->private, *pos - 1) : ((void *) 1);
23348 +       return *pos ? unix_seq_idx(iter, *pos - 1) : ((void *) 1);
23349  }
23350  
23351  static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
23352  {
23353 +       struct unix_iter_state *iter = seq->private;
23354 +       struct sock *sk = v;
23355         ++*pos;
23356  
23357         if (v == (void *)1)
23358 -               return first_unix_socket(seq->private);
23359 -       return next_unix_socket(seq->private, v);
23360 +               sk = first_unix_socket(&iter->i);
23361 +       else
23362 +               sk = next_unix_socket(&iter->i, sk);
23363 +       while (sk && (sk->sk_net != iter->net))
23364 +               sk = next_unix_socket(&iter->i, sk);
23365 +       return sk;
23366  }
23367  
23368  static void unix_seq_stop(struct seq_file *seq, void *v)
23369 @@ -2064,7 +2088,7 @@
23370  {
23371         struct seq_file *seq;
23372         int rc = -ENOMEM;
23373 -       int *iter = kmalloc(sizeof(int), GFP_KERNEL);
23374 +       struct unix_iter_state *iter = kmalloc(sizeof(*iter), GFP_KERNEL);
23375  
23376         if (!iter)
23377                 goto out;
23378 @@ -2075,7 +2099,8 @@
23379  
23380         seq          = file->private_data;
23381         seq->private = iter;
23382 -       *iter = 0;
23383 +       iter->net = get_net(PROC_NET(inode));
23384 +       iter->i = 0;
23385  out:
23386         return rc;
23387  out_kfree:
23388 @@ -2083,12 +2108,20 @@
23389         goto out;
23390  }
23391  
23392 +static int unix_seq_release(struct inode *inode, struct file *file)
23393 +{
23394 +       struct seq_file *seq = file->private_data;
23395 +       struct unix_iter_state *iter = seq->private;
23396 +       put_net(iter->net);
23397 +       return seq_release_private(inode, file);
23398 +}
23399 +
23400  static const struct file_operations unix_seq_fops = {
23401         .owner          = THIS_MODULE,
23402         .open           = unix_seq_open,
23403         .read           = seq_read,
23404         .llseek         = seq_lseek,
23405 -       .release        = seq_release_private,
23406 +       .release        = unix_seq_release,
23407  };
23408  
23409  #endif
23410 @@ -2099,6 +2132,33 @@
23411         .owner  = THIS_MODULE,
23412  };
23413  
23414 +
23415 +static int unix_net_init(struct net *net)
23416 +{
23417 +       int error = -ENOMEM;
23418 +
23419 +       net->sysctl_unix_max_dgram_qlen = 10;
23420 +#ifdef CONFIG_PROC_FS
23421 +       if (!proc_net_fops_create(net, "unix", 0, &unix_seq_fops))
23422 +               goto out;
23423 +#endif
23424 +       unix_sysctl_register(net);
23425 +       error = 0;
23426 +out:
23427 +       return 0;
23428 +}
23429 +
23430 +static void unix_net_exit(struct net *net)
23431 +{
23432 +       unix_sysctl_unregister(net);
23433 +       proc_net_remove(net, "unix");
23434 +}
23435 +
23436 +static struct pernet_operations unix_net_ops = {
23437 +       .init = unix_net_init,
23438 +       .exit = unix_net_exit,
23439 +};
23440 +
23441  static int __init af_unix_init(void)
23442  {
23443         int rc = -1;
23444 @@ -2114,10 +2174,7 @@
23445         }
23446  
23447         sock_register(&unix_family_ops);
23448 -#ifdef CONFIG_PROC_FS
23449 -       proc_net_fops_create("unix", 0, &unix_seq_fops);
23450 -#endif
23451 -       unix_sysctl_register();
23452 +       register_pernet_subsys(&unix_net_ops);
23453  out:
23454         return rc;
23455  }
23456 @@ -2125,9 +2182,8 @@
23457  static void __exit af_unix_exit(void)
23458  {
23459         sock_unregister(PF_UNIX);
23460 -       unix_sysctl_unregister();
23461 -       proc_net_remove("unix");
23462         proto_unregister(&unix_proto);
23463 +       unregister_pernet_subsys(&unix_net_ops);
23464  }
23465  
23466  module_init(af_unix_init);
23467 diff -Nurb linux-2.6.22-try2/net/unix/sysctl_net_unix.c linux-2.6.22-try2-netns/net/unix/sysctl_net_unix.c
23468 --- linux-2.6.22-try2/net/unix/sysctl_net_unix.c        2007-12-19 13:37:59.000000000 -0500
23469 +++ linux-2.6.22-try2-netns/net/unix/sysctl_net_unix.c  2007-12-19 22:49:20.000000000 -0500
23470 @@ -14,47 +14,71 @@
23471  
23472  #include <net/af_unix.h>
23473  
23474 -static ctl_table unix_table[] = {
23475 +static struct unix_sysctl_table {
23476 +       struct ctl_table_header *sysctl_header;
23477 +       struct ctl_table        unix_table[2];
23478 +       struct ctl_table        unix_net_table[2];
23479 +       struct ctl_table        unix_root_table[2];
23480 +} unix_sysctl = {
23481 +       .unix_table = {
23482         {
23483                 .ctl_name       = NET_UNIX_MAX_DGRAM_QLEN,
23484                 .procname       = "max_dgram_qlen",
23485 -               .data           = &sysctl_unix_max_dgram_qlen,
23486 +                       .data           = &init_net.sysctl_unix_max_dgram_qlen,
23487                 .maxlen         = sizeof(int),
23488                 .mode           = 0644,
23489                 .proc_handler   = &proc_dointvec
23490         },
23491 -       { .ctl_name = 0 }
23492 -};
23493 -
23494 -static ctl_table unix_net_table[] = {
23495 +               {}
23496 +       },
23497 +       .unix_net_table = {
23498         {
23499                 .ctl_name       = NET_UNIX,
23500                 .procname       = "unix",
23501                 .mode           = 0555,
23502 -               .child          = unix_table
23503 +                       .child          = unix_sysctl.unix_table
23504         },
23505 -       { .ctl_name = 0 }
23506 -};
23507 -
23508 -static ctl_table unix_root_table[] = {
23509 +               {}
23510 +       },
23511 +       .unix_root_table = {
23512         {
23513                 .ctl_name       = CTL_NET,
23514                 .procname       = "net",
23515                 .mode           = 0555,
23516 -               .child          = unix_net_table
23517 +                       .child          = unix_sysctl.unix_net_table
23518         },
23519 -       { .ctl_name = 0 }
23520 +               {}
23521 +       }
23522  };
23523  
23524 -static struct ctl_table_header * unix_sysctl_header;
23525 -
23526 -void unix_sysctl_register(void)
23527 +void unix_sysctl_register(struct net *net)
23528  {
23529 -       unix_sysctl_header = register_sysctl_table(unix_root_table);
23530 +       struct unix_sysctl_table *table;
23531 +       int i;
23532 +
23533 +       table = kmemdup(&unix_sysctl, sizeof(*table), GFP_KERNEL);
23534 +       if (!table)
23535 +               return;
23536 +       for (i = 0; i < ARRAY_SIZE(table->unix_table) - 1; i++)
23537 +               table->unix_table[i].data += (char *)net - (char *)&init_net;
23538 +
23539 +       table->unix_net_table[0].child = table->unix_table;
23540 +       table->unix_root_table[0].child = table->unix_net_table;
23541 +
23542 +       table->sysctl_header = 
23543 +               register_net_sysctl_table(net, table->unix_root_table);
23544 +       if (!table->sysctl_header) {
23545 +               kfree(table);
23546 +               return;
23547 +       }
23548 +       net->unix_sysctl = table;
23549  }
23550  
23551 -void unix_sysctl_unregister(void)
23552 +void unix_sysctl_unregister(struct net *net)
23553  {
23554 -       unregister_sysctl_table(unix_sysctl_header);
23555 +       struct unix_sysctl_table *table = net->unix_sysctl;
23556 +       if (table)
23557 +               unregister_net_sysctl_table(table->sysctl_header);
23558 +       kfree(table);
23559  }
23560  
23561 diff -Nurb linux-2.6.22-try2/net/wanrouter/wanproc.c linux-2.6.22-try2-netns/net/wanrouter/wanproc.c
23562 --- linux-2.6.22-try2/net/wanrouter/wanproc.c   2007-12-19 13:37:59.000000000 -0500
23563 +++ linux-2.6.22-try2-netns/net/wanrouter/wanproc.c     2007-12-19 22:49:20.000000000 -0500
23564 @@ -28,6 +28,7 @@
23565  #include <linux/wanrouter.h>   /* WAN router API definitions */
23566  #include <linux/seq_file.h>
23567  #include <linux/smp_lock.h>
23568 +#include <net/net_namespace.h>
23569  
23570  #include <asm/io.h>
23571  
23572 @@ -287,7 +288,7 @@
23573  int __init wanrouter_proc_init(void)
23574  {
23575         struct proc_dir_entry *p;
23576 -       proc_router = proc_mkdir(ROUTER_NAME, proc_net);
23577 +       proc_router = proc_mkdir(ROUTER_NAME, init_net.proc_net);
23578         if (!proc_router)
23579                 goto fail;
23580  
23581 @@ -303,7 +304,7 @@
23582  fail_stat:
23583         remove_proc_entry("config", proc_router);
23584  fail_config:
23585 -       remove_proc_entry(ROUTER_NAME, proc_net);
23586 +       remove_proc_entry(ROUTER_NAME, init_net.proc_net);
23587  fail:
23588         return -ENOMEM;
23589  }
23590 @@ -316,7 +317,7 @@
23591  {
23592         remove_proc_entry("config", proc_router);
23593         remove_proc_entry("status", proc_router);
23594 -       remove_proc_entry(ROUTER_NAME, proc_net);
23595 +       remove_proc_entry(ROUTER_NAME, init_net.proc_net);
23596  }
23597  
23598  /*
23599 diff -Nurb linux-2.6.22-try2/net/wireless/wext.c linux-2.6.22-try2-netns/net/wireless/wext.c
23600 --- linux-2.6.22-try2/net/wireless/wext.c       2007-12-19 13:37:59.000000000 -0500
23601 +++ linux-2.6.22-try2-netns/net/wireless/wext.c 2007-12-19 22:49:20.000000000 -0500
23602 @@ -95,6 +95,7 @@
23603  #include <linux/interrupt.h>
23604  
23605  #include <linux/wireless.h>            /* Pretty obvious */
23606 +#include <net/net_namespace.h>
23607  #include <net/iw_handler.h>            /* New driver API */
23608  #include <net/netlink.h>
23609  #include <net/wext.h>
23610 @@ -672,7 +673,22 @@
23611  
23612  static int wireless_seq_open(struct inode *inode, struct file *file)
23613  {
23614 -       return seq_open(file, &wireless_seq_ops);
23615 +       struct seq_file *seq;
23616 +       int res;
23617 +       res = seq_open(file, &wireless_seq_ops);
23618 +       if (!res) {
23619 +               seq = file->private_data;
23620 +               seq->private = get_net(PROC_NET(inode));
23621 +       }
23622 +       return res;
23623 +}
23624 +
23625 +static int wireless_seq_release(struct inode *inode, struct file *file)
23626 +{
23627 +       struct seq_file *seq = file->private_data;
23628 +       struct net *net = seq->private;
23629 +       put_net(net);
23630 +       return seq_release(inode, file);
23631  }
23632  
23633  static const struct file_operations wireless_seq_fops = {
23634 @@ -680,17 +696,22 @@
23635         .open    = wireless_seq_open,
23636         .read    = seq_read,
23637         .llseek  = seq_lseek,
23638 -       .release = seq_release,
23639 +       .release = wireless_seq_release,
23640  };
23641  
23642 -int __init wext_proc_init(void)
23643 +int wext_proc_init(struct net *net)
23644  {
23645         /* Create /proc/net/wireless entry */
23646 -       if (!proc_net_fops_create("wireless", S_IRUGO, &wireless_seq_fops))
23647 +       if (!proc_net_fops_create(net, "wireless", S_IRUGO, &wireless_seq_fops))
23648                 return -ENOMEM;
23649  
23650         return 0;
23651  }
23652 +
23653 +void wext_proc_exit(struct net *net)
23654 +{
23655 +       proc_net_remove(net, "wireless");
23656 +}
23657  #endif /* CONFIG_PROC_FS */
23658  
23659  /************************** IOCTL SUPPORT **************************/
23660 @@ -1010,7 +1031,7 @@
23661   * Main IOCTl dispatcher.
23662   * Check the type of IOCTL and call the appropriate wrapper...
23663   */
23664 -static int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd)
23665 +static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd)
23666  {
23667         struct net_device *dev;
23668         iw_handler      handler;
23669 @@ -1019,7 +1040,7 @@
23670          * The copy_to/from_user() of ifr is also dealt with in there */
23671  
23672         /* Make sure the device exist */
23673 -       if ((dev = __dev_get_by_name(ifr->ifr_name)) == NULL)
23674 +       if ((dev = __dev_get_by_name(net, ifr->ifr_name)) == NULL)
23675                 return -ENODEV;
23676  
23677         /* A bunch of special cases, then the generic case...
23678 @@ -1053,7 +1074,7 @@
23679  }
23680  
23681  /* entry point from dev ioctl */
23682 -int wext_handle_ioctl(struct ifreq *ifr, unsigned int cmd,
23683 +int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd,
23684                       void __user *arg)
23685  {
23686         int ret;
23687 @@ -1065,9 +1086,9 @@
23688             && !capable(CAP_NET_ADMIN))
23689                 return -EPERM;
23690  
23691 -       dev_load(ifr->ifr_name);
23692 +       dev_load(net, ifr->ifr_name);
23693         rtnl_lock();
23694 -       ret = wireless_process_ioctl(ifr, cmd);
23695 +       ret = wireless_process_ioctl(net, ifr, cmd);
23696         rtnl_unlock();
23697         if (IW_IS_GET(cmd) && copy_to_user(arg, ifr, sizeof(struct ifreq)))
23698                 return -EFAULT;
23699 @@ -1111,8 +1132,13 @@
23700  {
23701         struct sk_buff *skb;
23702  
23703 -       while ((skb = skb_dequeue(&wireless_nlevent_queue)))
23704 -               rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
23705 +       while ((skb = skb_dequeue(&wireless_nlevent_queue))) {
23706 +               struct net_device *dev = skb->dev;
23707 +               struct net *net = dev->nd_net;
23708 +               skb->dev = NULL;
23709 +               rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
23710 +               dev_put(dev);
23711 +       }
23712  }
23713  
23714  static DECLARE_TASKLET(wireless_nlevent_tasklet, wireless_nlevent_process, 0);
23715 @@ -1173,6 +1199,9 @@
23716                 kfree_skb(skb);
23717                 return;
23718         }
23719 +       /* Remember the device until we are in process context */
23720 +       dev_hold(dev);
23721 +       skb->dev = dev;
23722         NETLINK_CB(skb).dst_group = RTNLGRP_LINK;
23723         skb_queue_tail(&wireless_nlevent_queue, skb);
23724         tasklet_schedule(&wireless_nlevent_tasklet);
23725 diff -Nurb linux-2.6.22-try2/net/x25/af_x25.c linux-2.6.22-try2-netns/net/x25/af_x25.c
23726 --- linux-2.6.22-try2/net/x25/af_x25.c  2007-12-19 13:38:00.000000000 -0500
23727 +++ linux-2.6.22-try2-netns/net/x25/af_x25.c    2007-12-19 22:49:20.000000000 -0500
23728 @@ -191,6 +191,9 @@
23729         struct net_device *dev = ptr;
23730         struct x25_neigh *nb;
23731  
23732 +       if (dev->nd_net != &init_net)
23733 +               return NOTIFY_DONE;
23734 +
23735         if (dev->type == ARPHRD_X25
23736  #if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE)
23737          || dev->type == ARPHRD_ETHER
23738 @@ -466,10 +469,10 @@
23739         .obj_size = sizeof(struct x25_sock),
23740  };
23741  
23742 -static struct sock *x25_alloc_socket(void)
23743 +static struct sock *x25_alloc_socket(struct net *net)
23744  {
23745         struct x25_sock *x25;
23746 -       struct sock *sk = sk_alloc(AF_X25, GFP_ATOMIC, &x25_proto, 1);
23747 +       struct sock *sk = sk_alloc(net, AF_X25, GFP_ATOMIC, &x25_proto, 1);
23748  
23749         if (!sk)
23750                 goto out;
23751 @@ -485,17 +488,20 @@
23752         return sk;
23753  }
23754  
23755 -static int x25_create(struct socket *sock, int protocol)
23756 +static int x25_create(struct net *net, struct socket *sock, int protocol)
23757  {
23758         struct sock *sk;
23759         struct x25_sock *x25;
23760         int rc = -ESOCKTNOSUPPORT;
23761  
23762 +       if (net != &init_net)
23763 +               return -EAFNOSUPPORT;
23764 +
23765         if (sock->type != SOCK_SEQPACKET || protocol)
23766                 goto out;
23767  
23768         rc = -ENOMEM;
23769 -       if ((sk = x25_alloc_socket()) == NULL)
23770 +       if ((sk = x25_alloc_socket(net)) == NULL)
23771                 goto out;
23772  
23773         x25 = x25_sk(sk);
23774 @@ -546,7 +552,7 @@
23775         if (osk->sk_type != SOCK_SEQPACKET)
23776                 goto out;
23777  
23778 -       if ((sk = x25_alloc_socket()) == NULL)
23779 +       if ((sk = x25_alloc_socket(osk->sk_net)) == NULL)
23780                 goto out;
23781  
23782         x25 = x25_sk(sk);
23783 diff -Nurb linux-2.6.22-try2/net/x25/x25_dev.c linux-2.6.22-try2-netns/net/x25/x25_dev.c
23784 --- linux-2.6.22-try2/net/x25/x25_dev.c 2007-12-19 13:38:00.000000000 -0500
23785 +++ linux-2.6.22-try2-netns/net/x25/x25_dev.c   2007-12-19 22:49:20.000000000 -0500
23786 @@ -95,6 +95,9 @@
23787         struct sk_buff *nskb;
23788         struct x25_neigh *nb;
23789  
23790 +       if (dev->nd_net != &init_net)
23791 +               goto drop;
23792 +
23793         nskb = skb_copy(skb, GFP_ATOMIC);
23794         if (!nskb)
23795                 goto drop;
23796 diff -Nurb linux-2.6.22-try2/net/x25/x25_proc.c linux-2.6.22-try2-netns/net/x25/x25_proc.c
23797 --- linux-2.6.22-try2/net/x25/x25_proc.c        2007-12-19 13:38:00.000000000 -0500
23798 +++ linux-2.6.22-try2-netns/net/x25/x25_proc.c  2007-12-19 22:49:20.000000000 -0500
23799 @@ -20,6 +20,7 @@
23800  #include <linux/init.h>
23801  #include <linux/proc_fs.h>
23802  #include <linux/seq_file.h>
23803 +#include <net/net_namespace.h>
23804  #include <net/sock.h>
23805  #include <net/x25.h>
23806  
23807 @@ -301,7 +302,7 @@
23808         struct proc_dir_entry *p;
23809         int rc = -ENOMEM;
23810  
23811 -       x25_proc_dir = proc_mkdir("x25", proc_net);
23812 +       x25_proc_dir = proc_mkdir("x25", init_net.proc_net);
23813         if (!x25_proc_dir)
23814                 goto out;
23815  
23816 @@ -328,7 +329,7 @@
23817  out_socket:
23818         remove_proc_entry("route", x25_proc_dir);
23819  out_route:
23820 -       remove_proc_entry("x25", proc_net);
23821 +       remove_proc_entry("x25", init_net.proc_net);
23822         goto out;
23823  }
23824  
23825 @@ -337,7 +338,7 @@
23826         remove_proc_entry("forward", x25_proc_dir);
23827         remove_proc_entry("route", x25_proc_dir);
23828         remove_proc_entry("socket", x25_proc_dir);
23829 -       remove_proc_entry("x25", proc_net);
23830 +       remove_proc_entry("x25", init_net.proc_net);
23831  }
23832  
23833  #else /* CONFIG_PROC_FS */
23834 diff -Nurb linux-2.6.22-try2/net/x25/x25_route.c linux-2.6.22-try2-netns/net/x25/x25_route.c
23835 --- linux-2.6.22-try2/net/x25/x25_route.c       2007-12-19 13:38:00.000000000 -0500
23836 +++ linux-2.6.22-try2-netns/net/x25/x25_route.c 2007-12-19 22:49:20.000000000 -0500
23837 @@ -129,7 +129,7 @@
23838   */
23839  struct net_device *x25_dev_get(char *devname)
23840  {
23841 -       struct net_device *dev = dev_get_by_name(devname);
23842 +       struct net_device *dev = dev_get_by_name(&init_net, devname);
23843  
23844         if (dev &&
23845             (!(dev->flags & IFF_UP) || (dev->type != ARPHRD_X25
23846 diff -Nurb linux-2.6.22-try2/net/xfrm/xfrm_policy.c linux-2.6.22-try2-netns/net/xfrm/xfrm_policy.c
23847 --- linux-2.6.22-try2/net/xfrm/xfrm_policy.c    2007-12-19 13:38:00.000000000 -0500
23848 +++ linux-2.6.22-try2-netns/net/xfrm/xfrm_policy.c      2007-12-19 22:49:20.000000000 -0500
23849 @@ -30,8 +30,6 @@
23850  
23851  #include "xfrm_hash.h"
23852  
23853 -int sysctl_xfrm_larval_drop __read_mostly;
23854 -
23855  DEFINE_MUTEX(xfrm_cfg_mutex);
23856  EXPORT_SYMBOL(xfrm_cfg_mutex);
23857  
23858 @@ -1570,7 +1568,7 @@
23859  
23860                 if (unlikely(nx<0)) {
23861                         err = nx;
23862 -                       if (err == -EAGAIN && sysctl_xfrm_larval_drop) {
23863 +                       if (err == -EAGAIN && init_net.sysctl_xfrm_larval_drop) {
23864                                 /* EREMOTE tells the caller to generate
23865                                  * a one-shot blackhole route.
23866                                  */
23867 @@ -1954,8 +1952,8 @@
23868  void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev)
23869  {
23870         while ((dst = dst->child) && dst->xfrm && dst->dev == dev) {
23871 -               dst->dev = &loopback_dev;
23872 -               dev_hold(&loopback_dev);
23873 +               dst->dev = &init_net.loopback_dev;
23874 +               dev_hold(dst->dev);
23875                 dev_put(dev);
23876         }
23877  }
23878 @@ -2357,6 +2355,11 @@
23879  
23880  static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
23881  {
23882 +       struct net_device *dev = ptr;
23883 +
23884 +       if (dev->nd_net != &init_net)
23885 +               return NOTIFY_DONE;
23886 +
23887         switch (event) {
23888         case NETDEV_DOWN:
23889                 xfrm_flush_bundles();
23890 diff -Nurb linux-2.6.22-try2/net/xfrm/xfrm_state.c linux-2.6.22-try2-netns/net/xfrm/xfrm_state.c
23891 --- linux-2.6.22-try2/net/xfrm/xfrm_state.c     2007-12-19 13:38:00.000000000 -0500
23892 +++ linux-2.6.22-try2-netns/net/xfrm/xfrm_state.c       2007-12-19 22:49:20.000000000 -0500
23893 @@ -28,14 +28,6 @@
23894  struct sock *xfrm_nl;
23895  EXPORT_SYMBOL(xfrm_nl);
23896  
23897 -u32 sysctl_xfrm_aevent_etime __read_mostly = XFRM_AE_ETIME;
23898 -EXPORT_SYMBOL(sysctl_xfrm_aevent_etime);
23899 -
23900 -u32 sysctl_xfrm_aevent_rseqth __read_mostly = XFRM_AE_SEQT_SIZE;
23901 -EXPORT_SYMBOL(sysctl_xfrm_aevent_rseqth);
23902 -
23903 -u32 sysctl_xfrm_acq_expires __read_mostly = 30;
23904 -
23905  /* Each xfrm_state may be linked to two tables:
23906  
23907     1. Hash table by (spi,daddr,ah/esp) to find SA by SPI. (input,ctl)
23908 @@ -665,8 +657,8 @@
23909                                 h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, family);
23910                                 hlist_add_head(&x->byspi, xfrm_state_byspi+h);
23911                         }
23912 -                       x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires;
23913 -                       x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
23914 +                       x->lft.hard_add_expires_seconds = init_net.sysctl_xfrm_acq_expires;
23915 +                       x->timer.expires = jiffies + init_net.sysctl_xfrm_acq_expires*HZ;
23916                         add_timer(&x->timer);
23917                         xfrm_state_num++;
23918                         xfrm_hash_grow_check(x->bydst.next != NULL);
23919 @@ -815,9 +807,9 @@
23920                 x->props.family = family;
23921                 x->props.mode = mode;
23922                 x->props.reqid = reqid;
23923 -               x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires;
23924 +               x->lft.hard_add_expires_seconds = init_net.sysctl_xfrm_acq_expires;
23925                 xfrm_state_hold(x);
23926 -               x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
23927 +               x->timer.expires = jiffies + init_net.sysctl_xfrm_acq_expires*HZ;
23928                 add_timer(&x->timer);
23929                 hlist_add_head(&x->bydst, xfrm_state_bydst+h);
23930                 h = xfrm_src_hash(daddr, saddr, family);
23931 @@ -1775,6 +1767,19 @@
23932  
23933  EXPORT_SYMBOL(xfrm_init_state);
23934  
23935 +
23936 +static int xfrm_state_pernet_init(struct net *net)
23937 +{
23938 +       net->sysctl_xfrm_aevent_etime = XFRM_AE_ETIME;
23939 +       net->sysctl_xfrm_aevent_rseqth = XFRM_AE_SEQT_SIZE;
23940 +       net->sysctl_xfrm_acq_expires = 30;
23941 +       return 0;
23942 +}
23943 +
23944 +static struct pernet_operations xfrm_state_net_ops = {
23945 +       .init = xfrm_state_pernet_init,
23946 +};
23947 +
23948  void __init xfrm_state_init(void)
23949  {
23950         unsigned int sz;
23951 @@ -1789,5 +1794,7 @@
23952         xfrm_state_hmask = ((sz / sizeof(struct hlist_head)) - 1);
23953  
23954         INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task);
23955 +
23956 +       register_pernet_subsys(&xfrm_state_net_ops);
23957  }
23958  
23959 diff -Nurb linux-2.6.22-try2/net/xfrm/xfrm_user.c linux-2.6.22-try2-netns/net/xfrm/xfrm_user.c
23960 --- linux-2.6.22-try2/net/xfrm/xfrm_user.c      2007-12-19 13:38:00.000000000 -0500
23961 +++ linux-2.6.22-try2-netns/net/xfrm/xfrm_user.c        2007-12-19 22:49:20.000000000 -0500
23962 @@ -374,7 +374,8 @@
23963         return err;
23964  }
23965  
23966 -static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
23967 +static struct xfrm_state *xfrm_state_construct(struct net *net,
23968 +                                              struct xfrm_usersa_info *p,
23969                                                struct rtattr **xfrma,
23970                                                int *errp)
23971  {
23972 @@ -410,9 +411,9 @@
23973                 goto error;
23974  
23975         x->km.seq = p->seq;
23976 -       x->replay_maxdiff = sysctl_xfrm_aevent_rseqth;
23977 +       x->replay_maxdiff = net->sysctl_xfrm_aevent_rseqth;
23978         /* sysctl_xfrm_aevent_etime is in 100ms units */
23979 -       x->replay_maxage = (sysctl_xfrm_aevent_etime*HZ)/XFRM_AE_ETH_M;
23980 +       x->replay_maxage = (net->sysctl_xfrm_aevent_etime*HZ)/XFRM_AE_ETH_M;
23981         x->preplay.bitmap = 0;
23982         x->preplay.seq = x->replay.seq+x->replay_maxdiff;
23983         x->preplay.oseq = x->replay.oseq +x->replay_maxdiff;
23984 @@ -436,6 +437,7 @@
23985  static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
23986                 struct rtattr **xfrma)
23987  {
23988 +       struct net *net = skb->sk->sk_net;
23989         struct xfrm_usersa_info *p = NLMSG_DATA(nlh);
23990         struct xfrm_state *x;
23991         int err;
23992 @@ -445,7 +447,7 @@
23993         if (err)
23994                 return err;
23995  
23996 -       x = xfrm_state_construct(p, xfrma, &err);
23997 +       x = xfrm_state_construct(net, p, xfrma, &err);
23998         if (!x)
23999                 return err;
24000  
24001 @@ -2559,7 +2561,7 @@
24002  
24003         printk(KERN_INFO "Initializing XFRM netlink socket\n");
24004  
24005 -       nlsk = netlink_kernel_create(NETLINK_XFRM, XFRMNLGRP_MAX,
24006 +       nlsk = netlink_kernel_create(&init_net, NETLINK_XFRM, XFRMNLGRP_MAX,
24007                                      xfrm_netlink_rcv, NULL, THIS_MODULE);
24008         if (nlsk == NULL)
24009                 return -ENOMEM;
24010 diff -Nurb linux-2.6.22-try2/security/selinux/hooks.c linux-2.6.22-try2-netns/security/selinux/hooks.c
24011 --- linux-2.6.22-try2/security/selinux/hooks.c  2007-12-19 15:29:23.000000000 -0500
24012 +++ linux-2.6.22-try2-netns/security/selinux/hooks.c    2007-12-19 22:49:20.000000000 -0500
24013 @@ -3231,8 +3231,8 @@
24014  /* Range of port numbers used to automatically bind.
24015     Need to determine whether we should perform a name_bind
24016     permission check between the socket and the port number. */
24017 -#define ip_local_port_range_0 sysctl_local_port_range[0]
24018 -#define ip_local_port_range_1 sysctl_local_port_range[1]
24019 +#define ip_local_port_range_0 (sk->sk_net->sysctl_local_port_range[0])
24020 +#define ip_local_port_range_1 (sk->sk_net->sysctl_local_port_range[1])
24021  
24022  static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
24023  {
24024 @@ -3976,6 +3976,10 @@
24025                                                 const struct net_device *out,
24026                                                 int (*okfn)(struct sk_buff *))
24027  {
24028 +       /* Only filter packets in the initial network namespace */
24029 +       if ((in?in:out)->nd_net != &init_net)
24030 +               return NF_ACCEPT;
24031 +
24032         return selinux_ip_postroute_last(hooknum, pskb, in, out, okfn, PF_INET);
24033  }
24034  
24035 @@ -3987,6 +3991,10 @@
24036                                                 const struct net_device *out,
24037                                                 int (*okfn)(struct sk_buff *))
24038  {
24039 +       /* Only filter packets in the initial network namespace */
24040 +       if ((in?in:out)->nd_net != &init_net)
24041 +               return NF_ACCEPT;
24042 +
24043         return selinux_ip_postroute_last(hooknum, pskb, in, out, okfn, PF_INET6);
24044  }
24045  
24046 diff -Nurb linux-2.6.22-try2/security/selinux/netif.c linux-2.6.22-try2-netns/security/selinux/netif.c
24047 --- linux-2.6.22-try2/security/selinux/netif.c  2007-12-19 13:38:00.000000000 -0500
24048 +++ linux-2.6.22-try2-netns/security/selinux/netif.c    2007-12-19 22:49:20.000000000 -0500
24049 @@ -20,6 +20,7 @@
24050  #include <linux/notifier.h>
24051  #include <linux/netdevice.h>
24052  #include <linux/rcupdate.h>
24053 +#include <net/net_namespace.h>
24054  
24055  #include "security.h"
24056  #include "objsec.h"
24057 @@ -234,6 +235,9 @@
24058  {
24059         struct net_device *dev = ptr;
24060  
24061 +       if (dev->nd_net != &init_net)
24062 +               return NOTIFY_DONE;
24063 +
24064         if (event == NETDEV_DOWN)
24065                 sel_netif_kill(dev);
24066  
24067 diff -Nurb linux-2.6.22-try2/security/selinux/netlink.c linux-2.6.22-try2-netns/security/selinux/netlink.c
24068 --- linux-2.6.22-try2/security/selinux/netlink.c        2007-12-19 13:38:00.000000000 -0500
24069 +++ linux-2.6.22-try2-netns/security/selinux/netlink.c  2007-12-19 22:49:20.000000000 -0500
24070 @@ -17,6 +17,7 @@
24071  #include <linux/skbuff.h>
24072  #include <linux/netlink.h>
24073  #include <linux/selinux_netlink.h>
24074 +#include <net/net_namespace.h>
24075  
24076  static struct sock *selnl;
24077  
24078 @@ -104,8 +105,8 @@
24079  
24080  static int __init selnl_init(void)
24081  {
24082 -       selnl = netlink_kernel_create(NETLINK_SELINUX, SELNLGRP_MAX, NULL, NULL,
24083 -                                     THIS_MODULE);
24084 +       selnl = netlink_kernel_create(&init_net, NETLINK_SELINUX,
24085 +                                     SELNLGRP_MAX, NULL, NULL, THIS_MODULE);
24086         if (selnl == NULL)
24087                 panic("SELinux:  Cannot create netlink socket.");
24088         netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV);