diff -Nurb linux-2.6.22-570/Documentation/DocBook/Makefile linux-2.6.22-590/Documentation/DocBook/Makefile
--- linux-2.6.22-570/Documentation/DocBook/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/Documentation/DocBook/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/DocBook/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -11,7 +11,7 @@
procfs-guide.xml writing_usb_driver.xml \
kernel-api.xml filesystems.xml lsm.xml usb.xml \
# The build process is as follows (targets):
diff -Nurb linux-2.6.22-570/Documentation/DocBook/kgdb.tmpl linux-2.6.22-590/Documentation/DocBook/kgdb.tmpl
--- linux-2.6.22-570/Documentation/DocBook/kgdb.tmpl 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/Documentation/DocBook/kgdb.tmpl 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/DocBook/kgdb.tmpl 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+</book>
diff -Nurb linux-2.6.22-570/Documentation/accounting/getdelays.c linux-2.6.22-590/Documentation/accounting/getdelays.c
--- linux-2.6.22-570/Documentation/accounting/getdelays.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/Documentation/accounting/getdelays.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/accounting/getdelays.c 2008-01-29 22:12:30.000000000 -0500
@@ -49,6 +49,7 @@
int dbg;
int print_delays;
err(1,"write error\n");
diff -Nurb linux-2.6.22-570/Documentation/accounting/taskstats-struct.txt linux-2.6.22-590/Documentation/accounting/taskstats-struct.txt
--- linux-2.6.22-570/Documentation/accounting/taskstats-struct.txt 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/Documentation/accounting/taskstats-struct.txt 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/accounting/taskstats-struct.txt 2008-01-29 22:12:30.000000000 -0500
@@ -22,6 +22,8 @@
/* Extended accounting fields end */
Their values are collected if CONFIG_TASK_XACCT is set.
}
diff -Nurb linux-2.6.22-570/Documentation/cachetlb.txt linux-2.6.22-590/Documentation/cachetlb.txt
--- linux-2.6.22-570/Documentation/cachetlb.txt 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/Documentation/cachetlb.txt 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/cachetlb.txt 2008-01-29 22:12:30.000000000 -0500
@@ -253,7 +253,7 @@
The first of these two routines is invoked after map_vm_area()
require a whole different set of interfaces to handle properly.
diff -Nurb linux-2.6.22-570/Documentation/containers.txt linux-2.6.22-590/Documentation/containers.txt
--- linux-2.6.22-570/Documentation/containers.txt 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/Documentation/containers.txt 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/containers.txt 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,543 @@
+ CONTAINERS
+ -------
+
diff -Nurb linux-2.6.22-570/Documentation/cpuidle/core.txt linux-2.6.22-590/Documentation/cpuidle/core.txt
--- linux-2.6.22-570/Documentation/cpuidle/core.txt 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/Documentation/cpuidle/core.txt 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/cpuidle/core.txt 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,17 @@
+
+ Supporting multiple CPU idle levels in kernel
+
diff -Nurb linux-2.6.22-570/Documentation/cpuidle/driver.txt linux-2.6.22-590/Documentation/cpuidle/driver.txt
--- linux-2.6.22-570/Documentation/cpuidle/driver.txt 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/Documentation/cpuidle/driver.txt 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/cpuidle/driver.txt 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,24 @@
+
+
+int cpuidle_force_redetect(struct cpuidle_device *dev);
diff -Nurb linux-2.6.22-570/Documentation/cpuidle/governor.txt linux-2.6.22-590/Documentation/cpuidle/governor.txt
--- linux-2.6.22-570/Documentation/cpuidle/governor.txt 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/Documentation/cpuidle/governor.txt 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/cpuidle/governor.txt 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,24 @@
+
+
+
diff -Nurb linux-2.6.22-570/Documentation/cpuidle/sysfs.txt linux-2.6.22-590/Documentation/cpuidle/sysfs.txt
--- linux-2.6.22-570/Documentation/cpuidle/sysfs.txt 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/Documentation/cpuidle/sysfs.txt 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/cpuidle/sysfs.txt 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,27 @@
+
+
+
diff -Nurb linux-2.6.22-570/Documentation/cpusets.txt linux-2.6.22-590/Documentation/cpusets.txt
--- linux-2.6.22-570/Documentation/cpusets.txt 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/Documentation/cpusets.txt 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/cpusets.txt 2008-01-29 22:12:30.000000000 -0500
@@ -7,6 +7,7 @@
Portions Copyright (c) 2004-2006 Silicon Graphics, Inc.
Modified by Paul Jackson <pj@sgi.com>
diff -Nurb linux-2.6.22-570/Documentation/feature-removal-schedule.txt linux-2.6.22-590/Documentation/feature-removal-schedule.txt
--- linux-2.6.22-570/Documentation/feature-removal-schedule.txt 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/Documentation/feature-removal-schedule.txt 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/feature-removal-schedule.txt 2008-01-29 22:12:30.000000000 -0500
@@ -162,6 +162,33 @@
---------------------------
Why: These functions are a leftover from 2.4 times. They have several
diff -Nurb linux-2.6.22-570/Documentation/filesystems/00-INDEX linux-2.6.22-590/Documentation/filesystems/00-INDEX
--- linux-2.6.22-570/Documentation/filesystems/00-INDEX 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/Documentation/filesystems/00-INDEX 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/filesystems/00-INDEX 2008-01-29 22:12:30.000000000 -0500
@@ -84,6 +84,8 @@
- info and mount options for the UDF filesystem.
ufs.txt
vfs.txt
diff -Nurb linux-2.6.22-570/Documentation/filesystems/Locking linux-2.6.22-590/Documentation/filesystems/Locking
--- linux-2.6.22-570/Documentation/filesystems/Locking 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/Documentation/filesystems/Locking 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/filesystems/Locking 2008-01-29 22:12:30.000000000 -0500
@@ -510,12 +510,14 @@
prototypes:
void (*open)(struct vm_area_struct*);
================================================================================
diff -Nurb linux-2.6.22-570/Documentation/filesystems/configfs/configfs.txt linux-2.6.22-590/Documentation/filesystems/configfs/configfs.txt
--- linux-2.6.22-570/Documentation/filesystems/configfs/configfs.txt 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/Documentation/filesystems/configfs/configfs.txt 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/filesystems/configfs/configfs.txt 2008-01-29 22:12:30.000000000 -0500
@@ -238,6 +238,8 @@
struct config_group *(*make_group)(struct config_group *group,
const char *name);
NOTE: Committable items are currently unimplemented.
diff -Nurb linux-2.6.22-570/Documentation/filesystems/unionfs/00-INDEX linux-2.6.22-590/Documentation/filesystems/unionfs/00-INDEX
--- linux-2.6.22-570/Documentation/filesystems/unionfs/00-INDEX 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/Documentation/filesystems/unionfs/00-INDEX 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/filesystems/unionfs/00-INDEX 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,10 @@
+00-INDEX
+ - this file.
+ - Usage information and examples.
diff -Nurb linux-2.6.22-570/Documentation/filesystems/unionfs/concepts.txt linux-2.6.22-590/Documentation/filesystems/unionfs/concepts.txt
--- linux-2.6.22-570/Documentation/filesystems/unionfs/concepts.txt 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/Documentation/filesystems/unionfs/concepts.txt 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/filesystems/unionfs/concepts.txt 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,75 @@
+Unionfs 2.0 CONCEPTS:
+=====================
+For more information, see <http://unionfs.filesystems.org/>.
diff -Nurb linux-2.6.22-570/Documentation/filesystems/unionfs/issues.txt linux-2.6.22-590/Documentation/filesystems/unionfs/issues.txt
--- linux-2.6.22-570/Documentation/filesystems/unionfs/issues.txt 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/Documentation/filesystems/unionfs/issues.txt 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/filesystems/unionfs/issues.txt 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,39 @@
+KNOWN Unionfs 2.0 ISSUES:
+=========================
+For more information, see <http://unionfs.filesystems.org/>.
diff -Nurb linux-2.6.22-570/Documentation/filesystems/unionfs/rename.txt linux-2.6.22-590/Documentation/filesystems/unionfs/rename.txt
--- linux-2.6.22-570/Documentation/filesystems/unionfs/rename.txt 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/Documentation/filesystems/unionfs/rename.txt 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/filesystems/unionfs/rename.txt 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,31 @@
+Rename is a complex beast. The following table shows which rename(2) operations
+should succeed and which should fail.
+
diff -Nurb linux-2.6.22-570/Documentation/filesystems/unionfs/usage.txt linux-2.6.22-590/Documentation/filesystems/unionfs/usage.txt
--- linux-2.6.22-570/Documentation/filesystems/unionfs/usage.txt 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/Documentation/filesystems/unionfs/usage.txt 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/filesystems/unionfs/usage.txt 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,90 @@
+Unionfs is a stackable unification file system, which can appear to merge
+the contents of several directories (branches), while keeping their physical
+For more information, see <http://unionfs.filesystems.org/>.
diff -Nurb linux-2.6.22-570/Documentation/firmware_class/firmware_sample_firmware_class.c linux-2.6.22-590/Documentation/firmware_class/firmware_sample_firmware_class.c
--- linux-2.6.22-570/Documentation/firmware_class/firmware_sample_firmware_class.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/Documentation/firmware_class/firmware_sample_firmware_class.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/firmware_class/firmware_sample_firmware_class.c 2008-01-29 22:12:30.000000000 -0500
@@ -78,6 +78,7 @@
firmware_loading_show, firmware_loading_store);
struct class_device *class_dev = to_class_dev(kobj);
diff -Nurb linux-2.6.22-570/Documentation/power/freezing-of-tasks.txt linux-2.6.22-590/Documentation/power/freezing-of-tasks.txt
--- linux-2.6.22-570/Documentation/power/freezing-of-tasks.txt 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/Documentation/power/freezing-of-tasks.txt 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/power/freezing-of-tasks.txt 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,160 @@
+Freezing of tasks
+ (C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL
-the actual snapshotting.
diff -Nurb linux-2.6.22-570/Documentation/power/swsusp.txt linux-2.6.22-590/Documentation/power/swsusp.txt
--- linux-2.6.22-570/Documentation/power/swsusp.txt 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/Documentation/power/swsusp.txt 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/power/swsusp.txt 2008-01-29 22:12:30.000000000 -0500
@@ -140,21 +140,11 @@
website, and not to the Linux Kernel Mailing List. We are working
toward merging suspend2 into the mainline kernel.
diff -Nurb linux-2.6.22-570/Documentation/scsi/scsi_fc_transport.txt linux-2.6.22-590/Documentation/scsi/scsi_fc_transport.txt
--- linux-2.6.22-570/Documentation/scsi/scsi_fc_transport.txt 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/Documentation/scsi/scsi_fc_transport.txt 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/scsi/scsi_fc_transport.txt 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,450 @@
+ SCSI FC Tansport
+ =============================================
+
diff -Nurb linux-2.6.22-570/Documentation/sysctl/kernel.txt linux-2.6.22-590/Documentation/sysctl/kernel.txt
--- linux-2.6.22-570/Documentation/sysctl/kernel.txt 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/Documentation/sysctl/kernel.txt 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/Documentation/sysctl/kernel.txt 2008-01-29 22:12:30.000000000 -0500
@@ -29,6 +29,7 @@
- java-interpreter [ binfmt_java, obsolete ]
- kstack_depth_to_print [ X86 only ]
osrelease, ostype & version:
# cat osrelease
+diff -Nurb linux-2.6.22-570/Documentation/sysfs-rules.txt linux-2.6.22-590/Documentation/sysfs-rules.txt
+--- linux-2.6.22-570/Documentation/sysfs-rules.txt 1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.22-590/Documentation/sysfs-rules.txt 2008-01-29 22:12:30.000000000 -0500
+@@ -0,0 +1,166 @@
++Rules on how to access information in the Linux kernel sysfs
++
++The kernel exported sysfs exports internal kernel implementation-details
++and depends on internal kernel structures and layout. It is agreed upon
++by the kernel developers that the Linux kernel does not provide a stable
++internal API. As sysfs is a direct export of kernel internal
++structures, the sysfs interface can not provide a stable interface eighter,
++it may always change along with internal kernel changes.
++
++To minimize the risk of breaking users of sysfs, which are in most cases
++low-level userspace applications, with a new kernel release, the users
++of sysfs must follow some rules to use an as abstract-as-possible way to
++access this filesystem. The current udev and HAL programs already
++implement this and users are encouraged to plug, if possible, into the
++abstractions these programs provide instead of accessing sysfs
++directly.
++
++But if you really do want or need to access sysfs directly, please follow
++the following rules and then your programs should work with future
++versions of the sysfs interface.
++
++- Do not use libsysfs
++ It makes assumptions about sysfs which are not true. Its API does not
++ offer any abstraction, it exposes all the kernel driver-core
++ implementation details in its own API. Therefore it is not better than
++ reading directories and opening the files yourself.
++ Also, it is not actively maintained, in the sense of reflecting the
++ current kernel-development. The goal of providing a stable interface
++ to sysfs has failed, it causes more problems, than it solves. It
++ violates many of the rules in this document.
++
++- sysfs is always at /sys
++ Parsing /proc/mounts is a waste of time. Other mount points are a
++ system configuration bug you should not try to solve. For test cases,
++ possibly support a SYSFS_PATH environment variable to overwrite the
++ applications behavior, but never try to search for sysfs. Never try
++ to mount it, if you are not an early boot script.
++
++- devices are only "devices"
++ There is no such thing like class-, bus-, physical devices,
++ interfaces, and such that you can rely on in userspace. Everything is
++ just simply a "device". Class-, bus-, physical, ... types are just
++ kernel implementation details, which should not be expected by
++ applications that look for devices in sysfs.
++
++ The properties of a device are:
++ o devpath (/devices/pci0000:00/0000:00:1d.1/usb2/2-2/2-2:1.0)
++ - identical to the DEVPATH value in the event sent from the kernel
++ at device creation and removal
++ - the unique key to the device at that point in time
++ - the kernels path to the device-directory without the leading
++ /sys, and always starting with with a slash
++ - all elements of a devpath must be real directories. Symlinks
++ pointing to /sys/devices must always be resolved to their real
++ target, and the target path must be used to access the device.
++ That way the devpath to the device matches the devpath of the
++ kernel used at event time.
++ - using or exposing symlink values as elements in a devpath string
++ is a bug in the application
++
++ o kernel name (sda, tty, 0000:00:1f.2, ...)
++ - a directory name, identical to the last element of the devpath
++ - applications need to handle spaces and characters like '!' in
++ the name
++
++ o subsystem (block, tty, pci, ...)
++ - simple string, never a path or a link
++ - retrieved by reading the "subsystem"-link and using only the
++ last element of the target path
++
++ o driver (tg3, ata_piix, uhci_hcd)
++ - a simple string, which may contain spaces, never a path or a
++ link
++ - it is retrieved by reading the "driver"-link and using only the
++ last element of the target path
++ - devices which do not have "driver"-link, just do not have a
++ driver; copying the driver value in a child device context, is a
++ bug in the application
++
++ o attributes
++ - the files in the device directory or files below a subdirectories
++ of the same device directory
++ - accessing attributes reached by a symlink pointing to another device,
++ like the "device"-link, is a bug in the application
++
++ Everything else is just a kernel driver-core implementation detail,
++ that should not be assumed to be stable across kernel releases.
++
++- Properties of parent devices never belong into a child device.
++ Always look at the parent devices themselves for determining device
++ context properties. If the device 'eth0' or 'sda' does not have a
++ "driver"-link, then this device does not have a driver. Its value is empty.
++ Never copy any property of the parent-device into a child-device. Parent
++ device-properties may change dynamically without any notice to the
++ child device.
++
++- Hierarchy in a single device-tree
++ There is only one valid place in sysfs where hierarchy can be examined
++ and this is below: /sys/devices.
++ It is planned, that all device directories will end up in the tree
++ below this directory.
++
++- Classification by subsystem
++ There are currently three places for classification of devices:
++ /sys/block, /sys/class and /sys/bus. It is planned that these will
++ not contain any device-directories themselves, but only flat lists of
++ symlinks pointing to the unified /sys/devices tree.
++ All three places have completely different rules on how to access
++ device information. It is planned to merge all three
++ classification-directories into one place at /sys/subsystem,
++ following the layout of the bus-directories. All buses and
++ classes, including the converted block-subsystem, will show up
++ there.
++ The devices belonging to a subsystem will create a symlink in the
++ "devices" directory at /sys/subsystem/<name>/devices.
++
++ If /sys/subsystem exists, /sys/bus, /sys/class and /sys/block can be
++ ignored. If it does not exist, you have always to scan all three
++ places, as the kernel is free to move a subsystem from one place to
++ the other, as long as the devices are still reachable by the same
++ subsystem name.
++
++ Assuming /sys/class/<subsystem> and /sys/bus/<subsystem>, or
++ /sys/block and /sys/class/block are not interchangeable, is a bug in
++ the application.
++
++- Block
++ The converted block-subsystem at /sys/class/block, or
++ /sys/subsystem/block will contain the links for disks and partitions
++ at the same level, never in a hierarchy. Assuming the block-subsytem to
++ contain only disks and not partition-devices in the same flat list is
++ a bug in the application.
++
++- "device"-link and <subsystem>:<kernel name>-links
++ Never depend on the "device"-link. The "device"-link is a workaround
++ for the old layout, where class-devices are not created in
++ /sys/devices/ like the bus-devices. If the link-resolving of a
++ device-directory does not end in /sys/devices/, you can use the
++ "device"-link to find the parent devices in /sys/devices/. That is the
++ single valid use of the "device"-link, it must never appear in any
++ path as an element. Assuming the existence of the "device"-link for
++ a device in /sys/devices/ is a bug in the application.
++ Accessing /sys/class/net/eth0/device is a bug in the application.
++
++ Never depend on the class-specific links back to the /sys/class
++ directory. These links are also a workaround for the design mistake
++ that class-devices are not created in /sys/devices. If a device
++ directory does not contain directories for child devices, these links
++ may be used to find the child devices in /sys/class. That is the single
++ valid use of these links, they must never appear in any path as an
++ element. Assuming the existence of these links for devices which are
++ real child device directories in the /sys/devices tree, is a bug in
++ the application.
++
++ It is planned to remove all these links when when all class-device
++ directories live in /sys/devices.
++
++- Position of devices along device chain can change.
++ Never depend on a specific parent device position in the devpath,
++ or the chain of parent devices. The kernel is free to insert devices into
++ the chain. You must always request the parent device you are looking for
++ by its subsystem value. You need to walk up the chain until you find
++ the device that matches the expected subsystem. Depending on a specific
++ position of a parent device, or exposing relative paths, using "../" to
++ access the chain of parents, is a bug in the application.
++
diff -Nurb linux-2.6.22-570/MAINTAINERS linux-2.6.22-590/MAINTAINERS
--- linux-2.6.22-570/MAINTAINERS 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/MAINTAINERS 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/MAINTAINERS 2008-01-29 22:12:30.000000000 -0500
@@ -232,15 +232,15 @@
S: Supported
P: Oliver Neukum
M: oliver@neukum.name
diff -Nurb linux-2.6.22-570/Makefile linux-2.6.22-590/Makefile
---- linux-2.6.22-570/Makefile 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/Makefile 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/Makefile 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/Makefile 2008-01-29 22:12:30.000000000 -0500
+@@ -1,7 +1,7 @@
+ VERSION = 2
+ PATCHLEVEL = 6
+ SUBLEVEL = 22
+-EXTRAVERSION = .14-vs2.3.0.29
++EXTRAVERSION = -prep
+ NAME = Holy Dancing Manatees, Batman!
+
+ # *DOCUMENTATION*
@@ -496,6 +496,11 @@
CFLAGS += -fomit-frame-pointer
endif
ifdef CONFIG_DEBUG_INFO
CFLAGS += -g
endif
+diff -Nurb linux-2.6.22-570/Makefile.orig linux-2.6.22-590/Makefile.orig
+--- linux-2.6.22-570/Makefile.orig 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/Makefile.orig 1969-12-31 19:00:00.000000000 -0500
+@@ -1,1493 +0,0 @@
+-VERSION = 2
+-PATCHLEVEL = 6
+-SUBLEVEL = 22
+-EXTRAVERSION = .14
+-NAME = Holy Dancing Manatees, Batman!
+-
+-# *DOCUMENTATION*
+-# To see a list of typical targets execute "make help"
+-# More info can be located in ./README
+-# Comments in this file are targeted only to the developer, do not
+-# expect to learn how to build the kernel reading this file.
+-
+-# Do not:
+-# o use make's built-in rules and variables
+-# (this increases performance and avoid hard-to-debug behavour);
+-# o print "Entering directory ...";
+-MAKEFLAGS += -rR --no-print-directory
+-
+-# We are using a recursive build, so we need to do a little thinking
+-# to get the ordering right.
+-#
+-# Most importantly: sub-Makefiles should only ever modify files in
+-# their own directory. If in some directory we have a dependency on
+-# a file in another dir (which doesn't happen often, but it's often
+-# unavoidable when linking the built-in.o targets which finally
+-# turn into vmlinux), we will call a sub make in that other dir, and
+-# after that we are sure that everything which is in that other dir
+-# is now up to date.
+-#
+-# The only cases where we need to modify files which have global
+-# effects are thus separated out and done before the recursive
+-# descending is started. They are now explicitly listed as the
+-# prepare rule.
+-
+-# To put more focus on warnings, be less verbose as default
+-# Use 'make V=1' to see the full commands
+-
+-ifdef V
+- ifeq ("$(origin V)", "command line")
+- KBUILD_VERBOSE = $(V)
+- endif
+-endif
+-ifndef KBUILD_VERBOSE
+- KBUILD_VERBOSE = 0
+-endif
+-
+-# Call a source code checker (by default, "sparse") as part of the
+-# C compilation.
+-#
+-# Use 'make C=1' to enable checking of only re-compiled files.
+-# Use 'make C=2' to enable checking of *all* source files, regardless
+-# of whether they are re-compiled or not.
+-#
+-# See the file "Documentation/sparse.txt" for more details, including
+-# where to get the "sparse" utility.
+-
+-ifdef C
+- ifeq ("$(origin C)", "command line")
+- KBUILD_CHECKSRC = $(C)
+- endif
+-endif
+-ifndef KBUILD_CHECKSRC
+- KBUILD_CHECKSRC = 0
+-endif
+-
+-# Use make M=dir to specify directory of external module to build
+-# Old syntax make ... SUBDIRS=$PWD is still supported
+-# Setting the environment variable KBUILD_EXTMOD take precedence
+-ifdef SUBDIRS
+- KBUILD_EXTMOD ?= $(SUBDIRS)
+-endif
+-ifdef M
+- ifeq ("$(origin M)", "command line")
+- KBUILD_EXTMOD := $(M)
+- endif
+-endif
+-
+-
+-# kbuild supports saving output files in a separate directory.
+-# To locate output files in a separate directory two syntaxes are supported.
+-# In both cases the working directory must be the root of the kernel src.
+-# 1) O=
+-# Use "make O=dir/to/store/output/files/"
+-#
+-# 2) Set KBUILD_OUTPUT
+-# Set the environment variable KBUILD_OUTPUT to point to the directory
+-# where the output files shall be placed.
+-# export KBUILD_OUTPUT=dir/to/store/output/files/
+-# make
+-#
+-# The O= assignment takes precedence over the KBUILD_OUTPUT environment
+-# variable.
+-
+-
+-# KBUILD_SRC is set on invocation of make in OBJ directory
+-# KBUILD_SRC is not intended to be used by the regular user (for now)
+-ifeq ($(KBUILD_SRC),)
+-
+-# OK, Make called in directory where kernel src resides
+-# Do we want to locate output files in a separate directory?
+-ifdef O
+- ifeq ("$(origin O)", "command line")
+- KBUILD_OUTPUT := $(O)
+- endif
+-endif
+-
+-# That's our default target when none is given on the command line
+-PHONY := _all
+-_all:
+-
+-ifneq ($(KBUILD_OUTPUT),)
+-# Invoke a second make in the output directory, passing relevant variables
+-# check that the output directory actually exists
+-saved-output := $(KBUILD_OUTPUT)
+-KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd)
+-$(if $(KBUILD_OUTPUT),, \
+- $(error output directory "$(saved-output)" does not exist))
+-
+-PHONY += $(MAKECMDGOALS)
+-
+-$(filter-out _all,$(MAKECMDGOALS)) _all:
+- $(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \
+- KBUILD_SRC=$(CURDIR) \
+- KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile $@
+-
+-# Leave processing to above invocation of make
+-skip-makefile := 1
+-endif # ifneq ($(KBUILD_OUTPUT),)
+-endif # ifeq ($(KBUILD_SRC),)
+-
+-# We process the rest of the Makefile if this is the final invocation of make
+-ifeq ($(skip-makefile),)
+-
+-# If building an external module we do not care about the all: rule
+-# but instead _all depend on modules
+-PHONY += all
+-ifeq ($(KBUILD_EXTMOD),)
+-_all: all
+-else
+-_all: modules
+-endif
+-
+-srctree := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR))
+-TOPDIR := $(srctree)
+-# FIXME - TOPDIR is obsolete, use srctree/objtree
+-objtree := $(CURDIR)
+-src := $(srctree)
+-obj := $(objtree)
+-
+-VPATH := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD))
+-
+-export srctree objtree VPATH TOPDIR
+-
+-
+-# SUBARCH tells the usermode build what the underlying arch is. That is set
+-# first, and if a usermode build is happening, the "ARCH=um" on the command
+-# line overrides the setting of ARCH below. If a native build is happening,
+-# then ARCH is assigned, getting whatever value it gets normally, and
+-# SUBARCH is subsequently ignored.
+-
+-SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
+- -e s/arm.*/arm/ -e s/sa110/arm/ \
+- -e s/s390x/s390/ -e s/parisc64/parisc/ \
+- -e s/ppc.*/powerpc/ -e s/mips.*/mips/ )
+-
+-# Cross compiling and selecting different set of gcc/bin-utils
+-# ---------------------------------------------------------------------------
+-#
+-# When performing cross compilation for other architectures ARCH shall be set
+-# to the target architecture. (See arch/* for the possibilities).
+-# ARCH can be set during invocation of make:
+-# make ARCH=ia64
+-# Another way is to have ARCH set in the environment.
+-# The default ARCH is the host where make is executed.
+-
+-# CROSS_COMPILE specify the prefix used for all executables used
+-# during compilation. Only gcc and related bin-utils executables
+-# are prefixed with $(CROSS_COMPILE).
+-# CROSS_COMPILE can be set on the command line
+-# make CROSS_COMPILE=ia64-linux-
+-# Alternatively CROSS_COMPILE can be set in the environment.
+-# Default value for CROSS_COMPILE is not to prefix executables
+-# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
+-
+-ARCH ?= $(SUBARCH)
+-CROSS_COMPILE ?=
+-
+-# Architecture as present in compile.h
+-UTS_MACHINE := $(ARCH)
+-
+-KCONFIG_CONFIG ?= .config
+-
+-# SHELL used by kbuild
+-CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
+- else if [ -x /bin/bash ]; then echo /bin/bash; \
+- else echo sh; fi ; fi)
+-
+-HOSTCC = gcc
+-HOSTCXX = g++
+-HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
+-HOSTCXXFLAGS = -O2
+-
+-# Decide whether to build built-in, modular, or both.
+-# Normally, just do built-in.
+-
+-KBUILD_MODULES :=
+-KBUILD_BUILTIN := 1
+-
+-# If we have only "make modules", don't compile built-in objects.
+-# When we're building modules with modversions, we need to consider
+-# the built-in objects during the descend as well, in order to
+-# make sure the checksums are up to date before we record them.
+-
+-ifeq ($(MAKECMDGOALS),modules)
+- KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1)
+-endif
+-
+-# If we have "make <whatever> modules", compile modules
+-# in addition to whatever we do anyway.
+-# Just "make" or "make all" shall build modules as well
+-
+-ifneq ($(filter all _all modules,$(MAKECMDGOALS)),)
+- KBUILD_MODULES := 1
+-endif
+-
+-ifeq ($(MAKECMDGOALS),)
+- KBUILD_MODULES := 1
+-endif
+-
+-export KBUILD_MODULES KBUILD_BUILTIN
+-export KBUILD_CHECKSRC KBUILD_SRC KBUILD_EXTMOD
+-
+-# Beautify output
+-# ---------------------------------------------------------------------------
+-#
+-# Normally, we echo the whole command before executing it. By making
+-# that echo $($(quiet)$(cmd)), we now have the possibility to set
+-# $(quiet) to choose other forms of output instead, e.g.
+-#
+-# quiet_cmd_cc_o_c = Compiling $(RELDIR)/$@
+-# cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
+-#
+-# If $(quiet) is empty, the whole command will be printed.
+-# If it is set to "quiet_", only the short version will be printed.
+-# If it is set to "silent_", nothing will be printed at all, since
+-# the variable $(silent_cmd_cc_o_c) doesn't exist.
+-#
+-# A simple variant is to prefix commands with $(Q) - that's useful
+-# for commands that shall be hidden in non-verbose mode.
+-#
+-# $(Q)ln $@ :<
+-#
+-# If KBUILD_VERBOSE equals 0 then the above command will be hidden.
+-# If KBUILD_VERBOSE equals 1 then the above command is displayed.
+-
+-ifeq ($(KBUILD_VERBOSE),1)
+- quiet =
+- Q =
+-else
+- quiet=quiet_
+- Q = @
+-endif
+-
+-# If the user is running make -s (silent mode), suppress echoing of
+-# commands
+-
+-ifneq ($(findstring s,$(MAKEFLAGS)),)
+- quiet=silent_
+-endif
+-
+-export quiet Q KBUILD_VERBOSE
+-
+-
+-# Look for make include files relative to root of kernel src
+-MAKEFLAGS += --include-dir=$(srctree)
+-
+-# We need some generic definitions.
+-include $(srctree)/scripts/Kbuild.include
+-
+-# Make variables (CC, etc...)
+-
+-AS = $(CROSS_COMPILE)as
+-LD = $(CROSS_COMPILE)ld
+-CC = $(CROSS_COMPILE)gcc
+-CPP = $(CC) -E
+-AR = $(CROSS_COMPILE)ar
+-NM = $(CROSS_COMPILE)nm
+-STRIP = $(CROSS_COMPILE)strip
+-OBJCOPY = $(CROSS_COMPILE)objcopy
+-OBJDUMP = $(CROSS_COMPILE)objdump
+-AWK = awk
+-GENKSYMS = scripts/genksyms/genksyms
+-DEPMOD = /sbin/depmod
+-KALLSYMS = scripts/kallsyms
+-PERL = perl
+-CHECK = sparse
+-
+-CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise $(CF)
+-MODFLAGS = -DMODULE
+-CFLAGS_MODULE = $(MODFLAGS)
+-AFLAGS_MODULE = $(MODFLAGS)
+-LDFLAGS_MODULE = -r
+-CFLAGS_KERNEL =
+-AFLAGS_KERNEL =
+-
+-
+-# Use LINUXINCLUDE when you must reference the include/ directory.
+-# Needed to be compatible with the O= option
+-LINUXINCLUDE := -Iinclude \
+- $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \
+- -include include/linux/autoconf.h
+-
+-CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
+-
+-CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
+- -fno-strict-aliasing -fno-common
+-AFLAGS := -D__ASSEMBLY__
+-
+-# Read KERNELRELEASE from include/config/kernel.release (if it exists)
+-KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
+-KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
+-
+-export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
+-export ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
+-export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE
+-export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
+-
+-export CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
+-export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
+-export AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
+-
+-# When compiling out-of-tree modules, put MODVERDIR in the module
+-# tree rather than in the kernel tree. The kernel tree might
+-# even be read-only.
+-export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_versions
+-
+-# Files to ignore in find ... statements
+-
+-RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS -o -name .pc -o -name .hg -o -name .git \) -prune -o
+-export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS --exclude .pc --exclude .hg --exclude .git
+-
+-# ===========================================================================
+-# Rules shared between *config targets and build targets
+-
+-# Basic helpers built in scripts/
+-PHONY += scripts_basic
+-scripts_basic:
+- $(Q)$(MAKE) $(build)=scripts/basic
+-
+-# To avoid any implicit rule to kick in, define an empty command.
+-scripts/basic/%: scripts_basic ;
+-
+-PHONY += outputmakefile
+-# outputmakefile generates a Makefile in the output directory, if using a
+-# separate output directory. This allows convenient use of make in the
+-# output directory.
+-outputmakefile:
+-ifneq ($(KBUILD_SRC),)
+- $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \
+- $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)
+-endif
+-
+-# To make sure we do not include .config for any of the *config targets
+-# catch them early, and hand them over to scripts/kconfig/Makefile
+-# It is allowed to specify more targets when calling make, including
+-# mixing *config targets and build targets.
+-# For example 'make oldconfig all'.
+-# Detect when mixed targets is specified, and make a second invocation
+-# of make so .config is not included in this case either (for *config).
+-
+-no-dot-config-targets := clean mrproper distclean \
+- cscope TAGS tags help %docs check% \
+- include/linux/version.h headers_% \
+- kernelrelease kernelversion
+-
+-config-targets := 0
+-mixed-targets := 0
+-dot-config := 1
+-
+-ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)
+- ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)
+- dot-config := 0
+- endif
+-endif
+-
+-ifeq ($(KBUILD_EXTMOD),)
+- ifneq ($(filter config %config,$(MAKECMDGOALS)),)
+- config-targets := 1
+- ifneq ($(filter-out config %config,$(MAKECMDGOALS)),)
+- mixed-targets := 1
+- endif
+- endif
+-endif
+-
+-ifeq ($(mixed-targets),1)
+-# ===========================================================================
+-# We're called with mixed targets (*config and build targets).
+-# Handle them one by one.
+-
+-%:: FORCE
+- $(Q)$(MAKE) -C $(srctree) KBUILD_SRC= $@
+-
+-else
+-ifeq ($(config-targets),1)
+-# ===========================================================================
+-# *config targets only - make sure prerequisites are updated, and descend
+-# in scripts/kconfig to make the *config target
+-
+-# Read arch specific Makefile to set KBUILD_DEFCONFIG as needed.
+-# KBUILD_DEFCONFIG may point out an alternative default configuration
+-# used for 'make defconfig'
+-include $(srctree)/arch/$(ARCH)/Makefile
+-export KBUILD_DEFCONFIG
+-
+-config %config: scripts_basic outputmakefile FORCE
+- $(Q)mkdir -p include/linux include/config
+- $(Q)$(MAKE) $(build)=scripts/kconfig $@
+-
+-else
+-# ===========================================================================
+-# Build targets only - this includes vmlinux, arch specific targets, clean
+-# targets and others. In general all targets except *config targets.
+-
+-ifeq ($(KBUILD_EXTMOD),)
+-# Additional helpers built in scripts/
+-# Carefully list dependencies so we do not try to build scripts twice
+-# in parallel
+-PHONY += scripts
+-scripts: scripts_basic include/config/auto.conf
+- $(Q)$(MAKE) $(build)=$(@)
+-
+-# Objects we will link into vmlinux / subdirs we need to visit
+-init-y := init/
+-drivers-y := drivers/ sound/
+-net-y := net/
+-libs-y := lib/
+-core-y := usr/
+-endif # KBUILD_EXTMOD
+-
+-ifeq ($(dot-config),1)
+-# Read in config
+--include include/config/auto.conf
+-
+-ifeq ($(KBUILD_EXTMOD),)
+-# Read in dependencies to all Kconfig* files, make sure to run
+-# oldconfig if changes are detected.
+--include include/config/auto.conf.cmd
+-
+-# To avoid any implicit rule to kick in, define an empty command
+-$(KCONFIG_CONFIG) include/config/auto.conf.cmd: ;
+-
+-# If .config is newer than include/config/auto.conf, someone tinkered
+-# with it and forgot to run make oldconfig.
+-# if auto.conf.cmd is missing then we are probably in a cleaned tree so
+-# we execute the config step to be sure to catch updated Kconfig files
+-include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
+- $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
+-else
+-# external modules needs include/linux/autoconf.h and include/config/auto.conf
+-# but do not care if they are up-to-date. Use auto.conf to trigger the test
+-PHONY += include/config/auto.conf
+-
+-include/config/auto.conf:
+- $(Q)test -e include/linux/autoconf.h -a -e $@ || ( \
+- echo; \
+- echo " ERROR: Kernel configuration is invalid."; \
+- echo " include/linux/autoconf.h or $@ are missing."; \
+- echo " Run 'make oldconfig && make prepare' on kernel src to fix it."; \
+- echo; \
+- /bin/false)
+-
+-endif # KBUILD_EXTMOD
+-
+-else
+-# Dummy target needed, because used as prerequisite
+-include/config/auto.conf: ;
+-endif # $(dot-config)
+-
+-# The all: target is the default when no target is given on the
+-# command line.
+-# This allow a user to issue only 'make' to build a kernel including modules
+-# Defaults vmlinux but it is usually overridden in the arch makefile
+-all: vmlinux
+-
+-ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
+-CFLAGS += -Os
+-else
+-CFLAGS += -O2
+-endif
+-
+-include $(srctree)/arch/$(ARCH)/Makefile
+-
+-ifdef CONFIG_FRAME_POINTER
+-CFLAGS += -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,)
+-else
+-CFLAGS += -fomit-frame-pointer
+-endif
+-
+-ifdef CONFIG_DEBUG_INFO
+-CFLAGS += -g
+-endif
+-
+-# Force gcc to behave correct even for buggy distributions
+-CFLAGS += $(call cc-option, -fno-stack-protector)
+-
+-# arch Makefile may override CC so keep this after arch Makefile is included
+-NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
+-CHECKFLAGS += $(NOSTDINC_FLAGS)
+-
+-# warn about C99 declaration after statement
+-CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
+-
+-# disable pointer signed / unsigned warnings in gcc 4.0
+-CFLAGS += $(call cc-option,-Wno-pointer-sign,)
+-
+-# Default kernel image to build when no specific target is given.
+-# KBUILD_IMAGE may be overruled on the command line or
+-# set in the environment
+-# Also any assignments in arch/$(ARCH)/Makefile take precedence over
+-# this default value
+-export KBUILD_IMAGE ?= vmlinux
+-
+-#
+-# INSTALL_PATH specifies where to place the updated kernel and system map
+-# images. Default is /boot, but you can set it to other values
+-export INSTALL_PATH ?= /boot
+-
+-#
+-# INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory
+-# relocations required by build roots. This is not defined in the
+-# makefile but the argument can be passed to make if needed.
+-#
+-
+-MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
+-export MODLIB
+-
+-#
+-# INSTALL_MOD_STRIP, if defined, will cause modules to be
+-# stripped after they are installed. If INSTALL_MOD_STRIP is '1', then
+-# the default option --strip-debug will be used. Otherwise,
+-# INSTALL_MOD_STRIP will used as the options to the strip command.
+-
+-ifdef INSTALL_MOD_STRIP
+-ifeq ($(INSTALL_MOD_STRIP),1)
+-mod_strip_cmd = $(STRIP) --strip-debug
+-else
+-mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP)
+-endif # INSTALL_MOD_STRIP=1
+-else
+-mod_strip_cmd = true
+-endif # INSTALL_MOD_STRIP
+-export mod_strip_cmd
+-
+-
+-ifeq ($(KBUILD_EXTMOD),)
+-core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
+-
+-vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
+- $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
+- $(net-y) $(net-m) $(libs-y) $(libs-m)))
+-
+-vmlinux-alldirs := $(sort $(vmlinux-dirs) $(patsubst %/,%,$(filter %/, \
+- $(init-n) $(init-) \
+- $(core-n) $(core-) $(drivers-n) $(drivers-) \
+- $(net-n) $(net-) $(libs-n) $(libs-))))
+-
+-init-y := $(patsubst %/, %/built-in.o, $(init-y))
+-core-y := $(patsubst %/, %/built-in.o, $(core-y))
+-drivers-y := $(patsubst %/, %/built-in.o, $(drivers-y))
+-net-y := $(patsubst %/, %/built-in.o, $(net-y))
+-libs-y1 := $(patsubst %/, %/lib.a, $(libs-y))
+-libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y))
+-libs-y := $(libs-y1) $(libs-y2)
+-
+-# Build vmlinux
+-# ---------------------------------------------------------------------------
+-# vmlinux is built from the objects selected by $(vmlinux-init) and
+-# $(vmlinux-main). Most are built-in.o files from top-level directories
+-# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
+-# Ordering when linking is important, and $(vmlinux-init) must be first.
+-#
+-# vmlinux
+-# ^
+-# |
+-# +-< $(vmlinux-init)
+-# | +--< init/version.o + more
+-# |
+-# +--< $(vmlinux-main)
+-# | +--< driver/built-in.o mm/built-in.o + more
+-# |
+-# +-< kallsyms.o (see description in CONFIG_KALLSYMS section)
+-#
+-# vmlinux version (uname -v) cannot be updated during normal
+-# descending-into-subdirs phase since we do not yet know if we need to
+-# update vmlinux.
+-# Therefore this step is delayed until just before final link of vmlinux -
+-# except in the kallsyms case where it is done just before adding the
+-# symbols to the kernel.
+-#
+-# System.map is generated to document addresses of all kernel symbols
+-
+-vmlinux-init := $(head-y) $(init-y)
+-vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
+-vmlinux-all := $(vmlinux-init) $(vmlinux-main)
+-vmlinux-lds := arch/$(ARCH)/kernel/vmlinux.lds
+-export KBUILD_VMLINUX_OBJS := $(vmlinux-all)
+-
+-# Rule to link vmlinux - also used during CONFIG_KALLSYMS
+-# May be overridden by arch/$(ARCH)/Makefile
+-quiet_cmd_vmlinux__ ?= LD $@
+- cmd_vmlinux__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) -o $@ \
+- -T $(vmlinux-lds) $(vmlinux-init) \
+- --start-group $(vmlinux-main) --end-group \
+- $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) FORCE ,$^)
+-
+-# Generate new vmlinux version
+-quiet_cmd_vmlinux_version = GEN .version
+- cmd_vmlinux_version = set -e; \
+- if [ ! -r .version ]; then \
+- rm -f .version; \
+- echo 1 >.version; \
+- else \
+- mv .version .old_version; \
+- expr 0$$(cat .old_version) + 1 >.version; \
+- fi; \
+- $(MAKE) $(build)=init
+-
+-# Generate System.map
+-quiet_cmd_sysmap = SYSMAP
+- cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap
+-
+-# Link of vmlinux
+-# If CONFIG_KALLSYMS is set .version is already updated
+-# Generate System.map and verify that the content is consistent
+-# Use + in front of the vmlinux_version rule to silent warning with make -j2
+-# First command is ':' to allow us to use + in front of the rule
+-define rule_vmlinux__
+- :
+- $(if $(CONFIG_KALLSYMS),,+$(call cmd,vmlinux_version))
+-
+- $(call cmd,vmlinux__)
+- $(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
+-
+- $(Q)$(if $($(quiet)cmd_sysmap), \
+- echo ' $($(quiet)cmd_sysmap) System.map' &&) \
+- $(cmd_sysmap) $@ System.map; \
+- if [ $$? -ne 0 ]; then \
+- rm -f $@; \
+- /bin/false; \
+- fi;
+- $(verify_kallsyms)
+-endef
+-
+-
+-ifdef CONFIG_KALLSYMS
+-# Generate section listing all symbols and add it into vmlinux $(kallsyms.o)
+-# It's a three stage process:
+-# o .tmp_vmlinux1 has all symbols and sections, but __kallsyms is
+-# empty
+-# Running kallsyms on that gives us .tmp_kallsyms1.o with
+-# the right size - vmlinux version (uname -v) is updated during this step
+-# o .tmp_vmlinux2 now has a __kallsyms section of the right size,
+-# but due to the added section, some addresses have shifted.
+-# From here, we generate a correct .tmp_kallsyms2.o
+-# o The correct .tmp_kallsyms2.o is linked into the final vmlinux.
+-# o Verify that the System.map from vmlinux matches the map from
+-# .tmp_vmlinux2, just in case we did not generate kallsyms correctly.
+-# o If CONFIG_KALLSYMS_EXTRA_PASS is set, do an extra pass using
+-# .tmp_vmlinux3 and .tmp_kallsyms3.o. This is only meant as a
+-# temporary bypass to allow the kernel to be built while the
+-# maintainers work out what went wrong with kallsyms.
+-
+-ifdef CONFIG_KALLSYMS_EXTRA_PASS
+-last_kallsyms := 3
+-else
+-last_kallsyms := 2
+-endif
+-
+-kallsyms.o := .tmp_kallsyms$(last_kallsyms).o
+-
+-define verify_kallsyms
+- $(Q)$(if $($(quiet)cmd_sysmap), \
+- echo ' $($(quiet)cmd_sysmap) .tmp_System.map' &&) \
+- $(cmd_sysmap) .tmp_vmlinux$(last_kallsyms) .tmp_System.map
+- $(Q)cmp -s System.map .tmp_System.map || \
+- (echo Inconsistent kallsyms data; \
+- echo Try setting CONFIG_KALLSYMS_EXTRA_PASS; \
+- rm .tmp_kallsyms* ; /bin/false )
+-endef
+-
+-# Update vmlinux version before link
+-# Use + in front of this rule to silent warning about make -j1
+-# First command is ':' to allow us to use + in front of this rule
+-cmd_ksym_ld = $(cmd_vmlinux__)
+-define rule_ksym_ld
+- :
+- +$(call cmd,vmlinux_version)
+- $(call cmd,vmlinux__)
+- $(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
+-endef
+-
+-# Generate .S file with all kernel symbols
+-quiet_cmd_kallsyms = KSYM $@
+- cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) \
+- $(if $(CONFIG_KALLSYMS_ALL),--all-symbols) > $@
+-
+-.tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE
+- $(call if_changed_dep,as_o_S)
+-
+-.tmp_kallsyms%.S: .tmp_vmlinux% $(KALLSYMS)
+- $(call cmd,kallsyms)
+-
+-# .tmp_vmlinux1 must be complete except kallsyms, so update vmlinux version
+-.tmp_vmlinux1: $(vmlinux-lds) $(vmlinux-all) FORCE
+- $(call if_changed_rule,ksym_ld)
+-
+-.tmp_vmlinux2: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms1.o FORCE
+- $(call if_changed,vmlinux__)
+-
+-.tmp_vmlinux3: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms2.o FORCE
+- $(call if_changed,vmlinux__)
+-
+-# Needs to visit scripts/ before $(KALLSYMS) can be used.
+-$(KALLSYMS): scripts ;
+-
+-# Generate some data for debugging strange kallsyms problems
+-debug_kallsyms: .tmp_map$(last_kallsyms)
+-
+-.tmp_map%: .tmp_vmlinux% FORCE
+- ($(OBJDUMP) -h $< | $(AWK) '/^ +[0-9]/{print $$4 " 0 " $$2}'; $(NM) $<) | sort > $@
+-
+-.tmp_map3: .tmp_map2
+-
+-.tmp_map2: .tmp_map1
+-
+-endif # ifdef CONFIG_KALLSYMS
+-
+-# vmlinux image - including updated kernel symbols
+-vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
+-ifdef CONFIG_HEADERS_CHECK
+- $(Q)$(MAKE) -f $(srctree)/Makefile headers_check
+-endif
+- $(call if_changed_rule,vmlinux__)
+- $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@
+- $(Q)rm -f .old_version
+-
+-# The actual objects are generated when descending,
+-# make sure no implicit rule kicks in
+-$(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
+-
+-# Handle descending into subdirectories listed in $(vmlinux-dirs)
+-# Preset locale variables to speed up the build process. Limit locale
+-# tweaks to this spot to avoid wrong language settings when running
+-# make menuconfig etc.
+-# Error messages still appears in the original language
+-
+-PHONY += $(vmlinux-dirs)
+-$(vmlinux-dirs): prepare scripts
+- $(Q)$(MAKE) $(build)=$@
+-
+-# Build the kernel release string
+-#
+-# The KERNELRELEASE value built here is stored in the file
+-# include/config/kernel.release, and is used when executing several
+-# make targets, such as "make install" or "make modules_install."
+-#
+-# The eventual kernel release string consists of the following fields,
+-# shown in a hierarchical format to show how smaller parts are concatenated
+-# to form the larger and final value, with values coming from places like
+-# the Makefile, kernel config options, make command line options and/or
+-# SCM tag information.
+-#
+-# $(KERNELVERSION)
+-# $(VERSION) eg, 2
+-# $(PATCHLEVEL) eg, 6
+-# $(SUBLEVEL) eg, 18
+-# $(EXTRAVERSION) eg, -rc6
+-# $(localver-full)
+-# $(localver)
+-# localversion* (files without backups, containing '~')
+-# $(CONFIG_LOCALVERSION) (from kernel config setting)
+-# $(localver-auto) (only if CONFIG_LOCALVERSION_AUTO is set)
+-# ./scripts/setlocalversion (SCM tag, if one exists)
+-# $(LOCALVERSION) (from make command line if provided)
+-#
+-# Note how the final $(localver-auto) string is included *only* if the
+-# kernel config option CONFIG_LOCALVERSION_AUTO is selected. Also, at the
+-# moment, only git is supported but other SCMs can edit the script
+-# scripts/setlocalversion and add the appropriate checks as needed.
+-
+-pattern = ".*/localversion[^~]*"
+-string = $(shell cat /dev/null \
+- `find $(objtree) $(srctree) -maxdepth 1 -regex $(pattern) | sort -u`)
+-
+-localver = $(subst $(space),, $(string) \
+- $(patsubst "%",%,$(CONFIG_LOCALVERSION)))
+-
+-# If CONFIG_LOCALVERSION_AUTO is set scripts/setlocalversion is called
+-# and if the SCM is know a tag from the SCM is appended.
+-# The appended tag is determined by the SCM used.
+-#
+-# Currently, only git is supported.
+-# Other SCMs can edit scripts/setlocalversion and add the appropriate
+-# checks as needed.
+-ifdef CONFIG_LOCALVERSION_AUTO
+- _localver-auto = $(shell $(CONFIG_SHELL) \
+- $(srctree)/scripts/setlocalversion $(srctree))
+- localver-auto = $(LOCALVERSION)$(_localver-auto)
+-endif
+-
+-localver-full = $(localver)$(localver-auto)
+-
+-# Store (new) KERNELRELASE string in include/config/kernel.release
+-kernelrelease = $(KERNELVERSION)$(localver-full)
+-include/config/kernel.release: include/config/auto.conf FORCE
+- $(Q)rm -f $@
+- $(Q)echo $(kernelrelease) > $@
+-
+-
+-# Things we need to do before we recursively start building the kernel
+-# or the modules are listed in "prepare".
+-# A multi level approach is used. prepareN is processed before prepareN-1.
+-# archprepare is used in arch Makefiles and when processed asm symlink,
+-# version.h and scripts_basic is processed / created.
+-
+-# Listed in dependency order
+-PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3
+-
+-# prepare3 is used to check if we are building in a separate output directory,
+-# and if so do:
+-# 1) Check that make has not been executed in the kernel src $(srctree)
+-# 2) Create the include2 directory, used for the second asm symlink
+-prepare3: include/config/kernel.release
+-ifneq ($(KBUILD_SRC),)
+- @echo ' Using $(srctree) as source for kernel'
+- $(Q)if [ -f $(srctree)/.config -o -d $(srctree)/include/config ]; then \
+- echo " $(srctree) is not clean, please run 'make mrproper'";\
+- echo " in the '$(srctree)' directory.";\
+- /bin/false; \
+- fi;
+- $(Q)if [ ! -d include2 ]; then mkdir -p include2; fi;
+- $(Q)ln -fsn $(srctree)/include/asm-$(ARCH) include2/asm
+-endif
+-
+-# prepare2 creates a makefile if using a separate output directory
+-prepare2: prepare3 outputmakefile
+-
+-prepare1: prepare2 include/linux/version.h include/linux/utsrelease.h \
+- include/asm include/config/auto.conf
+-ifneq ($(KBUILD_MODULES),)
+- $(Q)mkdir -p $(MODVERDIR)
+- $(Q)rm -f $(MODVERDIR)/*
+-endif
+-
+-archprepare: prepare1 scripts_basic
+-
+-prepare0: archprepare FORCE
+- $(Q)$(MAKE) $(build)=.
+- $(Q)$(MAKE) $(build)=. missing-syscalls
+-
+-# All the preparing..
+-prepare: prepare0
+-
+-# Leave this as default for preprocessing vmlinux.lds.S, which is now
+-# done in arch/$(ARCH)/kernel/Makefile
+-
+-export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
+-
+-# FIXME: The asm symlink changes when $(ARCH) changes. That's
+-# hard to detect, but I suppose "make mrproper" is a good idea
+-# before switching between archs anyway.
+-
+-include/asm:
+- @echo ' SYMLINK $@ -> include/asm-$(ARCH)'
+- $(Q)if [ ! -d include ]; then mkdir -p include; fi;
+- @ln -fsn asm-$(ARCH) $@
+-
+-# Generate some files
+-# ---------------------------------------------------------------------------
+-
+-# KERNELRELEASE can change from a few different places, meaning version.h
+-# needs to be updated, so this check is forced on all builds
+-
+-uts_len := 64
+-define filechk_utsrelease.h
+- if [ `echo -n "$(KERNELRELEASE)" | wc -c ` -gt $(uts_len) ]; then \
+- echo '"$(KERNELRELEASE)" exceeds $(uts_len) characters' >&2; \
+- exit 1; \
+- fi; \
+- (echo \#define UTS_RELEASE \"$(KERNELRELEASE)\";)
+-endef
+-
+-define filechk_version.h
+- (echo \#define LINUX_VERSION_CODE $(shell \
+- expr $(VERSION) \* 65536 + $(PATCHLEVEL) \* 256 + $(SUBLEVEL)); \
+- echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))';)
+-endef
+-
+-include/linux/version.h: $(srctree)/Makefile FORCE
+- $(call filechk,version.h)
+-
+-include/linux/utsrelease.h: include/config/kernel.release FORCE
+- $(call filechk,utsrelease.h)
+-
+-# ---------------------------------------------------------------------------
+-
+-PHONY += depend dep
+-depend dep:
+- @echo '*** Warning: make $@ is unnecessary now.'
+-
+-# ---------------------------------------------------------------------------
+-# Kernel headers
+-INSTALL_HDR_PATH=$(objtree)/usr
+-export INSTALL_HDR_PATH
+-
+-HDRARCHES=$(filter-out generic,$(patsubst $(srctree)/include/asm-%/Kbuild,%,$(wildcard $(srctree)/include/asm-*/Kbuild)))
+-
+-PHONY += headers_install_all
+-headers_install_all: include/linux/version.h scripts_basic FORCE
+- $(Q)$(MAKE) $(build)=scripts scripts/unifdef
+- $(Q)for arch in $(HDRARCHES); do \
+- $(MAKE) ARCH=$$arch -f $(srctree)/scripts/Makefile.headersinst obj=include BIASMDIR=-bi-$$arch ;\
+- done
+-
+-PHONY += headers_install
+-headers_install: include/linux/version.h scripts_basic FORCE
+- @if [ ! -r $(srctree)/include/asm-$(ARCH)/Kbuild ]; then \
+- echo '*** Error: Headers not exportable for this architecture ($(ARCH))'; \
+- exit 1 ; fi
+- $(Q)$(MAKE) $(build)=scripts scripts/unifdef
+- $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst obj=include
+-
+-PHONY += headers_check_all
+-headers_check_all: headers_install_all
+- $(Q)for arch in $(HDRARCHES); do \
+- $(MAKE) ARCH=$$arch -f $(srctree)/scripts/Makefile.headersinst obj=include BIASMDIR=-bi-$$arch HDRCHECK=1 ;\
+- done
+-
+-PHONY += headers_check
+-headers_check: headers_install
+- $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst obj=include HDRCHECK=1
+-
+-# ---------------------------------------------------------------------------
+-# Modules
+-
+-ifdef CONFIG_MODULES
+-
+-# By default, build modules as well
+-
+-all: modules
+-
+-# Build modules
+-
+-PHONY += modules
+-modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux)
+- @echo ' Building modules, stage 2.';
+- $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
+-
+-
+-# Target to prepare building external modules
+-PHONY += modules_prepare
+-modules_prepare: prepare scripts
+-
+-# Target to install modules
+-PHONY += modules_install
+-modules_install: _modinst_ _modinst_post
+-
+-PHONY += _modinst_
+-_modinst_:
+- @if [ -z "`$(DEPMOD) -V 2>/dev/null | grep module-init-tools`" ]; then \
+- echo "Warning: you may need to install module-init-tools"; \
+- echo "See http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt";\
+- sleep 1; \
+- fi
+- @rm -rf $(MODLIB)/kernel
+- @rm -f $(MODLIB)/source
+- @mkdir -p $(MODLIB)/kernel
+- @ln -s $(srctree) $(MODLIB)/source
+- @if [ ! $(objtree) -ef $(MODLIB)/build ]; then \
+- rm -f $(MODLIB)/build ; \
+- ln -s $(objtree) $(MODLIB)/build ; \
+- fi
+- $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
+-
+-# If System.map exists, run depmod. This deliberately does not have a
+-# dependency on System.map since that would run the dependency tree on
+-# vmlinux. This depmod is only for convenience to give the initial
+-# boot a modules.dep even before / is mounted read-write. However the
+-# boot script depmod is the master version.
+-ifeq "$(strip $(INSTALL_MOD_PATH))" ""
+-depmod_opts :=
+-else
+-depmod_opts := -b $(INSTALL_MOD_PATH) -r
+-endif
+-PHONY += _modinst_post
+-_modinst_post: _modinst_
+- if [ -r System.map -a -x $(DEPMOD) ]; then $(DEPMOD) -ae -F System.map $(depmod_opts) $(KERNELRELEASE); fi
+-
+-else # CONFIG_MODULES
+-
+-# Modules not configured
+-# ---------------------------------------------------------------------------
+-
+-modules modules_install: FORCE
+- @echo
+- @echo "The present kernel configuration has modules disabled."
+- @echo "Type 'make config' and enable loadable module support."
+- @echo "Then build a kernel with module support enabled."
+- @echo
+- @exit 1
+-
+-endif # CONFIG_MODULES
+-
+-###
+-# Cleaning is done on three levels.
+-# make clean Delete most generated files
+-# Leave enough to build external modules
+-# make mrproper Delete the current configuration, and all generated files
+-# make distclean Remove editor backup files, patch leftover files and the like
+-
+-# Directories & files removed with 'make clean'
+-CLEAN_DIRS += $(MODVERDIR)
+-CLEAN_FILES += vmlinux System.map \
+- .tmp_kallsyms* .tmp_version .tmp_vmlinux* .tmp_System.map
+-
+-# Directories & files removed with 'make mrproper'
+-MRPROPER_DIRS += include/config include2 usr/include
+-MRPROPER_FILES += .config .config.old include/asm .version .old_version \
+- include/linux/autoconf.h include/linux/version.h \
+- include/linux/utsrelease.h \
+- Module.symvers tags TAGS cscope*
+-
+-# clean - Delete most, but leave enough to build external modules
+-#
+-clean: rm-dirs := $(CLEAN_DIRS)
+-clean: rm-files := $(CLEAN_FILES)
+-clean-dirs := $(addprefix _clean_,$(srctree) $(vmlinux-alldirs))
+-
+-PHONY += $(clean-dirs) clean archclean
+-$(clean-dirs):
+- $(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
+-
+-clean: archclean $(clean-dirs)
+- $(call cmd,rmdirs)
+- $(call cmd,rmfiles)
+- @find . $(RCS_FIND_IGNORE) \
+- \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
+- -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
+- -o -name '*.symtypes' \) \
+- -type f -print | xargs rm -f
+-
+-# mrproper - Delete all generated files, including .config
+-#
+-mrproper: rm-dirs := $(wildcard $(MRPROPER_DIRS))
+-mrproper: rm-files := $(wildcard $(MRPROPER_FILES))
+-mrproper-dirs := $(addprefix _mrproper_,Documentation/DocBook scripts)
+-
+-PHONY += $(mrproper-dirs) mrproper archmrproper
+-$(mrproper-dirs):
+- $(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@)
+-
+-mrproper: clean archmrproper $(mrproper-dirs)
+- $(call cmd,rmdirs)
+- $(call cmd,rmfiles)
+-
+-# distclean
+-#
+-PHONY += distclean
+-
+-distclean: mrproper
+- @find $(srctree) $(RCS_FIND_IGNORE) \
+- \( -name '*.orig' -o -name '*.rej' -o -name '*~' \
+- -o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
+- -o -name '.*.rej' -o -size 0 \
+- -o -name '*%' -o -name '.*.cmd' -o -name 'core' \) \
+- -type f -print | xargs rm -f
+-
+-
+-# Packaging of the kernel to various formats
+-# ---------------------------------------------------------------------------
+-# rpm target kept for backward compatibility
+-package-dir := $(srctree)/scripts/package
+-
+-%pkg: include/config/kernel.release FORCE
+- $(Q)$(MAKE) $(build)=$(package-dir) $@
+-rpm: include/config/kernel.release FORCE
+- $(Q)$(MAKE) $(build)=$(package-dir) $@
+-
+-
+-# Brief documentation of the typical targets used
+-# ---------------------------------------------------------------------------
+-
+-boards := $(wildcard $(srctree)/arch/$(ARCH)/configs/*_defconfig)
+-boards := $(notdir $(boards))
+-
+-help:
+- @echo 'Cleaning targets:'
+- @echo ' clean - Remove most generated files but keep the config and'
+- @echo ' enough build support to build external modules'
+- @echo ' mrproper - Remove all generated files + config + various backup files'
+- @echo ' distclean - mrproper + remove editor backup and patch files'
+- @echo ''
+- @echo 'Configuration targets:'
+- @$(MAKE) -f $(srctree)/scripts/kconfig/Makefile help
+- @echo ''
+- @echo 'Other generic targets:'
+- @echo ' all - Build all targets marked with [*]'
+- @echo '* vmlinux - Build the bare kernel'
+- @echo '* modules - Build all modules'
+- @echo ' modules_install - Install all modules to INSTALL_MOD_PATH (default: /)'
+- @echo ' dir/ - Build all files in dir and below'
+- @echo ' dir/file.[ois] - Build specified target only'
+- @echo ' dir/file.ko - Build module including final link'
+- @echo ' rpm - Build a kernel as an RPM package'
+- @echo ' tags/TAGS - Generate tags file for editors'
+- @echo ' cscope - Generate cscope index'
+- @echo ' kernelrelease - Output the release version string'
+- @echo ' kernelversion - Output the version stored in Makefile'
+- @if [ -r $(srctree)/include/asm-$(ARCH)/Kbuild ]; then \
+- echo ' headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH'; \
+- echo ' (default: $(INSTALL_HDR_PATH))'; \
+- fi
+- @echo ''
+- @echo 'Static analysers'
+- @echo ' checkstack - Generate a list of stack hogs'
+- @echo ' namespacecheck - Name space analysis on compiled kernel'
+- @if [ -r $(srctree)/include/asm-$(ARCH)/Kbuild ]; then \
+- echo ' headers_check - Sanity check on exported headers'; \
+- fi
+- @echo ''
+- @echo 'Kernel packaging:'
+- @$(MAKE) $(build)=$(package-dir) help
+- @echo ''
+- @echo 'Documentation targets:'
+- @$(MAKE) -f $(srctree)/Documentation/DocBook/Makefile dochelp
+- @echo ''
+- @echo 'Architecture specific targets ($(ARCH)):'
+- @$(if $(archhelp),$(archhelp),\
+- echo ' No architecture specific help defined for $(ARCH)')
+- @echo ''
+- @$(if $(boards), \
+- $(foreach b, $(boards), \
+- printf " %-24s - Build for %s\\n" $(b) $(subst _defconfig,,$(b));) \
+- echo '')
+-
+- @echo ' make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build'
+- @echo ' make V=2 [targets] 2 => give reason for rebuild of target'
+- @echo ' make O=dir [targets] Locate all output files in "dir", including .config'
+- @echo ' make C=1 [targets] Check all c source with $$CHECK (sparse by default)'
+- @echo ' make C=2 [targets] Force check of all c source with $$CHECK'
+- @echo ''
+- @echo 'Execute "make" or "make all" to build all targets marked with [*] '
+- @echo 'For further info see the ./README file'
+-
+-
+-# Documentation targets
+-# ---------------------------------------------------------------------------
+-%docs: scripts_basic FORCE
+- $(Q)$(MAKE) $(build)=Documentation/DocBook $@
+-
+-else # KBUILD_EXTMOD
+-
+-###
+-# External module support.
+-# When building external modules the kernel used as basis is considered
+-# read-only, and no consistency checks are made and the make
+-# system is not used on the basis kernel. If updates are required
+-# in the basis kernel ordinary make commands (without M=...) must
+-# be used.
+-#
+-# The following are the only valid targets when building external
+-# modules.
+-# make M=dir clean Delete all automatically generated files
+-# make M=dir modules Make all modules in specified dir
+-# make M=dir Same as 'make M=dir modules'
+-# make M=dir modules_install
+-# Install the modules built in the module directory
+-# Assumes install directory is already created
+-
+-# We are always building modules
+-KBUILD_MODULES := 1
+-PHONY += crmodverdir
+-crmodverdir:
+- $(Q)mkdir -p $(MODVERDIR)
+- $(Q)rm -f $(MODVERDIR)/*
+-
+-PHONY += $(objtree)/Module.symvers
+-$(objtree)/Module.symvers:
+- @test -e $(objtree)/Module.symvers || ( \
+- echo; \
+- echo " WARNING: Symbol version dump $(objtree)/Module.symvers"; \
+- echo " is missing; modules will have no dependencies and modversions."; \
+- echo )
+-
+-module-dirs := $(addprefix _module_,$(KBUILD_EXTMOD))
+-PHONY += $(module-dirs) modules
+-$(module-dirs): crmodverdir $(objtree)/Module.symvers
+- $(Q)$(MAKE) $(build)=$(patsubst _module_%,%,$@)
+-
+-modules: $(module-dirs)
+- @echo ' Building modules, stage 2.';
+- $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
+-
+-PHONY += modules_install
+-modules_install: _emodinst_ _emodinst_post
+-
+-install-dir := $(if $(INSTALL_MOD_DIR),$(INSTALL_MOD_DIR),extra)
+-PHONY += _emodinst_
+-_emodinst_:
+- $(Q)mkdir -p $(MODLIB)/$(install-dir)
+- $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
+-
+-# Run depmod only is we have System.map and depmod is executable
+-quiet_cmd_depmod = DEPMOD $(KERNELRELEASE)
+- cmd_depmod = if [ -r System.map -a -x $(DEPMOD) ]; then \
+- $(DEPMOD) -ae -F System.map \
+- $(if $(strip $(INSTALL_MOD_PATH)), \
+- -b $(INSTALL_MOD_PATH) -r) \
+- $(KERNELRELEASE); \
+- fi
+-
+-PHONY += _emodinst_post
+-_emodinst_post: _emodinst_
+- $(call cmd,depmod)
+-
+-clean-dirs := $(addprefix _clean_,$(KBUILD_EXTMOD))
+-
+-PHONY += $(clean-dirs) clean
+-$(clean-dirs):
+- $(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
+-
+-clean: rm-dirs := $(MODVERDIR)
+-clean: $(clean-dirs)
+- $(call cmd,rmdirs)
+- @find $(KBUILD_EXTMOD) $(RCS_FIND_IGNORE) \
+- \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
+- -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \) \
+- -type f -print | xargs rm -f
+-
+-help:
+- @echo ' Building external modules.'
+- @echo ' Syntax: make -C path/to/kernel/src M=$$PWD target'
+- @echo ''
+- @echo ' modules - default target, build the module(s)'
+- @echo ' modules_install - install the module'
+- @echo ' clean - remove generated files in module directory only'
+- @echo ''
+-
+-# Dummies...
+-PHONY += prepare scripts
+-prepare: ;
+-scripts: ;
+-endif # KBUILD_EXTMOD
+-
+-# Generate tags for editors
+-# ---------------------------------------------------------------------------
+-
+-#We want __srctree to totally vanish out when KBUILD_OUTPUT is not set
+-#(which is the most common case IMHO) to avoid unneeded clutter in the big tags file.
+-#Adding $(srctree) adds about 20M on i386 to the size of the output file!
+-
+-ifeq ($(src),$(obj))
+-__srctree =
+-else
+-__srctree = $(srctree)/
+-endif
+-
+-ifeq ($(ALLSOURCE_ARCHS),)
+-ifeq ($(ARCH),um)
+-ALLINCLUDE_ARCHS := $(ARCH) $(SUBARCH)
+-else
+-ALLINCLUDE_ARCHS := $(ARCH)
+-endif
+-else
+-#Allow user to specify only ALLSOURCE_PATHS on the command line, keeping existing behavour.
+-ALLINCLUDE_ARCHS := $(ALLSOURCE_ARCHS)
+-endif
+-
+-ALLSOURCE_ARCHS := $(ARCH)
+-
+-define find-sources
+- ( for ARCH in $(ALLSOURCE_ARCHS) ; do \
+- find $(__srctree)arch/$${ARCH} $(RCS_FIND_IGNORE) \
+- -name $1 -print; \
+- done ; \
+- find $(__srctree)security/selinux/include $(RCS_FIND_IGNORE) \
+- -name $1 -print; \
+- find $(__srctree)include $(RCS_FIND_IGNORE) \
+- \( -name config -o -name 'asm-*' \) -prune \
+- -o -name $1 -print; \
+- for ARCH in $(ALLINCLUDE_ARCHS) ; do \
+- find $(__srctree)include/asm-$${ARCH} $(RCS_FIND_IGNORE) \
+- -name $1 -print; \
+- done ; \
+- find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \
+- -name $1 -print; \
+- find $(__srctree) $(RCS_FIND_IGNORE) \
+- \( -name include -o -name arch \) -prune -o \
+- -name $1 -print; \
+- )
+-endef
+-
+-define all-sources
+- $(call find-sources,'*.[chS]')
+-endef
+-define all-kconfigs
+- $(call find-sources,'Kconfig*')
+-endef
+-define all-defconfigs
+- $(call find-sources,'defconfig')
+-endef
+-
+-define xtags
+- if $1 --version 2>&1 | grep -iq exuberant; then \
+- $(all-sources) | xargs $1 -a \
+- -I __initdata,__exitdata,__acquires,__releases \
+- -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
+- --extra=+f --c-kinds=+px \
+- --regex-asm='/ENTRY\(([^)]*)\).*/\1/'; \
+- $(all-kconfigs) | xargs $1 -a \
+- --langdef=kconfig \
+- --language-force=kconfig \
+- --regex-kconfig='/^[[:blank:]]*config[[:blank:]]+([[:alnum:]_]+)/\1/'; \
+- $(all-defconfigs) | xargs -r $1 -a \
+- --langdef=dotconfig \
+- --language-force=dotconfig \
+- --regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/'; \
+- elif $1 --version 2>&1 | grep -iq emacs; then \
+- $(all-sources) | xargs $1 -a; \
+- $(all-kconfigs) | xargs $1 -a \
+- --regex='/^[ \t]*config[ \t]+\([a-zA-Z0-9_]+\)/\1/'; \
+- $(all-defconfigs) | xargs -r $1 -a \
+- --regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/'; \
+- else \
+- $(all-sources) | xargs $1 -a; \
+- fi
+-endef
+-
+-quiet_cmd_cscope-file = FILELST cscope.files
+- cmd_cscope-file = (echo \-k; echo \-q; $(all-sources)) > cscope.files
+-
+-quiet_cmd_cscope = MAKE cscope.out
+- cmd_cscope = cscope -b
+-
+-cscope: FORCE
+- $(call cmd,cscope-file)
+- $(call cmd,cscope)
+-
+-quiet_cmd_TAGS = MAKE $@
+-define cmd_TAGS
+- rm -f $@; \
+- $(call xtags,etags)
+-endef
+-
+-TAGS: FORCE
+- $(call cmd,TAGS)
+-
+-quiet_cmd_tags = MAKE $@
+-define cmd_tags
+- rm -f $@; \
+- $(call xtags,ctags)
+-endef
+-
+-tags: FORCE
+- $(call cmd,tags)
+-
+-
+-# Scripts to check various things for consistency
+-# ---------------------------------------------------------------------------
+-
+-includecheck:
+- find * $(RCS_FIND_IGNORE) \
+- -name '*.[hcS]' -type f -print | sort \
+- | xargs $(PERL) -w scripts/checkincludes.pl
+-
+-versioncheck:
+- find * $(RCS_FIND_IGNORE) \
+- -name '*.[hcS]' -type f -print | sort \
+- | xargs $(PERL) -w scripts/checkversion.pl
+-
+-namespacecheck:
+- $(PERL) $(srctree)/scripts/namespace.pl
+-
+-endif #ifeq ($(config-targets),1)
+-endif #ifeq ($(mixed-targets),1)
+-
+-PHONY += checkstack kernelrelease kernelversion
+-
+-# UML needs a little special treatment here. It wants to use the host
+-# toolchain, so needs $(SUBARCH) passed to checkstack.pl. Everyone
+-# else wants $(ARCH), including people doing cross-builds, which means
+-# that $(SUBARCH) doesn't work here.
+-ifeq ($(ARCH), um)
+-CHECKSTACK_ARCH := $(SUBARCH)
+-else
+-CHECKSTACK_ARCH := $(ARCH)
+-endif
+-checkstack:
+- $(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \
+- $(PERL) $(src)/scripts/checkstack.pl $(CHECKSTACK_ARCH)
+-
+-kernelrelease:
+- $(if $(wildcard include/config/kernel.release), $(Q)echo $(KERNELRELEASE), \
+- $(error kernelrelease not valid - run 'make prepare' to update it))
+-kernelversion:
+- @echo $(KERNELVERSION)
+-
+-# Single targets
+-# ---------------------------------------------------------------------------
+-# Single targets are compatible with:
+-# - build whith mixed source and output
+-# - build with separate output dir 'make O=...'
+-# - external modules
+-#
+-# target-dir => where to store outputfile
+-# build-dir => directory in kernel source tree to use
+-
+-ifeq ($(KBUILD_EXTMOD),)
+- build-dir = $(patsubst %/,%,$(dir $@))
+- target-dir = $(dir $@)
+-else
+- zap-slash=$(filter-out .,$(patsubst %/,%,$(dir $@)))
+- build-dir = $(KBUILD_EXTMOD)$(if $(zap-slash),/$(zap-slash))
+- target-dir = $(if $(KBUILD_EXTMOD),$(dir $<),$(dir $@))
+-endif
+-
+-%.s: %.c prepare scripts FORCE
+- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+-%.i: %.c prepare scripts FORCE
+- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+-%.o: %.c prepare scripts FORCE
+- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+-%.lst: %.c prepare scripts FORCE
+- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+-%.s: %.S prepare scripts FORCE
+- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+-%.o: %.S prepare scripts FORCE
+- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+-%.symtypes: %.c prepare scripts FORCE
+- $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+-
+-# Modules
+-/ %/: prepare scripts FORCE
+- $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
+- $(build)=$(build-dir)
+-%.ko: prepare scripts FORCE
+- $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
+- $(build)=$(build-dir) $(@:.ko=.o)
+- $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
+-
+-# FIXME Should go into a make.lib or something
+-# ===========================================================================
+-
+-quiet_cmd_rmdirs = $(if $(wildcard $(rm-dirs)),CLEAN $(wildcard $(rm-dirs)))
+- cmd_rmdirs = rm -rf $(rm-dirs)
+-
+-quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN $(wildcard $(rm-files)))
+- cmd_rmfiles = rm -f $(rm-files)
+-
+-
+-a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(AFLAGS_KERNEL) \
+- $(NOSTDINC_FLAGS) $(CPPFLAGS) \
+- $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(basetarget).o)
+-
+-quiet_cmd_as_o_S = AS $@
+-cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $<
+-
+-# read all saved command lines
+-
+-targets := $(wildcard $(sort $(targets)))
+-cmd_files := $(wildcard .*.cmd $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
+-
+-ifneq ($(cmd_files),)
+- $(cmd_files): ; # Do not try to update included dependency files
+- include $(cmd_files)
+-endif
+-
+-# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=dir
+-# Usage:
+-# $(Q)$(MAKE) $(clean)=dir
+-clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj
+-
+-endif # skip-makefile
+-
+-PHONY += FORCE
+-FORCE:
+-
+-# Cancel implicit rules on top Makefile, `-rR' will apply to sub-makes.
+-Makefile: ;
+-
+-# Declare the contents of the .PHONY variable as phony. We keep that
+-# information in a variable se we can use it in if_changed and friends.
+-.PHONY: $(PHONY)
diff -Nurb linux-2.6.22-570/arch/arm/Kconfig linux-2.6.22-590/arch/arm/Kconfig
---- linux-2.6.22-570/arch/arm/Kconfig 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/Kconfig 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/arm/Kconfig 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/arm/Kconfig 2008-01-29 22:12:30.000000000 -0500
@@ -1034,6 +1034,8 @@
source "drivers/rtc/Kconfig"
source "fs/Kconfig"
diff -Nurb linux-2.6.22-570/arch/arm/boot/.gitignore.rej linux-2.6.22-590/arch/arm/boot/.gitignore.rej
--- linux-2.6.22-570/arch/arm/boot/.gitignore.rej 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/arm/boot/.gitignore.rej 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/boot/.gitignore.rej 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,10 @@
+***************
+*** 1,2 ****
++ uImage
diff -Nurb linux-2.6.22-570/arch/arm/kernel/Makefile linux-2.6.22-590/arch/arm/kernel/Makefile
--- linux-2.6.22-570/arch/arm/kernel/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/kernel/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/kernel/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -20,6 +20,7 @@
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
diff -Nurb linux-2.6.22-570/arch/arm/kernel/kgdb-jmp.S linux-2.6.22-590/arch/arm/kernel/kgdb-jmp.S
--- linux-2.6.22-570/arch/arm/kernel/kgdb-jmp.S 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/arm/kernel/kgdb-jmp.S 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/kernel/kgdb-jmp.S 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,32 @@
+/*
+ * arch/arm/kernel/kgdb-jmp.S
+ ldmia r0,{r0-pc}^
diff -Nurb linux-2.6.22-570/arch/arm/kernel/kgdb.c linux-2.6.22-590/arch/arm/kernel/kgdb.c
--- linux-2.6.22-570/arch/arm/kernel/kgdb.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/arm/kernel/kgdb.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/kernel/kgdb.c 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,202 @@
+/*
+ * arch/arm/kernel/kgdb.c
+};
diff -Nurb linux-2.6.22-570/arch/arm/kernel/setup.c linux-2.6.22-590/arch/arm/kernel/setup.c
--- linux-2.6.22-570/arch/arm/kernel/setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/kernel/setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/kernel/setup.c 2008-01-29 22:12:30.000000000 -0500
@@ -832,6 +832,11 @@
conswitchp = &dummy_con;
#endif
diff -Nurb linux-2.6.22-570/arch/arm/kernel/traps.c linux-2.6.22-590/arch/arm/kernel/traps.c
---- linux-2.6.22-570/arch/arm/kernel/traps.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/kernel/traps.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/arm/kernel/traps.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/arm/kernel/traps.c 2008-01-29 22:12:30.000000000 -0500
@@ -301,6 +301,7 @@
unsigned int instr;
struct undef_hook *hook;
extern char __vectors_start[], __vectors_end[];
diff -Nurb linux-2.6.22-570/arch/arm/mach-iop13xx/setup.c linux-2.6.22-590/arch/arm/mach-iop13xx/setup.c
--- linux-2.6.22-570/arch/arm/mach-iop13xx/setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/mach-iop13xx/setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/mach-iop13xx/setup.c 2008-01-29 22:12:30.000000000 -0500
@@ -25,6 +25,7 @@
#include <asm/hardware.h>
#include <asm/irq.h>
__setup("iop13xx_init_i2c", iop13xx_init_i2c_setup);
diff -Nurb linux-2.6.22-570/arch/arm/mach-iop32x/glantank.c linux-2.6.22-590/arch/arm/mach-iop32x/glantank.c
--- linux-2.6.22-570/arch/arm/mach-iop32x/glantank.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/mach-iop32x/glantank.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/mach-iop32x/glantank.c 2008-01-29 22:12:30.000000000 -0500
@@ -180,6 +180,8 @@
platform_device_register(&iop3xx_i2c1_device);
platform_device_register(&glantank_flash_device);
}
diff -Nurb linux-2.6.22-570/arch/arm/mach-iop32x/iq31244.c linux-2.6.22-590/arch/arm/mach-iop32x/iq31244.c
--- linux-2.6.22-570/arch/arm/mach-iop32x/iq31244.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/mach-iop32x/iq31244.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/mach-iop32x/iq31244.c 2008-01-29 22:12:30.000000000 -0500
@@ -298,9 +298,14 @@
platform_device_register(&iop3xx_i2c1_device);
platform_device_register(&iq31244_flash_device);
static int __init force_ep80219_setup(char *str)
diff -Nurb linux-2.6.22-570/arch/arm/mach-iop32x/iq80321.c linux-2.6.22-590/arch/arm/mach-iop32x/iq80321.c
--- linux-2.6.22-570/arch/arm/mach-iop32x/iq80321.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/mach-iop32x/iq80321.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/mach-iop32x/iq80321.c 2008-01-29 22:12:30.000000000 -0500
@@ -181,6 +181,9 @@
platform_device_register(&iop3xx_i2c1_device);
platform_device_register(&iq80321_flash_device);
MACHINE_START(IQ80321, "Intel IQ80321")
diff -Nurb linux-2.6.22-570/arch/arm/mach-iop32x/n2100.c linux-2.6.22-590/arch/arm/mach-iop32x/n2100.c
--- linux-2.6.22-570/arch/arm/mach-iop32x/n2100.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/mach-iop32x/n2100.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/mach-iop32x/n2100.c 2008-01-29 22:12:30.000000000 -0500
@@ -245,6 +245,8 @@
platform_device_register(&iop3xx_i2c0_device);
platform_device_register(&n2100_flash_device);
diff -Nurb linux-2.6.22-570/arch/arm/mach-iop33x/iq80331.c linux-2.6.22-590/arch/arm/mach-iop33x/iq80331.c
--- linux-2.6.22-570/arch/arm/mach-iop33x/iq80331.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/mach-iop33x/iq80331.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/mach-iop33x/iq80331.c 2008-01-29 22:12:30.000000000 -0500
@@ -136,6 +136,9 @@
platform_device_register(&iop33x_uart0_device);
platform_device_register(&iop33x_uart1_device);
MACHINE_START(IQ80331, "Intel IQ80331")
diff -Nurb linux-2.6.22-570/arch/arm/mach-iop33x/iq80332.c linux-2.6.22-590/arch/arm/mach-iop33x/iq80332.c
--- linux-2.6.22-570/arch/arm/mach-iop33x/iq80332.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/mach-iop33x/iq80332.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/mach-iop33x/iq80332.c 2008-01-29 22:12:30.000000000 -0500
@@ -136,6 +136,9 @@
platform_device_register(&iop33x_uart0_device);
platform_device_register(&iop33x_uart1_device);
MACHINE_START(IQ80332, "Intel IQ80332")
diff -Nurb linux-2.6.22-570/arch/arm/mach-ixp2000/core.c linux-2.6.22-590/arch/arm/mach-ixp2000/core.c
--- linux-2.6.22-570/arch/arm/mach-ixp2000/core.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/mach-ixp2000/core.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/mach-ixp2000/core.c 2008-01-29 22:12:30.000000000 -0500
@@ -34,6 +34,7 @@
#include <asm/system.h>
#include <asm/tlbflush.h>
diff -Nurb linux-2.6.22-570/arch/arm/mach-ixp2000/ixdp2x01.c linux-2.6.22-590/arch/arm/mach-ixp2000/ixdp2x01.c
--- linux-2.6.22-570/arch/arm/mach-ixp2000/ixdp2x01.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/mach-ixp2000/ixdp2x01.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/mach-ixp2000/ixdp2x01.c 2008-01-29 22:12:30.000000000 -0500
@@ -38,6 +38,7 @@
#include <asm/system.h>
#include <asm/hardware.h>
diff -Nurb linux-2.6.22-570/arch/arm/mach-ixp4xx/coyote-setup.c linux-2.6.22-590/arch/arm/mach-ixp4xx/coyote-setup.c
--- linux-2.6.22-570/arch/arm/mach-ixp4xx/coyote-setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/mach-ixp4xx/coyote-setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/mach-ixp4xx/coyote-setup.c 2008-01-29 22:12:30.000000000 -0500
@@ -96,6 +96,10 @@
}
#ifdef CONFIG_ARCH_ADI_COYOTE
diff -Nurb linux-2.6.22-570/arch/arm/mach-ixp4xx/ixdp425-setup.c linux-2.6.22-590/arch/arm/mach-ixp4xx/ixdp425-setup.c
--- linux-2.6.22-570/arch/arm/mach-ixp4xx/ixdp425-setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/mach-ixp4xx/ixdp425-setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/mach-ixp4xx/ixdp425-setup.c 2008-01-29 22:12:30.000000000 -0500
@@ -76,7 +76,8 @@
.mapbase = IXP4XX_UART1_BASE_PHYS,
.membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
.boot_params = 0x0100,
diff -Nurb linux-2.6.22-570/arch/arm/mach-omap1/serial.c linux-2.6.22-590/arch/arm/mach-omap1/serial.c
--- linux-2.6.22-570/arch/arm/mach-omap1/serial.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/mach-omap1/serial.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/mach-omap1/serial.c 2008-01-29 22:12:30.000000000 -0500
@@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <linux/serial.h>
diff -Nurb linux-2.6.22-570/arch/arm/mach-pnx4008/core.c linux-2.6.22-590/arch/arm/mach-pnx4008/core.c
--- linux-2.6.22-570/arch/arm/mach-pnx4008/core.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/mach-pnx4008/core.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/mach-pnx4008/core.c 2008-01-29 22:12:30.000000000 -0500
@@ -224,6 +224,10 @@
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
/* Switch on the UART clocks */
static struct map_desc pnx4008_io_desc[] __initdata = {
diff -Nurb linux-2.6.22-570/arch/arm/mach-pxa/Makefile linux-2.6.22-590/arch/arm/mach-pxa/Makefile
--- linux-2.6.22-570/arch/arm/mach-pxa/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/mach-pxa/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/mach-pxa/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -31,6 +31,7 @@
# Misc features
obj-$(CONFIG_PM) += pm.o sleep.o
obj-$(CONFIG_PM) += standby.o
diff -Nurb linux-2.6.22-570/arch/arm/mach-pxa/kgdb-serial.c linux-2.6.22-590/arch/arm/mach-pxa/kgdb-serial.c
--- linux-2.6.22-570/arch/arm/mach-pxa/kgdb-serial.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/arm/mach-pxa/kgdb-serial.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/mach-pxa/kgdb-serial.c 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,97 @@
+/*
+ * linux/arch/arm/mach-pxa/kgdb-serial.c
+};
diff -Nurb linux-2.6.22-570/arch/arm/mach-versatile/core.c linux-2.6.22-590/arch/arm/mach-versatile/core.c
--- linux-2.6.22-570/arch/arm/mach-versatile/core.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/mach-versatile/core.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/mach-versatile/core.c 2008-01-29 22:12:30.000000000 -0500
@@ -184,6 +184,14 @@
.type = MT_DEVICE
},
.virtual = IO_ADDRESS(VERSATILE_PCI_CORE_BASE),
diff -Nurb linux-2.6.22-570/arch/arm/mm/extable.c linux-2.6.22-590/arch/arm/mm/extable.c
--- linux-2.6.22-570/arch/arm/mm/extable.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/mm/extable.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/mm/extable.c 2008-01-29 22:12:30.000000000 -0500
@@ -2,6 +2,7 @@
* linux/arch/arm/mm/extable.c
*/
}
diff -Nurb linux-2.6.22-570/arch/arm/plat-iop/Makefile linux-2.6.22-590/arch/arm/plat-iop/Makefile
--- linux-2.6.22-570/arch/arm/plat-iop/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/arm/plat-iop/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/plat-iop/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -12,6 +12,7 @@
obj-$(CONFIG_ARCH_IOP32X) += time.o
obj-$(CONFIG_ARCH_IOP32X) += io.o
obj-$(CONFIG_ARCH_IOP13XX) += cp6.o
diff -Nurb linux-2.6.22-570/arch/arm/plat-iop/adma.c linux-2.6.22-590/arch/arm/plat-iop/adma.c
--- linux-2.6.22-570/arch/arm/plat-iop/adma.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/arm/plat-iop/adma.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/arm/plat-iop/adma.c 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,209 @@
+/*
+ * platform device definitions for the iop3xx dma/xor engines
+
+arch_initcall(iop3xx_adma_cap_init);
diff -Nurb linux-2.6.22-570/arch/i386/Kconfig linux-2.6.22-590/arch/i386/Kconfig
---- linux-2.6.22-570/arch/i386/Kconfig 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/i386/Kconfig 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/i386/Kconfig 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/i386/Kconfig 2008-01-29 22:12:30.000000000 -0500
@@ -1053,6 +1053,8 @@
source "arch/i386/kernel/cpu/cpufreq/Kconfig"
menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
diff -Nurb linux-2.6.22-570/arch/i386/kernel/Makefile linux-2.6.22-590/arch/i386/kernel/Makefile
---- linux-2.6.22-570/arch/i386/kernel/Makefile 2008-03-15 10:34:19.000000000 -0400
-+++ linux-2.6.22-590/arch/i386/kernel/Makefile 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/i386/kernel/Makefile 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/arch/i386/kernel/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -39,6 +39,7 @@
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_HPET_TIMER) += hpet.o
obj-$(CONFIG_PARAVIRT) += paravirt.o
diff -Nurb linux-2.6.22-570/arch/i386/kernel/acpi/boot.c linux-2.6.22-590/arch/i386/kernel/acpi/boot.c
--- linux-2.6.22-570/arch/i386/kernel/acpi/boot.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/i386/kernel/acpi/boot.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/i386/kernel/acpi/boot.c 2008-01-29 22:12:30.000000000 -0500
@@ -950,14 +950,6 @@
},
{
DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
diff -Nurb linux-2.6.22-570/arch/i386/kernel/apm.c linux-2.6.22-590/arch/i386/kernel/apm.c
--- linux-2.6.22-570/arch/i386/kernel/apm.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/i386/kernel/apm.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/i386/kernel/apm.c 2008-01-29 22:12:30.000000000 -0500
@@ -222,6 +222,7 @@
#include <linux/capability.h>
#include <linux/device.h>
if (num_online_cpus() > 1 && !smp ) {
diff -Nurb linux-2.6.22-570/arch/i386/kernel/io_apic.c linux-2.6.22-590/arch/i386/kernel/io_apic.c
---- linux-2.6.22-570/arch/i386/kernel/io_apic.c 2008-03-15 10:34:19.000000000 -0400
-+++ linux-2.6.22-590/arch/i386/kernel/io_apic.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/i386/kernel/io_apic.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/arch/i386/kernel/io_apic.c 2008-01-29 22:12:30.000000000 -0500
@@ -667,6 +667,7 @@
set_pending_irq(i, cpumask_of_cpu(0));
}
try_to_freeze();
diff -Nurb linux-2.6.22-570/arch/i386/kernel/kgdb-jmp.S linux-2.6.22-590/arch/i386/kernel/kgdb-jmp.S
--- linux-2.6.22-570/arch/i386/kernel/kgdb-jmp.S 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/i386/kernel/kgdb-jmp.S 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/i386/kernel/kgdb-jmp.S 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,74 @@
+/*
+ * arch/i386/kernel/kgdb-jmp.S
+ jmp *%edx /* Jump to saved PC. */
diff -Nurb linux-2.6.22-570/arch/i386/kernel/kgdb.c linux-2.6.22-590/arch/i386/kernel/kgdb.c
--- linux-2.6.22-570/arch/i386/kernel/kgdb.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/i386/kernel/kgdb.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/i386/kernel/kgdb.c 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,388 @@
+/*
+ *
+ .correct_hw_break = kgdb_correct_hw_break,
+};
diff -Nurb linux-2.6.22-570/arch/i386/kernel/process.c linux-2.6.22-590/arch/i386/kernel/process.c
---- linux-2.6.22-570/arch/i386/kernel/process.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/i386/kernel/process.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/i386/kernel/process.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/i386/kernel/process.c 2008-01-29 22:12:30.000000000 -0500
@@ -179,13 +179,13 @@
/* endless idle loop with no priority at all */
idle = pm_idle;
diff -Nurb linux-2.6.22-570/arch/i386/kernel/setup.c linux-2.6.22-590/arch/i386/kernel/setup.c
--- linux-2.6.22-570/arch/i386/kernel/setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/i386/kernel/setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/i386/kernel/setup.c 2008-01-29 22:12:30.000000000 -0500
@@ -124,6 +124,7 @@
#endif
* FIXME: This isn't an official loader_type right
diff -Nurb linux-2.6.22-570/arch/i386/kernel/signal.c linux-2.6.22-590/arch/i386/kernel/signal.c
--- linux-2.6.22-570/arch/i386/kernel/signal.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/i386/kernel/signal.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/i386/kernel/signal.c 2008-01-29 22:12:30.000000000 -0500
@@ -199,6 +199,13 @@
return eax;
return 0;
}
diff -Nurb linux-2.6.22-570/arch/i386/kernel/syscall_table.S linux-2.6.22-590/arch/i386/kernel/syscall_table.S
---- linux-2.6.22-570/arch/i386/kernel/syscall_table.S 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/i386/kernel/syscall_table.S 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/i386/kernel/syscall_table.S 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/i386/kernel/syscall_table.S 2008-01-29 22:12:30.000000000 -0500
@@ -323,3 +323,6 @@
.long sys_signalfd
.long sys_timerfd
+ .long sys_frevoke /* 325 */
+ .long sys_fallocate
diff -Nurb linux-2.6.22-570/arch/i386/kernel/traps.c linux-2.6.22-590/arch/i386/kernel/traps.c
---- linux-2.6.22-570/arch/i386/kernel/traps.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/i386/kernel/traps.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/i386/kernel/traps.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/i386/kernel/traps.c 2008-01-29 22:12:30.000000000 -0500
@@ -97,6 +97,11 @@
int kstack_depth_to_print = 24;
+#endif
diff -Nurb linux-2.6.22-570/arch/i386/kernel/unwind.S linux-2.6.22-590/arch/i386/kernel/unwind.S
--- linux-2.6.22-570/arch/i386/kernel/unwind.S 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/i386/kernel/unwind.S 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/i386/kernel/unwind.S 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,36 @@
+/* Assembler support code for dwarf2 unwinder */
+#include <linux/linkage.h>
+ENDPROC(arch_unwind_init_running)
diff -Nurb linux-2.6.22-570/arch/i386/mach-voyager/voyager_thread.c linux-2.6.22-590/arch/i386/mach-voyager/voyager_thread.c
--- linux-2.6.22-570/arch/i386/mach-voyager/voyager_thread.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/i386/mach-voyager/voyager_thread.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/i386/mach-voyager/voyager_thread.c 2008-01-29 22:12:30.000000000 -0500
@@ -52,7 +52,7 @@
NULL,
};
string, ret);
}
diff -Nurb linux-2.6.22-570/arch/i386/mm/fault.c linux-2.6.22-590/arch/i386/mm/fault.c
---- linux-2.6.22-570/arch/i386/mm/fault.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/i386/mm/fault.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/i386/mm/fault.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/i386/mm/fault.c 2008-01-29 22:12:30.000000000 -0500
@@ -284,6 +284,8 @@
return 0;
}
/*
* Oops. The kernel tried to access some bad page. We'll have to
* terminate things with extreme prejudice.
+diff -Nurb linux-2.6.22-570/arch/ia64/hp/sim/simeth.c linux-2.6.22-590/arch/ia64/hp/sim/simeth.c
+--- linux-2.6.22-570/arch/ia64/hp/sim/simeth.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/arch/ia64/hp/sim/simeth.c 2008-01-29 22:12:30.000000000 -0500
+@@ -300,6 +300,9 @@
+ return NOTIFY_DONE;
+ }
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ if ( event != NETDEV_UP && event != NETDEV_DOWN ) return NOTIFY_DONE;
+
+ /*
diff -Nurb linux-2.6.22-570/arch/ia64/kernel/Makefile linux-2.6.22-590/arch/ia64/kernel/Makefile
--- linux-2.6.22-570/arch/ia64/kernel/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ia64/kernel/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ia64/kernel/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -35,6 +35,7 @@
obj-$(CONFIG_PCI_MSI) += msi_ia64.o
mca_recovery-y += mca_drv.o mca_drv_asm.o
ifneq ($(CONFIG_IA64_ESI),)
diff -Nurb linux-2.6.22-570/arch/ia64/kernel/kgdb-jmp.S linux-2.6.22-590/arch/ia64/kernel/kgdb-jmp.S
--- linux-2.6.22-570/arch/ia64/kernel/kgdb-jmp.S 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/ia64/kernel/kgdb-jmp.S 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ia64/kernel/kgdb-jmp.S 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,238 @@
+/* setjmp() and longjmp() assembler support for kdb on ia64.
+
+END(kgdb_fault_longjmp)
diff -Nurb linux-2.6.22-570/arch/ia64/kernel/kgdb.c linux-2.6.22-590/arch/ia64/kernel/kgdb.c
--- linux-2.6.22-570/arch/ia64/kernel/kgdb.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/ia64/kernel/kgdb.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ia64/kernel/kgdb.c 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,944 @@
+/*
+ *
+};
diff -Nurb linux-2.6.22-570/arch/ia64/kernel/smp.c linux-2.6.22-590/arch/ia64/kernel/smp.c
--- linux-2.6.22-570/arch/ia64/kernel/smp.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ia64/kernel/smp.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ia64/kernel/smp.c 2008-01-29 22:12:30.000000000 -0500
@@ -48,6 +48,7 @@
#include <asm/tlbflush.h>
#include <asm/unistd.h>
* this function sends a 'generic call function' IPI to all other CPUs
* in the system.
diff -Nurb linux-2.6.22-570/arch/ia64/kernel/traps.c linux-2.6.22-590/arch/ia64/kernel/traps.c
---- linux-2.6.22-570/arch/ia64/kernel/traps.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/ia64/kernel/traps.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/ia64/kernel/traps.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/ia64/kernel/traps.c 2008-01-29 22:12:30.000000000 -0500
@@ -155,8 +155,12 @@
break;
sig = SIGILL; code = __ILL_BREAK;
diff -Nurb linux-2.6.22-570/arch/ia64/mm/extable.c linux-2.6.22-590/arch/ia64/mm/extable.c
--- linux-2.6.22-570/arch/ia64/mm/extable.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ia64/mm/extable.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ia64/mm/extable.c 2008-01-29 22:12:30.000000000 -0500
@@ -6,6 +6,7 @@
*/
}
diff -Nurb linux-2.6.22-570/arch/ia64/mm/fault.c linux-2.6.22-590/arch/ia64/mm/fault.c
---- linux-2.6.22-570/arch/ia64/mm/fault.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/ia64/mm/fault.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/ia64/mm/fault.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/ia64/mm/fault.c 2008-01-29 22:12:30.000000000 -0500
@@ -255,6 +255,10 @@
*/
bust_spinlocks(1);
printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference (address %016lx)\n", address);
else
diff -Nurb linux-2.6.22-570/arch/mips/Kconfig linux-2.6.22-590/arch/mips/Kconfig
---- linux-2.6.22-570/arch/mips/Kconfig 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/Kconfig 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/mips/Kconfig 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/mips/Kconfig 2008-01-29 22:12:30.000000000 -0500
@@ -30,7 +30,6 @@
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
bool
diff -Nurb linux-2.6.22-570/arch/mips/Kconfig.debug linux-2.6.22-590/arch/mips/Kconfig.debug
--- linux-2.6.22-570/arch/mips/Kconfig.debug 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/Kconfig.debug 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/Kconfig.debug 2008-01-29 22:12:30.000000000 -0500
@@ -46,28 +46,6 @@
arch/mips/kernel/smtc.c. This debugging option result in significant
overhead so should be disabled in production kernels.
depends on SIBYTE_SB1xxx_SOC
diff -Nurb linux-2.6.22-570/arch/mips/au1000/common/Makefile linux-2.6.22-590/arch/mips/au1000/common/Makefile
--- linux-2.6.22-570/arch/mips/au1000/common/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/au1000/common/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/au1000/common/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -10,5 +10,4 @@
au1xxx_irqmap.o clocks.o platform.o power.o setup.o \
sleeper.o cputable.o dma.o dbdma.o gpio.o
-#endif
diff -Nurb linux-2.6.22-570/arch/mips/basler/excite/Makefile linux-2.6.22-590/arch/mips/basler/excite/Makefile
--- linux-2.6.22-570/arch/mips/basler/excite/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/basler/excite/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/basler/excite/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -5,5 +5,4 @@
obj-$(CONFIG_BASLER_EXCITE) += excite_irq.o excite_prom.o excite_setup.o \
excite_device.o excite_procfs.o
-}
diff -Nurb linux-2.6.22-570/arch/mips/basler/excite/excite_irq.c linux-2.6.22-590/arch/mips/basler/excite/excite_irq.c
--- linux-2.6.22-570/arch/mips/basler/excite/excite_irq.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/basler/excite/excite_irq.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/basler/excite/excite_irq.c 2008-01-29 22:12:30.000000000 -0500
@@ -50,10 +50,6 @@
mips_cpu_irq_init();
rm7k_cpu_irq_init();
}
diff -Nurb linux-2.6.22-570/arch/mips/basler/excite/excite_setup.c linux-2.6.22-590/arch/mips/basler/excite/excite_setup.c
--- linux-2.6.22-570/arch/mips/basler/excite/excite_setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/basler/excite/excite_setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/basler/excite/excite_setup.c 2008-01-29 22:12:30.000000000 -0500
@@ -95,13 +95,13 @@
/* Take the DUART out of reset */
titan_writel(0x00ff1cff, CPRR);
* Set up serial port #0. Do not use autodetection; the result is
diff -Nurb linux-2.6.22-570/arch/mips/ddb5xxx/ddb5477/Makefile linux-2.6.22-590/arch/mips/ddb5xxx/ddb5477/Makefile
--- linux-2.6.22-570/arch/mips/ddb5xxx/ddb5477/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/ddb5xxx/ddb5477/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/ddb5xxx/ddb5477/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -5,4 +5,3 @@
obj-y += irq.o irq_5477.o setup.o lcd44780.o
-}
diff -Nurb linux-2.6.22-570/arch/mips/gt64120/momenco_ocelot/Makefile linux-2.6.22-590/arch/mips/gt64120/momenco_ocelot/Makefile
--- linux-2.6.22-570/arch/mips/gt64120/momenco_ocelot/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/gt64120/momenco_ocelot/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/gt64120/momenco_ocelot/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -3,5 +3,3 @@
#
-}
diff -Nurb linux-2.6.22-570/arch/mips/jmr3927/rbhma3100/Makefile linux-2.6.22-590/arch/mips/jmr3927/rbhma3100/Makefile
--- linux-2.6.22-570/arch/mips/jmr3927/rbhma3100/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/jmr3927/rbhma3100/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/jmr3927/rbhma3100/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -3,4 +3,3 @@
#
-}
diff -Nurb linux-2.6.22-570/arch/mips/kernel/Makefile linux-2.6.22-590/arch/mips/kernel/Makefile
--- linux-2.6.22-570/arch/mips/kernel/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/kernel/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/kernel/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -57,7 +57,8 @@
obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall64-n32.o signal_n32.o
obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o
obj-$(CONFIG_64BIT) += cpu-bugs64.o
diff -Nurb linux-2.6.22-570/arch/mips/kernel/cpu-probe.c linux-2.6.22-590/arch/mips/kernel/cpu-probe.c
--- linux-2.6.22-570/arch/mips/kernel/cpu-probe.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/kernel/cpu-probe.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/kernel/cpu-probe.c 2008-01-29 22:12:30.000000000 -0500
@@ -177,6 +177,17 @@
cpu_wait = r4k_wait;
-#endif
diff -Nurb linux-2.6.22-570/arch/mips/kernel/irq.c linux-2.6.22-590/arch/mips/kernel/irq.c
--- linux-2.6.22-570/arch/mips/kernel/irq.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/kernel/irq.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/kernel/irq.c 2008-01-29 22:12:30.000000000 -0500
@@ -25,6 +25,10 @@
#include <asm/atomic.h>
#include <asm/system.h>
}
diff -Nurb linux-2.6.22-570/arch/mips/kernel/kgdb-jmp.c linux-2.6.22-590/arch/mips/kernel/kgdb-jmp.c
--- linux-2.6.22-570/arch/mips/kernel/kgdb-jmp.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/mips/kernel/kgdb-jmp.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/kernel/kgdb-jmp.c 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,110 @@
+/*
+ * arch/mips/kernel/kgdb-jmp.c
+#endif
diff -Nurb linux-2.6.22-570/arch/mips/kernel/kgdb-setjmp.S linux-2.6.22-590/arch/mips/kernel/kgdb-setjmp.S
--- linux-2.6.22-570/arch/mips/kernel/kgdb-setjmp.S 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/mips/kernel/kgdb-setjmp.S 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/kernel/kgdb-setjmp.S 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,28 @@
+/*
+ * arch/mips/kernel/kgdb-jmp.c
+ .end kgdb_fault_setjmp
diff -Nurb linux-2.6.22-570/arch/mips/kernel/kgdb.c linux-2.6.22-590/arch/mips/kernel/kgdb.c
--- linux-2.6.22-570/arch/mips/kernel/kgdb.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/mips/kernel/kgdb.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/kernel/kgdb.c 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,299 @@
+/*
+ * arch/mips/kernel/kgdb.c
+}
diff -Nurb linux-2.6.22-570/arch/mips/kernel/kgdb_handler.S linux-2.6.22-590/arch/mips/kernel/kgdb_handler.S
--- linux-2.6.22-570/arch/mips/kernel/kgdb_handler.S 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/mips/kernel/kgdb_handler.S 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/kernel/kgdb_handler.S 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,339 @@
+/*
+ * arch/mips/kernel/kgdb_handler.S
+ jr ra
+ .end kgdbfault
diff -Nurb linux-2.6.22-570/arch/mips/kernel/traps.c linux-2.6.22-590/arch/mips/kernel/traps.c
---- linux-2.6.22-570/arch/mips/kernel/traps.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/kernel/traps.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/mips/kernel/traps.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/mips/kernel/traps.c 2008-01-29 22:12:30.000000000 -0500
@@ -10,6 +10,8 @@
* Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
* Copyright (C) 2000, 01 MIPS Technologies, Inc.
else
diff -Nurb linux-2.6.22-570/arch/mips/mips-boards/atlas/Makefile linux-2.6.22-590/arch/mips/mips-boards/atlas/Makefile
--- linux-2.6.22-570/arch/mips/mips-boards/atlas/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/mips-boards/atlas/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/mips-boards/atlas/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -17,4 +17,3 @@
#
-}
diff -Nurb linux-2.6.22-570/arch/mips/mips-boards/atlas/atlas_setup.c linux-2.6.22-590/arch/mips/mips-boards/atlas/atlas_setup.c
--- linux-2.6.22-570/arch/mips/mips-boards/atlas/atlas_setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/mips-boards/atlas/atlas_setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/mips-boards/atlas/atlas_setup.c 2008-01-29 22:12:30.000000000 -0500
@@ -37,10 +37,6 @@
extern void mips_time_init(void);
extern unsigned long mips_rtc_get_time(void);
-}
diff -Nurb linux-2.6.22-570/arch/mips/mips-boards/generic/init.c linux-2.6.22-590/arch/mips/mips-boards/generic/init.c
--- linux-2.6.22-570/arch/mips/mips-boards/generic/init.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/mips-boards/generic/init.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/mips-boards/generic/init.c 2008-01-29 22:12:30.000000000 -0500
@@ -37,15 +37,6 @@
#include <asm/mips-boards/malta.h>
void *base;
diff -Nurb linux-2.6.22-570/arch/mips/mips-boards/malta/malta_setup.c linux-2.6.22-590/arch/mips/mips-boards/malta/malta_setup.c
--- linux-2.6.22-570/arch/mips/mips-boards/malta/malta_setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/mips-boards/malta/malta_setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/mips-boards/malta/malta_setup.c 2008-01-29 22:12:30.000000000 -0500
@@ -39,10 +39,6 @@
extern void mips_time_init(void);
extern unsigned long mips_rtc_get_time(void);
diff -Nurb linux-2.6.22-570/arch/mips/mm/extable.c linux-2.6.22-590/arch/mips/mm/extable.c
--- linux-2.6.22-570/arch/mips/mm/extable.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/mm/extable.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/mm/extable.c 2008-01-29 22:12:30.000000000 -0500
@@ -3,6 +3,7 @@
*/
#include <linux/module.h>
}
diff -Nurb linux-2.6.22-570/arch/mips/momentum/ocelot_c/Makefile linux-2.6.22-590/arch/mips/momentum/ocelot_c/Makefile
--- linux-2.6.22-570/arch/mips/momentum/ocelot_c/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/momentum/ocelot_c/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/momentum/ocelot_c/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -4,5 +4,3 @@
obj-y += cpci-irq.o irq.o platform.o prom.o reset.o \
-}
diff -Nurb linux-2.6.22-570/arch/mips/pci/fixup-atlas.c linux-2.6.22-590/arch/mips/pci/fixup-atlas.c
--- linux-2.6.22-570/arch/mips/pci/fixup-atlas.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/pci/fixup-atlas.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/pci/fixup-atlas.c 2008-01-29 22:12:30.000000000 -0500
@@ -68,24 +68,3 @@
{
return 0;
-#endif
diff -Nurb linux-2.6.22-570/arch/mips/philips/pnx8550/common/Makefile linux-2.6.22-590/arch/mips/philips/pnx8550/common/Makefile
--- linux-2.6.22-570/arch/mips/philips/pnx8550/common/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/philips/pnx8550/common/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/philips/pnx8550/common/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -24,4 +24,3 @@
obj-y := setup.o prom.o int.o reset.o time.o proc.o platform.o
-}
diff -Nurb linux-2.6.22-570/arch/mips/philips/pnx8550/common/setup.c linux-2.6.22-590/arch/mips/philips/pnx8550/common/setup.c
--- linux-2.6.22-570/arch/mips/philips/pnx8550/common/setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/philips/pnx8550/common/setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/philips/pnx8550/common/setup.c 2008-01-29 22:12:30.000000000 -0500
@@ -145,16 +145,5 @@
ip3106_baud(UART_BASE, pnx8550_console_port) = 5;
}
}
diff -Nurb linux-2.6.22-570/arch/mips/pmc-sierra/yosemite/Makefile linux-2.6.22-590/arch/mips/pmc-sierra/yosemite/Makefile
--- linux-2.6.22-570/arch/mips/pmc-sierra/yosemite/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/pmc-sierra/yosemite/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/pmc-sierra/yosemite/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -4,5 +4,4 @@
obj-y += irq.o i2c-yosemite.o prom.o py-console.o setup.o
-}
diff -Nurb linux-2.6.22-570/arch/mips/pmc-sierra/yosemite/irq.c linux-2.6.22-590/arch/mips/pmc-sierra/yosemite/irq.c
--- linux-2.6.22-570/arch/mips/pmc-sierra/yosemite/irq.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/pmc-sierra/yosemite/irq.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/pmc-sierra/yosemite/irq.c 2008-01-29 22:12:30.000000000 -0500
@@ -137,10 +137,6 @@
}
}
#endif
diff -Nurb linux-2.6.22-570/arch/mips/sgi-ip22/ip22-setup.c linux-2.6.22-590/arch/mips/sgi-ip22/ip22-setup.c
--- linux-2.6.22-570/arch/mips/sgi-ip22/ip22-setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/sgi-ip22/ip22-setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/sgi-ip22/ip22-setup.c 2008-01-29 22:12:30.000000000 -0500
@@ -101,30 +101,6 @@
add_preferred_console("arc", 0, NULL);
}
ULONG *gfxinfo;
diff -Nurb linux-2.6.22-570/arch/mips/sgi-ip27/Makefile linux-2.6.22-590/arch/mips/sgi-ip27/Makefile
--- linux-2.6.22-570/arch/mips/sgi-ip27/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/sgi-ip27/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/sgi-ip27/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -7,5 +7,4 @@
ip27-xtalk.o
-}
diff -Nurb linux-2.6.22-570/arch/mips/sibyte/bcm1480/irq.c linux-2.6.22-590/arch/mips/sibyte/bcm1480/irq.c
--- linux-2.6.22-570/arch/mips/sibyte/bcm1480/irq.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/sibyte/bcm1480/irq.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/sibyte/bcm1480/irq.c 2008-01-29 22:12:30.000000000 -0500
@@ -57,30 +57,6 @@
extern unsigned long ht_eoi_space;
#endif
unsigned long base;
diff -Nurb linux-2.6.22-570/arch/mips/sibyte/cfe/setup.c linux-2.6.22-590/arch/mips/sibyte/cfe/setup.c
--- linux-2.6.22-570/arch/mips/sibyte/cfe/setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/sibyte/cfe/setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/sibyte/cfe/setup.c 2008-01-29 22:12:30.000000000 -0500
@@ -58,10 +58,6 @@
extern unsigned long initrd_start, initrd_end;
#endif
char *ptr;
diff -Nurb linux-2.6.22-570/arch/mips/sibyte/sb1250/Makefile linux-2.6.22-590/arch/mips/sibyte/sb1250/Makefile
--- linux-2.6.22-570/arch/mips/sibyte/sb1250/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/sibyte/sb1250/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/sibyte/sb1250/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -3,3 +3,4 @@
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_SIBYTE_STANDALONE) += prom.o
+obj-$(CONFIG_KGDB_SIBYTE) += kgdb_sibyte.o
diff -Nurb linux-2.6.22-570/arch/mips/sibyte/sb1250/irq.c linux-2.6.22-590/arch/mips/sibyte/sb1250/irq.c
--- linux-2.6.22-570/arch/mips/sibyte/sb1250/irq.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/sibyte/sb1250/irq.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/sibyte/sb1250/irq.c 2008-01-29 22:12:30.000000000 -0500
@@ -29,6 +29,7 @@
#include <asm/signal.h>
#include <asm/system.h>
#endif
diff -Nurb linux-2.6.22-570/arch/mips/sibyte/sb1250/kgdb_sibyte.c linux-2.6.22-590/arch/mips/sibyte/sb1250/kgdb_sibyte.c
--- linux-2.6.22-570/arch/mips/sibyte/sb1250/kgdb_sibyte.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/mips/sibyte/sb1250/kgdb_sibyte.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/sibyte/sb1250/kgdb_sibyte.c 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,144 @@
+/*
+ * arch/mips/sibyte/sb1250/kgdb_sibyte.c
+};
diff -Nurb linux-2.6.22-570/arch/mips/sibyte/swarm/Makefile linux-2.6.22-590/arch/mips/sibyte/swarm/Makefile
--- linux-2.6.22-570/arch/mips/sibyte/swarm/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/sibyte/swarm/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/sibyte/swarm/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -1,3 +1 @@
lib-y = setup.o rtc_xicor1241.o rtc_m41t81.o
-
-
diff -Nurb linux-2.6.22-570/arch/mips/tx4927/common/Makefile linux-2.6.22-590/arch/mips/tx4927/common/Makefile
--- linux-2.6.22-570/arch/mips/tx4927/common/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/tx4927/common/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/tx4927/common/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -9,4 +9,3 @@
obj-y += tx4927_prom.o tx4927_setup.o tx4927_irq.o
-}
diff -Nurb linux-2.6.22-570/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c linux-2.6.22-590/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
--- linux-2.6.22-570/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c 2008-01-29 22:12:30.000000000 -0500
@@ -76,7 +76,7 @@
#include <linux/hdreg.h>
#include <linux/ide.h>
argptr = prom_getcmdline();
diff -Nurb linux-2.6.22-570/arch/mips/tx4938/common/Makefile linux-2.6.22-590/arch/mips/tx4938/common/Makefile
--- linux-2.6.22-570/arch/mips/tx4938/common/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/tx4938/common/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/tx4938/common/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -7,5 +7,4 @@
#
-
diff -Nurb linux-2.6.22-570/arch/mips/tx4938/toshiba_rbtx4938/setup.c linux-2.6.22-590/arch/mips/tx4938/toshiba_rbtx4938/setup.c
--- linux-2.6.22-570/arch/mips/tx4938/toshiba_rbtx4938/setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/mips/tx4938/toshiba_rbtx4938/setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/mips/tx4938/toshiba_rbtx4938/setup.c 2008-01-29 22:12:30.000000000 -0500
@@ -30,7 +30,7 @@
#include <asm/io.h>
#include <asm/bootinfo.h>
}
#ifdef CONFIG_SERIAL_TXX9_CONSOLE
diff -Nurb linux-2.6.22-570/arch/powerpc/Kconfig linux-2.6.22-590/arch/powerpc/Kconfig
---- linux-2.6.22-570/arch/powerpc/Kconfig 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/Kconfig 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/powerpc/Kconfig 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/powerpc/Kconfig 2008-01-29 22:12:30.000000000 -0500
@@ -4,12 +4,7 @@
mainmenu "Linux/PowerPC Kernel Configuration"
help
diff -Nurb linux-2.6.22-570/arch/powerpc/Kconfig.debug linux-2.6.22-590/arch/powerpc/Kconfig.debug
--- linux-2.6.22-570/arch/powerpc/Kconfig.debug 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/Kconfig.debug 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/Kconfig.debug 2008-01-29 22:12:30.000000000 -0500
@@ -41,52 +41,9 @@
This option will add a small amount of overhead to all hypervisor
calls.
depends on PPC64
diff -Nurb linux-2.6.22-570/arch/powerpc/boot/44x.c linux-2.6.22-590/arch/powerpc/boot/44x.c
--- linux-2.6.22-570/arch/powerpc/boot/44x.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/boot/44x.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/boot/44x.c 2008-01-29 22:12:30.000000000 -0500
@@ -38,3 +38,48 @@
dt_fixup_memory(0, memsize);
+}
diff -Nurb linux-2.6.22-570/arch/powerpc/boot/44x.h linux-2.6.22-590/arch/powerpc/boot/44x.h
--- linux-2.6.22-570/arch/powerpc/boot/44x.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/boot/44x.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/boot/44x.h 2008-01-29 22:12:30.000000000 -0500
@@ -11,6 +11,9 @@
#define _PPC_BOOT_44X_H_
#endif /* _PPC_BOOT_44X_H_ */
diff -Nurb linux-2.6.22-570/arch/powerpc/boot/Makefile linux-2.6.22-590/arch/powerpc/boot/Makefile
--- linux-2.6.22-570/arch/powerpc/boot/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/boot/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/boot/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -43,8 +43,8 @@
src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
src-boot := $(src-wlib) $(src-plat) empty.c
diff -Nurb linux-2.6.22-570/arch/powerpc/boot/cuboot-83xx.c linux-2.6.22-590/arch/powerpc/boot/cuboot-83xx.c
--- linux-2.6.22-570/arch/powerpc/boot/cuboot-83xx.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/boot/cuboot-83xx.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/boot/cuboot-83xx.c 2008-01-29 22:12:30.000000000 -0500
@@ -12,12 +12,12 @@
#include "ops.h"
platform_ops.fixups = platform_fixups;
diff -Nurb linux-2.6.22-570/arch/powerpc/boot/cuboot-85xx.c linux-2.6.22-590/arch/powerpc/boot/cuboot-85xx.c
--- linux-2.6.22-570/arch/powerpc/boot/cuboot-85xx.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/boot/cuboot-85xx.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/boot/cuboot-85xx.c 2008-01-29 22:12:30.000000000 -0500
@@ -12,12 +12,12 @@
#include "ops.h"
platform_ops.fixups = platform_fixups;
diff -Nurb linux-2.6.22-570/arch/powerpc/boot/cuboot-ebony.c linux-2.6.22-590/arch/powerpc/boot/cuboot-ebony.c
--- linux-2.6.22-570/arch/powerpc/boot/cuboot-ebony.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/boot/cuboot-ebony.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/boot/cuboot-ebony.c 2008-01-29 22:12:30.000000000 -0500
@@ -15,28 +15,16 @@
#include "ops.h"
#include "stdio.h"
}
diff -Nurb linux-2.6.22-570/arch/powerpc/boot/cuboot.c linux-2.6.22-590/arch/powerpc/boot/cuboot.c
--- linux-2.6.22-570/arch/powerpc/boot/cuboot.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/powerpc/boot/cuboot.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/boot/cuboot.c 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,35 @@
+/*
+ * Compatibility for old (not device tree aware) U-Boot versions
+}
diff -Nurb linux-2.6.22-570/arch/powerpc/boot/cuboot.h linux-2.6.22-590/arch/powerpc/boot/cuboot.h
--- linux-2.6.22-570/arch/powerpc/boot/cuboot.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/powerpc/boot/cuboot.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/boot/cuboot.h 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,14 @@
+#ifndef _PPC_BOOT_CUBOOT_H_
+#define _PPC_BOOT_CUBOOT_H_
+#endif /* _PPC_BOOT_CUBOOT_H_ */
diff -Nurb linux-2.6.22-570/arch/powerpc/boot/dcr.h linux-2.6.22-590/arch/powerpc/boot/dcr.h
--- linux-2.6.22-570/arch/powerpc/boot/dcr.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/boot/dcr.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/boot/dcr.h 2008-01-29 22:12:30.000000000 -0500
@@ -26,6 +26,43 @@
#define SDRAM_CONFIG_BANK_SIZE(reg) \
(0x00400000 << ((reg & SDRAM_CONFIG_SIZE_MASK) >> 17))
#define DCRN_CPC0_ER 0x0b1
diff -Nurb linux-2.6.22-570/arch/powerpc/boot/dts/ebony.dts linux-2.6.22-590/arch/powerpc/boot/dts/ebony.dts
--- linux-2.6.22-570/arch/powerpc/boot/dts/ebony.dts 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/boot/dts/ebony.dts 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/boot/dts/ebony.dts 2008-01-29 22:12:30.000000000 -0500
@@ -135,11 +135,9 @@
#address-cells = <2>;
#size-cells = <1>;
diff -Nurb linux-2.6.22-570/arch/powerpc/boot/dts/holly.dts linux-2.6.22-590/arch/powerpc/boot/dts/holly.dts
--- linux-2.6.22-570/arch/powerpc/boot/dts/holly.dts 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/boot/dts/holly.dts 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/boot/dts/holly.dts 2008-01-29 22:12:30.000000000 -0500
@@ -46,7 +46,7 @@
tsi109@c0000000 {
};
diff -Nurb linux-2.6.22-570/arch/powerpc/boot/dts/mpc7448hpc2.dts linux-2.6.22-590/arch/powerpc/boot/dts/mpc7448hpc2.dts
--- linux-2.6.22-570/arch/powerpc/boot/dts/mpc7448hpc2.dts 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/boot/dts/mpc7448hpc2.dts 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/boot/dts/mpc7448hpc2.dts 2008-01-29 22:12:30.000000000 -0500
@@ -45,7 +45,7 @@
#address-cells = <1>;
#size-cells = <1>;
#size-cells = <2>;
diff -Nurb linux-2.6.22-570/arch/powerpc/boot/ebony.c linux-2.6.22-590/arch/powerpc/boot/ebony.c
--- linux-2.6.22-570/arch/powerpc/boot/ebony.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/boot/ebony.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/boot/ebony.c 2008-01-29 22:12:30.000000000 -0500
@@ -100,28 +100,13 @@
ibm440gp_fixup_clocks(sysclk, 6 * 1843200);
ibm44x_fixup_memsize();
ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
diff -Nurb linux-2.6.22-570/arch/powerpc/boot/of.c linux-2.6.22-590/arch/powerpc/boot/of.c
--- linux-2.6.22-570/arch/powerpc/boot/of.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/boot/of.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/boot/of.c 2008-01-29 22:12:30.000000000 -0500
@@ -15,8 +15,7 @@
#include "page.h"
#include "ops.h"
loader_info.initrd_addr = a1;
diff -Nurb linux-2.6.22-570/arch/powerpc/boot/of.h linux-2.6.22-590/arch/powerpc/boot/of.h
--- linux-2.6.22-570/arch/powerpc/boot/of.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/powerpc/boot/of.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/boot/of.h 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,15 @@
+#ifndef _PPC_BOOT_OF_H_
+#define _PPC_BOOT_OF_H_
+#endif /* _PPC_BOOT_OF_H_ */
diff -Nurb linux-2.6.22-570/arch/powerpc/boot/ofconsole.c linux-2.6.22-590/arch/powerpc/boot/ofconsole.c
--- linux-2.6.22-570/arch/powerpc/boot/ofconsole.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/powerpc/boot/ofconsole.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/boot/ofconsole.c 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,45 @@
+/*
+ * OF console routines
+}
diff -Nurb linux-2.6.22-570/arch/powerpc/boot/oflib.c linux-2.6.22-590/arch/powerpc/boot/oflib.c
--- linux-2.6.22-570/arch/powerpc/boot/oflib.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/powerpc/boot/oflib.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/boot/oflib.c 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+}
diff -Nurb linux-2.6.22-570/arch/powerpc/configs/holly_defconfig linux-2.6.22-590/arch/powerpc/configs/holly_defconfig
--- linux-2.6.22-570/arch/powerpc/configs/holly_defconfig 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/configs/holly_defconfig 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/configs/holly_defconfig 2008-01-29 22:12:30.000000000 -0500
@@ -190,7 +190,8 @@
# CONFIG_RESOURCES_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
# CONFIG_WANT_DEVICE_TREE is not set
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/Makefile linux-2.6.22-590/arch/powerpc/kernel/Makefile
--- linux-2.6.22-570/arch/powerpc/kernel/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/kernel/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/kernel/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -12,7 +12,8 @@
obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
obj-$(CONFIG_PCI_MSI) += msi.o
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/head_32.S linux-2.6.22-590/arch/powerpc/kernel/head_32.S
--- linux-2.6.22-570/arch/powerpc/kernel/head_32.S 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/kernel/head_32.S 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/kernel/head_32.S 2008-01-29 22:12:30.000000000 -0500
@@ -9,7 +9,6 @@
* rewritten by Paul Mackerras.
* Copyright (C) 1996 Paul Mackerras.
#ifdef CONFIG_8260
/* Jump into the system reset for the rom.
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/irq.c linux-2.6.22-590/arch/powerpc/kernel/irq.c
---- linux-2.6.22-570/arch/powerpc/kernel/irq.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/kernel/irq.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/powerpc/kernel/irq.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/powerpc/kernel/irq.c 2008-01-29 22:12:30.000000000 -0500
@@ -7,7 +7,6 @@
* Copyright (C) 1996-2001 Cort Dougan
* Adapted for Power Macintosh by Paul Mackerras
* modify it under the terms of the GNU General Public License
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/isa-bridge.c linux-2.6.22-590/arch/powerpc/kernel/isa-bridge.c
--- linux-2.6.22-570/arch/powerpc/kernel/isa-bridge.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/powerpc/kernel/isa-bridge.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/kernel/isa-bridge.c 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,271 @@
+/*
+ * Routines for tracking a legacy ISA bridge
+arch_initcall(isa_bridge_init);
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/kgdb.c linux-2.6.22-590/arch/powerpc/kernel/kgdb.c
--- linux-2.6.22-570/arch/powerpc/kernel/kgdb.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/powerpc/kernel/kgdb.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/kernel/kgdb.c 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,499 @@
+/*
+ * arch/powerpc/kernel/kgdb.c
+arch_initcall(kgdb_arch_init);
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/kgdb_setjmp32.S linux-2.6.22-590/arch/powerpc/kernel/kgdb_setjmp32.S
--- linux-2.6.22-570/arch/powerpc/kernel/kgdb_setjmp32.S 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/powerpc/kernel/kgdb_setjmp32.S 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/kernel/kgdb_setjmp32.S 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras
+ blr
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/kgdb_setjmp64.S linux-2.6.22-590/arch/powerpc/kernel/kgdb_setjmp64.S
--- linux-2.6.22-570/arch/powerpc/kernel/kgdb_setjmp64.S 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/powerpc/kernel/kgdb_setjmp64.S 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/kernel/kgdb_setjmp64.S 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras
+ blr
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/legacy_serial.c linux-2.6.22-590/arch/powerpc/kernel/legacy_serial.c
--- linux-2.6.22-570/arch/powerpc/kernel/legacy_serial.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/kernel/legacy_serial.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/kernel/legacy_serial.c 2008-01-29 22:12:30.000000000 -0500
@@ -11,6 +11,9 @@
#include <asm/udbg.h>
#include <asm/pci-bridge.h>
DBG("Registering platform serial ports\n");
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/misc_32.S linux-2.6.22-590/arch/powerpc/kernel/misc_32.S
---- linux-2.6.22-570/arch/powerpc/kernel/misc_32.S 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/kernel/misc_32.S 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/powerpc/kernel/misc_32.S 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/powerpc/kernel/misc_32.S 2008-01-29 22:12:30.000000000 -0500
@@ -392,7 +392,7 @@
mtspr SPRN_L1CSR0,r3
isync
mtmsr r0
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/of_platform.c linux-2.6.22-590/arch/powerpc/kernel/of_platform.c
--- linux-2.6.22-570/arch/powerpc/kernel/of_platform.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/kernel/of_platform.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/kernel/of_platform.c 2008-01-29 22:12:30.000000000 -0500
@@ -427,14 +427,6 @@
/* Process "ranges" property */
pci_process_bridge_OF_ranges(phb, dev->node, 0);
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/pci_64.c linux-2.6.22-590/arch/powerpc/kernel/pci_64.c
--- linux-2.6.22-570/arch/powerpc/kernel/pci_64.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/kernel/pci_64.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/kernel/pci_64.c 2008-01-29 22:12:30.000000000 -0500
@@ -11,7 +11,7 @@
* 2 of the License, or (at your option) any later version.
*/
}
}
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/process.c linux-2.6.22-590/arch/powerpc/kernel/process.c
---- linux-2.6.22-570/arch/powerpc/kernel/process.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/kernel/process.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/powerpc/kernel/process.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/powerpc/kernel/process.c 2008-01-29 22:12:30.000000000 -0500
@@ -219,22 +219,26 @@
}
#endif /* CONFIG_SMP */
void
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/prom_init.c linux-2.6.22-590/arch/powerpc/kernel/prom_init.c
--- linux-2.6.22-570/arch/powerpc/kernel/prom_init.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/kernel/prom_init.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/kernel/prom_init.c 2008-01-29 22:12:30.000000000 -0500
@@ -635,6 +635,7 @@
/* ibm,dynamic-reconfiguration-memory property supported */
#define OV5_DRCONF_MEMORY 0x20
-#endif /* _PPC64_PTRACE_COMMON_H */
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/ptrace.c linux-2.6.22-590/arch/powerpc/kernel/ptrace.c
--- linux-2.6.22-570/arch/powerpc/kernel/ptrace.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/kernel/ptrace.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/kernel/ptrace.c 2008-01-29 22:12:30.000000000 -0500
@@ -35,11 +35,11 @@
#include <asm/pgtable.h>
#include <asm/system.h>
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/ptrace32.c linux-2.6.22-590/arch/powerpc/kernel/ptrace32.c
--- linux-2.6.22-570/arch/powerpc/kernel/ptrace32.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/kernel/ptrace32.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/kernel/ptrace32.c 2008-01-29 22:12:30.000000000 -0500
@@ -33,13 +33,55 @@
#include <asm/pgtable.h>
#include <asm/system.h>
ret = ptrace_request(child, request, addr, data);
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/rtas_pci.c linux-2.6.22-590/arch/powerpc/kernel/rtas_pci.c
--- linux-2.6.22-570/arch/powerpc/kernel/rtas_pci.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/kernel/rtas_pci.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/kernel/rtas_pci.c 2008-01-29 22:12:30.000000000 -0500
@@ -278,10 +278,8 @@
{
struct device_node *node;
__FUNCTION__, b->name);
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/setup_32.c linux-2.6.22-590/arch/powerpc/kernel/setup_32.c
--- linux-2.6.22-570/arch/powerpc/kernel/setup_32.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/kernel/setup_32.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/kernel/setup_32.c 2008-01-29 22:12:30.000000000 -0500
@@ -45,10 +45,6 @@
#define DBG(fmt...)
panic_timeout = 180;
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/signal.c linux-2.6.22-590/arch/powerpc/kernel/signal.c
--- linux-2.6.22-570/arch/powerpc/kernel/signal.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/powerpc/kernel/signal.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/kernel/signal.c 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,180 @@
+/*
+ * Common signal handling code for both 32 and 64 bits
+}
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/signal.h linux-2.6.22-590/arch/powerpc/kernel/signal.h
--- linux-2.6.22-570/arch/powerpc/kernel/signal.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/powerpc/kernel/signal.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/kernel/signal.h 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Coproration
+#endif /* _POWERPC_ARCH_SIGNAL_H */
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/signal_32.c linux-2.6.22-590/arch/powerpc/kernel/signal_32.c
--- linux-2.6.22-570/arch/powerpc/kernel/signal_32.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/kernel/signal_32.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/kernel/signal_32.c 2008-01-29 22:12:30.000000000 -0500
@@ -51,12 +51,11 @@
#include <asm/pgtable.h>
#endif
-}
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/signal_64.c linux-2.6.22-590/arch/powerpc/kernel/signal_64.c
--- linux-2.6.22-570/arch/powerpc/kernel/signal_64.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/kernel/signal_64.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/kernel/signal_64.c 2008-01-29 22:12:30.000000000 -0500
@@ -34,9 +34,9 @@
#include <asm/syscalls.h>
#include <asm/vdso.h>
-}
-EXPORT_SYMBOL(do_signal);
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/sys_ppc32.c linux-2.6.22-590/arch/powerpc/kernel/sys_ppc32.c
---- linux-2.6.22-570/arch/powerpc/kernel/sys_ppc32.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/kernel/sys_ppc32.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/powerpc/kernel/sys_ppc32.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/powerpc/kernel/sys_ppc32.c 2008-01-29 22:12:30.000000000 -0500
@@ -773,6 +773,13 @@
return sys_truncate(path, (high << 32) | low);
}
unsigned long low)
{
diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/vdso.c linux-2.6.22-590/arch/powerpc/kernel/vdso.c
---- linux-2.6.22-570/arch/powerpc/kernel/vdso.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/kernel/vdso.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/powerpc/kernel/vdso.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/powerpc/kernel/vdso.c 2008-01-29 22:12:30.000000000 -0500
@@ -671,7 +671,7 @@
/*
* Fill up the "systemcfg" stuff for backward compatiblity
vdso_data->processor = mfspr(SPRN_PVR);
diff -Nurb linux-2.6.22-570/arch/powerpc/mm/44x_mmu.c linux-2.6.22-590/arch/powerpc/mm/44x_mmu.c
--- linux-2.6.22-570/arch/powerpc/mm/44x_mmu.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/mm/44x_mmu.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/mm/44x_mmu.c 2008-01-29 22:12:30.000000000 -0500
@@ -12,7 +12,6 @@
* Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
* and Cort Dougan (PReP) (cort@cs.nmt.edu)
* Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
diff -Nurb linux-2.6.22-570/arch/powerpc/mm/4xx_mmu.c linux-2.6.22-590/arch/powerpc/mm/4xx_mmu.c
--- linux-2.6.22-570/arch/powerpc/mm/4xx_mmu.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/mm/4xx_mmu.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/mm/4xx_mmu.c 2008-01-29 22:12:30.000000000 -0500
@@ -9,7 +9,6 @@
* Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
* and Cort Dougan (PReP) (cort@cs.nmt.edu)
* Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
diff -Nurb linux-2.6.22-570/arch/powerpc/mm/Makefile linux-2.6.22-590/arch/powerpc/mm/Makefile
--- linux-2.6.22-570/arch/powerpc/mm/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/mm/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/mm/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -11,8 +11,7 @@
hash-$(CONFIG_PPC_NATIVE) := hash_native_64.o
obj-$(CONFIG_PPC64) += init_64.o pgtable_64.o mmu_context_64.o \
obj-$(CONFIG_40x) += 4xx_mmu.o
obj-$(CONFIG_44x) += 44x_mmu.o
diff -Nurb linux-2.6.22-570/arch/powerpc/mm/fault.c linux-2.6.22-590/arch/powerpc/mm/fault.c
---- linux-2.6.22-570/arch/powerpc/mm/fault.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/mm/fault.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/powerpc/mm/fault.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/powerpc/mm/fault.c 2008-01-29 22:12:30.000000000 -0500
@@ -29,6 +29,7 @@
#include <linux/module.h>
#include <linux/kprobes.h>
switch (regs->trap) {
diff -Nurb linux-2.6.22-570/arch/powerpc/mm/fsl_booke_mmu.c linux-2.6.22-590/arch/powerpc/mm/fsl_booke_mmu.c
--- linux-2.6.22-570/arch/powerpc/mm/fsl_booke_mmu.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/mm/fsl_booke_mmu.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/mm/fsl_booke_mmu.c 2008-01-29 22:12:30.000000000 -0500
@@ -14,7 +14,6 @@
* Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
* and Cort Dougan (PReP) (cort@cs.nmt.edu)
* Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
diff -Nurb linux-2.6.22-570/arch/powerpc/mm/hash_native_64.c linux-2.6.22-590/arch/powerpc/mm/hash_native_64.c
--- linux-2.6.22-570/arch/powerpc/mm/hash_native_64.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/mm/hash_native_64.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/mm/hash_native_64.c 2008-01-29 22:12:30.000000000 -0500
@@ -104,7 +104,7 @@
spin_unlock(&native_tlbie_lock);
}
unsigned long flags;
diff -Nurb linux-2.6.22-570/arch/powerpc/mm/hash_utils_64.c linux-2.6.22-590/arch/powerpc/mm/hash_utils_64.c
--- linux-2.6.22-570/arch/powerpc/mm/hash_utils_64.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/mm/hash_utils_64.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/mm/hash_utils_64.c 2008-01-29 22:12:30.000000000 -0500
@@ -87,7 +87,7 @@
static unsigned long _SDR1;
struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
-}
diff -Nurb linux-2.6.22-570/arch/powerpc/mm/init_32.c linux-2.6.22-590/arch/powerpc/mm/init_32.c
--- linux-2.6.22-570/arch/powerpc/mm/init_32.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/mm/init_32.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/mm/init_32.c 2008-01-29 22:12:30.000000000 -0500
@@ -5,7 +5,6 @@
* Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
* and Cort Dougan (PReP) (cort@cs.nmt.edu)
* Derived from "arch/i386/mm/init.c"
diff -Nurb linux-2.6.22-570/arch/powerpc/mm/init_64.c linux-2.6.22-590/arch/powerpc/mm/init_64.c
--- linux-2.6.22-570/arch/powerpc/mm/init_64.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/mm/init_64.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/mm/init_64.c 2008-01-29 22:12:30.000000000 -0500
@@ -5,7 +5,6 @@
* Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
* and Cort Dougan (PReP) (cort@cs.nmt.edu)
* Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
diff -Nurb linux-2.6.22-570/arch/powerpc/mm/mem.c linux-2.6.22-590/arch/powerpc/mm/mem.c
--- linux-2.6.22-570/arch/powerpc/mm/mem.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/mm/mem.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/mm/mem.c 2008-01-29 22:12:30.000000000 -0500
@@ -5,7 +5,6 @@
* Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
* and Cort Dougan (PReP) (cort@cs.nmt.edu)
* Derived from "arch/i386/mm/init.c"
diff -Nurb linux-2.6.22-570/arch/powerpc/mm/mmu_context_32.c linux-2.6.22-590/arch/powerpc/mm/mmu_context_32.c
--- linux-2.6.22-570/arch/powerpc/mm/mmu_context_32.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/mm/mmu_context_32.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/mm/mmu_context_32.c 2008-01-29 22:12:30.000000000 -0500
@@ -11,7 +11,6 @@
* Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
* and Cort Dougan (PReP) (cort@cs.nmt.edu)
* Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
diff -Nurb linux-2.6.22-570/arch/powerpc/mm/mmu_decl.h linux-2.6.22-590/arch/powerpc/mm/mmu_decl.h
--- linux-2.6.22-570/arch/powerpc/mm/mmu_decl.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/mm/mmu_decl.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/mm/mmu_decl.h 2008-01-29 22:12:30.000000000 -0500
@@ -8,7 +8,6 @@
* Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
* and Cort Dougan (PReP) (cort@cs.nmt.edu)
#endif
diff -Nurb linux-2.6.22-570/arch/powerpc/mm/pgtable_32.c linux-2.6.22-590/arch/powerpc/mm/pgtable_32.c
--- linux-2.6.22-570/arch/powerpc/mm/pgtable_32.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/mm/pgtable_32.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/mm/pgtable_32.c 2008-01-29 22:12:30.000000000 -0500
@@ -8,7 +8,6 @@
* Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
* and Cort Dougan (PReP) (cort@cs.nmt.edu)
static int __change_page_attr(struct page *page, pgprot_t prot)
diff -Nurb linux-2.6.22-570/arch/powerpc/mm/pgtable_64.c linux-2.6.22-590/arch/powerpc/mm/pgtable_64.c
--- linux-2.6.22-570/arch/powerpc/mm/pgtable_64.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/mm/pgtable_64.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/mm/pgtable_64.c 2008-01-29 22:12:30.000000000 -0500
@@ -7,7 +7,6 @@
* Modifications by Paul Mackerras (PowerMac) (paulus@samba.org)
* and Cort Dougan (PReP) (cort@cs.nmt.edu)
-}
diff -Nurb linux-2.6.22-570/arch/powerpc/mm/ppc_mmu_32.c linux-2.6.22-590/arch/powerpc/mm/ppc_mmu_32.c
--- linux-2.6.22-570/arch/powerpc/mm/ppc_mmu_32.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/mm/ppc_mmu_32.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/mm/ppc_mmu_32.c 2008-01-29 22:12:30.000000000 -0500
@@ -11,7 +11,6 @@
* Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
* and Cort Dougan (PReP) (cort@cs.nmt.edu)
total_memory >> 20, Hash_size >> 10, Hash);
diff -Nurb linux-2.6.22-570/arch/powerpc/mm/tlb_32.c linux-2.6.22-590/arch/powerpc/mm/tlb_32.c
--- linux-2.6.22-570/arch/powerpc/mm/tlb_32.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/mm/tlb_32.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/mm/tlb_32.c 2008-01-29 22:12:30.000000000 -0500
@@ -11,7 +11,6 @@
* Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
* and Cort Dougan (PReP) (cort@cs.nmt.edu)
* Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
diff -Nurb linux-2.6.22-570/arch/powerpc/mm/tlb_64.c linux-2.6.22-590/arch/powerpc/mm/tlb_64.c
--- linux-2.6.22-570/arch/powerpc/mm/tlb_64.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/mm/tlb_64.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/mm/tlb_64.c 2008-01-29 22:12:30.000000000 -0500
@@ -8,7 +8,6 @@
* Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
* and Cort Dougan (PReP) (cort@cs.nmt.edu)
+#endif /* CONFIG_HOTPLUG */
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/Kconfig linux-2.6.22-590/arch/powerpc/platforms/Kconfig
--- linux-2.6.22-570/arch/powerpc/platforms/Kconfig 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/platforms/Kconfig 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/Kconfig 2008-01-29 22:12:30.000000000 -0500
@@ -16,13 +16,6 @@
bool "Embedded 6xx/7xx/7xxx-based board"
depends on PPC32 && (BROKEN||BROKEN_ON_SMP)
source "arch/powerpc/platforms/pseries/Kconfig"
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/Kconfig.cputype linux-2.6.22-590/arch/powerpc/platforms/Kconfig.cputype
--- linux-2.6.22-570/arch/powerpc/platforms/Kconfig.cputype 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/powerpc/platforms/Kconfig.cputype 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/Kconfig.cputype 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,252 @@
+config PPC64
+ bool "64-bit kernel"
- depends on !4xx && !8xx && APUS
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/cell/io-workarounds.c linux-2.6.22-590/arch/powerpc/platforms/cell/io-workarounds.c
--- linux-2.6.22-570/arch/powerpc/platforms/cell/io-workarounds.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/platforms/cell/io-workarounds.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/cell/io-workarounds.c 2008-01-29 22:12:30.000000000 -0500
@@ -102,7 +102,7 @@
vaddr = (unsigned long)PCI_FIX_ADDR(addr);
/* Try to find a PTE. If not, clear the paddr, we'll do
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/cell/spufs/file.c linux-2.6.22-590/arch/powerpc/platforms/cell/spufs/file.c
--- linux-2.6.22-570/arch/powerpc/platforms/cell/spufs/file.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/platforms/cell/spufs/file.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/cell/spufs/file.c 2008-01-29 22:12:30.000000000 -0500
@@ -28,6 +28,7 @@
#include <linux/pagemap.h>
#include <linux/poll.h>
{ "ibox", &spufs_ibox_fops, 0444, },
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/cell/spufs/run.c linux-2.6.22-590/arch/powerpc/platforms/cell/spufs/run.c
--- linux-2.6.22-570/arch/powerpc/platforms/cell/spufs/run.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/platforms/cell/spufs/run.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/cell/spufs/run.c 2008-01-29 22:12:30.000000000 -0500
@@ -142,8 +142,12 @@
runcntl = SPU_RUNCNTL_RUNNABLE;
ctx->ops->runcntl_write(ctx, runcntl);
force_sig(SIGTRAP, current);
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/iseries/call_hpt.h linux-2.6.22-590/arch/powerpc/platforms/iseries/call_hpt.h
--- linux-2.6.22-570/arch/powerpc/platforms/iseries/call_hpt.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/platforms/iseries/call_hpt.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/iseries/call_hpt.h 2008-01-29 22:12:30.000000000 -0500
@@ -76,24 +76,25 @@
return compressedStatus;
}
}
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/iseries/htab.c linux-2.6.22-590/arch/powerpc/platforms/iseries/htab.c
--- linux-2.6.22-570/arch/powerpc/platforms/iseries/htab.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/platforms/iseries/htab.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/iseries/htab.c 2008-01-29 22:12:30.000000000 -0500
@@ -44,7 +44,7 @@
unsigned long vflags, int psize)
{
/*
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/iseries/pci.c linux-2.6.22-590/arch/powerpc/platforms/iseries/pci.c
--- linux-2.6.22-570/arch/powerpc/platforms/iseries/pci.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/platforms/iseries/pci.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/iseries/pci.c 2008-01-29 22:12:30.000000000 -0500
@@ -742,6 +742,11 @@
/* Install IO hooks */
ppc_pci_io = iseries_pci_io;
"of device tree\n");
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/maple/pci.c linux-2.6.22-590/arch/powerpc/platforms/maple/pci.c
--- linux-2.6.22-570/arch/powerpc/platforms/maple/pci.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/platforms/maple/pci.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/maple/pci.c 2008-01-29 22:12:30.000000000 -0500
@@ -519,23 +519,6 @@
DBG(" <- maple_pci_irq_fixup\n");
}
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/pasemi/pci.c linux-2.6.22-590/arch/powerpc/platforms/pasemi/pci.c
--- linux-2.6.22-570/arch/powerpc/platforms/pasemi/pci.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/platforms/pasemi/pci.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/pasemi/pci.c 2008-01-29 22:12:30.000000000 -0500
@@ -150,29 +150,11 @@
printk(KERN_INFO "Found PA-PXP PCI host bridge.\n");
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/powermac/pci.c linux-2.6.22-590/arch/powerpc/platforms/powermac/pci.c
--- linux-2.6.22-570/arch/powerpc/platforms/powermac/pci.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/platforms/powermac/pci.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/powermac/pci.c 2008-01-29 22:12:30.000000000 -0500
@@ -1006,19 +1006,6 @@
#endif /* CONFIG_PPC32 */
}
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/powermac/setup.c linux-2.6.22-590/arch/powerpc/platforms/powermac/setup.c
--- linux-2.6.22-570/arch/powerpc/platforms/powermac/setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/platforms/powermac/setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/powermac/setup.c 2008-01-29 22:12:30.000000000 -0500
@@ -98,8 +98,6 @@
int sccdbg;
#endif
smu_init();
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/ps3/htab.c linux-2.6.22-590/arch/powerpc/platforms/ps3/htab.c
--- linux-2.6.22-570/arch/powerpc/platforms/ps3/htab.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/platforms/ps3/htab.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/ps3/htab.c 2008-01-29 22:12:30.000000000 -0500
@@ -34,7 +34,7 @@
#define DBG(fmt...) do{if(0)printk(fmt);}while(0)
#endif
DBG("%s:%d: lpar %016lxh, virt %016lxh\n", __func__, __LINE__,
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/pseries/Makefile linux-2.6.22-590/arch/powerpc/platforms/pseries/Makefile
--- linux-2.6.22-570/arch/powerpc/platforms/pseries/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/platforms/pseries/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/pseries/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -8,7 +8,7 @@
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_XICS) += xics.o
obj-$(CONFIG_PCI_MSI) += msi.o
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/pseries/eeh.c linux-2.6.22-590/arch/powerpc/platforms/pseries/eeh.c
--- linux-2.6.22-570/arch/powerpc/platforms/pseries/eeh.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/platforms/pseries/eeh.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/pseries/eeh.c 2008-01-29 22:12:30.000000000 -0500
@@ -1,6 +1,8 @@
/*
* eeh.c
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/pseries/eeh_cache.c linux-2.6.22-590/arch/powerpc/platforms/pseries/eeh_cache.c
--- linux-2.6.22-570/arch/powerpc/platforms/pseries/eeh_cache.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/platforms/pseries/eeh_cache.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/pseries/eeh_cache.c 2008-01-29 22:12:30.000000000 -0500
@@ -2,7 +2,8 @@
* eeh_cache.c
* PCI address cache; allows the lookup of PCI devices based on I/O address
#ifdef DEBUG
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/pseries/eeh_driver.c linux-2.6.22-590/arch/powerpc/platforms/pseries/eeh_driver.c
--- linux-2.6.22-570/arch/powerpc/platforms/pseries/eeh_driver.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/platforms/pseries/eeh_driver.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/pseries/eeh_driver.c 2008-01-29 22:12:30.000000000 -0500
@@ -1,6 +1,7 @@
/*
* PCI Error Recovery Driver for RPA-compliant PPC64 platform.
#include <linux/interrupt.h>
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/pseries/eeh_sysfs.c linux-2.6.22-590/arch/powerpc/platforms/pseries/eeh_sysfs.c
--- linux-2.6.22-570/arch/powerpc/platforms/pseries/eeh_sysfs.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/powerpc/platforms/pseries/eeh_sysfs.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/pseries/eeh_sysfs.c 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,87 @@
+/*
+ * Sysfs entries for PCI Error Recovery for PAPR-compliant platform.
+
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/pseries/pci_dlpar.c linux-2.6.22-590/arch/powerpc/platforms/pseries/pci_dlpar.c
--- linux-2.6.22-570/arch/powerpc/platforms/pseries/pci_dlpar.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/platforms/pseries/pci_dlpar.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/pseries/pci_dlpar.c 2008-01-29 22:12:30.000000000 -0500
@@ -110,8 +110,6 @@
}
}
}
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/pseries/pseries.h linux-2.6.22-590/arch/powerpc/platforms/pseries/pseries.h
--- linux-2.6.22-570/arch/powerpc/platforms/pseries/pseries.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/platforms/pseries/pseries.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/pseries/pseries.h 2008-01-29 22:12:30.000000000 -0500
@@ -33,6 +33,8 @@
static inline void setup_kexec_cpu_down_mpic(void) { }
#endif
diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/pseries/setup.c linux-2.6.22-590/arch/powerpc/platforms/pseries/setup.c
--- linux-2.6.22-570/arch/powerpc/platforms/pseries/setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/platforms/pseries/setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/platforms/pseries/setup.c 2008-01-29 22:12:30.000000000 -0500
@@ -399,6 +399,7 @@
* a good time to find other work to dispatch.
*/
diff -Nurb linux-2.6.22-570/arch/powerpc/sysdev/tsi108_dev.c linux-2.6.22-590/arch/powerpc/sysdev/tsi108_dev.c
--- linux-2.6.22-570/arch/powerpc/sysdev/tsi108_dev.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/powerpc/sysdev/tsi108_dev.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/powerpc/sysdev/tsi108_dev.c 2008-01-29 22:12:30.000000000 -0500
@@ -72,12 +72,11 @@
int ret;
sizeof(hw_info));
diff -Nurb linux-2.6.22-570/arch/ppc/8260_io/enet.c linux-2.6.22-590/arch/ppc/8260_io/enet.c
--- linux-2.6.22-570/arch/ppc/8260_io/enet.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/8260_io/enet.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/8260_io/enet.c 2008-01-29 22:12:30.000000000 -0500
@@ -477,9 +477,9 @@
}
else {
}
diff -Nurb linux-2.6.22-570/arch/ppc/8260_io/fcc_enet.c linux-2.6.22-590/arch/ppc/8260_io/fcc_enet.c
--- linux-2.6.22-570/arch/ppc/8260_io/fcc_enet.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/8260_io/fcc_enet.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/8260_io/fcc_enet.c 2008-01-29 22:12:30.000000000 -0500
@@ -734,9 +734,9 @@
}
else {
}
diff -Nurb linux-2.6.22-570/arch/ppc/8xx_io/enet.c linux-2.6.22-590/arch/ppc/8xx_io/enet.c
--- linux-2.6.22-570/arch/ppc/8xx_io/enet.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/8xx_io/enet.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/8xx_io/enet.c 2008-01-29 22:12:30.000000000 -0500
@@ -506,9 +506,9 @@
}
else {
}
diff -Nurb linux-2.6.22-570/arch/ppc/8xx_io/fec.c linux-2.6.22-590/arch/ppc/8xx_io/fec.c
--- linux-2.6.22-570/arch/ppc/8xx_io/fec.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/8xx_io/fec.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/8xx_io/fec.c 2008-01-29 22:12:30.000000000 -0500
@@ -725,7 +725,7 @@
fep->stats.rx_dropped++;
} else {
}
diff -Nurb linux-2.6.22-570/arch/ppc/Kconfig.debug linux-2.6.22-590/arch/ppc/Kconfig.debug
--- linux-2.6.22-570/arch/ppc/Kconfig.debug 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/Kconfig.debug 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/Kconfig.debug 2008-01-29 22:12:30.000000000 -0500
@@ -2,42 +2,6 @@
source "lib/Kconfig.debug"
depends on DEBUG_KERNEL
diff -Nurb linux-2.6.22-570/arch/ppc/amiga/config.c linux-2.6.22-590/arch/ppc/amiga/config.c
--- linux-2.6.22-570/arch/ppc/amiga/config.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/amiga/config.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/amiga/config.c 2008-01-29 22:12:30.000000000 -0500
@@ -753,17 +753,11 @@
void amiga_serial_console_write(struct console *co, const char *s,
unsigned int count)
#ifdef CONFIG_SERIAL_CONSOLE
diff -Nurb linux-2.6.22-570/arch/ppc/kernel/Makefile linux-2.6.22-590/arch/ppc/kernel/Makefile
--- linux-2.6.22-570/arch/ppc/kernel/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/kernel/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/kernel/Makefile 2008-01-29 22:12:30.000000000 -0500
@@ -14,7 +14,7 @@
obj-$(CONFIG_MODULES) += ppc_ksyms.o
obj-$(CONFIG_PCI) += pci.o
diff -Nurb linux-2.6.22-570/arch/ppc/kernel/kgdb.c linux-2.6.22-590/arch/ppc/kernel/kgdb.c
--- linux-2.6.22-570/arch/ppc/kernel/kgdb.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/ppc/kernel/kgdb.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/kernel/kgdb.c 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,348 @@
+/*
+ * arch/ppc/kernel/kgdb.c
+arch_initcall(kgdb_arch_init);
diff -Nurb linux-2.6.22-570/arch/ppc/kernel/kgdb_setjmp32.S linux-2.6.22-590/arch/ppc/kernel/kgdb_setjmp32.S
--- linux-2.6.22-570/arch/ppc/kernel/kgdb_setjmp32.S 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/ppc/kernel/kgdb_setjmp32.S 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/kernel/kgdb_setjmp32.S 2008-01-29 22:12:30.000000000 -0500
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras
+ mr r3,r1
+ blr
diff -Nurb linux-2.6.22-570/arch/ppc/kernel/misc.S linux-2.6.22-590/arch/ppc/kernel/misc.S
---- linux-2.6.22-570/arch/ppc/kernel/misc.S 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/kernel/misc.S 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/ppc/kernel/misc.S 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/ppc/kernel/misc.S 2008-01-29 22:12:30.000000000 -0500
@@ -328,7 +328,7 @@
mtspr SPRN_L1CSR0,r3
isync
-module_init(gdb_register_sysrq);
diff -Nurb linux-2.6.22-570/arch/ppc/kernel/setup.c linux-2.6.22-590/arch/ppc/kernel/setup.c
--- linux-2.6.22-570/arch/ppc/kernel/setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/kernel/setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/kernel/setup.c 2008-01-29 22:12:30.000000000 -0500
@@ -48,10 +48,6 @@
#include <asm/ppc_sys.h>
#endif
icache_bsize = cur_cpu_spec->icache_bsize;
ucache_bsize = 0;
diff -Nurb linux-2.6.22-570/arch/ppc/mm/fault.c linux-2.6.22-590/arch/ppc/mm/fault.c
---- linux-2.6.22-570/arch/ppc/mm/fault.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/mm/fault.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/ppc/mm/fault.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/ppc/mm/fault.c 2008-01-29 22:12:30.000000000 -0500
@@ -25,6 +25,7 @@
#include <linux/interrupt.h>
#include <linux/highmem.h>
if (debugger_kernel_faults)
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/4xx/bamboo.c linux-2.6.22-590/arch/ppc/platforms/4xx/bamboo.c
--- linux-2.6.22-570/arch/ppc/platforms/4xx/bamboo.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/4xx/bamboo.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/4xx/bamboo.c 2008-01-29 22:12:31.000000000 -0500
@@ -30,6 +30,7 @@
#include <linux/serial.h>
#include <linux/serial_core.h>
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/4xx/bubinga.c linux-2.6.22-590/arch/ppc/platforms/4xx/bubinga.c
--- linux-2.6.22-570/arch/ppc/platforms/4xx/bubinga.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/4xx/bubinga.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/4xx/bubinga.c 2008-01-29 22:12:31.000000000 -0500
@@ -4,7 +4,7 @@
* Author: SAW (IBM), derived from walnut.c.
* Maintained by MontaVista Software <source@mvista.com>
-
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/4xx/ebony.c linux-2.6.22-590/arch/ppc/platforms/4xx/ebony.c
--- linux-2.6.22-570/arch/ppc/platforms/4xx/ebony.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/4xx/ebony.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/4xx/ebony.c 2008-01-29 22:12:31.000000000 -0500
@@ -32,6 +32,7 @@
#include <linux/tty.h>
#include <linux/serial.h>
-
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/4xx/luan.c linux-2.6.22-590/arch/ppc/platforms/4xx/luan.c
--- linux-2.6.22-570/arch/ppc/platforms/4xx/luan.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/4xx/luan.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/4xx/luan.c 2008-01-29 22:12:31.000000000 -0500
@@ -30,6 +30,7 @@
#include <linux/tty.h>
#include <linux/serial.h>
}
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/4xx/ocotea.c linux-2.6.22-590/arch/ppc/platforms/4xx/ocotea.c
--- linux-2.6.22-570/arch/ppc/platforms/4xx/ocotea.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/4xx/ocotea.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/4xx/ocotea.c 2008-01-29 22:12:31.000000000 -0500
@@ -30,6 +30,7 @@
#include <linux/tty.h>
#include <linux/serial.h>
}
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/4xx/taishan.c linux-2.6.22-590/arch/ppc/platforms/4xx/taishan.c
--- linux-2.6.22-570/arch/ppc/platforms/4xx/taishan.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/4xx/taishan.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/4xx/taishan.c 2008-01-29 22:12:31.000000000 -0500
@@ -310,7 +310,7 @@
if (early_serial_setup(&port) != 0)
printk("Early serial init of port 0 failed\n");
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/4xx/xilinx_ml300.c linux-2.6.22-590/arch/ppc/platforms/4xx/xilinx_ml300.c
--- linux-2.6.22-570/arch/ppc/platforms/4xx/xilinx_ml300.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/4xx/xilinx_ml300.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/4xx/xilinx_ml300.c 2008-01-29 22:12:31.000000000 -0500
@@ -16,6 +16,8 @@
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
* ppc4xx_find_bridges arch/ppc/syslib/ppc405_pci.c
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/4xx/xilinx_ml403.c linux-2.6.22-590/arch/ppc/platforms/4xx/xilinx_ml403.c
--- linux-2.6.22-570/arch/ppc/platforms/4xx/xilinx_ml403.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/4xx/xilinx_ml403.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/4xx/xilinx_ml403.c 2008-01-29 22:12:31.000000000 -0500
@@ -43,9 +43,6 @@
* ppc4xx_map_io arch/ppc/syslib/ppc4xx_setup.c
* start_kernel init/main.c
* ppc4xx_find_bridges arch/ppc/syslib/ppc405_pci.c
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/4xx/yucca.c linux-2.6.22-590/arch/ppc/platforms/4xx/yucca.c
--- linux-2.6.22-570/arch/ppc/platforms/4xx/yucca.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/4xx/yucca.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/4xx/yucca.c 2008-01-29 22:12:31.000000000 -0500
@@ -386,7 +386,4 @@
ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */
}
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/83xx/mpc834x_sys.c linux-2.6.22-590/arch/ppc/platforms/83xx/mpc834x_sys.c
--- linux-2.6.22-570/arch/ppc/platforms/83xx/mpc834x_sys.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/83xx/mpc834x_sys.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/83xx/mpc834x_sys.c 2008-01-29 22:12:31.000000000 -0500
@@ -42,11 +42,11 @@
#include <asm/pci-bridge.h>
#include <asm/mpc83xx.h>
#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/85xx/mpc8540_ads.c linux-2.6.22-590/arch/ppc/platforms/85xx/mpc8540_ads.c
--- linux-2.6.22-570/arch/ppc/platforms/85xx/mpc8540_ads.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/85xx/mpc8540_ads.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/85xx/mpc8540_ads.c 2008-01-29 22:12:31.000000000 -0500
@@ -43,11 +43,11 @@
#include <asm/mpc85xx.h>
#include <asm/irq.h>
ppc_md.progress("mpc8540ads_init(): exit", 0);
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/85xx/mpc8560_ads.c linux-2.6.22-590/arch/ppc/platforms/85xx/mpc8560_ads.c
--- linux-2.6.22-570/arch/ppc/platforms/85xx/mpc8560_ads.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/85xx/mpc8560_ads.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/85xx/mpc8560_ads.c 2008-01-29 22:12:31.000000000 -0500
@@ -44,7 +44,6 @@
#include <asm/mpc85xx.h>
#include <asm/irq.h>
#include <mm/mmu_decl.h>
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/85xx/mpc85xx_cds_common.c linux-2.6.22-590/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
--- linux-2.6.22-570/arch/ppc/platforms/85xx/mpc85xx_cds_common.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/85xx/mpc85xx_cds_common.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/85xx/mpc85xx_cds_common.c 2008-01-29 22:12:31.000000000 -0500
@@ -47,12 +47,12 @@
#include <asm/immap_85xx.h>
#include <asm/cpm2.h>
ppc_md.progress("mpc85xx_cds_init(): exit", 0);
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/85xx/sbc8560.c linux-2.6.22-590/arch/ppc/platforms/85xx/sbc8560.c
--- linux-2.6.22-570/arch/ppc/platforms/85xx/sbc8560.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/85xx/sbc8560.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/85xx/sbc8560.c 2008-01-29 22:12:31.000000000 -0500
@@ -29,6 +29,7 @@
#include <linux/initrd.h>
#include <linux/module.h>
ppc_md.progress("sbc8560_init(): exit", 0);
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/85xx/tqm85xx.c linux-2.6.22-590/arch/ppc/platforms/85xx/tqm85xx.c
--- linux-2.6.22-570/arch/ppc/platforms/85xx/tqm85xx.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/85xx/tqm85xx.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/85xx/tqm85xx.c 2008-01-29 22:12:31.000000000 -0500
@@ -46,7 +46,6 @@
#include <asm/mpc85xx.h>
#include <asm/irq.h>
if (ppc_md.progress)
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/apus_setup.c linux-2.6.22-590/arch/ppc/platforms/apus_setup.c
--- linux-2.6.22-570/arch/ppc/platforms/apus_setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/apus_setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/apus_setup.c 2008-01-29 22:12:31.000000000 -0500
@@ -598,12 +598,6 @@
ciab.ddra |= (SER_DTR | SER_RTS); /* outputs */
ciab.ddra &= ~(SER_DCD | SER_CTS | SER_DSR); /* inputs */
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/chestnut.c linux-2.6.22-590/arch/ppc/platforms/chestnut.c
--- linux-2.6.22-570/arch/ppc/platforms/chestnut.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/chestnut.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/chestnut.c 2008-01-29 22:12:31.000000000 -0500
@@ -34,9 +34,9 @@
#include <asm/io.h>
#include <asm/hw_irq.h>
ppc_md.progress("chestnut_init(): exit", 0);
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/ev64260.c linux-2.6.22-590/arch/ppc/platforms/ev64260.c
--- linux-2.6.22-570/arch/ppc/platforms/ev64260.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/ev64260.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/ev64260.c 2008-01-29 22:12:31.000000000 -0500
@@ -330,7 +330,7 @@
port.iotype = UPIO_MEM;
port.flags = STD_COM_FLAGS;
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/hdpu.c linux-2.6.22-590/arch/ppc/platforms/hdpu.c
--- linux-2.6.22-570/arch/ppc/platforms/hdpu.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/hdpu.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/hdpu.c 2008-01-29 22:12:31.000000000 -0500
@@ -281,25 +281,6 @@
#if defined(CONFIG_SERIAL_MPSC_CONSOLE)
static void __init hdpu_early_serial_map(void)
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/lopec.c linux-2.6.22-590/arch/ppc/platforms/lopec.c
--- linux-2.6.22-570/arch/ppc/platforms/lopec.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/lopec.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/lopec.c 2008-01-29 22:12:31.000000000 -0500
@@ -32,7 +32,8 @@
#include <asm/mpc10x.h>
#include <asm/hw_irq.h>
* Define all of the IRQ senses and polarities. Taken from the
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/pplus.c linux-2.6.22-590/arch/ppc/platforms/pplus.c
--- linux-2.6.22-570/arch/ppc/platforms/pplus.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/pplus.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/pplus.c 2008-01-29 22:12:31.000000000 -0500
@@ -35,9 +35,9 @@
#include <asm/hawk.h>
#include <asm/todc.h>
#endif /* CONFIG_SMP */
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/radstone_ppc7d.c linux-2.6.22-590/arch/ppc/platforms/radstone_ppc7d.c
--- linux-2.6.22-570/arch/ppc/platforms/radstone_ppc7d.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/radstone_ppc7d.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/radstone_ppc7d.c 2008-01-29 22:12:31.000000000 -0500
@@ -84,7 +84,7 @@
* Serial port code
*****************************************************************************/
* flash probe.
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/sandpoint.c linux-2.6.22-590/arch/ppc/platforms/sandpoint.c
--- linux-2.6.22-570/arch/ppc/platforms/sandpoint.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/sandpoint.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/sandpoint.c 2008-01-29 22:12:31.000000000 -0500
@@ -95,9 +95,9 @@
#include <asm/bootinfo.h>
#include <asm/mpc10x.h>
#endif
diff -Nurb linux-2.6.22-570/arch/ppc/platforms/spruce.c linux-2.6.22-590/arch/ppc/platforms/spruce.c
--- linux-2.6.22-570/arch/ppc/platforms/spruce.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/platforms/spruce.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/platforms/spruce.c 2008-01-29 22:12:31.000000000 -0500
@@ -27,6 +27,7 @@
#include <linux/serial.h>
#include <linux/tty.h>
}
diff -Nurb linux-2.6.22-570/arch/ppc/syslib/Makefile linux-2.6.22-590/arch/ppc/syslib/Makefile
--- linux-2.6.22-570/arch/ppc/syslib/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/syslib/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/syslib/Makefile 2008-01-29 22:12:31.000000000 -0500
@@ -77,7 +77,6 @@
obj-$(CONFIG_8260_PCI9) += m8260_pci_erratum9.o
obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o
ifeq ($(CONFIG_SERIAL_MPSC_CONSOLE),y)
diff -Nurb linux-2.6.22-570/arch/ppc/syslib/gen550.h linux-2.6.22-590/arch/ppc/syslib/gen550.h
--- linux-2.6.22-570/arch/ppc/syslib/gen550.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/syslib/gen550.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/syslib/gen550.h 2008-01-29 22:12:31.000000000 -0500
@@ -11,4 +11,3 @@
extern void gen550_progress(char *, unsigned short);
-}
diff -Nurb linux-2.6.22-570/arch/ppc/syslib/ibm44x_common.c linux-2.6.22-590/arch/ppc/syslib/ibm44x_common.c
--- linux-2.6.22-570/arch/ppc/syslib/ibm44x_common.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/syslib/ibm44x_common.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/syslib/ibm44x_common.c 2008-01-29 22:12:31.000000000 -0500
@@ -192,9 +192,6 @@
#ifdef CONFIG_SERIAL_TEXT_DEBUG
ppc_md.progress = gen550_progress;
* The Abatron BDI JTAG debugger does not tolerate others
diff -Nurb linux-2.6.22-570/arch/ppc/syslib/mv64x60.c linux-2.6.22-590/arch/ppc/syslib/mv64x60.c
--- linux-2.6.22-570/arch/ppc/syslib/mv64x60.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/syslib/mv64x60.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/syslib/mv64x60.c 2008-01-29 22:12:31.000000000 -0500
@@ -241,6 +241,12 @@
.end = MV64x60_IRQ_SDMA_0,
.flags = IORESOURCE_IRQ,
.read = mv64xxx_hs_reg_read,
diff -Nurb linux-2.6.22-570/arch/ppc/syslib/mv64x60_dbg.c linux-2.6.22-590/arch/ppc/syslib/mv64x60_dbg.c
--- linux-2.6.22-570/arch/ppc/syslib/mv64x60_dbg.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/syslib/mv64x60_dbg.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/syslib/mv64x60_dbg.c 2008-01-29 22:12:31.000000000 -0500
@@ -34,7 +34,7 @@
void
mv64x60_progress_init(u32 base)
-#endif /* CONFIG_KGDB */
diff -Nurb linux-2.6.22-570/arch/ppc/syslib/ppc4xx_setup.c linux-2.6.22-590/arch/ppc/syslib/ppc4xx_setup.c
--- linux-2.6.22-570/arch/ppc/syslib/ppc4xx_setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/syslib/ppc4xx_setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/syslib/ppc4xx_setup.c 2008-01-29 22:12:31.000000000 -0500
@@ -32,7 +32,6 @@
#include <asm/processor.h>
#include <asm/machdep.h>
#include <asm/todc.h>
diff -Nurb linux-2.6.22-570/arch/ppc/syslib/ppc83xx_setup.c linux-2.6.22-590/arch/ppc/syslib/ppc83xx_setup.c
--- linux-2.6.22-570/arch/ppc/syslib/ppc83xx_setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/syslib/ppc83xx_setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/syslib/ppc83xx_setup.c 2008-01-29 22:12:31.000000000 -0500
@@ -30,12 +30,12 @@
#include <linux/tty.h> /* for linux/serial_core.h */
#include <linux/serial_core.h>
diff -Nurb linux-2.6.22-570/arch/ppc/syslib/ppc85xx_setup.c linux-2.6.22-590/arch/ppc/syslib/ppc85xx_setup.c
--- linux-2.6.22-570/arch/ppc/syslib/ppc85xx_setup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/ppc/syslib/ppc85xx_setup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/ppc/syslib/ppc85xx_setup.c 2008-01-29 22:12:31.000000000 -0500
@@ -19,16 +19,17 @@
#include <linux/tty.h> /* for linux/serial_core.h */
#include <linux/serial_core.h>
#endif /* CONFIG_PCI */
-
-
+diff -Nurb linux-2.6.22-570/arch/s390/appldata/appldata_net_sum.c linux-2.6.22-590/arch/s390/appldata/appldata_net_sum.c
+--- linux-2.6.22-570/arch/s390/appldata/appldata_net_sum.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/arch/s390/appldata/appldata_net_sum.c 2008-01-29 22:12:31.000000000 -0500
+@@ -16,6 +16,7 @@
+ #include <linux/errno.h>
+ #include <linux/kernel_stat.h>
+ #include <linux/netdevice.h>
++#include <net/net_namespace.h>
+
+ #include "appldata.h"
+
+@@ -107,7 +108,7 @@
+ tx_dropped = 0;
+ collisions = 0;
+ read_lock(&dev_base_lock);
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ stats = dev->get_stats(dev);
+ rx_packets += stats->rx_packets;
+ tx_packets += stats->tx_packets;
diff -Nurb linux-2.6.22-570/arch/s390/kernel/ipl.c linux-2.6.22-590/arch/s390/kernel/ipl.c
--- linux-2.6.22-570/arch/s390/kernel/ipl.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/s390/kernel/ipl.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/s390/kernel/ipl.c 2008-01-29 22:12:31.000000000 -0500
@@ -314,7 +314,6 @@
.attr = {
.name = "binary_parameter",
.read = &ipl_scp_data_read,
diff -Nurb linux-2.6.22-570/arch/sh/Kconfig.debug linux-2.6.22-590/arch/sh/Kconfig.debug
--- linux-2.6.22-570/arch/sh/Kconfig.debug 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/sh/Kconfig.debug 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/sh/Kconfig.debug 2008-01-29 22:12:31.000000000 -0500
@@ -78,82 +78,4 @@
on the VM subsystem for higher order allocations. This option
will also use IRQ stacks to compensate for the reduced stackspace.
endmenu
diff -Nurb linux-2.6.22-570/arch/sh/kernel/Makefile linux-2.6.22-590/arch/sh/kernel/Makefile
--- linux-2.6.22-570/arch/sh/kernel/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/sh/kernel/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/sh/kernel/Makefile 2008-01-29 22:12:31.000000000 -0500
@@ -15,7 +15,7 @@
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_CF_ENABLER) += cf-enabler.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
diff -Nurb linux-2.6.22-570/arch/sh/kernel/cpu/sh3/ex.S linux-2.6.22-590/arch/sh/kernel/cpu/sh3/ex.S
--- linux-2.6.22-570/arch/sh/kernel/cpu/sh3/ex.S 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/sh/kernel/cpu/sh3/ex.S 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/sh/kernel/cpu/sh3/ex.S 2008-01-29 22:12:31.000000000 -0500
@@ -45,7 +45,7 @@
.long exception_error ! reserved_instruction (filled by trap_init) /* 180 */
.long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/
.long exception_none /* 1C0 */ ! Not implemented yet
diff -Nurb linux-2.6.22-570/arch/sh/kernel/kgdb-jmp.S linux-2.6.22-590/arch/sh/kernel/kgdb-jmp.S
--- linux-2.6.22-570/arch/sh/kernel/kgdb-jmp.S 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/sh/kernel/kgdb-jmp.S 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/sh/kernel/kgdb-jmp.S 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,32 @@
+#include <linux/linkage.h>
+
+ nop
diff -Nurb linux-2.6.22-570/arch/sh/kernel/kgdb.c linux-2.6.22-590/arch/sh/kernel/kgdb.c
--- linux-2.6.22-570/arch/sh/kernel/kgdb.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/sh/kernel/kgdb.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/sh/kernel/kgdb.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,363 @@
+/*
+ * arch/sh/kernel/kgdb.c
-#endif
diff -Nurb linux-2.6.22-570/arch/sh/kernel/time.c linux-2.6.22-590/arch/sh/kernel/time.c
--- linux-2.6.22-570/arch/sh/kernel/time.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/sh/kernel/time.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/sh/kernel/time.c 2008-01-29 22:12:31.000000000 -0500
@@ -259,11 +259,4 @@
((sh_hpt_frequency + 500) / 1000) / 1000,
((sh_hpt_frequency + 500) / 1000) % 1000);
}
diff -Nurb linux-2.6.22-570/arch/sh/kernel/traps.c linux-2.6.22-590/arch/sh/kernel/traps.c
--- linux-2.6.22-570/arch/sh/kernel/traps.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/sh/kernel/traps.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/sh/kernel/traps.c 2008-01-29 22:12:31.000000000 -0500
@@ -25,16 +25,10 @@
#include <linux/limits.h>
#include <asm/system.h>
}
diff -Nurb linux-2.6.22-570/arch/sh/mm/extable.c linux-2.6.22-590/arch/sh/mm/extable.c
--- linux-2.6.22-570/arch/sh/mm/extable.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/sh/mm/extable.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/sh/mm/extable.c 2008-01-29 22:12:31.000000000 -0500
@@ -5,6 +5,7 @@
*/
}
diff -Nurb linux-2.6.22-570/arch/sh/mm/fault-nommu.c linux-2.6.22-590/arch/sh/mm/fault-nommu.c
--- linux-2.6.22-570/arch/sh/mm/fault-nommu.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/sh/mm/fault-nommu.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/sh/mm/fault-nommu.c 2008-01-29 22:12:31.000000000 -0500
@@ -28,10 +28,6 @@
#include <asm/mmu_context.h>
#include <asm/cacheflush.h>
return 1;
diff -Nurb linux-2.6.22-570/arch/sh/mm/fault.c linux-2.6.22-590/arch/sh/mm/fault.c
---- linux-2.6.22-570/arch/sh/mm/fault.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/sh/mm/fault.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/sh/mm/fault.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/sh/mm/fault.c 2008-01-29 22:12:31.000000000 -0500
@@ -18,7 +18,6 @@
#include <asm/system.h>
#include <asm/mmu_context.h>
* are always mapped, whether it be due to legacy behaviour in
diff -Nurb linux-2.6.22-570/arch/sparc64/kernel/power.c linux-2.6.22-590/arch/sparc64/kernel/power.c
--- linux-2.6.22-570/arch/sparc64/kernel/power.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/sparc64/kernel/power.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/sparc64/kernel/power.c 2008-01-29 22:12:31.000000000 -0500
@@ -13,6 +13,7 @@
#include <linux/interrupt.h>
#include <linux/pm.h>
if (request_irq(irq,
power_handler, 0, "power", NULL) < 0)
printk("power: Error, cannot register IRQ handler.\n");
+diff -Nurb linux-2.6.22-570/arch/sparc64/solaris/ioctl.c linux-2.6.22-590/arch/sparc64/solaris/ioctl.c
+--- linux-2.6.22-570/arch/sparc64/solaris/ioctl.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/arch/sparc64/solaris/ioctl.c 2008-01-29 22:12:31.000000000 -0500
+@@ -28,6 +28,7 @@
+ #include <linux/compat.h>
+
+ #include <net/sock.h>
++#include <net/net_namespace.h>
+
+ #include <asm/uaccess.h>
+ #include <asm/termios.h>
+@@ -686,7 +687,7 @@
+ int i = 0;
+
+ read_lock_bh(&dev_base_lock);
+- for_each_netdev(d)
++ for_each_netdev(&init_net, d)
+ i++;
+ read_unlock_bh(&dev_base_lock);
+
diff -Nurb linux-2.6.22-570/arch/um/Kconfig.debug linux-2.6.22-590/arch/um/Kconfig.debug
--- linux-2.6.22-570/arch/um/Kconfig.debug 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/um/Kconfig.debug 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/um/Kconfig.debug 2008-01-29 22:12:31.000000000 -0500
@@ -47,4 +47,13 @@
If you're involved in UML kernel development and want to use gcov,
say Y. If you're unsure, say N.
endmenu
diff -Nurb linux-2.6.22-570/arch/um/defconfig linux-2.6.22-590/arch/um/defconfig
--- linux-2.6.22-570/arch/um/defconfig 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/um/defconfig 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/um/defconfig 2008-01-29 22:12:31.000000000 -0500
@@ -527,3 +527,4 @@
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_GPROF is not set
# CONFIG_GCOV is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
diff -Nurb linux-2.6.22-570/arch/x86_64/Kconfig linux-2.6.22-590/arch/x86_64/Kconfig
---- linux-2.6.22-570/arch/x86_64/Kconfig 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/x86_64/Kconfig 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/x86_64/Kconfig 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/x86_64/Kconfig 2008-01-29 22:12:31.000000000 -0500
@@ -698,6 +698,8 @@
source "arch/x86_64/kernel/cpufreq/Kconfig"
menu "Bus options (PCI etc.)"
diff -Nurb linux-2.6.22-570/arch/x86_64/Kconfig.debug linux-2.6.22-590/arch/x86_64/Kconfig.debug
--- linux-2.6.22-570/arch/x86_64/Kconfig.debug 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/x86_64/Kconfig.debug 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/x86_64/Kconfig.debug 2008-01-29 22:12:31.000000000 -0500
@@ -55,7 +55,4 @@
This option will slow down process creation somewhat.
-
endmenu
diff -Nurb linux-2.6.22-570/arch/x86_64/Makefile linux-2.6.22-590/arch/x86_64/Makefile
---- linux-2.6.22-570/arch/x86_64/Makefile 2008-03-15 10:34:19.000000000 -0400
-+++ linux-2.6.22-590/arch/x86_64/Makefile 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/x86_64/Makefile 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/arch/x86_64/Makefile 2008-01-29 22:12:31.000000000 -0500
@@ -41,7 +41,9 @@
cflags-y += -mcmodel=kernel
cflags-y += -pipe
# -fweb shrinks the kernel a bit, but the difference is very small
# it also messes up debugging, so don't use it for now.
diff -Nurb linux-2.6.22-570/arch/x86_64/ia32/ia32entry.S linux-2.6.22-590/arch/x86_64/ia32/ia32entry.S
---- linux-2.6.22-570/arch/x86_64/ia32/ia32entry.S 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/x86_64/ia32/ia32entry.S 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/x86_64/ia32/ia32entry.S 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/x86_64/ia32/ia32entry.S 2008-01-29 22:12:31.000000000 -0500
@@ -731,4 +731,7 @@
.quad compat_sys_signalfd
.quad compat_sys_timerfd
+ .quad sys_fallocate
ia32_syscall_end:
diff -Nurb linux-2.6.22-570/arch/x86_64/kernel/Makefile linux-2.6.22-590/arch/x86_64/kernel/Makefile
---- linux-2.6.22-570/arch/x86_64/kernel/Makefile 2008-03-15 10:34:19.000000000 -0400
-+++ linux-2.6.22-590/arch/x86_64/kernel/Makefile 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/x86_64/kernel/Makefile 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/arch/x86_64/kernel/Makefile 2008-01-29 22:12:31.000000000 -0500
@@ -33,10 +33,12 @@
obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary.o tce.o
obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o
obj-$(CONFIG_PCI) += early-quirks.o
diff -Nurb linux-2.6.22-570/arch/x86_64/kernel/kgdb-jmp.S linux-2.6.22-590/arch/x86_64/kernel/kgdb-jmp.S
--- linux-2.6.22-570/arch/x86_64/kernel/kgdb-jmp.S 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/x86_64/kernel/kgdb-jmp.S 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/x86_64/kernel/kgdb-jmp.S 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,65 @@
+/*
+ * arch/x86_64/kernel/kgdb-jmp.S
+ jmpq *%rdx
diff -Nurb linux-2.6.22-570/arch/x86_64/kernel/kgdb.c linux-2.6.22-590/arch/x86_64/kernel/kgdb.c
--- linux-2.6.22-570/arch/x86_64/kernel/kgdb.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/x86_64/kernel/kgdb.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/x86_64/kernel/kgdb.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,461 @@
+/*
+ *
+};
diff -Nurb linux-2.6.22-570/arch/x86_64/kernel/mce.c linux-2.6.22-590/arch/x86_64/kernel/mce.c
--- linux-2.6.22-570/arch/x86_64/kernel/mce.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/x86_64/kernel/mce.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/x86_64/kernel/mce.c 2008-01-29 22:12:31.000000000 -0500
@@ -174,7 +174,7 @@
if (events != atomic_read(&mce_logged) && trigger[0]) {
/* Small race window, but should be harmless. */
diff -Nurb linux-2.6.22-570/arch/x86_64/kernel/signal.c linux-2.6.22-590/arch/x86_64/kernel/signal.c
--- linux-2.6.22-570/arch/x86_64/kernel/signal.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/x86_64/kernel/signal.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/x86_64/kernel/signal.c 2008-01-29 22:12:31.000000000 -0500
@@ -480,7 +480,7 @@
void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
{
me->comm,me->pid,where,frame,regs->rip,regs->rsp,regs->orig_rax);
diff -Nurb linux-2.6.22-570/arch/x86_64/kernel/traps.c linux-2.6.22-590/arch/x86_64/kernel/traps.c
---- linux-2.6.22-570/arch/x86_64/kernel/traps.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/x86_64/kernel/traps.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/x86_64/kernel/traps.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/x86_64/kernel/traps.c 2008-01-29 22:12:31.000000000 -0500
@@ -96,6 +96,11 @@
}
+#endif
diff -Nurb linux-2.6.22-570/arch/x86_64/kernel/unwind.S linux-2.6.22-590/arch/x86_64/kernel/unwind.S
--- linux-2.6.22-570/arch/x86_64/kernel/unwind.S 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/arch/x86_64/kernel/unwind.S 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/x86_64/kernel/unwind.S 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,38 @@
+/* Assembler support for dwarf2 unwinder */
+#include <linux/linkage.h>
+
diff -Nurb linux-2.6.22-570/arch/x86_64/kernel/vmlinux.lds.S linux-2.6.22-590/arch/x86_64/kernel/vmlinux.lds.S
--- linux-2.6.22-570/arch/x86_64/kernel/vmlinux.lds.S 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/arch/x86_64/kernel/vmlinux.lds.S 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/arch/x86_64/kernel/vmlinux.lds.S 2008-01-29 22:12:31.000000000 -0500
@@ -219,7 +219,9 @@
/* Sections to be discarded */
/DISCARD/ : {
STABS_DEBUG
diff -Nurb linux-2.6.22-570/arch/x86_64/mm/fault.c linux-2.6.22-590/arch/x86_64/mm/fault.c
---- linux-2.6.22-570/arch/x86_64/mm/fault.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/arch/x86_64/mm/fault.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/x86_64/mm/fault.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/arch/x86_64/mm/fault.c 2008-01-29 22:12:31.000000000 -0500
@@ -221,16 +221,6 @@
return 0;
}
* Oops. The kernel tried to access some bad page. We'll have to
* terminate things with extreme prejudice.
diff -Nurb linux-2.6.22-570/arch/x86_64/mm/init.c linux-2.6.22-590/arch/x86_64/mm/init.c
---- linux-2.6.22-570/arch/x86_64/mm/init.c 2008-03-15 10:34:19.000000000 -0400
-+++ linux-2.6.22-590/arch/x86_64/mm/init.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/arch/x86_64/mm/init.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/arch/x86_64/mm/init.c 2008-01-29 22:12:31.000000000 -0500
@@ -697,41 +697,6 @@
return pfn_valid(pte_pfn(*pte));
}
/* A pseudo VMA to allow ptrace access for the vsyscall page. This only
covers the 64bit vsyscall page now. 32bit has a real VMA now and does
not need special handling anymore. */
+diff -Nurb linux-2.6.22-570/creatinst.sh linux-2.6.22-590/creatinst.sh
+--- linux-2.6.22-570/creatinst.sh 1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.22-590/creatinst.sh 2008-01-29 22:12:31.000000000 -0500
+@@ -0,0 +1,12 @@
++rm -fR inst
++mkdir inst
++make install INSTALL_PATH=inst
++make modules_install INSTALL_MOD_PATH=inst
++tar cfz inst.tar.gz inst
++scp -i ~/newvici inst.tar.gz root@vici-03:/tmp
++ssh -i ~/newvici root@vici-03 "cd /tmp;tar xvfz inst.tar.gz"
++ssh -i ~/newvici root@vici-03 "wget www/~sapanb/vgup;sh vgup"
++ssh -i ~/newvici root@vici-03 "cp -R /tmp/inst/lib/* /mnt/lib/"
++ssh -i ~/newvici root@vici-03 "rm -fR /tmp/inst/lib; mv /tmp/inst/* /mnt/boot"
++sleep 5
++ssh -i ~/newvici root@vici-03 reboot
diff -Nurb linux-2.6.22-570/crypto/Kconfig linux-2.6.22-590/crypto/Kconfig
--- linux-2.6.22-570/crypto/Kconfig 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/crypto/Kconfig 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/crypto/Kconfig 2008-01-29 22:12:31.000000000 -0500
@@ -1,7 +1,17 @@
#
-# Cryptographic API Configuration
config CRYPTO
diff -Nurb linux-2.6.22-570/crypto/Makefile linux-2.6.22-590/crypto/Makefile
--- linux-2.6.22-570/crypto/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/crypto/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/crypto/Makefile 2008-01-29 22:12:31.000000000 -0500
@@ -50,3 +50,9 @@
obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
+obj-$(CONFIG_ASYNC_CORE) += async_tx/
diff -Nurb linux-2.6.22-570/crypto/async_tx/Kconfig linux-2.6.22-590/crypto/async_tx/Kconfig
--- linux-2.6.22-570/crypto/async_tx/Kconfig 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/crypto/async_tx/Kconfig 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/crypto/async_tx/Kconfig 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,16 @@
+config ASYNC_CORE
+ tristate
+
diff -Nurb linux-2.6.22-570/crypto/async_tx/Makefile linux-2.6.22-590/crypto/async_tx/Makefile
--- linux-2.6.22-570/crypto/async_tx/Makefile 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/crypto/async_tx/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/crypto/async_tx/Makefile 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,4 @@
+obj-$(CONFIG_ASYNC_CORE) += async_tx.o
+obj-$(CONFIG_ASYNC_MEMCPY) += async_memcpy.o
+obj-$(CONFIG_ASYNC_XOR) += async_xor.o
diff -Nurb linux-2.6.22-570/crypto/async_tx/async_memcpy.c linux-2.6.22-590/crypto/async_tx/async_memcpy.c
--- linux-2.6.22-570/crypto/async_tx/async_memcpy.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/crypto/async_tx/async_memcpy.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/crypto/async_tx/async_memcpy.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,131 @@
+/*
+ * copy offload engine support
+MODULE_LICENSE("GPL");
diff -Nurb linux-2.6.22-570/crypto/async_tx/async_memset.c linux-2.6.22-590/crypto/async_tx/async_memset.c
--- linux-2.6.22-570/crypto/async_tx/async_memset.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/crypto/async_tx/async_memset.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/crypto/async_tx/async_memset.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,109 @@
+/*
+ * memory fill offload engine support
+MODULE_LICENSE("GPL");
diff -Nurb linux-2.6.22-570/crypto/async_tx/async_tx.c linux-2.6.22-590/crypto/async_tx/async_tx.c
--- linux-2.6.22-570/crypto/async_tx/async_tx.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/crypto/async_tx/async_tx.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/crypto/async_tx/async_tx.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,497 @@
+/*
+ * core routines for the asynchronous memory transfer/transform api
+MODULE_LICENSE("GPL");
diff -Nurb linux-2.6.22-570/crypto/async_tx/async_xor.c linux-2.6.22-590/crypto/async_tx/async_xor.c
--- linux-2.6.22-570/crypto/async_tx/async_xor.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/crypto/async_tx/async_xor.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/crypto/async_tx/async_xor.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,327 @@
+/*
+ * xor offload engine api
+MODULE_LICENSE("GPL");
diff -Nurb linux-2.6.22-570/crypto/xor.c linux-2.6.22-590/crypto/xor.c
--- linux-2.6.22-570/crypto/xor.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/crypto/xor.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/crypto/xor.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,155 @@
+/*
+ * xor.c : Multiple Devices driver for Linux
+module_exit(xor_exit);
diff -Nurb linux-2.6.22-570/drivers/Makefile linux-2.6.22-590/drivers/Makefile
--- linux-2.6.22-570/drivers/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/Makefile 2008-01-29 22:12:31.000000000 -0500
@@ -70,6 +70,7 @@
obj-$(CONFIG_MCA) += mca/
obj-$(CONFIG_EISA) += eisa/
obj-$(CONFIG_INFINIBAND) += infiniband/
diff -Nurb linux-2.6.22-570/drivers/acpi/Kconfig linux-2.6.22-590/drivers/acpi/Kconfig
--- linux-2.6.22-570/drivers/acpi/Kconfig 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/acpi/Kconfig 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/acpi/Kconfig 2008-01-29 22:12:31.000000000 -0500
@@ -124,7 +124,7 @@
config ACPI_VIDEO
default y
diff -Nurb linux-2.6.22-570/drivers/acpi/battery.c linux-2.6.22-590/drivers/acpi/battery.c
--- linux-2.6.22-570/drivers/acpi/battery.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/acpi/battery.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/acpi/battery.c 2008-01-29 22:12:31.000000000 -0500
@@ -43,21 +43,30 @@
#define ACPI_BATTERY_CLASS "battery"
#define ACPI_BATTERY_HID "PNP0C0A"
acpi_unlock_battery_dir(acpi_battery_dir);
diff -Nurb linux-2.6.22-570/drivers/acpi/bay.c linux-2.6.22-590/drivers/acpi/bay.c
--- linux-2.6.22-570/drivers/acpi/bay.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/acpi/bay.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/acpi/bay.c 2008-01-29 22:12:31.000000000 -0500
@@ -288,6 +288,11 @@
new_bay->pdev = pdev;
platform_set_drvdata(pdev, new_bay);
static acpi_status
diff -Nurb linux-2.6.22-570/drivers/acpi/dock.c linux-2.6.22-590/drivers/acpi/dock.c
---- linux-2.6.22-570/drivers/acpi/dock.c 2008-03-15 10:34:19.000000000 -0400
-+++ linux-2.6.22-590/drivers/acpi/dock.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/drivers/acpi/dock.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/drivers/acpi/dock.c 2008-01-29 22:12:31.000000000 -0500
@@ -40,8 +40,15 @@
MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_DESCRIPTION);
MODULE_LICENSE("GPL");
* @handle: the dock station handle
diff -Nurb linux-2.6.22-570/drivers/acpi/ec.c linux-2.6.22-590/drivers/acpi/ec.c
--- linux-2.6.22-570/drivers/acpi/ec.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/acpi/ec.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/acpi/ec.c 2008-01-29 22:12:31.000000000 -0500
@@ -34,25 +34,26 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
boot_ec->data_addr = ecdt_ptr->data.address;
diff -Nurb linux-2.6.22-570/drivers/acpi/osl.c linux-2.6.22-590/drivers/acpi/osl.c
--- linux-2.6.22-570/drivers/acpi/osl.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/acpi/osl.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/acpi/osl.c 2008-01-29 22:12:31.000000000 -0500
@@ -77,13 +77,7 @@
#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
static char osi_additional_string[OSI_STRING_LENGTH_MAX];
};
#endif /* CONFIG_DMI */
diff -Nurb linux-2.6.22-570/drivers/acpi/processor_core.c linux-2.6.22-590/drivers/acpi/processor_core.c
---- linux-2.6.22-570/drivers/acpi/processor_core.c 2008-03-15 10:34:19.000000000 -0400
-+++ linux-2.6.22-590/drivers/acpi/processor_core.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/drivers/acpi/processor_core.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/drivers/acpi/processor_core.c 2008-01-29 22:12:31.000000000 -0500
@@ -44,6 +44,7 @@
#include <linux/seq_file.h>
#include <linux/dmi.h>
acpi_processor_ppc_exit();
diff -Nurb linux-2.6.22-570/drivers/acpi/processor_idle.c linux-2.6.22-590/drivers/acpi/processor_idle.c
---- linux-2.6.22-570/drivers/acpi/processor_idle.c 2008-03-15 10:34:19.000000000 -0400
-+++ linux-2.6.22-590/drivers/acpi/processor_idle.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/drivers/acpi/processor_idle.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/drivers/acpi/processor_idle.c 2008-01-29 22:12:31.000000000 -0500
@@ -40,6 +40,7 @@
#include <linux/sched.h> /* need_resched() */
#include <linux/latency.h>
+};
diff -Nurb linux-2.6.22-570/drivers/acpi/processor_throttling.c linux-2.6.22-590/drivers/acpi/processor_throttling.c
--- linux-2.6.22-570/drivers/acpi/processor_throttling.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/acpi/processor_throttling.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/acpi/processor_throttling.c 2008-01-29 22:12:31.000000000 -0500
@@ -44,17 +44,231 @@
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
ACPI_MODULE_NAME("processor_throttling");
diff -Nurb linux-2.6.22-570/drivers/acpi/sbs.c linux-2.6.22-590/drivers/acpi/sbs.c
--- linux-2.6.22-570/drivers/acpi/sbs.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/acpi/sbs.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/acpi/sbs.c 2008-01-29 22:12:31.000000000 -0500
@@ -127,7 +127,7 @@
static struct acpi_driver acpi_sbs_driver = {
.name = "sbs",
if (result)
diff -Nurb linux-2.6.22-570/drivers/acpi/system.c linux-2.6.22-590/drivers/acpi/system.c
--- linux-2.6.22-570/drivers/acpi/system.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/acpi/system.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/acpi/system.c 2008-01-29 22:12:31.000000000 -0500
@@ -39,15 +39,12 @@
#define ACPI_SYSTEM_CLASS "system"
subsys_initcall(acpi_system_init);
diff -Nurb linux-2.6.22-570/drivers/acpi/thermal.c linux-2.6.22-590/drivers/acpi/thermal.c
--- linux-2.6.22-570/drivers/acpi/thermal.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/acpi/thermal.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/acpi/thermal.c 2008-01-29 22:12:31.000000000 -0500
@@ -40,6 +40,7 @@
#include <linux/jiffies.h>
#include <linux/kmod.h>
case ACPI_THERMAL_NOTIFY_DEVICES:
diff -Nurb linux-2.6.22-570/drivers/acpi/utilities/uteval.c linux-2.6.22-590/drivers/acpi/utilities/uteval.c
--- linux-2.6.22-570/drivers/acpi/utilities/uteval.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/acpi/utilities/uteval.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/acpi/utilities/uteval.c 2008-01-29 22:12:31.000000000 -0500
@@ -62,16 +62,13 @@
static char *acpi_interfaces_supported[] = {
/* Operating System Vendor Strings */
diff -Nurb linux-2.6.22-570/drivers/acpi/video.c linux-2.6.22-590/drivers/acpi/video.c
--- linux-2.6.22-570/drivers/acpi/video.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/acpi/video.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/acpi/video.c 2008-01-29 22:12:31.000000000 -0500
@@ -33,6 +33,7 @@
#include <linux/seq_file.h>
/* --------------------------------------------------------------------------
Video Management
-------------------------------------------------------------------------- */
-@@ -626,6 +654,17 @@
+@@ -531,7 +559,6 @@
+
+ static void acpi_video_device_find_cap(struct acpi_video_device *device)
+ {
+- acpi_integer status;
+ acpi_handle h_dummy1;
+ int i;
+ u32 max_level = 0;
+@@ -565,9 +592,9 @@
+ device->cap._DSS = 1;
+ }
+
+- status = acpi_video_device_lcd_query_levels(device, &obj);
++ if (ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
+
+- if (obj && obj->type == ACPI_TYPE_PACKAGE && obj->package.count >= 2) {
++ if (obj->package.count >= 2) {
+ int count = 0;
+ union acpi_object *o;
+
+@@ -588,6 +615,7 @@
+ continue;
+ }
+ br->levels[count] = (u32) o->integer.value;
++
+ if (br->levels[count] > max_level)
+ max_level = br->levels[count];
+ count++;
+@@ -606,9 +634,13 @@
+ }
+ }
+
++ } else {
++ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available LCD brightness level\n"));
++ }
++
+ kfree(obj);
+
+- if (device->cap._BCL && device->cap._BCM && device->cap._BQC){
++ if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){
+ unsigned long tmp;
+ static int count = 0;
+ char *name;
+@@ -626,6 +658,17 @@
kfree(name);
}
return;
}
-@@ -1669,6 +1708,7 @@
+@@ -1669,6 +1712,7 @@
ACPI_DEVICE_NOTIFY,
acpi_video_device_notify);
backlight_device_unregister(device->backlight);
return 0;
}
+diff -Nurb linux-2.6.22-570/drivers/atm/idt77252.c linux-2.6.22-590/drivers/atm/idt77252.c
+--- linux-2.6.22-570/drivers/atm/idt77252.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/atm/idt77252.c 2008-01-29 22:12:31.000000000 -0500
+@@ -3576,7 +3576,7 @@
+ * XXX: <hack>
+ */
+ sprintf(tname, "eth%d", card->index);
+- tmp = dev_get_by_name(tname); /* jhs: was "tmp = dev_get(tname);" */
++ tmp = dev_get_by_name(&init_net, tname); /* jhs: was "tmp = dev_get(tname);" */
+ if (tmp) {
+ memcpy(card->atmdev->esi, tmp->dev_addr, 6);
+
diff -Nurb linux-2.6.22-570/drivers/base/bus.c linux-2.6.22-590/drivers/base/bus.c
--- linux-2.6.22-570/drivers/base/bus.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/base/bus.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/base/bus.c 2008-01-29 22:12:31.000000000 -0500
@@ -562,7 +562,6 @@
bus->drivers_probe_attr.attr.name = "drivers_probe";
retval = bus_create_file(bus, &bus->drivers_autoprobe_attr);
diff -Nurb linux-2.6.22-570/drivers/base/class.c linux-2.6.22-590/drivers/base/class.c
--- linux-2.6.22-570/drivers/base/class.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/base/class.c 2008-03-15 10:35:46.000000000 -0400
-@@ -312,9 +312,6 @@
++++ linux-2.6.22-590/drivers/base/class.c 2008-01-29 22:12:31.000000000 -0500
+@@ -134,6 +134,17 @@
+ }
+ }
+
++static int class_setup_shadowing(struct class *cls)
++{
++ const struct shadow_dir_operations *shadow_ops;
++
++ shadow_ops = cls->shadow_ops;
++ if (!shadow_ops)
++ return 0;
++
++ return sysfs_enable_shadowing(&cls->subsys.kobj, shadow_ops);
++}
++
+ int class_register(struct class * cls)
+ {
+ int error;
+@@ -152,11 +163,22 @@
+ subsys_set_kset(cls, class_subsys);
+
+ error = subsystem_register(&cls->subsys);
+- if (!error) {
+- error = add_class_attrs(class_get(cls));
+- class_put(cls);
+- }
++ if (error)
++ goto out;
++
++ error = class_setup_shadowing(cls);
++ if (error)
++ goto out_unregister;
++
++ error = add_class_attrs(cls);
++ if (error)
++ goto out_unregister;
++
++out:
+ return error;
++out_unregister:
++ subsystem_unregister(&cls->subsys);
++ goto out;
+ }
+
+ void class_unregister(struct class * cls)
+@@ -312,9 +334,6 @@
pr_debug("device class '%s': release.\n", cd->class_id);
if (cd->release)
cd->release(cd);
else if (cls->release)
-@@ -547,6 +544,9 @@
+@@ -547,6 +566,9 @@
return print_dev_t(buf, class_dev->devt);
}
static ssize_t store_uevent(struct class_device *class_dev,
const char *buf, size_t count)
{
-@@ -554,6 +554,9 @@
+@@ -554,6 +576,9 @@
return count;
}
void class_device_initialize(struct class_device *class_dev)
{
kobj_set_kset_s(class_dev, class_obj_subsys);
-@@ -603,34 +606,17 @@
+@@ -603,34 +628,17 @@
&parent_class->subsys.kobj, "subsystem");
if (error)
goto out3;
error = class_device_add_attrs(class_dev);
if (error)
goto out5;
-@@ -671,10 +657,10 @@
+@@ -671,10 +679,10 @@
out6:
class_device_remove_attrs(class_dev);
out5:
out3:
kobject_del(&class_dev->kobj);
out2:
-@@ -774,9 +760,9 @@
+@@ -774,9 +782,9 @@
sysfs_remove_link(&class_dev->kobj, "device");
}
sysfs_remove_link(&class_dev->kobj, "subsystem");
diff -Nurb linux-2.6.22-570/drivers/base/core.c linux-2.6.22-590/drivers/base/core.c
--- linux-2.6.22-570/drivers/base/core.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/base/core.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/base/core.c 2008-01-29 22:12:31.000000000 -0500
@@ -310,6 +310,9 @@
return count;
}
/*
* devices_subsys - structure to be registered with kobject core.
*/
-@@ -637,6 +643,80 @@
+@@ -616,8 +622,14 @@
+ return kobj;
+
+ /* or create a new class-directory at the parent device */
+- return kobject_kset_add_dir(&dev->class->class_dirs,
++ kobj = kobject_kset_add_dir(&dev->class->class_dirs,
+ parent_kobj, dev->class->name);
++
++ /* If we created a new class-directory setup shadowing */
++ if (kobj && dev->class->shadow_ops)
++ sysfs_enable_shadowing(kobj, dev->class->shadow_ops);
++
++ return kobj;
+ }
+
+ if (parent)
+@@ -637,6 +649,82 @@
return 0;
}
+ * If this is not a "fake" compatible device, then create the
+ * symlink from the class to the device.
+ */
-+ if (dev->kobj.parent == &dev->class->subsys.kobj)
-+ return 0;
++ if (dev->kobj.parent != &dev->class->subsys.kobj) {
+ error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
+ dev->bus_id);
+ if (error)
+ goto out_subsys;
++ }
+ /* only bus-device parents get a "device"-link */
+ if (dev->parent && dev->parent->bus) {
+ error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
+ sysfs_remove_link(&dev->kobj, "device");
+#endif
+out_busid:
++ if (dev->kobj.parent != &dev->class->subsys.kobj)
+ sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
+out_subsys:
+ sysfs_remove_link(&dev->kobj, "subsystem");
+#endif
+ sysfs_remove_link(&dev->kobj, "device");
+ }
++ if (dev->kobj.parent != &dev->class->subsys.kobj)
+ sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
+ sysfs_remove_link(&dev->kobj, "subsystem");
+}
/**
* device_add - add device to device hierarchy.
* @dev: device.
-@@ -651,7 +731,6 @@
+@@ -651,7 +739,6 @@
int device_add(struct device *dev)
{
struct device *parent = NULL;
struct class_interface *class_intf;
int error = -EINVAL;
-@@ -681,58 +760,17 @@
+@@ -681,58 +768,17 @@
blocking_notifier_call_chain(&dev->bus->bus_notifier,
BUS_NOTIFY_ADD_DEVICE, dev);
if ((error = device_add_attrs(dev)))
goto AttrsError;
if ((error = device_pm_add(dev)))
-@@ -756,7 +794,6 @@
+@@ -756,7 +802,6 @@
up(&dev->class->sem);
}
Done:
put_device(dev);
return error;
BusError:
-@@ -767,10 +804,10 @@
+@@ -767,10 +812,10 @@
BUS_NOTIFY_DEL_DEVICE, dev);
device_remove_attrs(dev);
AttrsError:
if (dev->class) {
sysfs_remove_link(&dev->kobj, "subsystem");
-@@ -792,7 +829,7 @@
+@@ -792,7 +837,7 @@
}
}
ueventattrError:
attrError:
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
kobject_del(&dev->kobj);
-@@ -869,10 +906,8 @@
+@@ -869,17 +914,15 @@
if (parent)
klist_del(&dev->knode_parent);
if (dev->class) {
sysfs_remove_link(&dev->kobj, "subsystem");
/* If this is not a "fake" compatible device, remove the
-@@ -926,7 +961,7 @@
+ * symlink from the class to the device. */
+ if (dev->kobj.parent != &dev->class->subsys.kobj)
+- sysfs_remove_link(&dev->class->subsys.kobj,
+- dev->bus_id);
++ sysfs_delete_link(&dev->class->subsys.kobj,
++ &dev->kobj, dev->bus_id);
+ if (parent) {
+ #ifdef CONFIG_SYSFS_DEPRECATED
+ char *class_name = make_class_name(dev->class->name,
+@@ -926,7 +969,7 @@
up(&dev->class->sem);
}
}
device_remove_attrs(dev);
bus_remove_device(dev);
-@@ -1155,7 +1190,7 @@
+@@ -1155,7 +1198,7 @@
{
char *old_class_name = NULL;
char *new_class_name = NULL;
int error;
dev = get_device(dev);
-@@ -1169,42 +1204,49 @@
+@@ -1169,42 +1212,46 @@
old_class_name = make_class_name(dev->class->name, &dev->kobj);
#endif
+ strlcpy(old_device_name, dev->bus_id, BUS_ID_SIZE);
strlcpy(dev->bus_id, new_name, BUS_ID_SIZE);
++ if (dev->class && (dev->kobj.parent != &dev->class->subsys.kobj)) {
++ error = sysfs_rename_link(&dev->class->subsys.kobj,
++ &dev->kobj, old_device_name, new_name);
++ if (error)
++ goto out;
++ }
++
error = kobject_rename(&dev->kobj, new_name);
+ if (error) {
+ strlcpy(dev->bus_id, old_device_name, BUS_ID_SIZE);
#ifdef CONFIG_SYSFS_DEPRECATED
if (old_class_name) {
++ error = -ENOMEM;
new_class_name = make_class_name(dev->class->name, &dev->kobj);
- if (new_class_name) {
+- if (new_class_name) {
- sysfs_create_link(&dev->parent->kobj, &dev->kobj,
- new_class_name);
-+ error = sysfs_create_link(&dev->parent->kobj,
-+ &dev->kobj, new_class_name);
-+ if (error)
-+ goto out;
- sysfs_remove_link(&dev->parent->kobj, old_class_name);
- }
- }
- #endif
+- sysfs_remove_link(&dev->parent->kobj, old_class_name);
+- }
+- }
+-#endif
++ if (!new_class_name)
++ goto out;
- if (dev->class) {
+- if (dev->class) {
- sysfs_remove_link(&dev->class->subsys.kobj,
- old_symlink_name);
- sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
-+ sysfs_remove_link(&dev->class->subsys.kobj, old_device_name);
-+ error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
- dev->bus_id);
-+ if (error) {
-+ /* Uh... how to unravel this if restoring can fail? */
-+ dev_err(dev, "%s: sysfs_create_symlink failed (%d)\n",
-+ __FUNCTION__, error);
+- dev->bus_id);
++ error = sysfs_rename_link(&dev->parent->kobj, &dev->kobj,
++ old_class_name, new_class_name);
++ if (error)
++ goto out;
}
-+ }
++#endif
+out:
put_device(dev);
return error;
}
+diff -Nurb linux-2.6.22-570/drivers/base/dd.c linux-2.6.22-590/drivers/base/dd.c
+--- linux-2.6.22-570/drivers/base/dd.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/base/dd.c 2008-01-29 22:12:31.000000000 -0500
+@@ -296,9 +296,8 @@
+ {
+ struct device_driver * drv;
+
+- drv = dev->driver;
++ drv = get_driver(dev->driver);
+ if (drv) {
+- get_driver(drv);
+ driver_sysfs_remove(dev);
+ sysfs_remove_link(&dev->kobj, "driver");
+ klist_remove(&dev->knode_driver);
diff -Nurb linux-2.6.22-570/drivers/base/firmware_class.c linux-2.6.22-590/drivers/base/firmware_class.c
--- linux-2.6.22-570/drivers/base/firmware_class.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/base/firmware_class.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/base/firmware_class.c 2008-01-29 22:12:31.000000000 -0500
@@ -175,7 +175,7 @@
static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store);
.write = firmware_data_write,
diff -Nurb linux-2.6.22-570/drivers/block/acsi_slm.c linux-2.6.22-590/drivers/block/acsi_slm.c
--- linux-2.6.22-570/drivers/block/acsi_slm.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/block/acsi_slm.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/block/acsi_slm.c 2008-01-29 22:12:31.000000000 -0500
@@ -367,7 +367,7 @@
int length;
int end;
return( -ENOMEM );
length = slm_getstats( (char *)page, iminor(node) );
+diff -Nurb linux-2.6.22-570/drivers/block/aoe/aoecmd.c linux-2.6.22-590/drivers/block/aoe/aoecmd.c
+--- linux-2.6.22-570/drivers/block/aoe/aoecmd.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/block/aoe/aoecmd.c 2008-01-29 22:12:31.000000000 -0500
+@@ -9,6 +9,7 @@
+ #include <linux/skbuff.h>
+ #include <linux/netdevice.h>
+ #include <linux/genhd.h>
++#include <net/net_namespace.h>
+ #include <asm/unaligned.h>
+ #include "aoe.h"
+
+@@ -194,7 +195,7 @@
+ sl = sl_tail = NULL;
+
+ read_lock(&dev_base_lock);
+- for_each_netdev(ifp) {
++ for_each_netdev(&init_net, ifp) {
+ dev_hold(ifp);
+ if (!is_aoe_netif(ifp))
+ goto cont;
+diff -Nurb linux-2.6.22-570/drivers/block/aoe/aoenet.c linux-2.6.22-590/drivers/block/aoe/aoenet.c
+--- linux-2.6.22-570/drivers/block/aoe/aoenet.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/block/aoe/aoenet.c 2008-01-29 22:12:31.000000000 -0500
+@@ -8,6 +8,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/netdevice.h>
+ #include <linux/moduleparam.h>
++#include <net/net_namespace.h>
+ #include <asm/unaligned.h>
+ #include "aoe.h"
+
+@@ -114,6 +115,9 @@
+ struct aoe_hdr *h;
+ u32 n;
+
++ if (ifp->nd_net != &init_net)
++ goto exit;
++
+ skb = skb_share_check(skb, GFP_ATOMIC);
+ if (skb == NULL)
+ return 0;
diff -Nurb linux-2.6.22-570/drivers/block/cciss_scsi.c linux-2.6.22-590/drivers/block/cciss_scsi.c
--- linux-2.6.22-570/drivers/block/cciss_scsi.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/block/cciss_scsi.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/block/cciss_scsi.c 2008-01-29 22:12:31.000000000 -0500
@@ -555,7 +555,6 @@
{
struct scsi_cmnd *cmd;
}
diff -Nurb linux-2.6.22-570/drivers/block/loop.c linux-2.6.22-590/drivers/block/loop.c
---- linux-2.6.22-570/drivers/block/loop.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/drivers/block/loop.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/drivers/block/loop.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/drivers/block/loop.c 2008-01-29 22:12:31.000000000 -0500
@@ -68,6 +68,7 @@
#include <linux/loop.h>
#include <linux/compat.h>
while (!kthread_should_stop() || lo->lo_bio) {
diff -Nurb linux-2.6.22-570/drivers/block/pktcdvd.c linux-2.6.22-590/drivers/block/pktcdvd.c
--- linux-2.6.22-570/drivers/block/pktcdvd.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/block/pktcdvd.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/block/pktcdvd.c 2008-01-29 22:12:31.000000000 -0500
@@ -146,8 +146,7 @@
**********************************************************/
DECLARE_WAITQUEUE(wait, current);
diff -Nurb linux-2.6.22-570/drivers/char/apm-emulation.c linux-2.6.22-590/drivers/char/apm-emulation.c
--- linux-2.6.22-570/drivers/char/apm-emulation.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/char/apm-emulation.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/char/apm-emulation.c 2008-01-29 22:12:31.000000000 -0500
@@ -20,6 +20,7 @@
#include <linux/sched.h>
#include <linux/pm.h>
#ifdef CONFIG_PROC_FS
diff -Nurb linux-2.6.22-570/drivers/char/hvc_console.c linux-2.6.22-590/drivers/char/hvc_console.c
--- linux-2.6.22-570/drivers/char/hvc_console.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/char/hvc_console.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/char/hvc_console.c 2008-01-29 22:12:31.000000000 -0500
@@ -674,11 +674,12 @@
* calling hvc_poll() who determines whether a console adapter support
* interrupts.
poll_mask = 0;
diff -Nurb linux-2.6.22-570/drivers/char/ipmi/ipmi_msghandler.c linux-2.6.22-590/drivers/char/ipmi/ipmi_msghandler.c
--- linux-2.6.22-570/drivers/char/ipmi/ipmi_msghandler.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/char/ipmi/ipmi_msghandler.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/char/ipmi/ipmi_msghandler.c 2008-01-29 22:12:31.000000000 -0500
@@ -2171,52 +2171,42 @@
int err;
diff -Nurb linux-2.6.22-570/drivers/char/keyboard.c linux-2.6.22-590/drivers/char/keyboard.c
--- linux-2.6.22-570/drivers/char/keyboard.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/char/keyboard.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/char/keyboard.c 2008-01-29 22:12:31.000000000 -0500
@@ -1150,6 +1150,7 @@
sysrq_down = 0;
if (sysrq_down && down && !rep) {
return;
}
#endif
+diff -Nurb linux-2.6.22-570/drivers/connector/connector.c linux-2.6.22-590/drivers/connector/connector.c
+--- linux-2.6.22-570/drivers/connector/connector.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/connector/connector.c 2008-01-29 22:12:31.000000000 -0500
+@@ -446,7 +446,7 @@
+ dev->id.idx = cn_idx;
+ dev->id.val = cn_val;
+
+- dev->nls = netlink_kernel_create(NETLINK_CONNECTOR,
++ dev->nls = netlink_kernel_create(&init_net, NETLINK_CONNECTOR,
+ CN_NETLINK_USERS + 0xf,
+ dev->input, NULL, THIS_MODULE);
+ if (!dev->nls)
diff -Nurb linux-2.6.22-570/drivers/cpufreq/cpufreq_stats.c linux-2.6.22-590/drivers/cpufreq/cpufreq_stats.c
--- linux-2.6.22-570/drivers/cpufreq/cpufreq_stats.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/cpufreq/cpufreq_stats.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/cpufreq/cpufreq_stats.c 2008-01-29 22:12:31.000000000 -0500
@@ -25,8 +25,7 @@
#define CPUFREQ_STATDEVICE_ATTR(_name,_mode,_show) \
diff -Nurb linux-2.6.22-570/drivers/cpufreq/cpufreq_userspace.c linux-2.6.22-590/drivers/cpufreq/cpufreq_userspace.c
--- linux-2.6.22-570/drivers/cpufreq/cpufreq_userspace.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/cpufreq/cpufreq_userspace.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/cpufreq/cpufreq_userspace.c 2008-01-29 22:12:31.000000000 -0500
@@ -120,7 +120,7 @@
static struct freq_attr freq_attr_scaling_setspeed =
};
diff -Nurb linux-2.6.22-570/drivers/cpufreq/freq_table.c linux-2.6.22-590/drivers/cpufreq/freq_table.c
--- linux-2.6.22-570/drivers/cpufreq/freq_table.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/cpufreq/freq_table.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/cpufreq/freq_table.c 2008-01-29 22:12:31.000000000 -0500
@@ -199,7 +199,6 @@
struct freq_attr cpufreq_freq_attr_scaling_available_freqs = {
.attr = { .name = "scaling_available_frequencies",
};
diff -Nurb linux-2.6.22-570/drivers/cpuidle/Kconfig linux-2.6.22-590/drivers/cpuidle/Kconfig
--- linux-2.6.22-570/drivers/cpuidle/Kconfig 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/cpuidle/Kconfig 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/cpuidle/Kconfig 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,39 @@
+menu "CPU idle PM support"
+
+endmenu
diff -Nurb linux-2.6.22-570/drivers/cpuidle/Makefile linux-2.6.22-590/drivers/cpuidle/Makefile
--- linux-2.6.22-570/drivers/cpuidle/Makefile 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/cpuidle/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/cpuidle/Makefile 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,5 @@
+#
+# Makefile for cpuidle.
+obj-y += cpuidle.o driver.o governor.o sysfs.o governors/
diff -Nurb linux-2.6.22-570/drivers/cpuidle/cpuidle.c linux-2.6.22-590/drivers/cpuidle/cpuidle.c
--- linux-2.6.22-570/drivers/cpuidle/cpuidle.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/cpuidle/cpuidle.c 2008-03-15 10:35:46.000000000 -0400
-@@ -0,0 +1,307 @@
++++ linux-2.6.22-590/drivers/cpuidle/cpuidle.c 2008-01-29 22:12:31.000000000 -0500
+@@ -0,0 +1,306 @@
+/*
+ * cpuidle.c - core cpuidle infrastructure
+ *
+LIST_HEAD(cpuidle_detected_devices);
+static void (*pm_idle_old)(void);
+
-+
+/**
+ * cpuidle_idle_call - the main idle loop
+ *
+core_initcall(cpuidle_init);
diff -Nurb linux-2.6.22-570/drivers/cpuidle/cpuidle.h linux-2.6.22-590/drivers/cpuidle/cpuidle.h
--- linux-2.6.22-570/drivers/cpuidle/cpuidle.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/cpuidle/cpuidle.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/cpuidle/cpuidle.h 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,50 @@
+/*
+ * cpuidle.h - The internal header file
+#endif /* __DRIVER_CPUIDLE_H */
diff -Nurb linux-2.6.22-570/drivers/cpuidle/driver.c linux-2.6.22-590/drivers/cpuidle/driver.c
--- linux-2.6.22-570/drivers/cpuidle/driver.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/cpuidle/driver.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/cpuidle/driver.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,276 @@
+/*
+ * driver.c - driver support
+
diff -Nurb linux-2.6.22-570/drivers/cpuidle/governor.c linux-2.6.22-590/drivers/cpuidle/governor.c
--- linux-2.6.22-570/drivers/cpuidle/governor.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/cpuidle/governor.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/cpuidle/governor.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,160 @@
+/*
+ * governor.c - governor support
+EXPORT_SYMBOL_GPL(cpuidle_unregister_governor);
diff -Nurb linux-2.6.22-570/drivers/cpuidle/governors/Makefile linux-2.6.22-590/drivers/cpuidle/governors/Makefile
--- linux-2.6.22-570/drivers/cpuidle/governors/Makefile 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/cpuidle/governors/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/cpuidle/governors/Makefile 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,6 @@
+#
+# Makefile for cpuidle governors.
+obj-$(CONFIG_CPU_IDLE_GOV_MENU) += menu.o
diff -Nurb linux-2.6.22-570/drivers/cpuidle/governors/ladder.c linux-2.6.22-590/drivers/cpuidle/governors/ladder.c
--- linux-2.6.22-570/drivers/cpuidle/governors/ladder.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/cpuidle/governors/ladder.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/cpuidle/governors/ladder.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,227 @@
+/*
+ * ladder.c - the residency ladder algorithm
+module_exit(exit_ladder);
diff -Nurb linux-2.6.22-570/drivers/cpuidle/governors/menu.c linux-2.6.22-590/drivers/cpuidle/governors/menu.c
--- linux-2.6.22-570/drivers/cpuidle/governors/menu.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/cpuidle/governors/menu.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/cpuidle/governors/menu.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,152 @@
+/*
+ * menu.c - the menu idle governor
+module_exit(exit_menu);
diff -Nurb linux-2.6.22-570/drivers/cpuidle/sysfs.c linux-2.6.22-590/drivers/cpuidle/sysfs.c
--- linux-2.6.22-570/drivers/cpuidle/sysfs.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/cpuidle/sysfs.c 2008-03-15 10:35:46.000000000 -0400
-@@ -0,0 +1,373 @@
++++ linux-2.6.22-590/drivers/cpuidle/sysfs.c 2008-01-29 22:12:31.000000000 -0500
+@@ -0,0 +1,393 @@
+/*
+ * sysfs.c - sysfs support
+ *
+
+#include "cpuidle.h"
+
++static unsigned int sysfs_switch;
++static int __init cpuidle_sysfs_setup(char *unused)
++{
++ sysfs_switch = 1;
++ return 1;
++}
++__setup("cpuidle_sysfs_switch", cpuidle_sysfs_setup);
++
+static ssize_t show_available_drivers(struct sys_device *dev, char *buf)
+{
+ ssize_t i = 0;
+ return count;
+}
+
++static SYSDEV_ATTR(current_driver_ro, 0444, show_current_driver, NULL);
++static SYSDEV_ATTR(current_governor_ro, 0444, show_current_governor, NULL);
++
++static struct attribute *cpuclass_default_attrs[] = {
++ &attr_current_driver_ro.attr,
++ &attr_current_governor_ro.attr,
++ NULL
++};
++
+static SYSDEV_ATTR(available_drivers, 0444, show_available_drivers, NULL);
+static SYSDEV_ATTR(available_governors, 0444, show_available_governors, NULL);
+static SYSDEV_ATTR(current_driver, 0644, show_current_driver,
+static SYSDEV_ATTR(current_governor, 0644, show_current_governor,
+ store_current_governor);
+
-+static struct attribute *cpuclass_default_attrs[] = {
++static struct attribute *cpuclass_switch_attrs[] = {
+ &attr_available_drivers.attr,
+ &attr_available_governors.attr,
+ &attr_current_driver.attr,
+ */
+int cpuidle_add_class_sysfs(struct sysdev_class *cls)
+{
++ if (sysfs_switch)
++ cpuclass_attr_group.attrs = cpuclass_switch_attrs;
++
+ return sysfs_create_group(&cls->kset.kobj, &cpuclass_attr_group);
+}
+
+ */
+int cpuidle_add_driver_sysfs(struct cpuidle_device *device)
+{
-+ int i, ret;
++ int i, ret = -ENOMEM;
+ struct cpuidle_state_kobj *kobj;
+
+ /* state statistics */
+}
diff -Nurb linux-2.6.22-570/drivers/dma/Kconfig linux-2.6.22-590/drivers/dma/Kconfig
--- linux-2.6.22-570/drivers/dma/Kconfig 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/dma/Kconfig 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/dma/Kconfig 2008-01-29 22:12:31.000000000 -0500
@@ -8,8 +8,8 @@
config DMA_ENGINE
bool "Support for DMA engines"
endmenu
diff -Nurb linux-2.6.22-570/drivers/dma/Makefile linux-2.6.22-590/drivers/dma/Makefile
--- linux-2.6.22-570/drivers/dma/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/dma/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/dma/Makefile 2008-01-29 22:12:31.000000000 -0500
@@ -1,3 +1,4 @@
obj-$(CONFIG_DMA_ENGINE) += dmaengine.o
obj-$(CONFIG_NET_DMA) += iovlock.o
+obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
diff -Nurb linux-2.6.22-570/drivers/dma/dmaengine.c linux-2.6.22-590/drivers/dma/dmaengine.c
--- linux-2.6.22-570/drivers/dma/dmaengine.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/dma/dmaengine.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/dma/dmaengine.c 2008-01-29 22:12:31.000000000 -0500
@@ -37,11 +37,11 @@
* Each device has a channels list, which runs unlocked but is never modified
* once the device is registered, it's just setup by the driver.
mutex_init(&dma_list_mutex);
diff -Nurb linux-2.6.22-570/drivers/dma/ioatdma.c linux-2.6.22-590/drivers/dma/ioatdma.c
--- linux-2.6.22-570/drivers/dma/ioatdma.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/dma/ioatdma.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/dma/ioatdma.c 2008-01-29 22:12:31.000000000 -0500
@@ -39,6 +39,7 @@
#define to_ioat_chan(chan) container_of(chan, struct ioat_dma_chan, common)
#define to_ioat_device(dev) container_of(dev, struct ioat_device, common)
diff -Nurb linux-2.6.22-570/drivers/dma/ioatdma.h linux-2.6.22-590/drivers/dma/ioatdma.h
--- linux-2.6.22-570/drivers/dma/ioatdma.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/dma/ioatdma.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/dma/ioatdma.h 2008-01-29 22:12:31.000000000 -0500
@@ -30,9 +30,6 @@
#define IOAT_LOW_COMPLETION_MASK 0xffffffc0
-
diff -Nurb linux-2.6.22-570/drivers/dma/iop-adma.c linux-2.6.22-590/drivers/dma/iop-adma.c
--- linux-2.6.22-570/drivers/dma/iop-adma.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/dma/iop-adma.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/dma/iop-adma.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,1465 @@
+/*
+ * offload engine driver for the Intel Xscale series of i/o processors
+MODULE_LICENSE("GPL");
diff -Nurb linux-2.6.22-570/drivers/edac/edac_mc.c linux-2.6.22-590/drivers/edac/edac_mc.c
--- linux-2.6.22-570/drivers/edac/edac_mc.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/edac/edac_mc.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/edac/edac_mc.c 2008-01-29 22:12:31.000000000 -0500
@@ -1906,6 +1906,7 @@
static int edac_kernel_thread(void *arg)
diff -Nurb linux-2.6.22-570/drivers/firmware/dcdbas.c linux-2.6.22-590/drivers/firmware/dcdbas.c
--- linux-2.6.22-570/drivers/firmware/dcdbas.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/firmware/dcdbas.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/firmware/dcdbas.c 2008-01-29 22:12:31.000000000 -0500
@@ -149,8 +149,9 @@
return count;
}
diff -Nurb linux-2.6.22-570/drivers/firmware/dcdbas.h linux-2.6.22-590/drivers/firmware/dcdbas.h
--- linux-2.6.22-570/drivers/firmware/dcdbas.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/firmware/dcdbas.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/firmware/dcdbas.h 2008-01-29 22:12:31.000000000 -0500
@@ -67,8 +67,7 @@
#define DCDBAS_BIN_ATTR_RW(_name) \
struct bin_attribute bin_attr_##_name = { \
}
diff -Nurb linux-2.6.22-570/drivers/firmware/dell_rbu.c linux-2.6.22-590/drivers/firmware/dell_rbu.c
--- linux-2.6.22-570/drivers/firmware/dell_rbu.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/firmware/dell_rbu.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/firmware/dell_rbu.c 2008-01-29 22:12:31.000000000 -0500
@@ -543,8 +543,9 @@
return ret_count;
}
};
diff -Nurb linux-2.6.22-570/drivers/firmware/edd.c linux-2.6.22-590/drivers/firmware/edd.c
--- linux-2.6.22-570/drivers/firmware/edd.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/firmware/edd.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/firmware/edd.c 2008-01-29 22:12:31.000000000 -0500
@@ -74,7 +74,7 @@
#define EDD_DEVICE_ATTR(_name,_mode,_show,_test) \
};
diff -Nurb linux-2.6.22-570/drivers/firmware/efivars.c linux-2.6.22-590/drivers/firmware/efivars.c
--- linux-2.6.22-570/drivers/firmware/efivars.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/firmware/efivars.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/firmware/efivars.c 2008-01-29 22:12:31.000000000 -0500
@@ -131,21 +131,21 @@
#define EFI_ATTR(_name, _mode, _show, _store) \
.store = _store, \
};
diff -Nurb linux-2.6.22-570/drivers/i2c/chips/eeprom.c linux-2.6.22-590/drivers/i2c/chips/eeprom.c
---- linux-2.6.22-570/drivers/i2c/chips/eeprom.c 2008-03-15 10:34:19.000000000 -0400
-+++ linux-2.6.22-590/drivers/i2c/chips/eeprom.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/drivers/i2c/chips/eeprom.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/drivers/i2c/chips/eeprom.c 2008-01-29 22:12:31.000000000 -0500
@@ -110,7 +110,8 @@
mutex_unlock(&data->update_lock);
}
.read = eeprom_read,
diff -Nurb linux-2.6.22-570/drivers/i2c/chips/max6875.c linux-2.6.22-590/drivers/i2c/chips/max6875.c
--- linux-2.6.22-570/drivers/i2c/chips/max6875.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/i2c/chips/max6875.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/i2c/chips/max6875.c 2008-01-29 22:12:31.000000000 -0500
@@ -125,8 +125,9 @@
mutex_unlock(&data->update_lock);
}
.size = USER_EEPROM_SIZE,
.read = max6875_read,
diff -Nurb linux-2.6.22-570/drivers/ieee1394/ieee1394_core.c linux-2.6.22-590/drivers/ieee1394/ieee1394_core.c
---- linux-2.6.22-570/drivers/ieee1394/ieee1394_core.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/drivers/ieee1394/ieee1394_core.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/drivers/ieee1394/ieee1394_core.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/drivers/ieee1394/ieee1394_core.c 2008-01-29 22:12:31.000000000 -0500
@@ -30,6 +30,7 @@
#include <linux/moduleparam.h>
#include <linux/bitops.h>
INIT_LIST_HEAD(&tmp);
diff -Nurb linux-2.6.22-570/drivers/ieee1394/nodemgr.c linux-2.6.22-590/drivers/ieee1394/nodemgr.c
--- linux-2.6.22-570/drivers/ieee1394/nodemgr.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/ieee1394/nodemgr.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/ieee1394/nodemgr.c 2008-01-29 22:12:31.000000000 -0500
@@ -1669,6 +1669,7 @@
unsigned int g, generation = 0;
int i, reset_cycles = 0;
nodemgr_create_host_dev_files(host);
diff -Nurb linux-2.6.22-570/drivers/ieee1394/sbp2.c linux-2.6.22-590/drivers/ieee1394/sbp2.c
---- linux-2.6.22-570/drivers/ieee1394/sbp2.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/drivers/ieee1394/sbp2.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/drivers/ieee1394/sbp2.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/drivers/ieee1394/sbp2.c 2008-01-29 22:12:31.000000000 -0500
@@ -1505,69 +1505,6 @@
}
}
SCpnt->sc_data_direction);
sbp2_link_orb_command(lu, cmd);
+diff -Nurb linux-2.6.22-570/drivers/infiniband/core/addr.c linux-2.6.22-590/drivers/infiniband/core/addr.c
+--- linux-2.6.22-570/drivers/infiniband/core/addr.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/infiniband/core/addr.c 2008-01-29 22:12:31.000000000 -0500
+@@ -110,7 +110,7 @@
+ __be32 ip = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
+ int ret;
+
+- dev = ip_dev_find(ip);
++ dev = ip_dev_find(&init_net, ip);
+ if (!dev)
+ return -EADDRNOTAVAIL;
+
+@@ -157,6 +157,7 @@
+ u32 dst_ip = dst_in->sin_addr.s_addr;
+
+ memset(&fl, 0, sizeof fl);
++ fl.fl_net = &init_net;
+ fl.nl_u.ip4_u.daddr = dst_ip;
+ if (ip_route_output_key(&rt, &fl))
+ return;
+@@ -178,6 +179,7 @@
+ int ret;
+
+ memset(&fl, 0, sizeof fl);
++ fl.fl_net = &init_net;
+ fl.nl_u.ip4_u.daddr = dst_ip;
+ fl.nl_u.ip4_u.saddr = src_ip;
+ ret = ip_route_output_key(&rt, &fl);
+@@ -262,7 +264,7 @@
+ __be32 dst_ip = dst_in->sin_addr.s_addr;
+ int ret;
+
+- dev = ip_dev_find(dst_ip);
++ dev = ip_dev_find(&init_net, dst_ip);
+ if (!dev)
+ return -EADDRNOTAVAIL;
+
+diff -Nurb linux-2.6.22-570/drivers/infiniband/core/cma.c linux-2.6.22-590/drivers/infiniband/core/cma.c
+--- linux-2.6.22-570/drivers/infiniband/core/cma.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/infiniband/core/cma.c 2008-01-29 22:12:31.000000000 -0500
+@@ -1267,7 +1267,7 @@
+ atomic_inc(&conn_id->dev_remove);
+ conn_id->state = CMA_CONNECT;
+
+- dev = ip_dev_find(iw_event->local_addr.sin_addr.s_addr);
++ dev = ip_dev_find(&init_net, iw_event->local_addr.sin_addr.s_addr);
+ if (!dev) {
+ ret = -EADDRNOTAVAIL;
+ cma_enable_remove(conn_id);
+@@ -1880,18 +1880,18 @@
+ if (ret)
+ goto err1;
+
+- if (port > sysctl_local_port_range[1]) {
+- if (next_port != sysctl_local_port_range[0]) {
++ if (port > init_net.sysctl_local_port_range[1]) {
++ if (next_port != init_net.sysctl_local_port_range[0]) {
+ idr_remove(ps, port);
+- next_port = sysctl_local_port_range[0];
++ next_port = init_net.sysctl_local_port_range[0];
+ goto retry;
+ }
+ ret = -EADDRNOTAVAIL;
+ goto err2;
+ }
+
+- if (port == sysctl_local_port_range[1])
+- next_port = sysctl_local_port_range[0];
++ if (port == init_net.sysctl_local_port_range[1])
++ next_port = init_net.sysctl_local_port_range[0];
+ else
+ next_port = port + 1;
+
+@@ -2774,8 +2774,9 @@
+
+ get_random_bytes(&next_port, sizeof next_port);
+ next_port = ((unsigned int) next_port %
+- (sysctl_local_port_range[1] - sysctl_local_port_range[0])) +
+- sysctl_local_port_range[0];
++ (init_net.sysctl_local_port_range[1] -
++ init_net.sysctl_local_port_range[0])) +
++ init_net.sysctl_local_port_range[0];
+ cma_wq = create_singlethread_workqueue("rdma_cm");
+ if (!cma_wq)
+ return -ENOMEM;
diff -Nurb linux-2.6.22-570/drivers/infiniband/core/sysfs.c linux-2.6.22-590/drivers/infiniband/core/sysfs.c
--- linux-2.6.22-570/drivers/infiniband/core/sysfs.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/infiniband/core/sysfs.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/infiniband/core/sysfs.c 2008-01-29 22:12:31.000000000 -0500
@@ -479,7 +479,6 @@
element->attr.attr.name = element->name;
diff -Nurb linux-2.6.22-570/drivers/infiniband/ulp/iser/iscsi_iser.c linux-2.6.22-590/drivers/infiniband/ulp/iser/iscsi_iser.c
--- linux-2.6.22-570/drivers/infiniband/ulp/iser/iscsi_iser.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/infiniband/ulp/iser/iscsi_iser.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/infiniband/ulp/iser/iscsi_iser.c 2008-01-29 22:12:31.000000000 -0500
@@ -134,19 +134,9 @@
{
struct iscsi_iser_conn *iser_conn = ctask->conn->dd_data;
.get_stats = iscsi_iser_conn_get_stats,
diff -Nurb linux-2.6.22-570/drivers/infiniband/ulp/iser/iscsi_iser.h linux-2.6.22-590/drivers/infiniband/ulp/iser/iscsi_iser.h
--- linux-2.6.22-570/drivers/infiniband/ulp/iser/iscsi_iser.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/infiniband/ulp/iser/iscsi_iser.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/infiniband/ulp/iser/iscsi_iser.h 2008-01-29 22:12:31.000000000 -0500
@@ -98,7 +98,7 @@
#define ISER_MAX_TX_MISC_PDUS 6 /* NOOP_OUT(2), TEXT(1), *
* SCSI_TMFUNC(2), LOGOUT(1) */
ISER_MAX_RX_MISC_PDUS)
diff -Nurb linux-2.6.22-570/drivers/infiniband/ulp/iser/iser_initiator.c linux-2.6.22-590/drivers/infiniband/ulp/iser/iser_initiator.c
--- linux-2.6.22-570/drivers/infiniband/ulp/iser/iser_initiator.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/infiniband/ulp/iser/iser_initiator.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/infiniband/ulp/iser/iser_initiator.c 2008-01-29 22:12:31.000000000 -0500
@@ -351,18 +351,12 @@
else
data_buf = &iser_ctask->data[ISER_DIR_OUT];
err = iser_prepare_read_cmd(ctask, edtl);
diff -Nurb linux-2.6.22-570/drivers/infiniband/ulp/iser/iser_verbs.c linux-2.6.22-590/drivers/infiniband/ulp/iser/iser_verbs.c
--- linux-2.6.22-570/drivers/infiniband/ulp/iser/iser_verbs.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/infiniband/ulp/iser/iser_verbs.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/infiniband/ulp/iser/iser_verbs.c 2008-01-29 22:12:31.000000000 -0500
@@ -155,8 +155,8 @@
params.max_pages_per_fmr = ISCSI_ISER_SG_TABLESIZE + 1;
/* make the pool size twice the max number of SCSI commands *
params.access = (IB_ACCESS_LOCAL_WRITE |
diff -Nurb linux-2.6.22-570/drivers/infiniband/ulp/srp/ib_srp.c linux-2.6.22-590/drivers/infiniband/ulp/srp/ib_srp.c
--- linux-2.6.22-570/drivers/infiniband/ulp/srp/ib_srp.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/infiniband/ulp/srp/ib_srp.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/infiniband/ulp/srp/ib_srp.c 2008-01-29 22:12:31.000000000 -0500
@@ -455,10 +455,7 @@
struct srp_target_port *target,
struct srp_request *req)
scmnd->host_scribble = (void *) -1L;
diff -Nurb linux-2.6.22-570/drivers/infiniband/ulp/srp/ib_srp.h linux-2.6.22-590/drivers/infiniband/ulp/srp/ib_srp.h
--- linux-2.6.22-570/drivers/infiniband/ulp/srp/ib_srp.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/infiniband/ulp/srp/ib_srp.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/infiniband/ulp/srp/ib_srp.h 2008-01-29 22:12:31.000000000 -0500
@@ -106,11 +106,6 @@
struct srp_iu *cmd;
struct srp_iu *tsk_mgmt;
u8 cmd_done;
diff -Nurb linux-2.6.22-570/drivers/input/gameport/gameport.c linux-2.6.22-590/drivers/input/gameport/gameport.c
--- linux-2.6.22-570/drivers/input/gameport/gameport.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/input/gameport/gameport.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/input/gameport/gameport.c 2008-01-29 22:12:31.000000000 -0500
@@ -445,6 +445,7 @@
static int gameport_thread(void *nothing)
wait_event_interruptible(gameport_wait,
diff -Nurb linux-2.6.22-570/drivers/input/mouse/psmouse.h linux-2.6.22-590/drivers/input/mouse/psmouse.h
--- linux-2.6.22-570/drivers/input/mouse/psmouse.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/input/mouse/psmouse.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/input/mouse/psmouse.h 2008-01-29 22:12:31.000000000 -0500
@@ -118,7 +118,6 @@
.attr = { \
.name = __stringify(_name), \
.store = psmouse_attr_set_helper, \
diff -Nurb linux-2.6.22-570/drivers/input/serio/serio.c linux-2.6.22-590/drivers/input/serio/serio.c
--- linux-2.6.22-570/drivers/input/serio/serio.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/input/serio/serio.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/input/serio/serio.c 2008-01-29 22:12:31.000000000 -0500
@@ -384,6 +384,7 @@
static int serio_thread(void *nothing)
wait_event_interruptible(serio_wait,
diff -Nurb linux-2.6.22-570/drivers/input/touchscreen/ucb1400_ts.c linux-2.6.22-590/drivers/input/touchscreen/ucb1400_ts.c
--- linux-2.6.22-570/drivers/input/touchscreen/ucb1400_ts.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/input/touchscreen/ucb1400_ts.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/input/touchscreen/ucb1400_ts.c 2008-01-29 22:12:31.000000000 -0500
@@ -292,6 +292,7 @@
sched_setscheduler(tsk, SCHED_FIFO, ¶m);
while (!kthread_should_stop()) {
unsigned int x, y, p;
long timeout;
+diff -Nurb linux-2.6.22-570/drivers/isdn/divert/divert_procfs.c linux-2.6.22-590/drivers/isdn/divert/divert_procfs.c
+--- linux-2.6.22-570/drivers/isdn/divert/divert_procfs.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/isdn/divert/divert_procfs.c 2008-01-29 22:12:31.000000000 -0500
+@@ -17,6 +17,7 @@
+ #include <linux/fs.h>
+ #endif
+ #include <linux/isdnif.h>
++#include <net/net_namespace.h>
+ #include "isdn_divert.h"
+
+
+@@ -284,12 +285,12 @@
+ init_waitqueue_head(&rd_queue);
+
+ #ifdef CONFIG_PROC_FS
+- isdn_proc_entry = proc_mkdir("net/isdn", NULL);
++ isdn_proc_entry = proc_mkdir("isdn", init_net.proc_net);
+ if (!isdn_proc_entry)
+ return (-1);
+ isdn_divert_entry = create_proc_entry("divert", S_IFREG | S_IRUGO, isdn_proc_entry);
+ if (!isdn_divert_entry) {
+- remove_proc_entry("net/isdn", NULL);
++ remove_proc_entry("isdn", init_net.proc_net);
+ return (-1);
+ }
+ isdn_divert_entry->proc_fops = &isdn_fops;
+@@ -309,7 +310,7 @@
+
+ #ifdef CONFIG_PROC_FS
+ remove_proc_entry("divert", isdn_proc_entry);
+- remove_proc_entry("net/isdn", NULL);
++ remove_proc_entry("isdn", init_net.proc_net);
+ #endif /* CONFIG_PROC_FS */
+
+ return (0);
+diff -Nurb linux-2.6.22-570/drivers/isdn/hardware/eicon/diva_didd.c linux-2.6.22-590/drivers/isdn/hardware/eicon/diva_didd.c
+--- linux-2.6.22-570/drivers/isdn/hardware/eicon/diva_didd.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/isdn/hardware/eicon/diva_didd.c 2008-01-29 22:12:31.000000000 -0500
+@@ -15,6 +15,7 @@
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/proc_fs.h>
++#include <net/net_namespace.h>
+
+ #include "platform.h"
+ #include "di_defs.h"
+@@ -86,7 +87,7 @@
+
+ static int DIVA_INIT_FUNCTION create_proc(void)
+ {
+- proc_net_eicon = proc_mkdir("net/eicon", NULL);
++ proc_net_eicon = proc_mkdir("eicon", init_net.proc_net);
+
+ if (proc_net_eicon) {
+ if ((proc_didd =
+@@ -102,7 +103,7 @@
+ static void remove_proc(void)
+ {
+ remove_proc_entry(DRIVERLNAME, proc_net_eicon);
+- remove_proc_entry("net/eicon", NULL);
++ remove_proc_entry("eicon", init_net.proc_net);
+ }
+
+ static int DIVA_INIT_FUNCTION divadidd_init(void)
+diff -Nurb linux-2.6.22-570/drivers/isdn/hysdn/hysdn_procconf.c linux-2.6.22-590/drivers/isdn/hysdn/hysdn_procconf.c
+--- linux-2.6.22-570/drivers/isdn/hysdn/hysdn_procconf.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/isdn/hysdn/hysdn_procconf.c 2008-01-29 22:12:31.000000000 -0500
+@@ -392,7 +392,7 @@
+ hysdn_card *card;
+ unsigned char conf_name[20];
+
+- hysdn_proc_entry = proc_mkdir(PROC_SUBDIR_NAME, proc_net);
++ hysdn_proc_entry = proc_mkdir(PROC_SUBDIR_NAME, init_net.proc_net);
+ if (!hysdn_proc_entry) {
+ printk(KERN_ERR "HYSDN: unable to create hysdn subdir\n");
+ return (-1);
+@@ -437,5 +437,5 @@
+ card = card->next; /* point to next card */
+ }
+
+- remove_proc_entry(PROC_SUBDIR_NAME, proc_net);
++ remove_proc_entry(PROC_SUBDIR_NAME, init_net.proc_net);
+ }
diff -Nurb linux-2.6.22-570/drivers/macintosh/therm_adt746x.c linux-2.6.22-590/drivers/macintosh/therm_adt746x.c
--- linux-2.6.22-570/drivers/macintosh/therm_adt746x.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/macintosh/therm_adt746x.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/macintosh/therm_adt746x.c 2008-01-29 22:12:31.000000000 -0500
@@ -335,6 +335,7 @@
{
struct thermostat* th = arg;
msleep_interruptible(2000);
diff -Nurb linux-2.6.22-570/drivers/macintosh/therm_pm72.c linux-2.6.22-590/drivers/macintosh/therm_pm72.c
--- linux-2.6.22-570/drivers/macintosh/therm_pm72.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/macintosh/therm_pm72.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/macintosh/therm_pm72.c 2008-01-29 22:12:31.000000000 -0500
@@ -1770,7 +1770,8 @@
"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
NULL };
diff -Nurb linux-2.6.22-570/drivers/macintosh/windfarm_core.c linux-2.6.22-590/drivers/macintosh/windfarm_core.c
--- linux-2.6.22-570/drivers/macintosh/windfarm_core.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/macintosh/windfarm_core.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/macintosh/windfarm_core.c 2008-01-29 22:12:31.000000000 -0500
@@ -80,7 +80,8 @@
"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
NULL };
new_sr->attr.store = NULL;
diff -Nurb linux-2.6.22-570/drivers/md/Kconfig linux-2.6.22-590/drivers/md/Kconfig
--- linux-2.6.22-570/drivers/md/Kconfig 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/md/Kconfig 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/md/Kconfig 2008-01-29 22:12:31.000000000 -0500
@@ -109,6 +109,8 @@
config MD_RAID456
tristate "RAID-4/RAID-5/RAID-6 mode"
endif
diff -Nurb linux-2.6.22-570/drivers/md/Makefile linux-2.6.22-590/drivers/md/Makefile
--- linux-2.6.22-570/drivers/md/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/md/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/md/Makefile 2008-01-29 22:12:31.000000000 -0500
@@ -17,7 +17,7 @@
hostprogs-y := mktables
$(obj)/raid6int1.c: $(src)/raid6int.uc $(src)/unroll.pl FORCE
diff -Nurb linux-2.6.22-570/drivers/md/dm-netlink.c linux-2.6.22-590/drivers/md/dm-netlink.c
--- linux-2.6.22-570/drivers/md/dm-netlink.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/md/dm-netlink.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/md/dm-netlink.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,103 @@
+/*
+ * Device Mapper Netlink Support (dm-netlink)
+}
diff -Nurb linux-2.6.22-570/drivers/md/dm-netlink.h linux-2.6.22-590/drivers/md/dm-netlink.h
--- linux-2.6.22-570/drivers/md/dm-netlink.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/md/dm-netlink.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/md/dm-netlink.h 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,50 @@
+/*
+ * Device Mapper Netlink Support
+
+#endif /* DM_NETLINK_H */
diff -Nurb linux-2.6.22-570/drivers/md/dm.c linux-2.6.22-590/drivers/md/dm.c
---- linux-2.6.22-570/drivers/md/dm.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/drivers/md/dm.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/drivers/md/dm.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/drivers/md/dm.c 2008-01-29 22:12:31.000000000 -0500
@@ -7,6 +7,7 @@
#include "dm.h"
static int __init dm_init(void)
diff -Nurb linux-2.6.22-570/drivers/md/md.c linux-2.6.22-590/drivers/md/md.c
--- linux-2.6.22-570/drivers/md/md.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/md/md.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/md/md.c 2008-01-29 22:12:31.000000000 -0500
@@ -4642,7 +4642,6 @@
* many dirty RAID5 blocks.
*/
static int get_ro(char *buffer, struct kernel_param *kp)
diff -Nurb linux-2.6.22-570/drivers/md/raid5.c linux-2.6.22-590/drivers/md/raid5.c
--- linux-2.6.22-570/drivers/md/raid5.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/md/raid5.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/md/raid5.c 2008-01-29 22:12:31.000000000 -0500
@@ -52,6 +52,7 @@
#include "raid6.h"
-module_exit(xor_exit);
diff -Nurb linux-2.6.22-570/drivers/media/dvb/dvb-core/dvb_frontend.c linux-2.6.22-590/drivers/media/dvb/dvb-core/dvb_frontend.c
--- linux-2.6.22-570/drivers/media/dvb/dvb-core/dvb_frontend.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/media/dvb/dvb-core/dvb_frontend.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/media/dvb/dvb-core/dvb_frontend.c 2008-01-29 22:12:31.000000000 -0500
@@ -523,6 +523,7 @@
dvb_frontend_init(fe);
restart:
diff -Nurb linux-2.6.22-570/drivers/media/video/cx88/cx88-tvaudio.c linux-2.6.22-590/drivers/media/video/cx88/cx88-tvaudio.c
--- linux-2.6.22-570/drivers/media/video/cx88/cx88-tvaudio.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/media/video/cx88/cx88-tvaudio.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/media/video/cx88/cx88-tvaudio.c 2008-01-29 22:12:31.000000000 -0500
@@ -906,6 +906,7 @@
u32 mode = 0;
if (kthread_should_stop())
diff -Nurb linux-2.6.22-570/drivers/media/video/msp3400-kthreads.c linux-2.6.22-590/drivers/media/video/msp3400-kthreads.c
--- linux-2.6.22-570/drivers/media/video/msp3400-kthreads.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/media/video/msp3400-kthreads.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/media/video/msp3400-kthreads.c 2008-01-29 22:12:31.000000000 -0500
@@ -23,6 +23,7 @@
#include <linux/module.h>
#include <linux/slab.h>
msp_sleep(state, -1);
diff -Nurb linux-2.6.22-570/drivers/media/video/tvaudio.c linux-2.6.22-590/drivers/media/video/tvaudio.c
--- linux-2.6.22-570/drivers/media/video/tvaudio.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/media/video/tvaudio.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/media/video/tvaudio.c 2008-01-29 22:12:31.000000000 -0500
@@ -271,7 +271,7 @@
struct CHIPDESC *desc = chiplist + chip->type;
if (!kthread_should_stop())
diff -Nurb linux-2.6.22-570/drivers/media/video/video-buf-dvb.c linux-2.6.22-590/drivers/media/video/video-buf-dvb.c
--- linux-2.6.22-570/drivers/media/video/video-buf-dvb.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/media/video/video-buf-dvb.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/media/video/video-buf-dvb.c 2008-01-29 22:12:31.000000000 -0500
@@ -47,6 +47,7 @@
int err;
for (;;) {
diff -Nurb linux-2.6.22-570/drivers/media/video/vivi.c linux-2.6.22-590/drivers/media/video/vivi.c
--- linux-2.6.22-570/drivers/media/video/vivi.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/media/video/vivi.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/media/video/vivi.c 2008-01-29 22:12:31.000000000 -0500
@@ -573,6 +573,7 @@
dprintk(1,"thread started\n");
-#endif /* _LINUX_COMPAT_H */
diff -Nurb linux-2.6.22-570/drivers/message/fusion/lsi/mpi.h linux-2.6.22-590/drivers/message/fusion/lsi/mpi.h
--- linux-2.6.22-570/drivers/message/fusion/lsi/mpi.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/message/fusion/lsi/mpi.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/message/fusion/lsi/mpi.h 2008-01-29 22:12:31.000000000 -0500
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2000-2006 LSI Logic Corporation.
#define MPI_HEADER_VERSION_UNIT_SHIFT (8)
diff -Nurb linux-2.6.22-570/drivers/message/fusion/lsi/mpi_cnfg.h linux-2.6.22-590/drivers/message/fusion/lsi/mpi_cnfg.h
--- linux-2.6.22-570/drivers/message/fusion/lsi/mpi_cnfg.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/message/fusion/lsi/mpi_cnfg.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/message/fusion/lsi/mpi_cnfg.h 2008-01-29 22:12:31.000000000 -0500
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2000-2006 LSI Logic Corporation.
diff -Nurb linux-2.6.22-570/drivers/message/fusion/lsi/mpi_history.txt linux-2.6.22-590/drivers/message/fusion/lsi/mpi_history.txt
--- linux-2.6.22-570/drivers/message/fusion/lsi/mpi_history.txt 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/message/fusion/lsi/mpi_history.txt 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/message/fusion/lsi/mpi_history.txt 2008-01-29 22:12:31.000000000 -0500
@@ -3,28 +3,28 @@
MPI Header File Change History
==============================
-
diff -Nurb linux-2.6.22-570/drivers/message/fusion/lsi/mpi_init.h linux-2.6.22-590/drivers/message/fusion/lsi/mpi_init.h
--- linux-2.6.22-570/drivers/message/fusion/lsi/mpi_init.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/message/fusion/lsi/mpi_init.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/message/fusion/lsi/mpi_init.h 2008-01-29 22:12:31.000000000 -0500
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2000-2006 LSI Logic Corporation.
{
diff -Nurb linux-2.6.22-570/drivers/message/fusion/lsi/mpi_ioc.h linux-2.6.22-590/drivers/message/fusion/lsi/mpi_ioc.h
--- linux-2.6.22-570/drivers/message/fusion/lsi/mpi_ioc.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/message/fusion/lsi/mpi_ioc.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/message/fusion/lsi/mpi_ioc.h 2008-01-29 22:12:31.000000000 -0500
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2000-2006 LSI Logic Corporation.
{
diff -Nurb linux-2.6.22-570/drivers/message/fusion/lsi/mpi_raid.h linux-2.6.22-590/drivers/message/fusion/lsi/mpi_raid.h
--- linux-2.6.22-570/drivers/message/fusion/lsi/mpi_raid.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/message/fusion/lsi/mpi_raid.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/message/fusion/lsi/mpi_raid.h 2008-01-29 22:12:31.000000000 -0500
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2001-2005 LSI Logic Corporation.
/* RAID Action reply message */
diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptbase.c linux-2.6.22-590/drivers/message/fusion/mptbase.c
--- linux-2.6.22-570/drivers/message/fusion/mptbase.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/message/fusion/mptbase.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/message/fusion/mptbase.c 2008-01-29 22:12:31.000000000 -0500
@@ -6,7 +6,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptbase.h linux-2.6.22-590/drivers/message/fusion/mptbase.h
--- linux-2.6.22-570/drivers/message/fusion/mptbase.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/message/fusion/mptbase.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/message/fusion/mptbase.h 2008-01-29 22:12:31.000000000 -0500
@@ -6,7 +6,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
#define show_mptmod_ver(s,ver) \
diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptctl.c linux-2.6.22-590/drivers/message/fusion/mptctl.c
--- linux-2.6.22-570/drivers/message/fusion/mptctl.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/message/fusion/mptctl.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/message/fusion/mptctl.c 2008-01-29 22:12:31.000000000 -0500
@@ -5,7 +5,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptctl.h linux-2.6.22-590/drivers/message/fusion/mptctl.h
--- linux-2.6.22-570/drivers/message/fusion/mptctl.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/message/fusion/mptctl.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/message/fusion/mptctl.h 2008-01-29 22:12:31.000000000 -0500
@@ -6,7 +6,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptfc.c linux-2.6.22-590/drivers/message/fusion/mptfc.c
--- linux-2.6.22-570/drivers/message/fusion/mptfc.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/message/fusion/mptfc.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/message/fusion/mptfc.c 2008-01-29 22:12:31.000000000 -0500
@@ -4,7 +4,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
#include <linux/init.h>
diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptlan.c linux-2.6.22-590/drivers/message/fusion/mptlan.c
--- linux-2.6.22-570/drivers/message/fusion/mptlan.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/message/fusion/mptlan.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/message/fusion/mptlan.c 2008-01-29 22:12:31.000000000 -0500
@@ -5,7 +5,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptlan.h linux-2.6.22-590/drivers/message/fusion/mptlan.h
--- linux-2.6.22-570/drivers/message/fusion/mptlan.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/message/fusion/mptlan.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/message/fusion/mptlan.h 2008-01-29 22:12:31.000000000 -0500
@@ -5,7 +5,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptsas.c linux-2.6.22-590/drivers/message/fusion/mptsas.c
--- linux-2.6.22-570/drivers/message/fusion/mptsas.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/message/fusion/mptsas.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/message/fusion/mptsas.c 2008-01-29 22:12:31.000000000 -0500
@@ -4,7 +4,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptscsih.c linux-2.6.22-590/drivers/message/fusion/mptscsih.c
--- linux-2.6.22-570/drivers/message/fusion/mptscsih.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/message/fusion/mptscsih.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/message/fusion/mptscsih.c 2008-01-29 22:12:31.000000000 -0500
@@ -4,7 +4,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptscsih.h linux-2.6.22-590/drivers/message/fusion/mptscsih.h
--- linux-2.6.22-570/drivers/message/fusion/mptscsih.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/message/fusion/mptscsih.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/message/fusion/mptscsih.h 2008-01-29 22:12:31.000000000 -0500
@@ -6,7 +6,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptspi.c linux-2.6.22-590/drivers/message/fusion/mptspi.c
--- linux-2.6.22-570/drivers/message/fusion/mptspi.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/message/fusion/mptspi.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/message/fusion/mptspi.c 2008-01-29 22:12:31.000000000 -0500
@@ -4,7 +4,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
#include <linux/init.h>
diff -Nurb linux-2.6.22-570/drivers/message/i2o/i2o_scsi.c linux-2.6.22-590/drivers/message/i2o/i2o_scsi.c
--- linux-2.6.22-570/drivers/message/i2o/i2o_scsi.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/message/i2o/i2o_scsi.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/message/i2o/i2o_scsi.c 2008-01-29 22:12:31.000000000 -0500
@@ -377,12 +377,8 @@
osm_err("SCSI error %08x\n", error);
diff -Nurb linux-2.6.22-570/drivers/mfd/ucb1x00-ts.c linux-2.6.22-590/drivers/mfd/ucb1x00-ts.c
--- linux-2.6.22-570/drivers/mfd/ucb1x00-ts.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/mfd/ucb1x00-ts.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mfd/ucb1x00-ts.c 2008-01-29 22:12:31.000000000 -0500
@@ -209,6 +209,7 @@
DECLARE_WAITQUEUE(wait, tsk);
int valid = 0;
unsigned int x, y, p;
diff -Nurb linux-2.6.22-570/drivers/misc/asus-laptop.c linux-2.6.22-590/drivers/misc/asus-laptop.c
--- linux-2.6.22-570/drivers/misc/asus-laptop.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/misc/asus-laptop.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/misc/asus-laptop.c 2008-01-29 22:12:31.000000000 -0500
@@ -737,8 +737,7 @@
struct device_attribute dev_attr_##_name = { \
.attr = { \
}
diff -Nurb linux-2.6.22-570/drivers/mmc/card/Kconfig linux-2.6.22-590/drivers/mmc/card/Kconfig
--- linux-2.6.22-570/drivers/mmc/card/Kconfig 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/mmc/card/Kconfig 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/card/Kconfig 2008-01-29 22:12:31.000000000 -0500
@@ -14,3 +14,21 @@
mount the filesystem. Almost everyone wishing MMC support
should say Y or M here.
+
diff -Nurb linux-2.6.22-570/drivers/mmc/card/block.c linux-2.6.22-590/drivers/mmc/card/block.c
--- linux-2.6.22-570/drivers/mmc/card/block.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/mmc/card/block.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/card/block.c 2008-01-29 22:12:31.000000000 -0500
@@ -262,7 +262,9 @@
}
req->rq_disk->disk_name, brq.cmd.error);
diff -Nurb linux-2.6.22-570/drivers/mmc/card/queue.c linux-2.6.22-590/drivers/mmc/card/queue.c
--- linux-2.6.22-570/drivers/mmc/card/queue.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/mmc/card/queue.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/card/queue.c 2008-01-29 22:12:31.000000000 -0500
@@ -11,12 +11,15 @@
*/
#include <linux/module.h>
+
diff -Nurb linux-2.6.22-570/drivers/mmc/card/queue.h linux-2.6.22-590/drivers/mmc/card/queue.h
--- linux-2.6.22-570/drivers/mmc/card/queue.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/mmc/card/queue.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/card/queue.h 2008-01-29 22:12:31.000000000 -0500
@@ -14,6 +14,9 @@
void *data;
struct request_queue *queue;
#endif
diff -Nurb linux-2.6.22-570/drivers/mmc/core/Kconfig linux-2.6.22-590/drivers/mmc/core/Kconfig
--- linux-2.6.22-570/drivers/mmc/core/Kconfig 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/mmc/core/Kconfig 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/core/Kconfig 2008-01-29 22:12:31.000000000 -0500
@@ -14,3 +14,16 @@
This option is usually just for embedded systems which use
a MMC/SD card for rootfs. Most people should say N here.
+
diff -Nurb linux-2.6.22-570/drivers/mmc/core/Makefile linux-2.6.22-590/drivers/mmc/core/Makefile
--- linux-2.6.22-570/drivers/mmc/core/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/mmc/core/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/core/Makefile 2008-01-29 22:12:31.000000000 -0500
@@ -7,5 +7,6 @@
endif
diff -Nurb linux-2.6.22-570/drivers/mmc/core/bus.c linux-2.6.22-590/drivers/mmc/core/bus.c
--- linux-2.6.22-570/drivers/mmc/core/bus.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/mmc/core/bus.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/core/bus.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,245 @@
+/*
+ * linux/drivers/mmc/core/bus.c
+
diff -Nurb linux-2.6.22-570/drivers/mmc/core/bus.h linux-2.6.22-590/drivers/mmc/core/bus.h
--- linux-2.6.22-570/drivers/mmc/core/bus.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/mmc/core/bus.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/core/bus.h 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,22 @@
+/*
+ * linux/drivers/mmc/core/bus.h
+
diff -Nurb linux-2.6.22-570/drivers/mmc/core/core.c linux-2.6.22-590/drivers/mmc/core/core.c
--- linux-2.6.22-570/drivers/mmc/core/core.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/mmc/core/core.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/core/core.c 2008-01-29 22:12:31.000000000 -0500
@@ -27,7 +27,9 @@
#include <linux/mmc/sd.h>
MODULE_LICENSE("GPL");
diff -Nurb linux-2.6.22-570/drivers/mmc/core/core.h linux-2.6.22-590/drivers/mmc/core/core.h
--- linux-2.6.22-570/drivers/mmc/core/core.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/mmc/core/core.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/core/core.h 2008-01-29 22:12:31.000000000 -0500
@@ -54,8 +54,6 @@
u32 mmc_select_voltage(struct mmc_host *host, u32 ocr);
void mmc_set_timing(struct mmc_host *host, unsigned int timing);
diff -Nurb linux-2.6.22-570/drivers/mmc/core/host.c linux-2.6.22-590/drivers/mmc/core/host.c
--- linux-2.6.22-570/drivers/mmc/core/host.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/mmc/core/host.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/core/host.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,156 @@
+/*
+ * linux/drivers/mmc/core/host.c
+
diff -Nurb linux-2.6.22-570/drivers/mmc/core/host.h linux-2.6.22-590/drivers/mmc/core/host.h
--- linux-2.6.22-570/drivers/mmc/core/host.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/mmc/core/host.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/core/host.h 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,18 @@
+/*
+ * linux/drivers/mmc/core/host.h
+
diff -Nurb linux-2.6.22-570/drivers/mmc/core/lock.c linux-2.6.22-590/drivers/mmc/core/lock.c
--- linux-2.6.22-570/drivers/mmc/core/lock.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/mmc/core/lock.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/core/lock.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,199 @@
+/*
+ * linux/drivers/mmc/core/lock.h
+
diff -Nurb linux-2.6.22-570/drivers/mmc/core/lock.h linux-2.6.22-590/drivers/mmc/core/lock.h
--- linux-2.6.22-570/drivers/mmc/core/lock.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/mmc/core/lock.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/core/lock.h 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,51 @@
+/*
+ * linux/drivers/mmc/core/lock.h
+#endif
diff -Nurb linux-2.6.22-570/drivers/mmc/core/mmc.c linux-2.6.22-590/drivers/mmc/core/mmc.c
--- linux-2.6.22-570/drivers/mmc/core/mmc.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/mmc/core/mmc.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/core/mmc.c 2008-01-29 22:12:31.000000000 -0500
@@ -18,6 +18,8 @@
#include "core.h"
diff -Nurb linux-2.6.22-570/drivers/mmc/core/mmc_ops.c linux-2.6.22-590/drivers/mmc/core/mmc_ops.c
--- linux-2.6.22-570/drivers/mmc/core/mmc_ops.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/mmc/core/mmc_ops.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/core/mmc_ops.c 2008-01-29 22:12:31.000000000 -0500
@@ -2,6 +2,8 @@
* linux/drivers/mmc/mmc_ops.h
*
+
diff -Nurb linux-2.6.22-570/drivers/mmc/core/mmc_ops.h linux-2.6.22-590/drivers/mmc/core/mmc_ops.h
--- linux-2.6.22-570/drivers/mmc/core/mmc_ops.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/mmc/core/mmc_ops.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/core/mmc_ops.h 2008-01-29 22:12:31.000000000 -0500
@@ -12,6 +12,8 @@
#ifndef _MMC_MMC_OPS_H
#define _MMC_MMC_OPS_H
diff -Nurb linux-2.6.22-570/drivers/mmc/core/sd.c linux-2.6.22-590/drivers/mmc/core/sd.c
--- linux-2.6.22-570/drivers/mmc/core/sd.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/mmc/core/sd.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/core/sd.c 2008-01-29 22:12:31.000000000 -0500
@@ -19,11 +19,11 @@
#include "core.h"
diff -Nurb linux-2.6.22-570/drivers/mmc/core/sysfs.c linux-2.6.22-590/drivers/mmc/core/sysfs.c
--- linux-2.6.22-570/drivers/mmc/core/sysfs.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/mmc/core/sysfs.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/core/sysfs.c 2008-01-29 22:12:31.000000000 -0500
@@ -2,6 +2,7 @@
* linux/drivers/mmc/core/sysfs.c
*
-module_exit(mmc_exit);
diff -Nurb linux-2.6.22-570/drivers/mmc/core/sysfs.h linux-2.6.22-590/drivers/mmc/core/sysfs.h
--- linux-2.6.22-570/drivers/mmc/core/sysfs.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/mmc/core/sysfs.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/core/sysfs.h 2008-01-29 22:12:31.000000000 -0500
@@ -11,17 +11,16 @@
#ifndef _MMC_CORE_SYSFS_H
#define _MMC_CORE_SYSFS_H
#endif
diff -Nurb linux-2.6.22-570/drivers/mmc/host/sdhci.c linux-2.6.22-590/drivers/mmc/host/sdhci.c
--- linux-2.6.22-570/drivers/mmc/host/sdhci.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/mmc/host/sdhci.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mmc/host/sdhci.c 2008-01-29 22:12:31.000000000 -0500
@@ -70,6 +70,14 @@
.driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE,
},
},
diff -Nurb linux-2.6.22-570/drivers/mtd/mtd_blkdevs.c linux-2.6.22-590/drivers/mtd/mtd_blkdevs.c
--- linux-2.6.22-570/drivers/mtd/mtd_blkdevs.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/mtd/mtd_blkdevs.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mtd/mtd_blkdevs.c 2008-01-29 22:12:31.000000000 -0500
@@ -16,6 +16,7 @@
#include <linux/mtd/mtd.h>
#include <linux/blkdev.h>
while (!kthread_should_stop()) {
diff -Nurb linux-2.6.22-570/drivers/mtd/ubi/wl.c linux-2.6.22-590/drivers/mtd/ubi/wl.c
--- linux-2.6.22-570/drivers/mtd/ubi/wl.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/mtd/ubi/wl.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/mtd/ubi/wl.c 2008-01-29 22:12:31.000000000 -0500
@@ -1346,6 +1346,7 @@
ubi_msg("background thread \"%s\" started, PID %d",
ubi->bgt_name, current->pid);
diff -Nurb linux-2.6.22-570/drivers/net/3c523.c linux-2.6.22-590/drivers/net/3c523.c
--- linux-2.6.22-570/drivers/net/3c523.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/3c523.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/3c523.c 2008-01-29 22:12:31.000000000 -0500
@@ -990,7 +990,7 @@
if (skb != NULL) {
skb_reserve(skb, 2); /* 16 byte alignment */
dev->last_rx = jiffies;
diff -Nurb linux-2.6.22-570/drivers/net/7990.c linux-2.6.22-590/drivers/net/7990.c
--- linux-2.6.22-570/drivers/net/7990.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/7990.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/7990.c 2008-01-29 22:12:31.000000000 -0500
@@ -333,9 +333,9 @@
skb_reserve (skb, 2); /* 16 byte align */
dev->last_rx = jiffies;
diff -Nurb linux-2.6.22-570/drivers/net/8139too.c linux-2.6.22-590/drivers/net/8139too.c
--- linux-2.6.22-570/drivers/net/8139too.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/8139too.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/8139too.c 2008-01-29 22:12:31.000000000 -0500
@@ -2017,7 +2017,7 @@
#if RX_BUF_IDX == 3
wrap_copy(skb, rx_ring, ring_offset+4, pkt_size);
skb_put (skb, pkt_size);
diff -Nurb linux-2.6.22-570/drivers/net/Kconfig linux-2.6.22-590/drivers/net/Kconfig
---- linux-2.6.22-570/drivers/net/Kconfig 2008-03-15 10:34:21.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/Kconfig 2008-03-15 10:35:46.000000000 -0400
-@@ -2555,6 +2555,18 @@
+--- linux-2.6.22-570/drivers/net/Kconfig 2008-01-29 22:12:19.000000000 -0500
++++ linux-2.6.22-590/drivers/net/Kconfig 2008-01-29 22:12:31.000000000 -0500
+@@ -119,6 +119,20 @@
+
+ If you don't know what to use this for, you don't need it.
+
++config ETUN
++ tristate "Ethernet tunnel device driver support"
++ depends on SYSFS
++ ---help---
++ ETUN provices a pair of network devices that can be used for
++ configuring interesting topolgies. What one devices transmits
++ the other receives and vice versa. The link level framing
++ is ethernet for wide compatibility with network stacks.
++
++ To compile this driver as a module, choose M here: the module
++ will be called etun.
++
++ If you don't know what to use this for, you don't need it.
++
+ config NET_SB1000
+ tristate "General Instruments Surfboard 1000"
+ depends on PNP
+@@ -2555,6 +2569,18 @@
source "drivers/s390/net/Kconfig"
tristate "iSeries Virtual Ethernet driver support"
depends on PPC_ISERIES
diff -Nurb linux-2.6.22-570/drivers/net/Makefile linux-2.6.22-590/drivers/net/Makefile
---- linux-2.6.22-570/drivers/net/Makefile 2008-03-15 10:34:21.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/Makefile 2008-03-15 10:35:46.000000000 -0400
-@@ -224,7 +224,10 @@
+--- linux-2.6.22-570/drivers/net/Makefile 2008-01-29 22:12:19.000000000 -0500
++++ linux-2.6.22-590/drivers/net/Makefile 2008-01-29 22:12:31.000000000 -0500
+@@ -186,6 +186,7 @@
+ obj-$(CONFIG_MACMACE) += macmace.o
+ obj-$(CONFIG_MAC89x0) += mac89x0.o
+ obj-$(CONFIG_TUN) += tun.o
++obj-$(CONFIG_ETUN) += etun.o
+ obj-$(CONFIG_NET_NETX) += netx-eth.o
+ obj-$(CONFIG_DL2K) += dl2k.o
+ obj-$(CONFIG_R8169) += r8169.o
+@@ -224,7 +225,10 @@
obj-$(CONFIG_ENP2611_MSF_NET) += ixp2000/
obj-$(CONFIG_NETCONSOLE) += netconsole.o
+
diff -Nurb linux-2.6.22-570/drivers/net/a2065.c linux-2.6.22-590/drivers/net/a2065.c
--- linux-2.6.22-570/drivers/net/a2065.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/a2065.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/a2065.c 2008-01-29 22:12:31.000000000 -0500
@@ -322,9 +322,9 @@
skb_reserve (skb, 2); /* 16 byte align */
dev->last_rx = jiffies;
diff -Nurb linux-2.6.22-570/drivers/net/ariadne.c linux-2.6.22-590/drivers/net/ariadne.c
--- linux-2.6.22-570/drivers/net/ariadne.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/ariadne.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/ariadne.c 2008-01-29 22:12:31.000000000 -0500
@@ -746,7 +746,7 @@
skb_reserve(skb,2); /* 16 byte align */
printk(KERN_DEBUG "RX pkt type 0x%04x from ",
diff -Nurb linux-2.6.22-570/drivers/net/arm/ep93xx_eth.c linux-2.6.22-590/drivers/net/arm/ep93xx_eth.c
--- linux-2.6.22-570/drivers/net/arm/ep93xx_eth.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/arm/ep93xx_eth.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/arm/ep93xx_eth.c 2008-01-29 22:12:31.000000000 -0500
@@ -258,7 +258,7 @@
skb_reserve(skb, 2);
dma_sync_single(NULL, ep->descs->rdesc[entry].buf_addr,
diff -Nurb linux-2.6.22-570/drivers/net/au1000_eth.c linux-2.6.22-590/drivers/net/au1000_eth.c
--- linux-2.6.22-570/drivers/net/au1000_eth.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/au1000_eth.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/au1000_eth.c 2008-01-29 22:12:31.000000000 -0500
@@ -1205,8 +1205,8 @@
continue;
}
netif_rx(skb); /* pass the packet to upper layers */
diff -Nurb linux-2.6.22-570/drivers/net/bnx2.c linux-2.6.22-590/drivers/net/bnx2.c
--- linux-2.6.22-570/drivers/net/bnx2.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/bnx2.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/bnx2.c 2008-01-29 22:12:31.000000000 -0500
@@ -6490,10 +6490,10 @@
memcpy(dev->perm_addr, bp->mac_addr, 6);
bp->name = board_info[ent->driver_data].name;
#ifdef BCM_VLAN
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
#endif
+diff -Nurb linux-2.6.22-570/drivers/net/bonding/bond_3ad.c linux-2.6.22-590/drivers/net/bonding/bond_3ad.c
+--- linux-2.6.22-570/drivers/net/bonding/bond_3ad.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/bonding/bond_3ad.c 2008-01-29 22:12:31.000000000 -0500
+@@ -29,6 +29,7 @@
+ #include <linux/ethtool.h>
+ #include <linux/if_bonding.h>
+ #include <linux/pkt_sched.h>
++#include <net/net_namespace.h>
+ #include "bonding.h"
+ #include "bond_3ad.h"
+
+@@ -2448,6 +2449,9 @@
+ struct slave *slave = NULL;
+ int ret = NET_RX_DROP;
+
++ if (dev->nd_net != &init_net)
++ goto out;
++
+ if (!(dev->flags & IFF_MASTER))
+ goto out;
+
+diff -Nurb linux-2.6.22-570/drivers/net/bonding/bond_alb.c linux-2.6.22-590/drivers/net/bonding/bond_alb.c
+--- linux-2.6.22-570/drivers/net/bonding/bond_alb.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/bonding/bond_alb.c 2008-01-29 22:12:31.000000000 -0500
+@@ -345,6 +345,9 @@
+ struct arp_pkt *arp = (struct arp_pkt *)skb->data;
+ int res = NET_RX_DROP;
+
++ if (bond_dev->nd_net != &init_net)
++ goto out;
++
+ if (!(bond_dev->flags & IFF_MASTER))
+ goto out;
+
+diff -Nurb linux-2.6.22-570/drivers/net/bonding/bond_main.c linux-2.6.22-590/drivers/net/bonding/bond_main.c
+--- linux-2.6.22-570/drivers/net/bonding/bond_main.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/drivers/net/bonding/bond_main.c 2008-01-29 22:12:31.000000000 -0500
+@@ -75,6 +75,7 @@
+ #include <linux/if_vlan.h>
+ #include <linux/if_bonding.h>
+ #include <net/route.h>
++#include <net/net_namespace.h>
+ #include "bonding.h"
+ #include "bond_3ad.h"
+ #include "bond_alb.h"
+@@ -2376,6 +2377,7 @@
+ * can tag the ARP with the proper VLAN tag.
+ */
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ fl.fl4_dst = targets[i];
+ fl.fl4_tos = RTO_ONLINK;
+
+@@ -2485,6 +2487,9 @@
+ unsigned char *arp_ptr;
+ u32 sip, tip;
+
++ if (dev->nd_net != &init_net)
++ goto out;
++
+ if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER))
+ goto out;
+
+@@ -3172,7 +3177,7 @@
+ {
+ int len = strlen(DRV_NAME);
+
+- for (bond_proc_dir = proc_net->subdir; bond_proc_dir;
++ for (bond_proc_dir = init_net.proc_net->subdir; bond_proc_dir;
+ bond_proc_dir = bond_proc_dir->next) {
+ if ((bond_proc_dir->namelen == len) &&
+ !memcmp(bond_proc_dir->name, DRV_NAME, len)) {
+@@ -3181,7 +3186,7 @@
+ }
+
+ if (!bond_proc_dir) {
+- bond_proc_dir = proc_mkdir(DRV_NAME, proc_net);
++ bond_proc_dir = proc_mkdir(DRV_NAME, init_net.proc_net);
+ if (bond_proc_dir) {
+ bond_proc_dir->owner = THIS_MODULE;
+ } else {
+@@ -3216,7 +3221,7 @@
+ bond_proc_dir->owner = NULL;
+ }
+ } else {
+- remove_proc_entry(DRV_NAME, proc_net);
++ remove_proc_entry(DRV_NAME, init_net.proc_net);
+ bond_proc_dir = NULL;
+ }
+ }
+@@ -3323,6 +3328,9 @@
+ {
+ struct net_device *event_dev = (struct net_device *)ptr;
+
++ if (event_dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ dprintk("event_dev: %s, event: %lx\n",
+ (event_dev ? event_dev->name : "None"),
+ event);
+@@ -3740,7 +3748,7 @@
+ }
+
+ down_write(&(bonding_rwsem));
+- slave_dev = dev_get_by_name(ifr->ifr_slave);
++ slave_dev = dev_get_by_name(&init_net, ifr->ifr_slave);
+
+ dprintk("slave_dev=%p: \n", slave_dev);
+
+diff -Nurb linux-2.6.22-570/drivers/net/bonding/bond_sysfs.c linux-2.6.22-590/drivers/net/bonding/bond_sysfs.c
+--- linux-2.6.22-570/drivers/net/bonding/bond_sysfs.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/bonding/bond_sysfs.c 2008-01-29 22:12:31.000000000 -0500
+@@ -35,6 +35,7 @@
+ #include <linux/ctype.h>
+ #include <linux/inet.h>
+ #include <linux/rtnetlink.h>
++#include <net/net_namespace.h>
+
+ /* #define BONDING_DEBUG 1 */
+ #include "bonding.h"
+@@ -299,7 +300,7 @@
+ read_unlock_bh(&bond->lock);
+ printk(KERN_INFO DRV_NAME ": %s: Adding slave %s.\n",
+ bond->dev->name, ifname);
+- dev = dev_get_by_name(ifname);
++ dev = dev_get_by_name(&init_net, ifname);
+ if (!dev) {
+ printk(KERN_INFO DRV_NAME
+ ": %s: Interface %s does not exist!\n",
diff -Nurb linux-2.6.22-570/drivers/net/dl2k.c linux-2.6.22-590/drivers/net/dl2k.c
--- linux-2.6.22-570/drivers/net/dl2k.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/dl2k.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/dl2k.c 2008-01-29 22:12:31.000000000 -0500
@@ -866,9 +866,9 @@
PCI_DMA_FROMDEVICE);
/* 16 byte align the IP header */
desc->fraginfo &
diff -Nurb linux-2.6.22-570/drivers/net/dummy.c linux-2.6.22-590/drivers/net/dummy.c
--- linux-2.6.22-570/drivers/net/dummy.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/dummy.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/dummy.c 2008-01-29 22:12:31.000000000 -0500
@@ -34,11 +34,17 @@
#include <linux/etherdevice.h>
#include <linux/init.h>
+MODULE_ALIAS_RTNL_LINK("dummy");
diff -Nurb linux-2.6.22-570/drivers/net/eepro100.c linux-2.6.22-590/drivers/net/eepro100.c
--- linux-2.6.22-570/drivers/net/eepro100.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/eepro100.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/eepro100.c 2008-01-29 22:12:31.000000000 -0500
@@ -1801,7 +1801,7 @@
#if 1 || USE_IP_CSUM
skb_copy_from_linear_data(sp->rx_skbuff[entry],
diff -Nurb linux-2.6.22-570/drivers/net/epic100.c linux-2.6.22-590/drivers/net/epic100.c
--- linux-2.6.22-570/drivers/net/epic100.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/epic100.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/epic100.c 2008-01-29 22:12:31.000000000 -0500
@@ -1201,7 +1201,7 @@
ep->rx_ring[entry].bufaddr,
ep->rx_buf_sz,
skb_put(skb, pkt_len);
pci_dma_sync_single_for_device(ep->pci_dev,
ep->rx_ring[entry].bufaddr,
+diff -Nurb linux-2.6.22-570/drivers/net/eql.c linux-2.6.22-590/drivers/net/eql.c
+--- linux-2.6.22-570/drivers/net/eql.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/eql.c 2008-01-29 22:12:31.000000000 -0500
+@@ -116,6 +116,7 @@
+ #include <linux/init.h>
+ #include <linux/timer.h>
+ #include <linux/netdevice.h>
++#include <net/net_namespace.h>
+
+ #include <linux/if.h>
+ #include <linux/if_arp.h>
+@@ -412,7 +413,7 @@
+ if (copy_from_user(&srq, srqp, sizeof (slaving_request_t)))
+ return -EFAULT;
+
+- slave_dev = dev_get_by_name(srq.slave_name);
++ slave_dev = dev_get_by_name(&init_net, srq.slave_name);
+ if (slave_dev) {
+ if ((master_dev->flags & IFF_UP) == IFF_UP) {
+ /* slave is not a master & not already a slave: */
+@@ -460,7 +461,7 @@
+ if (copy_from_user(&srq, srqp, sizeof (slaving_request_t)))
+ return -EFAULT;
+
+- slave_dev = dev_get_by_name(srq.slave_name);
++ slave_dev = dev_get_by_name(&init_net, srq.slave_name);
+ ret = -EINVAL;
+ if (slave_dev) {
+ spin_lock_bh(&eql->queue.lock);
+@@ -493,7 +494,7 @@
+ if (copy_from_user(&sc, scp, sizeof (slave_config_t)))
+ return -EFAULT;
+
+- slave_dev = dev_get_by_name(sc.slave_name);
++ slave_dev = dev_get_by_name(&init_net, sc.slave_name);
+ if (!slave_dev)
+ return -ENODEV;
+
+@@ -528,7 +529,7 @@
+ if (copy_from_user(&sc, scp, sizeof (slave_config_t)))
+ return -EFAULT;
+
+- slave_dev = dev_get_by_name(sc.slave_name);
++ slave_dev = dev_get_by_name(&init_net, sc.slave_name);
+ if (!slave_dev)
+ return -ENODEV;
+
+diff -Nurb linux-2.6.22-570/drivers/net/etun.c linux-2.6.22-590/drivers/net/etun.c
+--- linux-2.6.22-570/drivers/net/etun.c 1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.22-590/drivers/net/etun.c 2008-01-29 22:12:31.000000000 -0500
+@@ -0,0 +1,489 @@
++/*
++ * ETUN - Universal ETUN device driver.
++ * Copyright (C) 2006 Linux Networx
++ *
++ */
++
++#define DRV_NAME "etun"
++#define DRV_VERSION "1.0"
++#define DRV_DESCRIPTION "Ethernet pseudo tunnel device driver"
++#define DRV_COPYRIGHT "(C) 2007 Linux Networx"
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/spinlock.h>
++#include <linux/skbuff.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/ethtool.h>
++#include <linux/rtnetlink.h>
++#include <linux/if.h>
++#include <linux/if_ether.h>
++#include <linux/ctype.h>
++#include <linux/nsproxy.h>
++#include <net/net_namespace.h>
++#include <net/dst.h>
++
++
++/* Device cheksum strategy.
++ *
++ * etun is designed to a be a pair of virutal devices
++ * connecting two network stack instances.
++ *
++ * Typically it will either be used with ethernet bridging or
++ * it will be used to route packets between the two stacks.
++ *
++ * The only checksum offloading I can do is to completely
++ * skip the checksumming step all together.
++ *
++ * When used for ethernet bridging I don't believe any
++ * checksum off loading is safe.
++ * - If my source is an external interface the checksum may be
++ * invalid so I don't want to report I have already checked it.
++ * - If my destination is an external interface I don't want to put
++ * a packet on the wire with someone computing the checksum.
++ *
++ * When used for routing between two stacks checksums should
++ * be as unnecessary as they are on the loopback device.
++ *
++ * So by default I am safe and disable checksumming and
++ * other advanced features like SG and TSO.
++ *
++ * However because I think these features could be useful
++ * I provide the ethtool functions to and enable/disable
++ * them at runtime.
++ *
++ * If you think you can correctly enable these go ahead.
++ * For checksums both the transmitter and the receiver must
++ * agree before the are actually disabled.
++ */
++
++#define ETUN_NUM_STATS 1
++static struct {
++ const char string[ETH_GSTRING_LEN];
++} ethtool_stats_keys[ETUN_NUM_STATS] = {
++ { "partner_ifindex" },
++};
++
++struct etun_info {
++ struct net_device *rx_dev;
++ unsigned ip_summed;
++ struct net_device_stats stats;
++ struct list_head list;
++ struct net_device *dev;
++};
++
++/*
++ * I have to hold the rtnl_lock during device delete.
++ * So I use the rtnl_lock to protect my list manipulations
++ * as well. Crude but simple.
++ */
++static LIST_HEAD(etun_list);
++
++/*
++ * The higher levels take care of making this non-reentrant (it's
++ * called with bh's disabled).
++ */
++static int etun_xmit(struct sk_buff *skb, struct net_device *tx_dev)
++{
++ struct etun_info *tx_info = tx_dev->priv;
++ struct net_device *rx_dev = tx_info->rx_dev;
++ struct etun_info *rx_info = rx_dev->priv;
++
++ tx_info->stats.tx_packets++;
++ tx_info->stats.tx_bytes += skb->len;
++
++ /* Drop the skb state that was needed to get here */
++ skb_orphan(skb);
++ if (skb->dst)
++ skb->dst = dst_pop(skb->dst); /* Allow for smart routing */
++
++ /* Switch to the receiving device */
++ skb->pkt_type = PACKET_HOST;
++ skb->protocol = eth_type_trans(skb, rx_dev);
++ skb->dev = rx_dev;
++ skb->ip_summed = CHECKSUM_NONE;
++
++ /* If both halves agree no checksum is needed */
++ if (tx_dev->features & NETIF_F_NO_CSUM)
++ skb->ip_summed = rx_info->ip_summed;
++
++ rx_dev->last_rx = jiffies;
++ rx_info->stats.rx_packets++;
++ rx_info->stats.rx_bytes += skb->len;
++ netif_rx(skb);
++
++ return 0;
++}
++
++static struct net_device_stats *etun_get_stats(struct net_device *dev)
++{
++ struct etun_info *info = dev->priv;
++ return &info->stats;
++}
++
++/* ethtool interface */
++static int etun_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++ cmd->supported = 0;
++ cmd->advertising = 0;
++ cmd->speed = SPEED_10000; /* Memory is fast! */
++ cmd->duplex = DUPLEX_FULL;
++ cmd->port = PORT_TP;
++ cmd->phy_address = 0;
++ cmd->transceiver = XCVR_INTERNAL;
++ cmd->autoneg = AUTONEG_DISABLE;
++ cmd->maxtxpkt = 0;
++ cmd->maxrxpkt = 0;
++ return 0;
++}
++
++static void etun_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
++{
++ strcpy(info->driver, DRV_NAME);
++ strcpy(info->version, DRV_VERSION);
++ strcpy(info->fw_version, "N/A");
++}
++
++static void etun_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
++{
++ switch(stringset) {
++ case ETH_SS_STATS:
++ memcpy(buf, ðtool_stats_keys, sizeof(ethtool_stats_keys));
++ break;
++ case ETH_SS_TEST:
++ default:
++ break;
++ }
++}
++
++static int etun_get_stats_count(struct net_device *dev)
++{
++ return ETUN_NUM_STATS;
++}
++
++static void etun_get_ethtool_stats(struct net_device *dev,
++ struct ethtool_stats *stats, u64 *data)
++{
++ struct etun_info *info = dev->priv;
++
++ data[0] = info->rx_dev->ifindex;
++}
++
++static u32 etun_get_rx_csum(struct net_device *dev)
++{
++ struct etun_info *info = dev->priv;
++ return info->ip_summed == CHECKSUM_UNNECESSARY;
++}
++
++static int etun_set_rx_csum(struct net_device *dev, u32 data)
++{
++ struct etun_info *info = dev->priv;
++
++ info->ip_summed = data ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
++
++ return 0;
++}
++
++static u32 etun_get_tx_csum(struct net_device *dev)
++{
++ return (dev->features & NETIF_F_NO_CSUM) != 0;
++}
++
++static int etun_set_tx_csum(struct net_device *dev, u32 data)
++{
++ dev->features &= ~NETIF_F_NO_CSUM;
++ if (data)
++ dev->features |= NETIF_F_NO_CSUM;
++
++ return 0;
++}
++
++static struct ethtool_ops etun_ethtool_ops = {
++ .get_settings = etun_get_settings,
++ .get_drvinfo = etun_get_drvinfo,
++ .get_link = ethtool_op_get_link,
++ .get_rx_csum = etun_get_rx_csum,
++ .set_rx_csum = etun_set_rx_csum,
++ .get_tx_csum = etun_get_tx_csum,
++ .set_tx_csum = etun_set_tx_csum,
++ .get_sg = ethtool_op_get_sg,
++ .set_sg = ethtool_op_set_sg,
++#if 0 /* Does just setting the bit successfuly emulate tso? */
++ .get_tso = ethtool_op_get_tso,
++ .set_tso = ethtool_op_set_tso,
++#endif
++ .get_strings = etun_get_strings,
++ .get_stats_count = etun_get_stats_count,
++ .get_ethtool_stats = etun_get_ethtool_stats,
++ .get_perm_addr = ethtool_op_get_perm_addr,
++};
++
++static int etun_open(struct net_device *tx_dev)
++{
++ struct etun_info *tx_info = tx_dev->priv;
++ struct net_device *rx_dev = tx_info->rx_dev;
++ /* If we attempt to bring up etun in the small window before
++ * it is connected to it's partner error.
++ */
++ if (!rx_dev)
++ return -ENOTCONN;
++ if (rx_dev->flags & IFF_UP) {
++ netif_carrier_on(tx_dev);
++ netif_carrier_on(rx_dev);
++ }
++ netif_start_queue(tx_dev);
++ return 0;
++}
++
++static int etun_stop(struct net_device *tx_dev)
++{
++ struct etun_info *tx_info = tx_dev->priv;
++ struct net_device *rx_dev = tx_info->rx_dev;
++ netif_stop_queue(tx_dev);
++ if (netif_carrier_ok(tx_dev)) {
++ netif_carrier_off(tx_dev);
++ netif_carrier_off(rx_dev);
++ }
++ return 0;
++}
++
++static int etun_change_mtu(struct net_device *dev, int new_mtu)
++{
++ /* Don't allow ridiculously small mtus */
++ if (new_mtu < (ETH_ZLEN - ETH_HLEN))
++ return -EINVAL;
++ dev->mtu = new_mtu;
++ return 0;
++}
++
++static void etun_set_multicast_list(struct net_device *dev)
++{
++ /* Nothing sane I can do here */
++ return;
++}
++
++static int etun_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
++{
++ return -EOPNOTSUPP;
++}
++
++/* Only allow letters and numbers in an etun device name */
++static int is_valid_name(const char *name)
++{
++ const char *ptr;
++ for (ptr = name; *ptr; ptr++) {
++ if (!isalnum(*ptr))
++ return 0;
++ }
++ return 1;
++}
++
++static struct net_device *etun_alloc(struct net *net, const char *name)
++{
++ struct net_device *dev;
++ struct etun_info *info;
++ int err;
++
++ if (!name || !is_valid_name(name))
++ return ERR_PTR(-EINVAL);
++
++ dev = alloc_netdev(sizeof(struct etun_info), name, ether_setup);
++ if (!dev)
++ return ERR_PTR(-ENOMEM);
++
++ info = dev->priv;
++ info->dev = dev;
++ dev->nd_net = net;
++
++ random_ether_addr(dev->dev_addr);
++ dev->tx_queue_len = 0; /* A queue is silly for a loopback device */
++ dev->hard_start_xmit = etun_xmit;
++ dev->get_stats = etun_get_stats;
++ dev->open = etun_open;
++ dev->stop = etun_stop;
++ dev->set_multicast_list = etun_set_multicast_list;
++ dev->do_ioctl = etun_ioctl;
++ dev->features = NETIF_F_FRAGLIST
++ | NETIF_F_HIGHDMA
++ | NETIF_F_LLTX;
++ dev->flags = IFF_BROADCAST | IFF_MULTICAST |IFF_PROMISC;
++ dev->ethtool_ops = &etun_ethtool_ops;
++ dev->destructor = free_netdev;
++ dev->change_mtu = etun_change_mtu;
++ err = register_netdev(dev);
++ if (err) {
++ free_netdev(dev);
++ dev = ERR_PTR(err);
++ goto out;
++ }
++ netif_carrier_off(dev);
++out:
++ return dev;
++}
++
++static int etun_alloc_pair(struct net *net, const char *name0, const char *name1)
++{
++ struct net_device *dev0, *dev1;
++ struct etun_info *info0, *info1;
++
++ dev0 = etun_alloc(net, name0);
++ if (IS_ERR(dev0)) {
++ return PTR_ERR(dev0);
++ }
++ info0 = dev0->priv;
++
++ dev1 = etun_alloc(net, name1);
++ if (IS_ERR(dev1)) {
++ unregister_netdev(dev0);
++ return PTR_ERR(dev1);
++ }
++ info1 = dev1->priv;
++
++ dev_hold(dev0);
++ dev_hold(dev1);
++ info0->rx_dev = dev1;
++ info1->rx_dev = dev0;
++
++ /* Only place one member of the pair on the list
++ * so I don't confuse list_for_each_entry_safe,
++ * by deleting two list entries at once.
++ */
++ rtnl_lock();
++ list_add(&info0->list, &etun_list);
++ INIT_LIST_HEAD(&info1->list);
++ rtnl_unlock();
++
++ return 0;
++}
++
++static int etun_unregister_pair(struct net_device *dev0)
++{
++ struct etun_info *info0, *info1;
++ struct net_device *dev1;
++
++ ASSERT_RTNL();
++
++ if (!dev0)
++ return -ENODEV;
++
++ /* Ensure my network devices are not passing packets */
++ dev_close(dev0);
++ info0 = dev0->priv;
++ dev1 = info0->rx_dev;
++ info1 = dev1->priv;
++ dev_close(dev1);
++
++ /* Drop the cross device references */
++ dev_put(dev0);
++ dev_put(dev1);
++
++ /* Remove from the etun list */
++ if (!list_empty(&info0->list))
++ list_del_init(&info0->list);
++ if (!list_empty(&info1->list))
++ list_del_init(&info1->list);
++
++ unregister_netdevice(dev0);
++ unregister_netdevice(dev1);
++ return 0;
++}
++
++static int etun_noget(char *buffer, struct kernel_param *kp)
++{
++ return 0;
++}
++
++static int etun_newif(const char *val, struct kernel_param *kp)
++{
++ char name0[IFNAMSIZ], name1[IFNAMSIZ];
++ const char *mid;
++ int len, len0, len1;
++ if (!capable(CAP_NET_ADMIN))
++ return -EPERM;
++
++ /* Avoid frustration by removing trailing whitespace */
++ len = strlen(val);
++ while (isspace(val[len - 1]))
++ len--;
++
++ /* Split the string into 2 names */
++ mid = memchr(val, ',', len);
++ if (!mid)
++ return -EINVAL;
++
++ /* Get the first device name */
++ len0 = mid - val;
++ if (len0 > sizeof(name0) - 1)
++ len = sizeof(name0) - 1;
++ strncpy(name0, val, len0);
++ name0[len0] = '\0';
++
++ /* And the second device name */
++ len1 = len - (len0 + 1);
++ if (len1 > sizeof(name1) - 1)
++ len1 = sizeof(name1) - 1;
++ strncpy(name1, mid + 1, len1);
++ name1[len1] = '\0';
++
++ return etun_alloc_pair(current->nsproxy->net_ns, name0, name1);
++}
++
++static int etun_delif(const char *val, struct kernel_param *kp)
++{
++ char name[IFNAMSIZ];
++ int len;
++ struct net_device *dev;
++ int err;
++ if (!capable(CAP_NET_ADMIN))
++ return -EPERM;
++
++ /* Avoid frustration by removing trailing whitespace */
++ len = strlen(val);
++ while (isspace(val[len - 1]))
++ len--;
++
++ /* Get the device name */
++ if (len > sizeof(name) - 1)
++ return -EINVAL;
++ strncpy(name, val, len);
++ name[len] = '\0';
++
++ /* Double check I don't have strange characters in my device name */
++ if (!is_valid_name(name))
++ return -EINVAL;
++
++ rtnl_lock();
++ err = -ENODEV;
++ dev = __dev_get_by_name(current->nsproxy->net_ns, name);
++ err = etun_unregister_pair(dev);
++ rtnl_unlock();
++ return err;
++}
++
++static int __init etun_init(void)
++{
++ printk(KERN_INFO "etun: %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
++ printk(KERN_INFO "etun: %s\n", DRV_COPYRIGHT);
++
++ return 0;
++}
++
++static void etun_cleanup(void)
++{
++ struct etun_info *info, *tmp;
++ rtnl_lock();
++ list_for_each_entry_safe(info, tmp, &etun_list, list) {
++ etun_unregister_pair(info->dev);
++ }
++ rtnl_unlock();
++}
++
++module_param_call(newif, etun_newif, etun_noget, NULL, S_IWUSR);
++module_param_call(delif, etun_delif, etun_noget, NULL, S_IWUSR);
++module_init(etun_init);
++module_exit(etun_cleanup);
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_AUTHOR("Eric Biederman <ebiederm@xmission.com>");
++MODULE_LICENSE("GPL");
diff -Nurb linux-2.6.22-570/drivers/net/fealnx.c linux-2.6.22-590/drivers/net/fealnx.c
--- linux-2.6.22-570/drivers/net/fealnx.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/fealnx.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/fealnx.c 2008-01-29 22:12:31.000000000 -0500
@@ -1727,8 +1727,8 @@
/* Call copy + cksum if available. */
memcpy(skb_put(skb, pkt_len),
diff -Nurb linux-2.6.22-570/drivers/net/fec.c linux-2.6.22-590/drivers/net/fec.c
--- linux-2.6.22-570/drivers/net/fec.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/fec.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/fec.c 2008-01-29 22:12:31.000000000 -0500
@@ -648,7 +648,7 @@
fep->stats.rx_dropped++;
} else {
}
diff -Nurb linux-2.6.22-570/drivers/net/hamachi.c linux-2.6.22-590/drivers/net/hamachi.c
--- linux-2.6.22-570/drivers/net/hamachi.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/hamachi.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/hamachi.c 2008-01-29 22:12:31.000000000 -0500
@@ -1575,8 +1575,8 @@
PCI_DMA_FROMDEVICE);
/* Call copy + cksum if available. */
memcpy(skb_put(skb, pkt_len), hmp->rx_ring_dma
diff -Nurb linux-2.6.22-570/drivers/net/hamradio/baycom_epp.c linux-2.6.22-590/drivers/net/hamradio/baycom_epp.c
--- linux-2.6.22-570/drivers/net/hamradio/baycom_epp.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/hamradio/baycom_epp.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/hamradio/baycom_epp.c 2008-01-29 22:12:31.000000000 -0500
@@ -320,7 +320,7 @@
sprintf(portarg, "%ld", bc->pdev->port->base);
printk(KERN_DEBUG "%s: %s -s -p %s -m %s\n", bc_drvname, eppconfig_path, portarg, modearg);
}
/* ---------------------------------------------------------------------- */
+diff -Nurb linux-2.6.22-570/drivers/net/hamradio/bpqether.c linux-2.6.22-590/drivers/net/hamradio/bpqether.c
+--- linux-2.6.22-570/drivers/net/hamradio/bpqether.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/hamradio/bpqether.c 2008-01-29 22:12:31.000000000 -0500
+@@ -83,6 +83,7 @@
+
+ #include <net/ip.h>
+ #include <net/arp.h>
++#include <net/net_namespace.h>
+
+ #include <linux/bpqether.h>
+
+@@ -172,6 +173,9 @@
+ struct ethhdr *eth;
+ struct bpqdev *bpq;
+
++ if (dev->nd_net != &init_net)
++ goto drop;
++
+ if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
+ return NET_RX_DROP;
+
+@@ -559,6 +563,9 @@
+ {
+ struct net_device *dev = (struct net_device *)ptr;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ if (!dev_is_ethdev(dev))
+ return NOTIFY_DONE;
+
+@@ -594,7 +601,7 @@
+ static int __init bpq_init_driver(void)
+ {
+ #ifdef CONFIG_PROC_FS
+- if (!proc_net_fops_create("bpqether", S_IRUGO, &bpq_info_fops)) {
++ if (!proc_net_fops_create(&init_net, "bpqether", S_IRUGO, &bpq_info_fops)) {
+ printk(KERN_ERR
+ "bpq: cannot create /proc/net/bpqether entry.\n");
+ return -ENOENT;
+@@ -618,7 +625,7 @@
+
+ unregister_netdevice_notifier(&bpq_dev_notifier);
+
+- proc_net_remove("bpqether");
++ proc_net_remove(&init_net, "bpqether");
+
+ rtnl_lock();
+ while (!list_empty(&bpq_devices)) {
+diff -Nurb linux-2.6.22-570/drivers/net/hamradio/scc.c linux-2.6.22-590/drivers/net/hamradio/scc.c
+--- linux-2.6.22-570/drivers/net/hamradio/scc.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/hamradio/scc.c 2008-01-29 22:12:31.000000000 -0500
+@@ -174,6 +174,7 @@
+ #include <linux/seq_file.h>
+ #include <linux/bitops.h>
+
++#include <net/net_namespace.h>
+ #include <net/ax25.h>
+
+ #include <asm/irq.h>
+@@ -2114,7 +2115,7 @@
+ }
+ rtnl_unlock();
+
+- proc_net_fops_create("z8530drv", 0, &scc_net_seq_fops);
++ proc_net_fops_create(&init_net, "z8530drv", 0, &scc_net_seq_fops);
+
+ return 0;
+ }
+@@ -2169,7 +2170,7 @@
+ if (Vector_Latch)
+ release_region(Vector_Latch, 1);
+
+- proc_net_remove("z8530drv");
++ proc_net_remove(&init_net, "z8530drv");
+ }
+
+ MODULE_AUTHOR("Joerg Reuter <jreuter@yaina.de>");
+diff -Nurb linux-2.6.22-570/drivers/net/hamradio/yam.c linux-2.6.22-590/drivers/net/hamradio/yam.c
+--- linux-2.6.22-570/drivers/net/hamradio/yam.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/hamradio/yam.c 2008-01-29 22:12:31.000000000 -0500
+@@ -61,6 +61,7 @@
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+ #include <net/ax25.h>
++#include <net/net_namespace.h>
+
+ #include <linux/kernel.h>
+ #include <linux/proc_fs.h>
+@@ -1142,7 +1143,7 @@
+ yam_timer.expires = jiffies + HZ / 100;
+ add_timer(&yam_timer);
+
+- proc_net_fops_create("yam", S_IRUGO, &yam_info_fops);
++ proc_net_fops_create(&init_net, "yam", S_IRUGO, &yam_info_fops);
+ return 0;
+ error:
+ while (--i >= 0) {
+@@ -1174,7 +1175,7 @@
+ kfree(p);
+ }
+
+- proc_net_remove("yam");
++ proc_net_remove(&init_net, "yam");
+ }
+
+ /* --------------------------------------------------------------------- */
diff -Nurb linux-2.6.22-570/drivers/net/ibmveth.c linux-2.6.22-590/drivers/net/ibmveth.c
--- linux-2.6.22-570/drivers/net/ibmveth.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/ibmveth.c 2008-03-15 10:35:46.000000000 -0400
-@@ -1337,7 +1337,7 @@
++++ linux-2.6.22-590/drivers/net/ibmveth.c 2008-01-29 22:12:31.000000000 -0500
+@@ -47,6 +47,7 @@
+ #include <linux/mm.h>
+ #include <linux/ethtool.h>
+ #include <linux/proc_fs.h>
++#include <net/net_namespace.h>
+ #include <asm/semaphore.h>
+ #include <asm/hvcall.h>
+ #include <asm/atomic.h>
+@@ -97,7 +98,7 @@
+ static struct kobj_type ktype_veth_pool;
+
+ #ifdef CONFIG_PROC_FS
+-#define IBMVETH_PROC_DIR "net/ibmveth"
++#define IBMVETH_PROC_DIR "ibmveth"
+ static struct proc_dir_entry *ibmveth_proc_dir;
+ #endif
+
+@@ -1093,7 +1094,7 @@
+ #ifdef CONFIG_PROC_FS
+ static void ibmveth_proc_register_driver(void)
+ {
+- ibmveth_proc_dir = proc_mkdir(IBMVETH_PROC_DIR, NULL);
++ ibmveth_proc_dir = proc_mkdir(IBMVETH_PROC_DIR, init_net.proc_net);
+ if (ibmveth_proc_dir) {
+ SET_MODULE_OWNER(ibmveth_proc_dir);
+ }
+@@ -1101,7 +1102,7 @@
+
+ static void ibmveth_proc_unregister_driver(void)
+ {
+- remove_proc_entry(IBMVETH_PROC_DIR, NULL);
++ remove_proc_entry(IBMVETH_PROC_DIR, init_net.proc_net);
+ }
+
+ static void *ibmveth_seq_start(struct seq_file *seq, loff_t *pos)
+@@ -1337,7 +1338,7 @@
#define ATTR(_name, _mode) \
struct attribute veth_##_name##_attr = { \
static ATTR(active, 0644);
diff -Nurb linux-2.6.22-570/drivers/net/ifb.c linux-2.6.22-590/drivers/net/ifb.c
--- linux-2.6.22-570/drivers/net/ifb.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/ifb.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/ifb.c 2008-01-29 22:12:31.000000000 -0500
@@ -33,12 +33,15 @@
#include <linux/etherdevice.h>
#include <linux/init.h>
+MODULE_ALIAS_RTNL_LINK("ifb");
diff -Nurb linux-2.6.22-570/drivers/net/ixp2000/ixpdev.c linux-2.6.22-590/drivers/net/ixp2000/ixpdev.c
--- linux-2.6.22-570/drivers/net/ixp2000/ixpdev.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/ixp2000/ixpdev.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/ixp2000/ixpdev.c 2008-01-29 22:12:31.000000000 -0500
@@ -111,7 +111,7 @@
skb = dev_alloc_skb(desc->pkt_length + 2);
if (likely(skb != NULL)) {
diff -Nurb linux-2.6.22-570/drivers/net/kgdboe.c linux-2.6.22-590/drivers/net/kgdboe.c
--- linux-2.6.22-570/drivers/net/kgdboe.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/net/kgdboe.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/kgdboe.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,294 @@
+/*
+ * drivers/net/kgdboe.c
+ "[tgt-port]@<tgt-ip>/<tgt-macaddr>\n");
diff -Nurb linux-2.6.22-570/drivers/net/lance.c linux-2.6.22-590/drivers/net/lance.c
--- linux-2.6.22-570/drivers/net/lance.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/lance.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/lance.c 2008-01-29 22:12:31.000000000 -0500
@@ -1186,9 +1186,9 @@
}
skb_reserve(skb,2); /* 16 byte align */
skb->protocol=eth_type_trans(skb,dev);
netif_rx(skb);
dev->last_rx = jiffies;
+diff -Nurb linux-2.6.22-570/drivers/net/loopback.c linux-2.6.22-590/drivers/net/loopback.c
+--- linux-2.6.22-570/drivers/net/loopback.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/loopback.c 2008-01-29 22:12:31.000000000 -0500
+@@ -57,6 +57,7 @@
+ #include <linux/ip.h>
+ #include <linux/tcp.h>
+ #include <linux/percpu.h>
++#include <net/net_namespace.h>
+
+ struct pcpu_lstats {
+ unsigned long packets;
+@@ -199,39 +200,52 @@
+ .get_rx_csum = always_on,
+ };
+
++static int loopback_net_init(struct net *net)
++{
++ struct net_device *lo = &net->loopback_dev;
+ /*
+ * The loopback device is special. There is only one instance and
+ * it is statically allocated. Don't do this for other devices.
+ */
+-struct net_device loopback_dev = {
+- .name = "lo",
+- .get_stats = &get_stats,
+- .mtu = (16 * 1024) + 20 + 20 + 12,
+- .hard_start_xmit = loopback_xmit,
+- .hard_header = eth_header,
+- .hard_header_cache = eth_header_cache,
+- .header_cache_update = eth_header_cache_update,
+- .hard_header_len = ETH_HLEN, /* 14 */
+- .addr_len = ETH_ALEN, /* 6 */
+- .tx_queue_len = 0,
+- .type = ARPHRD_LOOPBACK, /* 0x0001*/
+- .rebuild_header = eth_rebuild_header,
+- .flags = IFF_LOOPBACK,
+- .features = NETIF_F_SG | NETIF_F_FRAGLIST
++ strcpy(lo->name, "lo");
++ lo->get_stats = &get_stats,
++ lo->mtu = (16 * 1024) + 20 + 20 + 12,
++ lo->hard_start_xmit = loopback_xmit,
++ lo->hard_header = eth_header,
++ lo->hard_header_cache = eth_header_cache,
++ lo->header_cache_update = eth_header_cache_update,
++ lo->hard_header_len = ETH_HLEN, /* 14 */
++ lo->addr_len = ETH_ALEN, /* 6 */
++ lo->tx_queue_len = 0,
++ lo->type = ARPHRD_LOOPBACK, /* 0x0001*/
++ lo->rebuild_header = eth_rebuild_header,
++ lo->flags = IFF_LOOPBACK,
++ lo->features = NETIF_F_SG | NETIF_F_FRAGLIST
+ #ifdef LOOPBACK_TSO
+ | NETIF_F_TSO
+ #endif
+ | NETIF_F_NO_CSUM | NETIF_F_HIGHDMA
+- | NETIF_F_LLTX,
+- .ethtool_ops = &loopback_ethtool_ops,
++ | NETIF_F_LLTX
++ | NETIF_F_NETNS_LOCAL,
++ lo->ethtool_ops = &loopback_ethtool_ops,
++ lo->nd_net = net;
++ return register_netdev(lo);
++}
++
++static void loopback_net_exit(struct net *net)
++{
++ unregister_netdev(&net->loopback_dev);
++}
++
++static struct pernet_operations loopback_net_ops = {
++ .init = loopback_net_init,
++ .exit = loopback_net_exit,
+ };
+
+ /* Setup and register the loopback device. */
+ static int __init loopback_init(void)
+ {
+- return register_netdev(&loopback_dev);
++ return register_pernet_device(&loopback_net_ops);
+ };
+
+ module_init(loopback_init);
+-
+-EXPORT_SYMBOL(loopback_dev);
diff -Nurb linux-2.6.22-570/drivers/net/natsemi.c linux-2.6.22-590/drivers/net/natsemi.c
---- linux-2.6.22-570/drivers/net/natsemi.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/natsemi.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/drivers/net/natsemi.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/drivers/net/natsemi.c 2008-01-29 22:12:31.000000000 -0500
@@ -2357,8 +2357,8 @@
np->rx_dma[entry],
buflen,
np->rx_dma[entry],
diff -Nurb linux-2.6.22-570/drivers/net/ni52.c linux-2.6.22-590/drivers/net/ni52.c
--- linux-2.6.22-570/drivers/net/ni52.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/ni52.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/ni52.c 2008-01-29 22:12:31.000000000 -0500
@@ -936,7 +936,7 @@
{
skb_reserve(skb,2);
dev->last_rx = jiffies;
diff -Nurb linux-2.6.22-570/drivers/net/ni65.c linux-2.6.22-590/drivers/net/ni65.c
--- linux-2.6.22-570/drivers/net/ni65.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/ni65.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/ni65.c 2008-01-29 22:12:31.000000000 -0500
@@ -1096,7 +1096,7 @@
#ifdef RCV_VIA_SKB
if( (unsigned long) (skb->data + R_BUF_SIZE) > 0x1000000) {
p->stats.rx_bytes += len;
diff -Nurb linux-2.6.22-570/drivers/net/pci-skeleton.c linux-2.6.22-590/drivers/net/pci-skeleton.c
--- linux-2.6.22-570/drivers/net/pci-skeleton.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/pci-skeleton.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/pci-skeleton.c 2008-01-29 22:12:31.000000000 -0500
@@ -1567,7 +1567,7 @@
if (skb) {
skb_reserve (skb, 2); /* 16 byte align the IP fields. */
skb->protocol = eth_type_trans (skb, dev);
diff -Nurb linux-2.6.22-570/drivers/net/pcnet32.c linux-2.6.22-590/drivers/net/pcnet32.c
--- linux-2.6.22-570/drivers/net/pcnet32.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/pcnet32.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/pcnet32.c 2008-01-29 22:12:31.000000000 -0500
@@ -1235,9 +1235,9 @@
lp->rx_dma_addr[entry],
pkt_len,
pci_dma_sync_single_for_device(lp->pci_dev,
lp->rx_dma_addr[entry],
pkt_len,
+diff -Nurb linux-2.6.22-570/drivers/net/pppoe.c linux-2.6.22-590/drivers/net/pppoe.c
+--- linux-2.6.22-570/drivers/net/pppoe.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/pppoe.c 2008-01-29 22:12:31.000000000 -0500
+@@ -78,6 +78,7 @@
+ #include <linux/proc_fs.h>
+ #include <linux/seq_file.h>
+
++#include <net/net_namespace.h>
+ #include <net/sock.h>
+
+ #include <asm/uaccess.h>
+@@ -210,7 +211,7 @@
+ struct net_device *dev;
+ int ifindex;
+
+- dev = dev_get_by_name(sp->sa_addr.pppoe.dev);
++ dev = dev_get_by_name(&init_net, sp->sa_addr.pppoe.dev);
+ if(!dev)
+ return NULL;
+ ifindex = dev->ifindex;
+@@ -295,6 +296,9 @@
+ {
+ struct net_device *dev = (struct net_device *) ptr;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ /* Only look at sockets that are using this specific device. */
+ switch (event) {
+ case NETDEV_CHANGEMTU:
+@@ -380,6 +384,9 @@
+ struct pppoe_hdr *ph;
+ struct pppox_sock *po;
+
++ if (dev->nd_net != &init_net)
++ goto drop;
++
+ if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
+ goto drop;
+
+@@ -412,6 +419,9 @@
+ struct pppoe_hdr *ph;
+ struct pppox_sock *po;
+
++ if (dev->nd_net != &init_net)
++ goto abort;
++
+ if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
+ goto abort;
+
+@@ -471,12 +481,12 @@
+ * Initialize a new struct sock.
+ *
+ **********************************************************************/
+-static int pppoe_create(struct socket *sock)
++static int pppoe_create(struct net *net, struct socket *sock)
+ {
+ int error = -ENOMEM;
+ struct sock *sk;
+
+- sk = sk_alloc(PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto, 1);
++ sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto, 1);
+ if (!sk)
+ goto out;
+
+@@ -588,7 +598,7 @@
+
+ /* Don't re-bind if sid==0 */
+ if (sp->sa_addr.pppoe.sid != 0) {
+- dev = dev_get_by_name(sp->sa_addr.pppoe.dev);
++ dev = dev_get_by_name(&init_net, sp->sa_addr.pppoe.dev);
+
+ error = -ENODEV;
+ if (!dev)
+@@ -1064,7 +1074,7 @@
+ {
+ struct proc_dir_entry *p;
+
+- p = create_proc_entry("net/pppoe", S_IRUGO, NULL);
++ p = create_proc_entry("pppoe", S_IRUGO, init_net.proc_net);
+ if (!p)
+ return -ENOMEM;
+
+@@ -1135,7 +1145,7 @@
+ dev_remove_pack(&pppoes_ptype);
+ dev_remove_pack(&pppoed_ptype);
+ unregister_netdevice_notifier(&pppoe_notifier);
+- remove_proc_entry("net/pppoe", NULL);
++ remove_proc_entry("pppoe", init_net.proc_net);
+ proto_unregister(&pppoe_sk_proto);
+ }
+
+diff -Nurb linux-2.6.22-570/drivers/net/pppox.c linux-2.6.22-590/drivers/net/pppox.c
+--- linux-2.6.22-570/drivers/net/pppox.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/pppox.c 2008-01-29 22:12:31.000000000 -0500
+@@ -107,10 +107,13 @@
+
+ EXPORT_SYMBOL(pppox_ioctl);
+
+-static int pppox_create(struct socket *sock, int protocol)
++static int pppox_create(struct net *net, struct socket *sock, int protocol)
+ {
+ int rc = -EPROTOTYPE;
+
++ if (net != &init_net)
++ return -EAFNOSUPPORT;
++
+ if (protocol < 0 || protocol > PX_MAX_PROTO)
+ goto out;
+
+@@ -126,7 +129,7 @@
+ !try_module_get(pppox_protos[protocol]->owner))
+ goto out;
+
+- rc = pppox_protos[protocol]->create(sock);
++ rc = pppox_protos[protocol]->create(net, sock);
+
+ module_put(pppox_protos[protocol]->owner);
+ out:
diff -Nurb linux-2.6.22-570/drivers/net/r8169.c linux-2.6.22-590/drivers/net/r8169.c
---- linux-2.6.22-570/drivers/net/r8169.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/r8169.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/drivers/net/r8169.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/drivers/net/r8169.c 2008-01-29 22:12:31.000000000 -0500
@@ -2492,7 +2492,7 @@
skb = dev_alloc_skb(pkt_size + align);
if (skb) {
ret = 0;
diff -Nurb linux-2.6.22-570/drivers/net/saa9730.c linux-2.6.22-590/drivers/net/saa9730.c
--- linux-2.6.22-570/drivers/net/saa9730.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/saa9730.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/saa9730.c 2008-01-29 22:12:31.000000000 -0500
@@ -690,9 +690,9 @@
lp->stats.rx_packets++;
skb_reserve(skb, 2); /* 16 byte align */
dev->last_rx = jiffies;
diff -Nurb linux-2.6.22-570/drivers/net/sgiseeq.c linux-2.6.22-590/drivers/net/sgiseeq.c
--- linux-2.6.22-570/drivers/net/sgiseeq.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/sgiseeq.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/sgiseeq.c 2008-01-29 22:12:31.000000000 -0500
@@ -320,7 +320,7 @@
skb_put(skb, len);
skb->protocol = eth_type_trans(skb, dev);
/* We don't want to receive our own packets */
+diff -Nurb linux-2.6.22-570/drivers/net/shaper.c linux-2.6.22-590/drivers/net/shaper.c
+--- linux-2.6.22-570/drivers/net/shaper.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/shaper.c 2008-01-29 22:12:31.000000000 -0500
+@@ -86,6 +86,7 @@
+
+ #include <net/dst.h>
+ #include <net/arp.h>
++#include <net/net_namespace.h>
+
+ struct shaper_cb {
+ unsigned long shapeclock; /* Time it should go out */
+@@ -488,7 +489,7 @@
+ {
+ case SHAPER_SET_DEV:
+ {
+- struct net_device *them=__dev_get_by_name(ss->ss_name);
++ struct net_device *them=__dev_get_by_name(&init_net, ss->ss_name);
+ if(them==NULL)
+ return -ENODEV;
+ if(sh->dev)
diff -Nurb linux-2.6.22-570/drivers/net/sis190.c linux-2.6.22-590/drivers/net/sis190.c
--- linux-2.6.22-570/drivers/net/sis190.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/sis190.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/sis190.c 2008-01-29 22:12:31.000000000 -0500
@@ -548,7 +548,7 @@
skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
if (skb) {
ret = 0;
diff -Nurb linux-2.6.22-570/drivers/net/starfire.c linux-2.6.22-590/drivers/net/starfire.c
--- linux-2.6.22-570/drivers/net/starfire.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/starfire.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/starfire.c 2008-01-29 22:12:31.000000000 -0500
@@ -1456,7 +1456,7 @@
pci_dma_sync_single_for_cpu(np->pci_dev,
np->rx_info[entry].mapping,
pkt_len, PCI_DMA_FROMDEVICE);
diff -Nurb linux-2.6.22-570/drivers/net/sun3_82586.c linux-2.6.22-590/drivers/net/sun3_82586.c
--- linux-2.6.22-570/drivers/net/sun3_82586.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/sun3_82586.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/sun3_82586.c 2008-01-29 22:12:31.000000000 -0500
@@ -777,7 +777,7 @@
{
skb_reserve(skb,2);
p->stats.rx_packets++;
diff -Nurb linux-2.6.22-570/drivers/net/sun3lance.c linux-2.6.22-590/drivers/net/sun3lance.c
--- linux-2.6.22-570/drivers/net/sun3lance.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/sun3lance.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/sun3lance.c 2008-01-29 22:12:31.000000000 -0500
@@ -853,10 +853,9 @@
skb_reserve( skb, 2 ); /* 16 byte align */
netif_rx( skb );
diff -Nurb linux-2.6.22-570/drivers/net/sunbmac.c linux-2.6.22-590/drivers/net/sunbmac.c
--- linux-2.6.22-570/drivers/net/sunbmac.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/sunbmac.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/sunbmac.c 2008-01-29 22:12:31.000000000 -0500
@@ -860,7 +860,7 @@
sbus_dma_sync_single_for_cpu(bp->bigmac_sdev,
this->rx_addr, len,
SBUS_DMA_FROMDEVICE);
diff -Nurb linux-2.6.22-570/drivers/net/sundance.c linux-2.6.22-590/drivers/net/sundance.c
--- linux-2.6.22-570/drivers/net/sundance.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/sundance.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/sundance.c 2008-01-29 22:12:31.000000000 -0500
@@ -1313,7 +1313,7 @@
np->rx_buf_sz,
PCI_DMA_FROMDEVICE);
np->rx_buf_sz,
diff -Nurb linux-2.6.22-570/drivers/net/sunlance.c linux-2.6.22-590/drivers/net/sunlance.c
--- linux-2.6.22-570/drivers/net/sunlance.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/sunlance.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/sunlance.c 2008-01-29 22:12:31.000000000 -0500
@@ -549,9 +549,9 @@
skb_reserve(skb, 2); /* 16 byte align */
dev->last_rx = jiffies;
diff -Nurb linux-2.6.22-570/drivers/net/sunqe.c linux-2.6.22-590/drivers/net/sunqe.c
--- linux-2.6.22-570/drivers/net/sunqe.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/sunqe.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/sunqe.c 2008-01-29 22:12:31.000000000 -0500
@@ -439,8 +439,8 @@
} else {
skb_reserve(skb, 2);
qep->dev->last_rx = jiffies;
diff -Nurb linux-2.6.22-570/drivers/net/tg3.c linux-2.6.22-590/drivers/net/tg3.c
--- linux-2.6.22-570/drivers/net/tg3.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/tg3.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/tg3.c 2008-01-29 22:12:31.000000000 -0500
@@ -11944,12 +11944,11 @@
* checksumming.
*/
tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
} else
tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS;
+diff -Nurb linux-2.6.22-570/drivers/net/tokenring/lanstreamer.c linux-2.6.22-590/drivers/net/tokenring/lanstreamer.c
+--- linux-2.6.22-570/drivers/net/tokenring/lanstreamer.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/tokenring/lanstreamer.c 2008-01-29 22:12:31.000000000 -0500
+@@ -250,7 +250,7 @@
+ #if STREAMER_NETWORK_MONITOR
+ #ifdef CONFIG_PROC_FS
+ if (!dev_streamer)
+- create_proc_read_entry("net/streamer_tr", 0, 0,
++ create_proc_read_entry("streamer_tr", 0, init_net.proc_net,
+ streamer_proc_info, NULL);
+ streamer_priv->next = dev_streamer;
+ dev_streamer = streamer_priv;
+@@ -423,7 +423,7 @@
+ }
+ }
+ if (!dev_streamer)
+- remove_proc_entry("net/streamer_tr", NULL);
++ remove_proc_entry("streamer_tr", init_net.proc_net);
+ }
+ #endif
+ #endif
+diff -Nurb linux-2.6.22-570/drivers/net/tokenring/olympic.c linux-2.6.22-590/drivers/net/tokenring/olympic.c
+--- linux-2.6.22-570/drivers/net/tokenring/olympic.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/tokenring/olympic.c 2008-01-29 22:12:31.000000000 -0500
+@@ -101,6 +101,7 @@
+ #include <linux/bitops.h>
+ #include <linux/jiffies.h>
+
++#include <net/net_namespace.h>
+ #include <net/checksum.h>
+
+ #include <asm/io.h>
+@@ -268,9 +269,9 @@
+ printk("Olympic: %s registered as: %s\n",olympic_priv->olympic_card_name,dev->name);
+ if (olympic_priv->olympic_network_monitor) { /* Must go after register_netdev as we need the device name */
+ char proc_name[20] ;
+- strcpy(proc_name,"net/olympic_") ;
++ strcpy(proc_name,"olympic_") ;
+ strcat(proc_name,dev->name) ;
+- create_proc_read_entry(proc_name,0,NULL,olympic_proc_info,(void *)dev) ;
++ create_proc_read_entry(proc_name,0,init_net.proc_net,olympic_proc_info,(void *)dev) ;
+ printk("Olympic: Network Monitor information: /proc/%s\n",proc_name);
+ }
+ return 0 ;
+@@ -1752,9 +1753,9 @@
+
+ if (olympic_priv->olympic_network_monitor) {
+ char proc_name[20] ;
+- strcpy(proc_name,"net/olympic_") ;
++ strcpy(proc_name,"olympic_") ;
+ strcat(proc_name,dev->name) ;
+- remove_proc_entry(proc_name,NULL);
++ remove_proc_entry(proc_name,init_net.proc_net);
+ }
+ unregister_netdev(dev) ;
+ iounmap(olympic_priv->olympic_mmio) ;
diff -Nurb linux-2.6.22-570/drivers/net/tulip/interrupt.c linux-2.6.22-590/drivers/net/tulip/interrupt.c
--- linux-2.6.22-570/drivers/net/tulip/interrupt.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/tulip/interrupt.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/tulip/interrupt.c 2008-01-29 22:12:31.000000000 -0500
@@ -197,8 +197,8 @@
tp->rx_buffers[entry].mapping,
pkt_len, PCI_DMA_FROMDEVICE);
memcpy(skb_put(skb, pkt_len),
diff -Nurb linux-2.6.22-570/drivers/net/tulip/winbond-840.c linux-2.6.22-590/drivers/net/tulip/winbond-840.c
--- linux-2.6.22-570/drivers/net/tulip/winbond-840.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/tulip/winbond-840.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/tulip/winbond-840.c 2008-01-29 22:12:31.000000000 -0500
@@ -1232,7 +1232,7 @@
pci_dma_sync_single_for_cpu(np->pci_dev,np->rx_addr[entry],
np->rx_skbuff[entry]->len,
np->rx_skbuff[entry]->len,
diff -Nurb linux-2.6.22-570/drivers/net/tulip/xircom_cb.c linux-2.6.22-590/drivers/net/tulip/xircom_cb.c
--- linux-2.6.22-570/drivers/net/tulip/xircom_cb.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/tulip/xircom_cb.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/tulip/xircom_cb.c 2008-01-29 22:12:31.000000000 -0500
@@ -1208,7 +1208,7 @@
goto out;
}
netif_rx(skb);
diff -Nurb linux-2.6.22-570/drivers/net/tulip/xircom_tulip_cb.c linux-2.6.22-590/drivers/net/tulip/xircom_tulip_cb.c
--- linux-2.6.22-570/drivers/net/tulip/xircom_tulip_cb.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/tulip/xircom_tulip_cb.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/tulip/xircom_tulip_cb.c 2008-01-29 22:12:31.000000000 -0500
@@ -1242,8 +1242,8 @@
&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
skb_reserve(skb, 2); /* 16 byte align the IP header */
memcpy(skb_put(skb, pkt_len),
diff -Nurb linux-2.6.22-570/drivers/net/tun.c linux-2.6.22-590/drivers/net/tun.c
--- linux-2.6.22-570/drivers/net/tun.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/tun.c 2008-03-15 10:35:46.000000000 -0400
-@@ -432,6 +432,7 @@
++++ linux-2.6.22-590/drivers/net/tun.c 2008-01-29 22:12:31.000000000 -0500
+@@ -62,6 +62,7 @@
+ #include <linux/if_ether.h>
+ #include <linux/if_tun.h>
+ #include <linux/crc32.h>
++#include <net/net_namespace.h>
+
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+@@ -432,6 +433,7 @@
init_waitqueue_head(&tun->read_wait);
tun->owner = -1;
SET_MODULE_OWNER(dev);
dev->open = tun_net_open;
-@@ -467,8 +468,11 @@
+@@ -467,11 +469,14 @@
return -EBUSY;
/* Check permissions */
+ !capable(CAP_NET_ADMIN))
return -EPERM;
}
- else if (__dev_get_by_name(ifr->ifr_name))
-@@ -610,6 +614,13 @@
+- else if (__dev_get_by_name(ifr->ifr_name))
++ else if (__dev_get_by_name(&init_net, ifr->ifr_name))
+ return -EINVAL;
+ else {
+ char *name;
+@@ -610,6 +615,13 @@
DBG(KERN_INFO "%s: owner set to %d\n", tun->dev->name, tun->owner);
break;
if (tun->dev->flags & IFF_UP) {
diff -Nurb linux-2.6.22-570/drivers/net/typhoon.c linux-2.6.22-590/drivers/net/typhoon.c
--- linux-2.6.22-570/drivers/net/typhoon.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/typhoon.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/typhoon.c 2008-01-29 22:12:31.000000000 -0500
@@ -1703,7 +1703,7 @@
pci_dma_sync_single_for_cpu(tp->pdev, dma_addr,
PKT_BUF_SZ,
PCI_DMA_FROMDEVICE);
diff -Nurb linux-2.6.22-570/drivers/net/usb/catc.c linux-2.6.22-590/drivers/net/usb/catc.c
--- linux-2.6.22-570/drivers/net/usb/catc.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/usb/catc.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/usb/catc.c 2008-01-29 22:12:31.000000000 -0500
@@ -255,7 +255,7 @@
if (!(skb = dev_alloc_skb(pkt_len)))
return;
skb->protocol = eth_type_trans(skb, catc->netdev);
diff -Nurb linux-2.6.22-570/drivers/net/usb/kaweth.c linux-2.6.22-590/drivers/net/usb/kaweth.c
--- linux-2.6.22-570/drivers/net/usb/kaweth.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/usb/kaweth.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/usb/kaweth.c 2008-01-29 22:12:31.000000000 -0500
@@ -635,7 +635,7 @@
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
diff -Nurb linux-2.6.22-570/drivers/net/via-rhine.c linux-2.6.22-590/drivers/net/via-rhine.c
--- linux-2.6.22-570/drivers/net/via-rhine.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/via-rhine.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/via-rhine.c 2008-01-29 22:12:31.000000000 -0500
@@ -1492,9 +1492,9 @@
rp->rx_buf_sz,
PCI_DMA_FROMDEVICE);
skb_put(skb, pkt_len);
pci_dma_sync_single_for_device(rp->pdev,
rp->rx_skbuff_dma[entry],
+diff -Nurb linux-2.6.22-570/drivers/net/wan/dlci.c linux-2.6.22-590/drivers/net/wan/dlci.c
+--- linux-2.6.22-570/drivers/net/wan/dlci.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/wan/dlci.c 2008-01-29 22:12:31.000000000 -0500
+@@ -361,7 +361,7 @@
+
+
+ /* validate slave device */
+- slave = dev_get_by_name(dlci->devname);
++ slave = dev_get_by_name(&init_net, dlci->devname);
+ if (!slave)
+ return -ENODEV;
+
+@@ -427,7 +427,7 @@
+ int err;
+
+ /* validate slave device */
+- master = __dev_get_by_name(dlci->devname);
++ master = __dev_get_by_name(&init_net, dlci->devname);
+ if (!master)
+ return(-ENODEV);
+
+@@ -513,6 +513,9 @@
+ {
+ struct net_device *dev = (struct net_device *) ptr;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ if (event == NETDEV_UNREGISTER) {
+ struct dlci_local *dlp;
+
+diff -Nurb linux-2.6.22-570/drivers/net/wan/hdlc.c linux-2.6.22-590/drivers/net/wan/hdlc.c
+--- linux-2.6.22-570/drivers/net/wan/hdlc.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/wan/hdlc.c 2008-01-29 22:12:31.000000000 -0500
+@@ -36,6 +36,7 @@
+ #include <linux/rtnetlink.h>
+ #include <linux/notifier.h>
+ #include <linux/hdlc.h>
++#include <net/net_namespace.h>
+
+
+ static const char* version = "HDLC support module revision 1.21";
+@@ -66,6 +67,12 @@
+ struct packet_type *p, struct net_device *orig_dev)
+ {
+ struct hdlc_device_desc *desc = dev_to_desc(dev);
++
++ if (dev->nd_net != &init_net) {
++ kfree_skb(skb);
++ return 0;
++ }
++
+ if (desc->netif_rx)
+ return desc->netif_rx(skb);
+
+@@ -102,6 +109,9 @@
+ unsigned long flags;
+ int on;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ if (dev->get_stats != hdlc_get_stats)
+ return NOTIFY_DONE; /* not an HDLC device */
+
+diff -Nurb linux-2.6.22-570/drivers/net/wan/lapbether.c linux-2.6.22-590/drivers/net/wan/lapbether.c
+--- linux-2.6.22-570/drivers/net/wan/lapbether.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/wan/lapbether.c 2008-01-29 22:12:31.000000000 -0500
+@@ -91,6 +91,9 @@
+ int len, err;
+ struct lapbethdev *lapbeth;
+
++ if (dev->nd_net != &init_net)
++ goto drop;
++
+ if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
+ return NET_RX_DROP;
+
+@@ -391,6 +394,9 @@
+ struct lapbethdev *lapbeth;
+ struct net_device *dev = ptr;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ if (!dev_is_ethdev(dev))
+ return NOTIFY_DONE;
+
+diff -Nurb linux-2.6.22-570/drivers/net/wan/sbni.c linux-2.6.22-590/drivers/net/wan/sbni.c
+--- linux-2.6.22-570/drivers/net/wan/sbni.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/wan/sbni.c 2008-01-29 22:12:31.000000000 -0500
+@@ -54,6 +54,7 @@
+ #include <linux/init.h>
+ #include <linux/delay.h>
+
++#include <net/net_namespace.h>
+ #include <net/arp.h>
+
+ #include <asm/io.h>
+@@ -1362,7 +1363,7 @@
+
+ if (copy_from_user( slave_name, ifr->ifr_data, sizeof slave_name ))
+ return -EFAULT;
+- slave_dev = dev_get_by_name( slave_name );
++ slave_dev = dev_get_by_name(&init_net, slave_name );
+ if( !slave_dev || !(slave_dev->flags & IFF_UP) ) {
+ printk( KERN_ERR "%s: trying to enslave non-active "
+ "device %s\n", dev->name, slave_name );
+diff -Nurb linux-2.6.22-570/drivers/net/wan/syncppp.c linux-2.6.22-590/drivers/net/wan/syncppp.c
+--- linux-2.6.22-570/drivers/net/wan/syncppp.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/wan/syncppp.c 2008-01-29 22:12:31.000000000 -0500
+@@ -51,6 +51,7 @@
+ #include <linux/spinlock.h>
+ #include <linux/rcupdate.h>
+
++#include <net/net_namespace.h>
+ #include <net/syncppp.h>
+
+ #include <asm/byteorder.h>
+@@ -1445,6 +1446,11 @@
+
+ static int sppp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *p, struct net_device *orig_dev)
+ {
++ if (dev->nd_net != &init_net) {
++ kfree_skb(skb);
++ return 0;
++ }
++
+ if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
+ return NET_RX_DROP;
+ sppp_input(dev,skb);
diff -Nurb linux-2.6.22-570/drivers/net/wireless/airo.c linux-2.6.22-590/drivers/net/wireless/airo.c
--- linux-2.6.22-570/drivers/net/wireless/airo.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/wireless/airo.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/wireless/airo.c 2008-01-29 22:12:31.000000000 -0500
@@ -3079,6 +3079,7 @@
struct airo_info *ai = dev->priv;
int locked;
while(1) {
/* make swsusp happy with our thread */
try_to_freeze();
+diff -Nurb linux-2.6.22-570/drivers/net/wireless/hostap/hostap_main.c linux-2.6.22-590/drivers/net/wireless/hostap/hostap_main.c
+--- linux-2.6.22-570/drivers/net/wireless/hostap/hostap_main.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/wireless/hostap/hostap_main.c 2008-01-29 22:12:31.000000000 -0500
+@@ -24,6 +24,7 @@
+ #include <linux/rtnetlink.h>
+ #include <linux/wireless.h>
+ #include <linux/etherdevice.h>
++#include <net/net_namespace.h>
+ #include <net/iw_handler.h>
+ #include <net/ieee80211.h>
+ #include <net/ieee80211_crypt.h>
+@@ -1094,8 +1095,8 @@
+
+ static int __init hostap_init(void)
+ {
+- if (proc_net != NULL) {
+- hostap_proc = proc_mkdir("hostap", proc_net);
++ if (init_net.proc_net != NULL) {
++ hostap_proc = proc_mkdir("hostap", init_net.proc_net);
+ if (!hostap_proc)
+ printk(KERN_WARNING "Failed to mkdir "
+ "/proc/net/hostap\n");
+@@ -1110,7 +1111,7 @@
+ {
+ if (hostap_proc != NULL) {
+ hostap_proc = NULL;
+- remove_proc_entry("hostap", proc_net);
++ remove_proc_entry("hostap", init_net.proc_net);
+ }
+ }
+
diff -Nurb linux-2.6.22-570/drivers/net/wireless/libertas/main.c linux-2.6.22-590/drivers/net/wireless/libertas/main.c
--- linux-2.6.22-570/drivers/net/wireless/libertas/main.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/wireless/libertas/main.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/wireless/libertas/main.c 2008-01-29 22:12:31.000000000 -0500
@@ -613,6 +613,7 @@
init_waitqueue_entry(&wait, current);
for (;;) {
lbs_deb_thread( "main-thread 111: intcounter=%d "
"currenttxskb=%p dnld_sent=%d\n",
+diff -Nurb linux-2.6.22-570/drivers/net/wireless/strip.c linux-2.6.22-590/drivers/net/wireless/strip.c
+--- linux-2.6.22-570/drivers/net/wireless/strip.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/net/wireless/strip.c 2008-01-29 22:12:31.000000000 -0500
+@@ -107,6 +107,7 @@
+ #include <linux/serialP.h>
+ #include <linux/rcupdate.h>
+ #include <net/arp.h>
++#include <net/net_namespace.h>
+
+ #include <linux/ip.h>
+ #include <linux/tcp.h>
+@@ -1971,7 +1972,7 @@
+ sizeof(zero_address))) {
+ struct net_device *dev;
+ read_lock_bh(&dev_base_lock);
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ if (dev->type == strip_info->dev->type &&
+ !memcmp(dev->dev_addr,
+ &strip_info->true_dev_addr,
+@@ -2787,7 +2788,7 @@
+ /*
+ * Register the status file with /proc
+ */
+- proc_net_fops_create("strip", S_IFREG | S_IRUGO, &strip_seq_fops);
++ proc_net_fops_create(&init_net, "strip", S_IFREG | S_IRUGO, &strip_seq_fops);
+
+ return status;
+ }
+@@ -2809,7 +2810,7 @@
+ }
+
+ /* Unregister with the /proc/net file here. */
+- proc_net_remove("strip");
++ proc_net_remove(&init_net, "strip");
+
+ if ((i = tty_unregister_ldisc(N_STRIP)))
+ printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i);
diff -Nurb linux-2.6.22-570/drivers/net/wireless/wl3501_cs.c linux-2.6.22-590/drivers/net/wireless/wl3501_cs.c
--- linux-2.6.22-570/drivers/net/wireless/wl3501_cs.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/wireless/wl3501_cs.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/wireless/wl3501_cs.c 2008-01-29 22:12:31.000000000 -0500
@@ -1011,7 +1011,7 @@
} else {
skb->dev = dev;
skb->protocol = eth_type_trans(skb, dev);
diff -Nurb linux-2.6.22-570/drivers/net/xen-netfront.c linux-2.6.22-590/drivers/net/xen-netfront.c
--- linux-2.6.22-570/drivers/net/xen-netfront.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/net/xen-netfront.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/xen-netfront.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,1995 @@
+/*
+ * Virtual network driver for conversing with remote driver backends.
+MODULE_LICENSE("GPL");
diff -Nurb linux-2.6.22-570/drivers/net/yellowfin.c linux-2.6.22-590/drivers/net/yellowfin.c
--- linux-2.6.22-570/drivers/net/yellowfin.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/net/yellowfin.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/net/yellowfin.c 2008-01-29 22:12:31.000000000 -0500
@@ -1137,7 +1137,7 @@
if (skb == NULL)
break;
skb_put(skb, pkt_len);
pci_dma_sync_single_for_device(yp->pci_dev, desc->addr,
yp->rx_buf_sz,
+diff -Nurb linux-2.6.22-570/drivers/parisc/led.c linux-2.6.22-590/drivers/parisc/led.c
+--- linux-2.6.22-570/drivers/parisc/led.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/parisc/led.c 2008-01-29 22:12:31.000000000 -0500
+@@ -359,7 +359,7 @@
+ * for reading should be OK */
+ read_lock(&dev_base_lock);
+ rcu_read_lock();
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ struct net_device_stats *stats;
+ struct in_device *in_dev = __in_dev_get_rcu(dev);
+ if (!in_dev || !in_dev->ifa_list)
diff -Nurb linux-2.6.22-570/drivers/parisc/pdc_stable.c linux-2.6.22-590/drivers/parisc/pdc_stable.c
--- linux-2.6.22-570/drivers/parisc/pdc_stable.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/parisc/pdc_stable.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/parisc/pdc_stable.c 2008-01-29 22:12:31.000000000 -0500
@@ -121,14 +121,14 @@
#define PDCS_ATTR(_name, _mode, _show, _store) \
};
diff -Nurb linux-2.6.22-570/drivers/pci/hotplug/acpiphp_ibm.c linux-2.6.22-590/drivers/pci/hotplug/acpiphp_ibm.c
--- linux-2.6.22-570/drivers/pci/hotplug/acpiphp_ibm.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/pci/hotplug/acpiphp_ibm.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/pci/hotplug/acpiphp_ibm.c 2008-01-29 22:12:31.000000000 -0500
@@ -106,6 +106,7 @@
static void ibm_handle_events(acpi_handle handle, u32 event, void *context);
static int ibm_get_table_from_acpi(char **bufp);
int bytes_read = -EINVAL;
diff -Nurb linux-2.6.22-570/drivers/pci/hotplug/rpadlpar_core.c linux-2.6.22-590/drivers/pci/hotplug/rpadlpar_core.c
--- linux-2.6.22-570/drivers/pci/hotplug/rpadlpar_core.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/pci/hotplug/rpadlpar_core.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/pci/hotplug/rpadlpar_core.c 2008-01-29 22:12:31.000000000 -0500
@@ -159,8 +159,8 @@
/* Claim new bus resources */
pcibios_claim_one_bus(dev->bus);
return -ERANGE;
diff -Nurb linux-2.6.22-570/drivers/pci/pci-sysfs.c linux-2.6.22-590/drivers/pci/pci-sysfs.c
--- linux-2.6.22-570/drivers/pci/pci-sysfs.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/pci/pci-sysfs.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/pci/pci-sysfs.c 2008-01-29 22:12:31.000000000 -0500
@@ -213,7 +213,8 @@
};
rom_attr->write = pci_write_rom;
retval = sysfs_create_bin_file(&pdev->dev.kobj, rom_attr);
diff -Nurb linux-2.6.22-570/drivers/pci/probe.c linux-2.6.22-590/drivers/pci/probe.c
---- linux-2.6.22-570/drivers/pci/probe.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/drivers/pci/probe.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/drivers/pci/probe.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/drivers/pci/probe.c 2008-01-29 22:12:31.000000000 -0500
@@ -39,7 +39,6 @@
b->legacy_io->attr.name = "legacy_io";
b->legacy_io->size = 0xffff;
class_device_create_bin_file(&b->class_dev, b->legacy_mem);
}
diff -Nurb linux-2.6.22-570/drivers/pcmcia/cs.c linux-2.6.22-590/drivers/pcmcia/cs.c
---- linux-2.6.22-570/drivers/pcmcia/cs.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/drivers/pcmcia/cs.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/drivers/pcmcia/cs.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/drivers/pcmcia/cs.c 2008-01-29 22:12:31.000000000 -0500
@@ -654,6 +654,7 @@
add_wait_queue(&skt->thread_wait, &wait);
complete(&skt->thread_done);
unsigned int events;
diff -Nurb linux-2.6.22-570/drivers/pcmcia/socket_sysfs.c linux-2.6.22-590/drivers/pcmcia/socket_sysfs.c
--- linux-2.6.22-570/drivers/pcmcia/socket_sysfs.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/pcmcia/socket_sysfs.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/pcmcia/socket_sysfs.c 2008-01-29 22:12:31.000000000 -0500
@@ -283,7 +283,9 @@
return (ret);
}
.write = pccard_store_cis,
diff -Nurb linux-2.6.22-570/drivers/pnp/driver.c linux-2.6.22-590/drivers/pnp/driver.c
--- linux-2.6.22-570/drivers/pnp/driver.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/pnp/driver.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/pnp/driver.c 2008-01-29 22:12:31.000000000 -0500
@@ -167,6 +167,8 @@
return error;
}
if (error)
diff -Nurb linux-2.6.22-570/drivers/pnp/pnpacpi/core.c linux-2.6.22-590/drivers/pnp/pnpacpi/core.c
--- linux-2.6.22-570/drivers/pnp/pnpacpi/core.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/pnp/pnpacpi/core.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/pnp/pnpacpi/core.c 2008-01-29 22:12:31.000000000 -0500
@@ -119,11 +119,23 @@
return ACPI_FAILURE(status) ? -ENODEV : 0;
}
static int __init pnpacpi_add_device(struct acpi_device *device)
diff -Nurb linux-2.6.22-570/drivers/pnp/pnpbios/core.c linux-2.6.22-590/drivers/pnp/pnpbios/core.c
--- linux-2.6.22-570/drivers/pnp/pnpbios/core.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/pnp/pnpbios/core.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/pnp/pnpbios/core.c 2008-01-29 22:12:31.000000000 -0500
@@ -147,7 +147,7 @@
info->location_id, info->serial, info->capabilities);
envp[i] = NULL;
int status;
diff -Nurb linux-2.6.22-570/drivers/rapidio/rio-sysfs.c linux-2.6.22-590/drivers/rapidio/rio-sysfs.c
--- linux-2.6.22-570/drivers/rapidio/rio-sysfs.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/rapidio/rio-sysfs.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/rapidio/rio-sysfs.c 2008-01-29 22:12:31.000000000 -0500
@@ -67,7 +67,8 @@
};
.read = rio_read_config,
diff -Nurb linux-2.6.22-570/drivers/rtc/rtc-ds1553.c linux-2.6.22-590/drivers/rtc/rtc-ds1553.c
--- linux-2.6.22-570/drivers/rtc/rtc-ds1553.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/rtc/rtc-ds1553.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/rtc/rtc-ds1553.c 2008-01-29 22:12:31.000000000 -0500
@@ -258,8 +258,9 @@
.ioctl = ds1553_rtc_ioctl,
};
.read = ds1553_nvram_read,
diff -Nurb linux-2.6.22-570/drivers/rtc/rtc-ds1742.c linux-2.6.22-590/drivers/rtc/rtc-ds1742.c
--- linux-2.6.22-570/drivers/rtc/rtc-ds1742.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/rtc/rtc-ds1742.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/rtc/rtc-ds1742.c 2008-01-29 22:12:31.000000000 -0500
@@ -127,8 +127,9 @@
.set_time = ds1742_rtc_set_time,
};
.write = ds1742_nvram_write,
diff -Nurb linux-2.6.22-570/drivers/s390/cio/chp.c linux-2.6.22-590/drivers/s390/cio/chp.c
--- linux-2.6.22-570/drivers/s390/cio/chp.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/s390/cio/chp.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/s390/cio/chp.c 2008-01-29 22:12:31.000000000 -0500
@@ -141,8 +141,9 @@
/*
* Channel measurement related functions
},
.size = sizeof(struct cmg_entry),
.read = chp_measurement_read,
+diff -Nurb linux-2.6.22-570/drivers/s390/net/qeth_main.c linux-2.6.22-590/drivers/s390/net/qeth_main.c
+--- linux-2.6.22-570/drivers/s390/net/qeth_main.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/s390/net/qeth_main.c 2008-01-29 22:12:31.000000000 -0500
+@@ -8127,7 +8127,7 @@
+ neigh->parms = neigh_parms_clone(parms);
+ rcu_read_unlock();
+
+- neigh->type = inet_addr_type(*(__be32 *) neigh->primary_key);
++ neigh->type = inet_addr_type(&init_net, *(__be32 *) neigh->primary_key);
+ neigh->nud_state = NUD_NOARP;
+ neigh->ops = arp_direct_ops;
+ neigh->output = neigh->ops->queue_xmit;
diff -Nurb linux-2.6.22-570/drivers/s390/net/qeth_sys.c linux-2.6.22-590/drivers/s390/net/qeth_sys.c
--- linux-2.6.22-570/drivers/s390/net/qeth_sys.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/s390/net/qeth_sys.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/s390/net/qeth_sys.c 2008-01-29 22:12:31.000000000 -0500
@@ -991,7 +991,7 @@
#define QETH_DEVICE_ATTR(_id,_name,_mode,_show,_store) \
};
diff -Nurb linux-2.6.22-570/drivers/s390/scsi/zfcp_aux.c linux-2.6.22-590/drivers/s390/scsi/zfcp_aux.c
--- linux-2.6.22-570/drivers/s390/scsi/zfcp_aux.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/s390/scsi/zfcp_aux.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/s390/scsi/zfcp_aux.c 2008-01-29 22:12:31.000000000 -0500
@@ -815,9 +815,7 @@
struct zfcp_unit *
zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun)
atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status);
diff -Nurb linux-2.6.22-570/drivers/s390/scsi/zfcp_erp.c linux-2.6.22-590/drivers/s390/scsi/zfcp_erp.c
--- linux-2.6.22-570/drivers/s390/scsi/zfcp_erp.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/s390/scsi/zfcp_erp.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/s390/scsi/zfcp_erp.c 2008-01-29 22:12:31.000000000 -0500
@@ -1986,6 +1986,10 @@
failed_openfcp:
zfcp_close_fsf(erp_action->adapter);
ZFCP_LOG_INFO("error: exchange of configuration data for "
diff -Nurb linux-2.6.22-570/drivers/sbus/char/bbc_envctrl.c linux-2.6.22-590/drivers/sbus/char/bbc_envctrl.c
--- linux-2.6.22-570/drivers/sbus/char/bbc_envctrl.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/sbus/char/bbc_envctrl.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/sbus/char/bbc_envctrl.c 2008-01-29 22:12:31.000000000 -0500
@@ -7,6 +7,7 @@
#include <linux/kthread.h>
#include <linux/delay.h>
diff -Nurb linux-2.6.22-570/drivers/sbus/char/envctrl.c linux-2.6.22-590/drivers/sbus/char/envctrl.c
--- linux-2.6.22-570/drivers/sbus/char/envctrl.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/sbus/char/envctrl.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/sbus/char/envctrl.c 2008-01-29 22:12:31.000000000 -0500
@@ -26,6 +26,7 @@
#include <linux/ioport.h>
#include <linux/miscdevice.h>
printk(KERN_CRIT "kenvctrld: WARNING: system shutdown failed!\n");
inprog = 0; /* unlikely to succeed, but we could try again */
diff -Nurb linux-2.6.22-570/drivers/scsi/3w-9xxx.c linux-2.6.22-590/drivers/scsi/3w-9xxx.c
---- linux-2.6.22-570/drivers/scsi/3w-9xxx.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/3w-9xxx.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/drivers/scsi/3w-9xxx.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/drivers/scsi/3w-9xxx.c 2008-01-29 22:12:31.000000000 -0500
@@ -1307,22 +1307,26 @@
wake_up(&tw_dev->ioctl_wqueue);
}
/* scsi_host_template initializer */
diff -Nurb linux-2.6.22-570/drivers/scsi/3w-xxxx.c linux-2.6.22-590/drivers/scsi/3w-xxxx.c
--- linux-2.6.22-570/drivers/scsi/3w-xxxx.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/3w-xxxx.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/3w-xxxx.c 2008-01-29 22:12:31.000000000 -0500
@@ -1274,12 +1274,8 @@
dprintk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data()\n");
diff -Nurb linux-2.6.22-570/drivers/scsi/53c700.c linux-2.6.22-590/drivers/scsi/53c700.c
--- linux-2.6.22-570/drivers/scsi/53c700.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/53c700.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/53c700.c 2008-01-29 22:12:31.000000000 -0500
@@ -585,16 +585,8 @@
struct NCR_700_command_slot *slot)
{
DEBUG((" scatter block %d: move %d[%08x] from 0x%lx\n",
diff -Nurb linux-2.6.22-570/drivers/scsi/53c700.h linux-2.6.22-590/drivers/scsi/53c700.h
--- linux-2.6.22-570/drivers/scsi/53c700.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/53c700.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/53c700.h 2008-01-29 22:12:31.000000000 -0500
@@ -177,6 +177,7 @@
__u8 state;
#define NCR_700_FLAG_AUTOSENSE 0x01
-#undef Ent_wait_reselect
diff -Nurb linux-2.6.22-570/drivers/scsi/BusLogic.c linux-2.6.22-590/drivers/scsi/BusLogic.c
--- linux-2.6.22-570/drivers/scsi/BusLogic.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/BusLogic.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/BusLogic.c 2008-01-29 22:12:31.000000000 -0500
@@ -304,16 +304,8 @@
static void BusLogic_DeallocateCCB(struct BusLogic_CCB *CCB)
{
case READ_10:
diff -Nurb linux-2.6.22-570/drivers/scsi/Kconfig linux-2.6.22-590/drivers/scsi/Kconfig
--- linux-2.6.22-570/drivers/scsi/Kconfig 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/Kconfig 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/Kconfig 2008-01-29 22:12:31.000000000 -0500
@@ -739,7 +739,7 @@
config SCSI_IBMMCA
depends on SUN3 && SCSI
diff -Nurb linux-2.6.22-570/drivers/scsi/Makefile linux-2.6.22-590/drivers/scsi/Makefile
--- linux-2.6.22-570/drivers/scsi/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/Makefile 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/Makefile 2008-01-29 22:12:31.000000000 -0500
@@ -37,7 +37,8 @@
obj-$(CONFIG_ISCSI_TCP) += libiscsi.o iscsi_tcp.o
diff -Nurb linux-2.6.22-570/drivers/scsi/NCR5380.c linux-2.6.22-590/drivers/scsi/NCR5380.c
--- linux-2.6.22-570/drivers/scsi/NCR5380.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/NCR5380.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/NCR5380.c 2008-01-29 22:12:31.000000000 -0500
@@ -347,7 +347,7 @@
if((r & bit) == val)
return 0;
struct NCR5380_hostdata *hostdata;
diff -Nurb linux-2.6.22-570/drivers/scsi/NCR5380.h linux-2.6.22-590/drivers/scsi/NCR5380.h
--- linux-2.6.22-570/drivers/scsi/NCR5380.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/NCR5380.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/NCR5380.h 2008-01-29 22:12:31.000000000 -0500
@@ -299,7 +299,7 @@
static irqreturn_t NCR5380_intr(int irq, void *dev_id);
#endif
static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag);
diff -Nurb linux-2.6.22-570/drivers/scsi/NCR53c406a.c linux-2.6.22-590/drivers/scsi/NCR53c406a.c
--- linux-2.6.22-570/drivers/scsi/NCR53c406a.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/NCR53c406a.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/NCR53c406a.c 2008-01-29 22:12:31.000000000 -0500
@@ -698,7 +698,7 @@
int i;
#endif /* USE_PIO */
diff -Nurb linux-2.6.22-570/drivers/scsi/a100u2w.c linux-2.6.22-590/drivers/scsi/a100u2w.c
--- linux-2.6.22-570/drivers/scsi/a100u2w.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/a100u2w.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/a100u2w.c 2008-01-29 22:12:31.000000000 -0500
@@ -19,27 +19,6 @@
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
scsi_host_put(shost);
diff -Nurb linux-2.6.22-570/drivers/scsi/a100u2w.h linux-2.6.22-590/drivers/scsi/a100u2w.h
--- linux-2.6.22-570/drivers/scsi/a100u2w.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/a100u2w.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/a100u2w.h 2008-01-29 22:12:31.000000000 -0500
@@ -18,27 +18,6 @@
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-#define ORC_WRLONG( adr,data) outl( (ULONG)(data), (int)(adr))
diff -Nurb linux-2.6.22-570/drivers/scsi/a4000t.c linux-2.6.22-590/drivers/scsi/a4000t.c
--- linux-2.6.22-570/drivers/scsi/a4000t.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/scsi/a4000t.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/a4000t.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,143 @@
+/*
+ * Detection routine for the NCR53c710 based Amiga SCSI Controllers for Linux.
+module_exit(a4000t_scsi_exit);
diff -Nurb linux-2.6.22-570/drivers/scsi/aacraid/aachba.c linux-2.6.22-590/drivers/scsi/aacraid/aachba.c
--- linux-2.6.22-570/drivers/scsi/aacraid/aachba.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/aacraid/aachba.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/aacraid/aachba.c 2008-01-29 22:12:31.000000000 -0500
@@ -169,6 +169,18 @@
module_param(acbsize, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. Valid values are 512, 2048, 4096 and 8192. Default is to use suggestion from Firmware.");
diff -Nurb linux-2.6.22-570/drivers/scsi/aacraid/aacraid.h linux-2.6.22-590/drivers/scsi/aacraid/aacraid.h
--- linux-2.6.22-570/drivers/scsi/aacraid/aacraid.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/aacraid/aacraid.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/aacraid/aacraid.h 2008-01-29 22:12:31.000000000 -0500
@@ -12,8 +12,8 @@
*----------------------------------------------------------------------------*/
+extern int check_reset;
diff -Nurb linux-2.6.22-570/drivers/scsi/aacraid/commsup.c linux-2.6.22-590/drivers/scsi/aacraid/commsup.c
--- linux-2.6.22-570/drivers/scsi/aacraid/commsup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/aacraid/commsup.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/aacraid/commsup.c 2008-01-29 22:12:31.000000000 -0500
@@ -1021,7 +1021,7 @@
}
if (dev->queues)
remove_wait_queue(&dev->queues->queue[HostNormCmdQueue].cmdready, &wait);
diff -Nurb linux-2.6.22-570/drivers/scsi/aacraid/linit.c linux-2.6.22-590/drivers/scsi/aacraid/linit.c
---- linux-2.6.22-570/drivers/scsi/aacraid/linit.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/aacraid/linit.c 2008-03-15 10:35:46.000000000 -0400
+--- linux-2.6.22-570/drivers/scsi/aacraid/linit.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/drivers/scsi/aacraid/linit.c 2008-01-29 22:12:31.000000000 -0500
@@ -39,10 +39,8 @@
#include <linux/pci.h>
#include <linux/slab.h>
error = pci_register_driver(&aac_pci_driver);
diff -Nurb linux-2.6.22-570/drivers/scsi/aacraid/rx.c linux-2.6.22-590/drivers/scsi/aacraid/rx.c
--- linux-2.6.22-570/drivers/scsi/aacraid/rx.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/aacraid/rx.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/aacraid/rx.c 2008-01-29 22:12:31.000000000 -0500
@@ -464,6 +464,8 @@
{
u32 var;
* Fill in the common function dispatch table.
diff -Nurb linux-2.6.22-570/drivers/scsi/advansys.c linux-2.6.22-590/drivers/scsi/advansys.c
--- linux-2.6.22-570/drivers/scsi/advansys.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/advansys.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/advansys.c 2008-01-29 22:12:31.000000000 -0500
@@ -798,7 +798,6 @@
#include <scsi/scsi_tcq.h>
#include <scsi/scsi.h>
-#endif /* _ADVANSYS_H */
diff -Nurb linux-2.6.22-570/drivers/scsi/aha152x.c linux-2.6.22-590/drivers/scsi/aha152x.c
--- linux-2.6.22-570/drivers/scsi/aha152x.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/aha152x.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/aha152x.c 2008-01-29 22:12:31.000000000 -0500
@@ -240,6 +240,7 @@
#include <linux/io.h>
#include <linux/blkdev.h>
SCpnt->use_sg = old_use_sg;
diff -Nurb linux-2.6.22-570/drivers/scsi/aha1740.c linux-2.6.22-590/drivers/scsi/aha1740.c
--- linux-2.6.22-570/drivers/scsi/aha1740.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/aha1740.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/aha1740.c 2008-01-29 22:12:31.000000000 -0500
@@ -271,19 +271,7 @@
continue;
}
host->ecb[ecbno].ses = 1; /* Suppress underrun errors */
diff -Nurb linux-2.6.22-570/drivers/scsi/aic7xxx/aic79xx_osm.c linux-2.6.22-590/drivers/scsi/aic7xxx/aic79xx_osm.c
--- linux-2.6.22-570/drivers/scsi/aic7xxx/aic79xx_osm.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/aic7xxx/aic79xx_osm.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/aic7xxx/aic79xx_osm.c 2008-01-29 22:12:31.000000000 -0500
@@ -376,21 +376,10 @@
ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb)
{
LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links);
diff -Nurb linux-2.6.22-570/drivers/scsi/aic7xxx/aic79xx_osm.h linux-2.6.22-590/drivers/scsi/aic7xxx/aic79xx_osm.h
--- linux-2.6.22-570/drivers/scsi/aic7xxx/aic79xx_osm.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/aic7xxx/aic79xx_osm.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/aic7xxx/aic79xx_osm.h 2008-01-29 22:12:31.000000000 -0500
@@ -781,7 +781,7 @@
static __inline
void ahd_set_residual(struct scb *scb, u_long resid)
static __inline
diff -Nurb linux-2.6.22-570/drivers/scsi/aic7xxx/aic7xxx_osm.c linux-2.6.22-590/drivers/scsi/aic7xxx/aic7xxx_osm.c
--- linux-2.6.22-570/drivers/scsi/aic7xxx/aic7xxx_osm.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/aic7xxx/aic7xxx_osm.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/aic7xxx/aic7xxx_osm.c 2008-01-29 22:12:31.000000000 -0500
@@ -402,18 +402,8 @@
cmd = scb->io_ctx;
scb->hscb->dataptr = 0;
diff -Nurb linux-2.6.22-570/drivers/scsi/aic7xxx/aic7xxx_osm.h linux-2.6.22-590/drivers/scsi/aic7xxx/aic7xxx_osm.h
--- linux-2.6.22-570/drivers/scsi/aic7xxx/aic7xxx_osm.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/aic7xxx/aic7xxx_osm.h 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/aic7xxx/aic7xxx_osm.h 2008-01-29 22:12:31.000000000 -0500
@@ -751,7 +751,7 @@
static __inline
void ahc_set_residual(struct scb *scb, u_long resid)
static __inline
diff -Nurb linux-2.6.22-570/drivers/scsi/aic7xxx_old.c linux-2.6.22-590/drivers/scsi/aic7xxx_old.c
--- linux-2.6.22-570/drivers/scsi/aic7xxx_old.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/aic7xxx_old.c 2008-03-15 10:35:46.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/aic7xxx_old.c 2008-01-29 22:12:31.000000000 -0500
@@ -2690,17 +2690,8 @@
struct aic7xxx_scb *scbp;
unsigned char queue_depth;
-#endif /* AMIGA7XX_H */
diff -Nurb linux-2.6.22-570/drivers/scsi/arcmsr/arcmsr.h linux-2.6.22-590/drivers/scsi/arcmsr/arcmsr.h
--- linux-2.6.22-570/drivers/scsi/arcmsr/arcmsr.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/arcmsr/arcmsr.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/arcmsr/arcmsr.h 2008-01-29 22:12:31.000000000 -0500
@@ -48,9 +48,10 @@
#define ARCMSR_MAX_OUTSTANDING_CMD 256
-
diff -Nurb linux-2.6.22-570/drivers/scsi/arcmsr/arcmsr_attr.c linux-2.6.22-590/drivers/scsi/arcmsr/arcmsr_attr.c
--- linux-2.6.22-570/drivers/scsi/arcmsr/arcmsr_attr.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/arcmsr/arcmsr_attr.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/arcmsr/arcmsr_attr.c 2008-01-29 22:12:31.000000000 -0500
@@ -59,8 +59,9 @@
struct class_device_attribute *arcmsr_host_attrs[];
.write = arcmsr_sysfs_iop_message_clear,
diff -Nurb linux-2.6.22-570/drivers/scsi/arcmsr/arcmsr_hba.c linux-2.6.22-590/drivers/scsi/arcmsr/arcmsr_hba.c
--- linux-2.6.22-570/drivers/scsi/arcmsr/arcmsr_hba.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/arcmsr/arcmsr_hba.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/arcmsr/arcmsr_hba.c 2008-01-29 22:12:31.000000000 -0500
@@ -57,6 +57,7 @@
#include <linux/dma-mapping.h>
#include <linux/timer.h>
-#endif /* BVME6000_SCSI_H */
diff -Nurb linux-2.6.22-570/drivers/scsi/bvme6000_scsi.c linux-2.6.22-590/drivers/scsi/bvme6000_scsi.c
--- linux-2.6.22-570/drivers/scsi/bvme6000_scsi.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/scsi/bvme6000_scsi.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/bvme6000_scsi.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,135 @@
+/*
+ * Detection routine for the NCR53c710 based BVME6000 SCSI Controllers for Linux.
+module_exit(bvme6000_scsi_exit);
diff -Nurb linux-2.6.22-570/drivers/scsi/dpt_i2o.c linux-2.6.22-590/drivers/scsi/dpt_i2o.c
--- linux-2.6.22-570/drivers/scsi/dpt_i2o.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/dpt_i2o.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/dpt_i2o.c 2008-01-29 22:12:31.000000000 -0500
@@ -2078,12 +2078,13 @@
u32 *lenptr;
int direction;
diff -Nurb linux-2.6.22-570/drivers/scsi/eata.c linux-2.6.22-590/drivers/scsi/eata.c
--- linux-2.6.22-570/drivers/scsi/eata.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/eata.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/eata.c 2008-01-29 22:12:31.000000000 -0500
@@ -1609,8 +1609,9 @@
static void map_dma(unsigned int i, struct hostdata *ha)
if (!DEV2H(cpp->data_len))
pci_dir = PCI_DMA_BIDIRECTIONAL;
diff -Nurb linux-2.6.22-570/drivers/scsi/esp_scsi.c linux-2.6.22-590/drivers/scsi/esp_scsi.c
---- linux-2.6.22-570/drivers/scsi/esp_scsi.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/esp_scsi.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/drivers/scsi/esp_scsi.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/drivers/scsi/esp_scsi.c 2008-01-29 22:12:31.000000000 -0500
@@ -324,17 +324,14 @@
static void esp_map_dma(struct esp *esp, struct scsi_cmnd *cmd)
{
tp->nego_goal_width = (width ? 1 : 0);
diff -Nurb linux-2.6.22-570/drivers/scsi/esp_scsi.h linux-2.6.22-590/drivers/scsi/esp_scsi.h
--- linux-2.6.22-570/drivers/scsi/esp_scsi.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/esp_scsi.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/esp_scsi.h 2008-01-29 22:12:31.000000000 -0500
@@ -517,8 +517,6 @@
struct sbus_dma *dma;
};
* 1) Allocate the host and private area using scsi_host_alloc()
diff -Nurb linux-2.6.22-570/drivers/scsi/fdomain.c linux-2.6.22-590/drivers/scsi/fdomain.c
--- linux-2.6.22-570/drivers/scsi/fdomain.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/fdomain.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/fdomain.c 2008-01-29 22:12:31.000000000 -0500
@@ -410,6 +410,8 @@
static char * fdomain = NULL;
module_param(fdomain, charp, 0);
SCpnt->SCp.have_data_in,
diff -Nurb linux-2.6.22-570/drivers/scsi/gdth.c linux-2.6.22-590/drivers/scsi/gdth.c
--- linux-2.6.22-570/drivers/scsi/gdth.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/gdth.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/gdth.c 2008-01-29 22:12:31.000000000 -0500
@@ -876,7 +876,7 @@
/* Vortex only makes RAID controllers.
* We do not really want to specify all 550 ids here, so wildcard match.
*(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8]));
/* 3. send to controller firmware */
diff -Nurb linux-2.6.22-570/drivers/scsi/hptiop.c linux-2.6.22-590/drivers/scsi/hptiop.c
---- linux-2.6.22-570/drivers/scsi/hptiop.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/hptiop.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/drivers/scsi/hptiop.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/drivers/scsi/hptiop.c 2008-01-29 22:12:31.000000000 -0500
@@ -339,20 +339,8 @@
scp = hba->reqs[tag].scp;
req->lun = scp->device->lun;
diff -Nurb linux-2.6.22-570/drivers/scsi/ibmmca.c linux-2.6.22-590/drivers/scsi/ibmmca.c
--- linux-2.6.22-570/drivers/scsi/ibmmca.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/ibmmca.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/ibmmca.c 2008-01-29 22:12:31.000000000 -0500
@@ -31,14 +31,21 @@
#include <linux/mca.h>
#include <linux/spinlock.h>
-#endif /* _IBMMCA_H */
diff -Nurb linux-2.6.22-570/drivers/scsi/ibmvscsi/ibmvscsi.c linux-2.6.22-590/drivers/scsi/ibmvscsi/ibmvscsi.c
--- linux-2.6.22-570/drivers/scsi/ibmvscsi/ibmvscsi.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/ibmvscsi/ibmvscsi.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/ibmvscsi/ibmvscsi.c 2008-01-29 22:12:31.000000000 -0500
@@ -173,8 +173,7 @@
}
}
diff -Nurb linux-2.6.22-570/drivers/scsi/ibmvscsi/ibmvscsi.h linux-2.6.22-590/drivers/scsi/ibmvscsi/ibmvscsi.h
--- linux-2.6.22-570/drivers/scsi/ibmvscsi/ibmvscsi.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/ibmvscsi/ibmvscsi.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/ibmvscsi/ibmvscsi.h 2008-01-29 22:12:31.000000000 -0500
@@ -45,6 +45,7 @@
#define MAX_INDIRECT_BUFS 10
dma_addr_t ext_list_token;
diff -Nurb linux-2.6.22-570/drivers/scsi/ibmvscsi/rpa_vscsi.c linux-2.6.22-590/drivers/scsi/ibmvscsi/rpa_vscsi.c
--- linux-2.6.22-570/drivers/scsi/ibmvscsi/rpa_vscsi.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/ibmvscsi/rpa_vscsi.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/ibmvscsi/rpa_vscsi.c 2008-01-29 22:12:31.000000000 -0500
@@ -177,7 +177,7 @@
memset(&hostdata->madapter_info, 0x00,
sizeof(hostdata->madapter_info));
}
diff -Nurb linux-2.6.22-570/drivers/scsi/initio.c linux-2.6.22-590/drivers/scsi/initio.c
--- linux-2.6.22-570/drivers/scsi/initio.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/initio.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/initio.c 2008-01-29 22:12:31.000000000 -0500
@@ -3,7 +3,8 @@
*
* Copyright (c) 1994-1998 Initio Corporation
+module_exit(initio_exit_driver);
diff -Nurb linux-2.6.22-570/drivers/scsi/initio.h linux-2.6.22-590/drivers/scsi/initio.h
--- linux-2.6.22-570/drivers/scsi/initio.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/initio.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/initio.h 2008-01-29 22:12:31.000000000 -0500
@@ -4,6 +4,8 @@
* Copyright (c) 1994-1998 Initio Corporation
* All rights reserved.
#define SCSI_ABORT_PENDING 2
diff -Nurb linux-2.6.22-570/drivers/scsi/ipr.c linux-2.6.22-590/drivers/scsi/ipr.c
--- linux-2.6.22-570/drivers/scsi/ipr.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/ipr.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/ipr.c 2008-01-29 22:12:31.000000000 -0500
@@ -540,32 +540,6 @@
}
} else
diff -Nurb linux-2.6.22-570/drivers/scsi/ips.c linux-2.6.22-590/drivers/scsi/ips.c
--- linux-2.6.22-570/drivers/scsi/ips.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/ips.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/ips.c 2008-01-29 22:12:31.000000000 -0500
@@ -211,19 +211,6 @@
#warning "This driver has only been tested on the x86/ia64/x86_64 platforms"
#endif
/*
diff -Nurb linux-2.6.22-570/drivers/scsi/ips.h linux-2.6.22-590/drivers/scsi/ips.h
--- linux-2.6.22-570/drivers/scsi/ips.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/ips.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/ips.h 2008-01-29 22:12:31.000000000 -0500
@@ -58,10 +58,6 @@
/*
* Some handy macros
* Raid Command Formats
diff -Nurb linux-2.6.22-570/drivers/scsi/iscsi_tcp.c linux-2.6.22-590/drivers/scsi/iscsi_tcp.c
--- linux-2.6.22-570/drivers/scsi/iscsi_tcp.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/iscsi_tcp.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/iscsi_tcp.c 2008-01-29 22:12:31.000000000 -0500
@@ -29,14 +29,15 @@
#include <linux/types.h>
#include <linux/list.h>
.get_stats = iscsi_conn_get_stats,
diff -Nurb linux-2.6.22-570/drivers/scsi/iscsi_tcp.h linux-2.6.22-590/drivers/scsi/iscsi_tcp.h
--- linux-2.6.22-570/drivers/scsi/iscsi_tcp.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/iscsi_tcp.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/iscsi_tcp.h 2008-01-29 22:12:31.000000000 -0500
@@ -29,11 +29,12 @@
#define IN_PROGRESS_HEADER_GATHER 0x1
#define IN_PROGRESS_DATA_RECV 0x2
struct iscsi_queue r2tpool;
diff -Nurb linux-2.6.22-570/drivers/scsi/jazz_esp.c linux-2.6.22-590/drivers/scsi/jazz_esp.c
--- linux-2.6.22-570/drivers/scsi/jazz_esp.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/jazz_esp.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/jazz_esp.c 2008-01-29 22:12:31.000000000 -0500
@@ -1,6 +1,6 @@
/* jazz_esp.c: ESP front-end for MIPS JAZZ systems.
*
esp->dev = dev;
diff -Nurb linux-2.6.22-570/drivers/scsi/libiscsi.c linux-2.6.22-590/drivers/scsi/libiscsi.c
--- linux-2.6.22-570/drivers/scsi/libiscsi.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/libiscsi.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/libiscsi.c 2008-01-29 22:12:31.000000000 -0500
@@ -22,7 +22,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
MODULE_LICENSE("GPL");
diff -Nurb linux-2.6.22-570/drivers/scsi/libsas/sas_expander.c linux-2.6.22-590/drivers/scsi/libsas/sas_expander.c
--- linux-2.6.22-570/drivers/scsi/libsas/sas_expander.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/libsas/sas_expander.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/libsas/sas_expander.c 2008-01-29 22:12:31.000000000 -0500
@@ -38,8 +38,10 @@
#if 0
struct expander_device *ex = &dev->ex_dev;
diff -Nurb linux-2.6.22-570/drivers/scsi/libsas/sas_scsi_host.c linux-2.6.22-590/drivers/scsi/libsas/sas_scsi_host.c
--- linux-2.6.22-570/drivers/scsi/libsas/sas_scsi_host.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/libsas/sas_scsi_host.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/libsas/sas_scsi_host.c 2008-01-29 22:12:31.000000000 -0500
@@ -40,6 +40,7 @@
#include <linux/err.h>
schedule();
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/Makefile linux-2.6.22-590/drivers/scsi/lpfc/Makefile
--- linux-2.6.22-570/drivers/scsi/lpfc/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/lpfc/Makefile 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/Makefile 2008-01-29 22:12:31.000000000 -0500
@@ -1,7 +1,7 @@
#/*******************************************************************
# * This file is part of the Emulex Linux Device Driver for *
+ lpfc_vport.o lpfc_debugfs.o
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc.h linux-2.6.22-590/drivers/scsi/lpfc/lpfc.h
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc.h 2008-01-29 22:12:31.000000000 -0500
@@ -19,8 +19,9 @@
* included with this package. *
*******************************************************************/
+
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_attr.c linux-2.6.22-590/drivers/scsi/lpfc/lpfc_attr.c
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_attr.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_attr.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_attr.c 2008-01-29 22:12:31.000000000 -0500
@@ -39,6 +39,7 @@
#include "lpfc_version.h"
#include "lpfc_compat.h"
lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo);
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_crtn.h linux-2.6.22-590/drivers/scsi/lpfc/lpfc_crtn.h
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_crtn.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_crtn.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_crtn.h 2008-01-29 22:12:31.000000000 -0500
@@ -23,92 +23,114 @@
struct fc_rport;
void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t);
#define HBA_EVENT_LINK_UP 2
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_ct.c linux-2.6.22-590/drivers/scsi/lpfc/lpfc_ct.c
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_ct.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_ct.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_ct.c 2008-01-29 22:12:31.000000000 -0500
@@ -40,6 +40,8 @@
#include "lpfc_logmsg.h"
#include "lpfc_crtn.h"
lpfc_vpd_t *vp = &phba->vpd;
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_debugfs.c linux-2.6.22-590/drivers/scsi/lpfc/lpfc_debugfs.c
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_debugfs.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_debugfs.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_debugfs.c 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,508 @@
+/*******************************************************************
+ * This file is part of the Emulex Linux Device Driver for *
+
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_debugfs.h linux-2.6.22-590/drivers/scsi/lpfc/lpfc_debugfs.h
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_debugfs.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_debugfs.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_debugfs.h 2008-01-29 22:12:31.000000000 -0500
@@ -0,0 +1,50 @@
+/*******************************************************************
+ * This file is part of the Emulex Linux Device Driver for *
+#endif /* H_LPFC_DEBUG_FS */
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_disc.h linux-2.6.22-590/drivers/scsi/lpfc/lpfc_disc.h
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_disc.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_disc.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_disc.h 2008-01-29 22:12:31.000000000 -0500
@@ -36,21 +36,23 @@
LPFC_EVT_WARM_START,
LPFC_EVT_KILL,
* The Port Login (PLOGI) list and Address Discovery (ADISC) list are used
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_els.c linux-2.6.22-590/drivers/scsi/lpfc/lpfc_els.c
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_els.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_els.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_els.c 2008-01-29 22:12:31.000000000 -0500
@@ -35,38 +35,38 @@
#include "lpfc.h"
#include "lpfc_logmsg.h"
+
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_hbadisc.c linux-2.6.22-590/drivers/scsi/lpfc/lpfc_hbadisc.c
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_hbadisc.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_hbadisc.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_hbadisc.c 2008-01-29 22:12:31.000000000 -0500
@@ -36,6 +36,8 @@
#include "lpfc.h"
#include "lpfc_logmsg.h"
struct lpfc_nodelist *
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_hw.h linux-2.6.22-590/drivers/scsi/lpfc/lpfc_hw.h
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_hw.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_hw.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_hw.h 2008-01-29 22:12:31.000000000 -0500
@@ -59,6 +59,12 @@
#define SLI2_IOCB_CMD_R3XTRA_ENTRIES 24
#define SLI2_IOCB_RSP_R3XTRA_ENTRIES 32
+}
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_init.c linux-2.6.22-590/drivers/scsi/lpfc/lpfc_init.c
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_init.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_init.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_init.c 2008-01-29 22:12:31.000000000 -0500
@@ -27,6 +27,7 @@
#include <linux/kthread.h>
#include <linux/pci.h>
/* Release all the lpfc_scsi_bufs maintained by this host. */
list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list, list) {
list_del(&sb->list);
-@@ -1348,126 +1504,177 @@
+@@ -1348,126 +1504,174 @@
phba->total_iocbq_bufs--;
}
- pci_release_regions(phba->pcidev);
- pci_disable_device(phba->pcidev);
-+ if (!shost->shost_classdev.kobj.dentry)
-+ goto out_put_shost;
++ list_add_tail(&vport->listentry, &phba->port_list);
++ return vport;
- idr_remove(&lpfc_hba_index, phba->brd_no);
- scsi_host_put(phba->host);
-+ list_add_tail(&vport->listentry, &phba->port_list);
-+ return vport;
-+
+out_put_shost:
+ scsi_host_put(shost);
+out:
fc_host_supported_classes(shost) = FC_COS_CLASS3;
memset(fc_host_supported_fc4s(shost), 0,
-@@ -1475,7 +1682,8 @@
+@@ -1475,7 +1679,8 @@
fc_host_supported_fc4s(shost)[2] = 1;
fc_host_supported_fc4s(shost)[7] = 1;
fc_host_supported_speeds(shost) = 0;
if (phba->lmt & LMT_10Gb)
-@@ -1488,8 +1696,8 @@
+@@ -1488,8 +1693,8 @@
fc_host_supported_speeds(shost) |= FC_PORTSPEED_1GBIT;
fc_host_maxframe_size(shost) =
/* This value is also unchanging */
memset(fc_host_active_fc4s(shost), 0,
-@@ -1497,20 +1705,20 @@
+@@ -1497,20 +1702,20 @@
fc_host_active_fc4s(shost)[2] = 1;
fc_host_active_fc4s(shost)[7] = 1;
unsigned long bar0map_len, bar2map_len;
int error = -ENODEV, retval;
int i;
-@@ -1521,61 +1729,46 @@
+@@ -1521,61 +1726,46 @@
if (pci_request_regions(pdev, LPFC_DRIVER_NAME))
goto out_disable_device;
pci_set_master(pdev);
retval = pci_set_mwi(pdev);
-@@ -1623,13 +1816,22 @@
+@@ -1623,13 +1813,22 @@
memset(phba->slim2p, 0, SLI2_SLIM_SIZE);
/* Initialize and populate the iocb list per host. */
INIT_LIST_HEAD(&phba->lpfc_iocb_list);
-@@ -1653,10 +1855,11 @@
+@@ -1653,10 +1852,11 @@
error = -ENOMEM;
goto out_free_iocbq;
}
}
/* Initialize HBA structure */
-@@ -1677,22 +1880,22 @@
+@@ -1677,22 +1877,22 @@
goto out_free_iocbq;
}
if (phba->cfg_use_msi) {
error = pci_enable_msi(phba->pcidev);
-@@ -1708,33 +1911,63 @@
+@@ -1708,33 +1908,63 @@
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"%d:0451 Enable interrupt handler failed\n",
phba->brd_no);
out_free_slim:
dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE, phba->slim2p,
phba->slim2p_mapping);
-@@ -1744,27 +1977,85 @@
+@@ -1744,27 +1974,85 @@
iounmap(phba->slim_memmap_p);
out_idr_remove:
idr_remove(&lpfc_hba_index, phba->brd_no);
+
+ kfree(vport->vname);
+ lpfc_free_sysfs_attr(vport);
-+
+
+- lpfc_remove_device(phba);
+ fc_remove_host(shost);
+ scsi_remove_host(shost);
+
+ spin_lock_irq(&phba->hbalock);
+ list_del_init(&vport->listentry);
+ spin_unlock_irq(&phba->hbalock);
-
-- lpfc_remove_device(phba);
++
+
+ lpfc_debugfs_terminate(vport);
+ lpfc_cleanup(vport);
}
/**
-@@ -1822,10 +2113,13 @@
+@@ -1822,10 +2110,13 @@
pci_set_master(pdev);
/* Re-establishing Link */
/* Take device offline; this will perform cleanup */
-@@ -1948,11 +2242,15 @@
+@@ -1948,11 +2239,15 @@
lpfc_transport_template =
fc_attach_transport(&lpfc_transport_functions);
return error;
}
-@@ -1962,6 +2260,7 @@
+@@ -1962,6 +2257,7 @@
{
pci_unregister_driver(&lpfc_driver);
fc_release_transport(lpfc_transport_template);
module_init(lpfc_init);
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_logmsg.h linux-2.6.22-590/drivers/scsi/lpfc/lpfc_logmsg.h
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_logmsg.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_logmsg.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_logmsg.h 2008-01-29 22:12:31.000000000 -0500
@@ -30,6 +30,7 @@
#define LOG_SLI 0x800 /* SLI events */
#define LOG_FCP_ERROR 0x1000 /* log errors, not underruns */
#define lpfc_printf_log(phba, level, mask, fmt, arg...) \
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_mbox.c linux-2.6.22-590/drivers/scsi/lpfc/lpfc_mbox.c
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_mbox.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_mbox.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_mbox.c 2008-01-29 22:12:31.000000000 -0500
@@ -82,6 +82,22 @@
}
{
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_mem.c linux-2.6.22-590/drivers/scsi/lpfc/lpfc_mem.c
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_mem.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_mem.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_mem.c 2008-01-29 22:12:31.000000000 -0500
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
+
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_nportdisc.c linux-2.6.22-590/drivers/scsi/lpfc/lpfc_nportdisc.c
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_nportdisc.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_nportdisc.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_nportdisc.c 2008-01-29 22:12:31.000000000 -0500
@@ -1,4 +1,4 @@
-/*******************************************************************
+ /*******************************************************************
lpfc_nlp_put(ndlp);
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_scsi.c linux-2.6.22-590/drivers/scsi/lpfc/lpfc_scsi.c
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_scsi.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_scsi.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_scsi.c 2008-01-29 22:12:31.000000000 -0500
@@ -37,10 +37,158 @@
#include "lpfc.h"
#include "lpfc_logmsg.h"
};
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_scsi.h linux-2.6.22-590/drivers/scsi/lpfc/lpfc_scsi.h
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_scsi.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_scsi.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_scsi.h 2008-01-29 22:12:31.000000000 -0500
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
uint32_t timeout;
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_sli.c linux-2.6.22-590/drivers/scsi/lpfc/lpfc_sli.c
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_sli.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_sli.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_sli.c 2008-01-29 22:12:32.000000000 -0500
@@ -38,23 +38,25 @@
#include "lpfc_crtn.h"
#include "lpfc_logmsg.h"
status);
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_sli.h linux-2.6.22-590/drivers/scsi/lpfc/lpfc_sli.h
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_sli.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_sli.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_sli.h 2008-01-29 22:12:32.000000000 -0500
@@ -20,6 +20,7 @@
/* forward declaration for LPFC_IOCB_t's use */
#define LPFC_MBOX_TMO_FLASH_CMD 300 /* Sec tmo for outstanding FLASH write
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_version.h linux-2.6.22-590/drivers/scsi/lpfc/lpfc_version.h
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_version.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_version.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_version.h 2008-01-29 22:12:32.000000000 -0500
@@ -18,7 +18,7 @@
* included with this package. *
*******************************************************************/
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_vport.c linux-2.6.22-590/drivers/scsi/lpfc/lpfc_vport.c
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_vport.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_vport.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_vport.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,523 @@
+/*******************************************************************
+ * This file is part of the Emulex Linux Device Driver for *
+EXPORT_SYMBOL(lpfc_vport_delete);
diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_vport.h linux-2.6.22-590/drivers/scsi/lpfc/lpfc_vport.h
--- linux-2.6.22-570/drivers/scsi/lpfc/lpfc_vport.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_vport.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/lpfc/lpfc_vport.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,113 @@
+/*******************************************************************
+ * This file is part of the Emulex Linux Device Driver for *
+#endif /* H_LPFC_VPORT */
diff -Nurb linux-2.6.22-570/drivers/scsi/mac53c94.c linux-2.6.22-590/drivers/scsi/mac53c94.c
--- linux-2.6.22-570/drivers/scsi/mac53c94.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/mac53c94.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/mac53c94.c 2008-01-29 22:12:32.000000000 -0500
@@ -77,7 +77,7 @@
for (i = 0; i < cmd->cmd_len; ++i)
printk(" %.2x", cmd->cmnd[i]);
st_le16(&dcmds->command, DBDMA_STOP);
diff -Nurb linux-2.6.22-570/drivers/scsi/megaraid/megaraid_mbox.c linux-2.6.22-590/drivers/scsi/megaraid/megaraid_mbox.c
--- linux-2.6.22-570/drivers/scsi/megaraid/megaraid_mbox.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/megaraid/megaraid_mbox.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/megaraid/megaraid_mbox.c 2008-01-29 22:12:32.000000000 -0500
@@ -1378,8 +1378,6 @@
{
struct scatterlist *sgl;
pdev_index = (scb->dev_channel * 16) +
diff -Nurb linux-2.6.22-570/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.22-590/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.22-570/drivers/scsi/megaraid/megaraid_sas.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/megaraid/megaraid_sas.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/megaraid/megaraid_sas.c 2008-01-29 22:12:32.000000000 -0500
@@ -433,34 +433,15 @@
int sge_count;
struct scatterlist *os_sgl;
diff -Nurb linux-2.6.22-570/drivers/scsi/megaraid.c linux-2.6.22-590/drivers/scsi/megaraid.c
--- linux-2.6.22-570/drivers/scsi/megaraid.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/megaraid.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/megaraid.c 2008-01-29 22:12:32.000000000 -0500
@@ -523,10 +523,8 @@
/*
* filter the internal and ioctl commands
scb->state |= SCB_ACTIVE;
diff -Nurb linux-2.6.22-570/drivers/scsi/mesh.c linux-2.6.22-590/drivers/scsi/mesh.c
--- linux-2.6.22-570/drivers/scsi/mesh.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/mesh.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/mesh.c 2008-01-29 22:12:32.000000000 -0500
@@ -421,7 +421,7 @@
for (i = 0; i < cmd->cmd_len; ++i)
printk(" %x", cmd->cmnd[i]);
-#endif /* MVME16x_SCSI_H */
diff -Nurb linux-2.6.22-570/drivers/scsi/mvme16x_scsi.c linux-2.6.22-590/drivers/scsi/mvme16x_scsi.c
--- linux-2.6.22-570/drivers/scsi/mvme16x_scsi.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/scsi/mvme16x_scsi.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/mvme16x_scsi.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,158 @@
+/*
+ * Detection routine for the NCR53c710 based MVME16x SCSI Controllers for Linux.
+module_exit(mvme16x_scsi_exit);
diff -Nurb linux-2.6.22-570/drivers/scsi/nsp32.c linux-2.6.22-590/drivers/scsi/nsp32.c
--- linux-2.6.22-570/drivers/scsi/nsp32.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/nsp32.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/nsp32.c 2008-01-29 22:12:32.000000000 -0500
@@ -49,10 +49,6 @@
#include <scsi/scsi_host.h>
#include <scsi/scsi_ioctl.h>
.id_table = nsp32_pci_table,
diff -Nurb linux-2.6.22-570/drivers/scsi/pcmcia/sym53c500_cs.c linux-2.6.22-590/drivers/scsi/pcmcia/sym53c500_cs.c
--- linux-2.6.22-570/drivers/scsi/pcmcia/sym53c500_cs.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/pcmcia/sym53c500_cs.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/pcmcia/sym53c500_cs.c 2008-01-29 22:12:32.000000000 -0500
@@ -370,8 +370,6 @@
DEB(unsigned char seq_reg;)
unsigned char status, int_reg;
printk("cmd[%d]=%02x ", i, SCpnt->cmnd[i]));
diff -Nurb linux-2.6.22-570/drivers/scsi/qla2xxx/qla_attr.c linux-2.6.22-590/drivers/scsi/qla2xxx/qla_attr.c
--- linux-2.6.22-570/drivers/scsi/qla2xxx/qla_attr.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/qla2xxx/qla_attr.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/qla2xxx/qla_attr.c 2008-01-29 22:12:32.000000000 -0500
@@ -11,8 +11,9 @@
/* SYSFS attributes --------------------------------------------------------- */
.read = qla2x00_sysfs_read_sfp,
diff -Nurb linux-2.6.22-570/drivers/scsi/qla2xxx/qla_dbg.c linux-2.6.22-590/drivers/scsi/qla2xxx/qla_dbg.c
--- linux-2.6.22-570/drivers/scsi/qla2xxx/qla_dbg.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/qla2xxx/qla_dbg.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/qla2xxx/qla_dbg.c 2008-01-29 22:12:32.000000000 -0500
@@ -1411,9 +1411,9 @@
printk("0x%02x ", cmd->cmnd[i]);
}
printk(" serial_number=%lx, SP=%p\n", cmd->serial_number, sp);
diff -Nurb linux-2.6.22-570/drivers/scsi/qla2xxx/qla_iocb.c linux-2.6.22-590/drivers/scsi/qla2xxx/qla_iocb.c
--- linux-2.6.22-570/drivers/scsi/qla2xxx/qla_iocb.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/qla2xxx/qla_iocb.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/qla2xxx/qla_iocb.c 2008-01-29 22:12:32.000000000 -0500
@@ -155,6 +155,8 @@
uint32_t *cur_dsd;
scsi_qla_host_t *ha;
return QLA_FUNCTION_FAILED;
diff -Nurb linux-2.6.22-570/drivers/scsi/qla2xxx/qla_isr.c linux-2.6.22-590/drivers/scsi/qla2xxx/qla_isr.c
--- linux-2.6.22-570/drivers/scsi/qla2xxx/qla_isr.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/qla2xxx/qla_isr.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/qla2xxx/qla_isr.c 2008-01-29 22:12:32.000000000 -0500
@@ -889,11 +889,11 @@
}
if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) {
static struct qla_init_msix_entry imsix_entries[QLA_MSIX_ENTRIES] = {
diff -Nurb linux-2.6.22-570/drivers/scsi/qla2xxx/qla_os.c linux-2.6.22-590/drivers/scsi/qla2xxx/qla_os.c
--- linux-2.6.22-570/drivers/scsi/qla2xxx/qla_os.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/qla2xxx/qla_os.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/qla2xxx/qla_os.c 2008-01-29 22:12:32.000000000 -0500
@@ -2426,13 +2426,7 @@
struct scsi_cmnd *cmd = sp->cmd;
CMD_SP(cmd) = NULL;
diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_dbg.c linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_dbg.c
--- linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_dbg.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_dbg.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_dbg.c 2008-01-29 22:12:32.000000000 -0500
@@ -6,176 +6,9 @@
*/
-#endif /* 0 */
diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_def.h linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_def.h
--- linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_def.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_def.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_def.h 2008-01-29 22:12:32.000000000 -0500
@@ -122,8 +122,7 @@
#define ISCSI_IPADDR_SIZE 4 /* IP address size */
#endif /*_QLA4XXX_H */
diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_fw.h linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_fw.h
--- linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_fw.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_fw.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_fw.h 2008-01-29 22:12:32.000000000 -0500
@@ -20,143 +20,23 @@
*************************************************************************/
/*************************************************************************/
diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_glbl.h linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_glbl.h
--- linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_glbl.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_glbl.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_glbl.h 2008-01-29 22:12:32.000000000 -0500
@@ -8,6 +8,9 @@
#ifndef __QLA4x_GBL_H
#define __QLA4x_GBL_H
extern int ql4xdiscoverywait;
diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_init.c linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_init.c
--- linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_init.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_init.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_init.c 2008-01-29 22:12:32.000000000 -0500
@@ -6,6 +6,9 @@
*/
ha->fw_ddb_index_map[fw_ddb_index] =
diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_iocb.c linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_iocb.c
--- linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_iocb.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_iocb.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_iocb.c 2008-01-29 22:12:32.000000000 -0500
@@ -6,6 +6,10 @@
*/
return QLA_ERROR;
diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_isr.c linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_isr.c
--- linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_isr.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_isr.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_isr.c 2008-01-29 22:12:32.000000000 -0500
@@ -6,6 +6,9 @@
*/
diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_mbx.c linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_mbx.c
--- linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_mbx.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_mbx.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_mbx.c 2008-01-29 22:12:32.000000000 -0500
@@ -6,6 +6,9 @@
*/
diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_nvram.c linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_nvram.c
--- linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_nvram.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_nvram.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_nvram.c 2008-01-29 22:12:32.000000000 -0500
@@ -6,6 +6,9 @@
*/
{
diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_os.c linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_os.c
--- linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_os.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_os.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_os.c 2008-01-29 22:12:32.000000000 -0500
@@ -10,6 +10,10 @@
#include <scsi/scsicam.h>
diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_version.h linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_version.h
--- linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_version.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_version.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/qla4xxx/ql4_version.h 2008-01-29 22:12:32.000000000 -0500
@@ -5,4 +5,5 @@
* See LICENSE.qla4xxx for copyright and licensing details.
*/
+
diff -Nurb linux-2.6.22-570/drivers/scsi/qlogicfas408.c linux-2.6.22-590/drivers/scsi/qlogicfas408.c
--- linux-2.6.22-570/drivers/scsi/qlogicfas408.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/qlogicfas408.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/qlogicfas408.c 2008-01-29 22:12:32.000000000 -0500
@@ -265,8 +265,6 @@
unsigned int message; /* scsi returned message */
unsigned int phase; /* recorded scsi phase */
rtrc(2)
diff -Nurb linux-2.6.22-570/drivers/scsi/scsi_debug.c linux-2.6.22-590/drivers/scsi/scsi_debug.c
--- linux-2.6.22-570/drivers/scsi/scsi_debug.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/scsi_debug.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/scsi_debug.c 2008-01-29 22:12:32.000000000 -0500
@@ -2405,7 +2405,7 @@
MODULE_PARM_DESC(delay, "# of jiffies to delay response(def=1)");
MODULE_PARM_DESC(dev_size_mb, "size in MB of ram shared by devs(def=8)");
MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)");
diff -Nurb linux-2.6.22-570/drivers/scsi/scsi_error.c linux-2.6.22-590/drivers/scsi/scsi_error.c
--- linux-2.6.22-570/drivers/scsi/scsi_error.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/scsi_error.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/scsi_error.c 2008-01-29 22:12:32.000000000 -0500
@@ -18,12 +18,13 @@
#include <linux/sched.h>
#include <linux/timer.h>
* counted against the load average as a running process.
diff -Nurb linux-2.6.22-570/drivers/scsi/scsi_lib.c linux-2.6.22-590/drivers/scsi/scsi_lib.c
--- linux-2.6.22-570/drivers/scsi/scsi_lib.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/scsi_lib.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/scsi_lib.c 2008-01-29 22:12:32.000000000 -0500
@@ -2290,3 +2290,41 @@
kunmap_atomic(virt, KM_BIO_SRC_IRQ);
}
+ }
+}
+EXPORT_SYMBOL(scsi_dma_unmap);
+diff -Nurb linux-2.6.22-570/drivers/scsi/scsi_netlink.c linux-2.6.22-590/drivers/scsi/scsi_netlink.c
+--- linux-2.6.22-570/drivers/scsi/scsi_netlink.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/scsi_netlink.c 2008-01-29 22:12:32.000000000 -0500
+@@ -167,7 +167,7 @@
+ return;
+ }
+
+- scsi_nl_sock = netlink_kernel_create(NETLINK_SCSITRANSPORT,
++ scsi_nl_sock = netlink_kernel_create(&init_net, NETLINK_SCSITRANSPORT,
+ SCSI_NL_GRP_CNT, scsi_nl_rcv, NULL,
+ THIS_MODULE);
+ if (!scsi_nl_sock) {
diff -Nurb linux-2.6.22-570/drivers/scsi/scsi_scan.c linux-2.6.22-590/drivers/scsi/scsi_scan.c
--- linux-2.6.22-570/drivers/scsi/scsi_scan.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/scsi_scan.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/scsi_scan.c 2008-01-29 22:12:32.000000000 -0500
@@ -1213,7 +1213,7 @@
* Given a struct scsi_lun of: 0a 04 0b 03 00 00 00 00, this function returns
* the integer: 0x0b030a04
* int_to_scsilun: reverts an int into a scsi_lun
diff -Nurb linux-2.6.22-570/drivers/scsi/scsi_sysfs.c linux-2.6.22-590/drivers/scsi/scsi_sysfs.c
--- linux-2.6.22-570/drivers/scsi/scsi_sysfs.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/scsi_sysfs.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/scsi_sysfs.c 2008-01-29 22:12:32.000000000 -0500
@@ -293,30 +293,18 @@
{
struct device_driver *drv = dev->driver;
struct bus_type scsi_bus_type = {
diff -Nurb linux-2.6.22-570/drivers/scsi/scsi_transport_fc.c linux-2.6.22-590/drivers/scsi/scsi_transport_fc.c
--- linux-2.6.22-570/drivers/scsi/scsi_transport_fc.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/scsi_transport_fc.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/scsi_transport_fc.c 2008-01-29 22:12:32.000000000 -0500
@@ -19,9 +19,10 @@
*
* ========
diff -Nurb linux-2.6.22-570/drivers/scsi/scsi_transport_iscsi.c linux-2.6.22-590/drivers/scsi/scsi_transport_iscsi.c
--- linux-2.6.22-570/drivers/scsi/scsi_transport_iscsi.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/scsi_transport_iscsi.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/scsi_transport_iscsi.c 2008-01-29 22:12:32.000000000 -0500
@@ -30,9 +30,9 @@
#include <scsi/scsi_transport_iscsi.h>
#include <scsi/iscsi_if.h>
SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo);
BUG_ON(count > ISCSI_SESSION_ATTRS);
+@@ -1437,7 +1523,7 @@
+ if (err)
+ goto unregister_conn_class;
+
+- nls = netlink_kernel_create(NETLINK_ISCSI, 1, iscsi_if_rx, NULL,
++ nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, 1, iscsi_if_rx, NULL,
+ THIS_MODULE);
+ if (!nls) {
+ err = -ENOBUFS;
diff -Nurb linux-2.6.22-570/drivers/scsi/sd.c linux-2.6.22-590/drivers/scsi/sd.c
--- linux-2.6.22-570/drivers/scsi/sd.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/sd.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/sd.c 2008-01-29 22:12:32.000000000 -0500
@@ -1515,7 +1515,7 @@
if (!scsi_device_online(sdp))
goto out;
"allocation failure.\n");
diff -Nurb linux-2.6.22-570/drivers/scsi/sg.c linux-2.6.22-590/drivers/scsi/sg.c
--- linux-2.6.22-570/drivers/scsi/sg.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/sg.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/sg.c 2008-01-29 22:12:32.000000000 -0500
@@ -1842,7 +1842,7 @@
int blk_size = buff_size;
struct page *p = NULL;
++blk_size; /* don't know why */
diff -Nurb linux-2.6.22-570/drivers/scsi/stex.c linux-2.6.22-590/drivers/scsi/stex.c
--- linux-2.6.22-570/drivers/scsi/stex.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/stex.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/stex.c 2008-01-29 22:12:32.000000000 -0500
@@ -395,53 +395,34 @@
static int stex_map_sg(struct st_hba *hba,
struct req_msg *req, struct st_ccb *ccb)
result = FAILED;
diff -Nurb linux-2.6.22-570/drivers/scsi/sun_esp.c linux-2.6.22-590/drivers/scsi/sun_esp.c
--- linux-2.6.22-570/drivers/scsi/sun_esp.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/sun_esp.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/sun_esp.c 2008-01-29 22:12:32.000000000 -0500
@@ -493,7 +493,7 @@
goto fail;
esp->dev = esp_dev;
diff -Nurb linux-2.6.22-570/drivers/scsi/sym53c416.c linux-2.6.22-590/drivers/scsi/sym53c416.c
--- linux-2.6.22-570/drivers/scsi/sym53c416.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/sym53c416.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/sym53c416.c 2008-01-29 22:12:32.000000000 -0500
@@ -332,8 +332,7 @@
int i;
unsigned long flags = 0;
printk(KERN_WARNING "sym53c416: Underflow, read %d bytes, request for %d bytes.\n", tot_trans, current_command->underflow);
diff -Nurb linux-2.6.22-570/drivers/scsi/tmscsim.c linux-2.6.22-590/drivers/scsi/tmscsim.c
--- linux-2.6.22-570/drivers/scsi/tmscsim.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/tmscsim.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/tmscsim.c 2008-01-29 22:12:32.000000000 -0500
@@ -457,27 +457,20 @@
error = 1;
DEBUG1(printk("%s(): Mapped sense buffer %p at %x\n", __FUNCTION__, pcmd->sense_buffer, cmdp->saved_dma_handle));
/* Add to free list */
diff -Nurb linux-2.6.22-570/drivers/scsi/tmscsim.h linux-2.6.22-590/drivers/scsi/tmscsim.h
--- linux-2.6.22-570/drivers/scsi/tmscsim.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/tmscsim.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/tmscsim.h 2008-01-29 22:12:32.000000000 -0500
@@ -258,13 +258,6 @@
#define H_BAD_CCB_OR_SG 0x1A
#define H_ABORT 0x0FF
#define SET_RES_TARGET_LNX(who, tgt) do { who &= ~RES_TARGET_LNX; who |= (int)(tgt) << 1; } while (0)
diff -Nurb linux-2.6.22-570/drivers/scsi/u14-34f.c linux-2.6.22-590/drivers/scsi/u14-34f.c
--- linux-2.6.22-570/drivers/scsi/u14-34f.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/u14-34f.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/u14-34f.c 2008-01-29 22:12:32.000000000 -0500
@@ -1111,7 +1111,7 @@
static void map_dma(unsigned int i, unsigned int j) {
unsigned int data_len = 0;
diff -Nurb linux-2.6.22-570/drivers/scsi/ultrastor.c linux-2.6.22-590/drivers/scsi/ultrastor.c
--- linux-2.6.22-570/drivers/scsi/ultrastor.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/ultrastor.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/ultrastor.c 2008-01-29 22:12:32.000000000 -0500
@@ -675,16 +675,15 @@
static inline void build_sg_list(struct mscp *mscp, struct scsi_cmnd *SCpnt)
my_mscp->scsi_command_link_id = 0; /*???*/
diff -Nurb linux-2.6.22-570/drivers/scsi/wd7000.c linux-2.6.22-590/drivers/scsi/wd7000.c
--- linux-2.6.22-570/drivers/scsi/wd7000.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/scsi/wd7000.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/wd7000.c 2008-01-29 22:12:32.000000000 -0500
@@ -1091,6 +1091,7 @@
unchar *cdb = (unchar *) SCpnt->cmnd;
unchar idlun;
/* FIXME: drop lock and yield here ? */
diff -Nurb linux-2.6.22-570/drivers/scsi/zorro7xx.c linux-2.6.22-590/drivers/scsi/zorro7xx.c
--- linux-2.6.22-570/drivers/scsi/zorro7xx.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/scsi/zorro7xx.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/scsi/zorro7xx.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,180 @@
+/*
+ * Detection routine for the NCR53c710 based Amiga SCSI Controllers for Linux.
+module_exit(zorro7xx_scsi_exit);
diff -Nurb linux-2.6.22-570/drivers/serial/8250.c linux-2.6.22-590/drivers/serial/8250.c
--- linux-2.6.22-570/drivers/serial/8250.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/serial/8250.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/serial/8250.c 2008-01-29 22:12:32.000000000 -0500
@@ -2845,6 +2845,25 @@
}
EXPORT_SYMBOL(serial8250_unregister_port);
int ret, i;
diff -Nurb linux-2.6.22-570/drivers/serial/8250_kgdb.c linux-2.6.22-590/drivers/serial/8250_kgdb.c
--- linux-2.6.22-570/drivers/serial/8250_kgdb.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/serial/8250_kgdb.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/serial/8250_kgdb.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,515 @@
+/*
+ * 8250 interface for kgdb.
+early_param("kgdb8250", kgdb8250_opt);
+#endif /* ! CONFIG_KGDB_8250_MODULE */
diff -Nurb linux-2.6.22-570/drivers/serial/Kconfig linux-2.6.22-590/drivers/serial/Kconfig
---- linux-2.6.22-570/drivers/serial/Kconfig 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/drivers/serial/Kconfig 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/drivers/serial/Kconfig 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/drivers/serial/Kconfig 2008-01-29 22:12:32.000000000 -0500
@@ -107,7 +107,7 @@
config SERIAL_8250_NR_UARTS
Set this to the number of serial ports you want the driver
diff -Nurb linux-2.6.22-570/drivers/serial/Makefile linux-2.6.22-590/drivers/serial/Makefile
--- linux-2.6.22-570/drivers/serial/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/serial/Makefile 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/serial/Makefile 2008-01-29 22:12:32.000000000 -0500
@@ -23,6 +23,7 @@
obj-$(CONFIG_SERIAL_8250_AU1X00) += 8250_au1x00.o
obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
+obj-$(CONFIG_KGDB_8250) += 8250_kgdb.o
diff -Nurb linux-2.6.22-570/drivers/serial/amba-pl011.c linux-2.6.22-590/drivers/serial/amba-pl011.c
--- linux-2.6.22-570/drivers/serial/amba-pl011.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/serial/amba-pl011.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/serial/amba-pl011.c 2008-01-29 22:12:32.000000000 -0500
@@ -332,7 +332,7 @@
/*
* Allocate the IRQ
diff -Nurb linux-2.6.22-570/drivers/serial/cpm_uart/Makefile linux-2.6.22-590/drivers/serial/cpm_uart/Makefile
--- linux-2.6.22-570/drivers/serial/cpm_uart/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/serial/cpm_uart/Makefile 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/serial/cpm_uart/Makefile 2008-01-29 22:12:32.000000000 -0500
@@ -7,5 +7,6 @@
# Select the correct platform objects.
cpm_uart-objs-$(CONFIG_CPM2) += cpm_uart_cpm2.o
cpm_uart-objs := cpm_uart_core.o $(cpm_uart-objs-y)
diff -Nurb linux-2.6.22-570/drivers/serial/cpm_uart/cpm_uart.h linux-2.6.22-590/drivers/serial/cpm_uart/cpm_uart.h
--- linux-2.6.22-570/drivers/serial/cpm_uart/cpm_uart.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/serial/cpm_uart/cpm_uart.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/serial/cpm_uart/cpm_uart.h 2008-01-29 22:12:32.000000000 -0500
@@ -50,6 +50,41 @@
#define SCC_WAIT_CLOSING 100
#endif /* CPM_UART_H */
diff -Nurb linux-2.6.22-570/drivers/serial/cpm_uart/cpm_uart_core.c linux-2.6.22-590/drivers/serial/cpm_uart/cpm_uart_core.c
--- linux-2.6.22-570/drivers/serial/cpm_uart/cpm_uart_core.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/serial/cpm_uart/cpm_uart_core.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/serial/cpm_uart/cpm_uart_core.c 2008-01-29 22:12:32.000000000 -0500
@@ -1073,22 +1073,17 @@
return 0;
}
if (cpm_uart_ports[con].set_lineif)
diff -Nurb linux-2.6.22-570/drivers/serial/cpm_uart/cpm_uart_cpm1.c linux-2.6.22-590/drivers/serial/cpm_uart/cpm_uart_cpm1.c
--- linux-2.6.22-570/drivers/serial/cpm_uart/cpm_uart_cpm1.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/serial/cpm_uart/cpm_uart_cpm1.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/serial/cpm_uart/cpm_uart_cpm1.c 2008-01-29 22:12:32.000000000 -0500
@@ -53,6 +53,7 @@
{
ushort val;
cpm_uart_ports[UART_SMC1].smcp = &cpmp->cp_smc[0];
diff -Nurb linux-2.6.22-570/drivers/serial/cpm_uart/cpm_uart_cpm2.c linux-2.6.22-590/drivers/serial/cpm_uart/cpm_uart_cpm2.c
--- linux-2.6.22-570/drivers/serial/cpm_uart/cpm_uart_cpm2.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/serial/cpm_uart/cpm_uart_cpm2.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/serial/cpm_uart/cpm_uart_cpm2.c 2008-01-29 22:12:32.000000000 -0500
@@ -289,6 +289,10 @@
#endif
pr_debug("CPM uart[-]:init portdesc\n");
cpm_uart_ports[UART_SMC1].smcp = (smc_t *) cpm2_map(im_smc[0]);
diff -Nurb linux-2.6.22-570/drivers/serial/cpm_uart/cpm_uart_kgdb.c linux-2.6.22-590/drivers/serial/cpm_uart/cpm_uart_kgdb.c
--- linux-2.6.22-570/drivers/serial/cpm_uart/cpm_uart_kgdb.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/serial/cpm_uart/cpm_uart_kgdb.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/serial/cpm_uart/cpm_uart_kgdb.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,185 @@
+/*
+ * drivers/serial/cpm_uart/cpm_uart_kgdb.c
+
diff -Nurb linux-2.6.22-570/drivers/serial/mpsc_kgdb.c linux-2.6.22-590/drivers/serial/mpsc_kgdb.c
--- linux-2.6.22-570/drivers/serial/mpsc_kgdb.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/serial/mpsc_kgdb.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/serial/mpsc_kgdb.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,345 @@
+/*
+ * drivers/serial/mpsc_kgdb.c
+};
diff -Nurb linux-2.6.22-570/drivers/serial/pl011_kgdb.c linux-2.6.22-590/drivers/serial/pl011_kgdb.c
--- linux-2.6.22-570/drivers/serial/pl011_kgdb.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/serial/pl011_kgdb.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/serial/pl011_kgdb.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,111 @@
+/*
+ * driver/serial/pl011_kgdb.c
+};
diff -Nurb linux-2.6.22-570/drivers/serial/pxa.c linux-2.6.22-590/drivers/serial/pxa.c
--- linux-2.6.22-570/drivers/serial/pxa.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/serial/pxa.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/serial/pxa.c 2008-01-29 22:12:32.000000000 -0500
@@ -42,6 +42,9 @@
#include <linux/tty.h>
#include <linux/tty_flip.h>
#endif
diff -Nurb linux-2.6.22-570/drivers/serial/serial_core.c linux-2.6.22-590/drivers/serial/serial_core.c
--- linux-2.6.22-570/drivers/serial/serial_core.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/serial/serial_core.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/serial/serial_core.c 2008-01-29 22:12:32.000000000 -0500
@@ -33,6 +33,7 @@
#include <linux/serial.h> /* for serial_state and serial_icounter_struct */
#include <linux/delay.h>
mutex_unlock(&port_mutex);
diff -Nurb linux-2.6.22-570/drivers/serial/serial_txx9.c linux-2.6.22-590/drivers/serial/serial_txx9.c
--- linux-2.6.22-570/drivers/serial/serial_txx9.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/serial/serial_txx9.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/serial/serial_txx9.c 2008-01-29 22:12:32.000000000 -0500
@@ -40,6 +40,10 @@
static char *serial_version = "1.09";
static char *serial_name = "TX39/49 Serial driver";
uart_remove_one_port(&serial_txx9_reg, &uart->port);
diff -Nurb linux-2.6.22-570/drivers/serial/serial_txx9_kgdb.c linux-2.6.22-590/drivers/serial/serial_txx9_kgdb.c
--- linux-2.6.22-570/drivers/serial/serial_txx9_kgdb.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/drivers/serial/serial_txx9_kgdb.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/serial/serial_txx9_kgdb.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,150 @@
+/*
+ * drivers/serial/serial_txx9_kgdb.c
+};
diff -Nurb linux-2.6.22-570/drivers/serial/sh-sci.c linux-2.6.22-590/drivers/serial/sh-sci.c
--- linux-2.6.22-570/drivers/serial/sh-sci.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/serial/sh-sci.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/serial/sh-sci.c 2008-01-29 22:12:32.000000000 -0500
@@ -118,7 +118,8 @@
do {
status = sci_in(port, SCxSR);
* FIXME: Most of this can go away.. at the moment, we rely on
diff -Nurb linux-2.6.22-570/drivers/spi/at25.c linux-2.6.22-590/drivers/spi/at25.c
--- linux-2.6.22-570/drivers/spi/at25.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/spi/at25.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/spi/at25.c 2008-01-29 22:12:32.000000000 -0500
@@ -111,7 +111,8 @@
}
at25->bin.read = at25_bin_read;
at25->bin.size = at25->chip.byte_len;
+diff -Nurb linux-2.6.22-570/drivers/usb/atm/cxacru.c linux-2.6.22-590/drivers/usb/atm/cxacru.c
+--- linux-2.6.22-570/drivers/usb/atm/cxacru.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/usb/atm/cxacru.c 2008-01-29 22:12:32.000000000 -0500
+@@ -171,7 +171,7 @@
+ struct delayed_work poll_work;
+ u32 card_info[CXINF_MAX];
+ struct mutex poll_state_serialize;
+- int poll_state;
++ enum cxacru_poll_state poll_state;
+
+ /* contol handles */
+ struct mutex cm_serialize;
+@@ -226,58 +226,48 @@
+
+ static ssize_t cxacru_sysfs_showattr_dB(s16 value, char *buf)
+ {
+- if (unlikely(value < 0)) {
+ return snprintf(buf, PAGE_SIZE, "%d.%02u\n",
+- value / 100, -value % 100);
+- } else {
+- return snprintf(buf, PAGE_SIZE, "%d.%02u\n",
+- value / 100, value % 100);
+- }
++ value / 100, abs(value) % 100);
+ }
+
+ static ssize_t cxacru_sysfs_showattr_bool(u32 value, char *buf)
+ {
+- switch (value) {
+- case 0: return snprintf(buf, PAGE_SIZE, "no\n");
+- case 1: return snprintf(buf, PAGE_SIZE, "yes\n");
+- default: return 0;
+- }
++ static char *str[] = { "no", "yes" };
++ if (unlikely(value >= ARRAY_SIZE(str)))
++ return snprintf(buf, PAGE_SIZE, "%u\n", value);
++ return snprintf(buf, PAGE_SIZE, "%s\n", str[value]);
+ }
+
+ static ssize_t cxacru_sysfs_showattr_LINK(u32 value, char *buf)
+ {
+- switch (value) {
+- case 1: return snprintf(buf, PAGE_SIZE, "not connected\n");
+- case 2: return snprintf(buf, PAGE_SIZE, "connected\n");
+- case 3: return snprintf(buf, PAGE_SIZE, "lost\n");
+- default: return snprintf(buf, PAGE_SIZE, "unknown (%u)\n", value);
+- }
++ static char *str[] = { NULL, "not connected", "connected", "lost" };
++ if (unlikely(value >= ARRAY_SIZE(str) || str[value] == NULL))
++ return snprintf(buf, PAGE_SIZE, "%u\n", value);
++ return snprintf(buf, PAGE_SIZE, "%s\n", str[value]);
+ }
+
+ static ssize_t cxacru_sysfs_showattr_LINE(u32 value, char *buf)
+ {
+- switch (value) {
+- case 0: return snprintf(buf, PAGE_SIZE, "down\n");
+- case 1: return snprintf(buf, PAGE_SIZE, "attempting to activate\n");
+- case 2: return snprintf(buf, PAGE_SIZE, "training\n");
+- case 3: return snprintf(buf, PAGE_SIZE, "channel analysis\n");
+- case 4: return snprintf(buf, PAGE_SIZE, "exchange\n");
+- case 5: return snprintf(buf, PAGE_SIZE, "up\n");
+- case 6: return snprintf(buf, PAGE_SIZE, "waiting\n");
+- case 7: return snprintf(buf, PAGE_SIZE, "initialising\n");
+- default: return snprintf(buf, PAGE_SIZE, "unknown (%u)\n", value);
+- }
++ static char *str[] = { "down", "attempting to activate",
++ "training", "channel analysis", "exchange", "up",
++ "waiting", "initialising"
++ };
++ if (unlikely(value >= ARRAY_SIZE(str)))
++ return snprintf(buf, PAGE_SIZE, "%u\n", value);
++ return snprintf(buf, PAGE_SIZE, "%s\n", str[value]);
+ }
+
+ static ssize_t cxacru_sysfs_showattr_MODU(u32 value, char *buf)
+ {
+- switch (value) {
+- case 0: return 0;
+- case 1: return snprintf(buf, PAGE_SIZE, "ANSI T1.413\n");
+- case 2: return snprintf(buf, PAGE_SIZE, "ITU-T G.992.1 (G.DMT)\n");
+- case 3: return snprintf(buf, PAGE_SIZE, "ITU-T G.992.2 (G.LITE)\n");
+- default: return snprintf(buf, PAGE_SIZE, "unknown (%u)\n", value);
+- }
++ static char *str[] = {
++ NULL,
++ "ANSI T1.413",
++ "ITU-T G.992.1 (G.DMT)",
++ "ITU-T G.992.2 (G.LITE)"
++ };
++ if (unlikely(value >= ARRAY_SIZE(str) || str[value] == NULL))
++ return snprintf(buf, PAGE_SIZE, "%u\n", value);
++ return snprintf(buf, PAGE_SIZE, "%s\n", str[value]);
+ }
+
+ /*
+@@ -308,11 +298,10 @@
+ struct cxacru_data *instance = usbatm_instance->driver_data;
+ u32 value = instance->card_info[CXINF_LINE_STARTABLE];
+
+- switch (value) {
+- case 0: return snprintf(buf, PAGE_SIZE, "running\n");
+- case 1: return snprintf(buf, PAGE_SIZE, "stopped\n");
+- default: return snprintf(buf, PAGE_SIZE, "unknown (%u)\n", value);
+- }
++ static char *str[] = { "running", "stopped" };
++ if (unlikely(value >= ARRAY_SIZE(str)))
++ return snprintf(buf, PAGE_SIZE, "%u\n", value);
++ return snprintf(buf, PAGE_SIZE, "%s\n", str[value]);
+ }
+
+ static ssize_t cxacru_sysfs_store_adsl_state(struct device *dev,
diff -Nurb linux-2.6.22-570/drivers/usb/atm/ueagle-atm.c linux-2.6.22-590/drivers/usb/atm/ueagle-atm.c
--- linux-2.6.22-570/drivers/usb/atm/ueagle-atm.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/usb/atm/ueagle-atm.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/usb/atm/ueagle-atm.c 2008-01-29 22:12:32.000000000 -0500
@@ -1168,6 +1168,7 @@
struct uea_softc *sc = data;
int ret = -EAGAIN;
uea_enters(INS_TO_USBDEV(sc));
while (!kthread_should_stop()) {
if (ret < 0 || sc->reset)
+diff -Nurb linux-2.6.22-570/drivers/usb/core/config.c linux-2.6.22-590/drivers/usb/core/config.c
+--- linux-2.6.22-570/drivers/usb/core/config.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/usb/core/config.c 2008-01-29 22:12:32.000000000 -0500
+@@ -274,6 +274,7 @@
+ struct usb_descriptor_header *header;
+ int len, retval;
+ u8 inums[USB_MAXINTERFACES], nalts[USB_MAXINTERFACES];
++ unsigned iad_num = 0;
+
+ memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);
+ if (config->desc.bDescriptorType != USB_DT_CONFIG ||
+@@ -351,6 +352,20 @@
+ ++n;
+ }
+
++ } else if (header->bDescriptorType ==
++ USB_DT_INTERFACE_ASSOCIATION) {
++ if (iad_num == USB_MAXIADS) {
++ dev_warn(ddev, "found more Interface "
++ "Association Descriptors "
++ "than allocated for in "
++ "configuration %d\n", cfgno);
++ } else {
++ config->intf_assoc[iad_num] =
++ (struct usb_interface_assoc_descriptor
++ *)header;
++ iad_num++;
++ }
++
+ } else if (header->bDescriptorType == USB_DT_DEVICE ||
+ header->bDescriptorType == USB_DT_CONFIG)
+ dev_warn(ddev, "config %d contains an unexpected "
+diff -Nurb linux-2.6.22-570/drivers/usb/core/devices.c linux-2.6.22-590/drivers/usb/core/devices.c
+--- linux-2.6.22-570/drivers/usb/core/devices.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/usb/core/devices.c 2008-01-29 22:12:32.000000000 -0500
+@@ -102,6 +102,10 @@
+ /* C: #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */
+ "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n";
+
++static const char *format_iad =
++/* A: FirstIf#=dd IfCount=dd Cls=xx(sssss) Sub=xx Prot=xx */
++ "A: FirstIf#=%2d IfCount=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x\n";
++
+ static const char *format_iface =
+ /* I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/
+ "I:%c If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n";
+@@ -146,6 +150,7 @@
+ {USB_CLASS_STILL_IMAGE, "still"},
+ {USB_CLASS_CSCID, "scard"},
+ {USB_CLASS_CONTENT_SEC, "c-sec"},
++ {USB_CLASS_VIDEO, "video"},
+ {-1, "unk."} /* leave as last */
+ };
+
+@@ -286,6 +291,21 @@
+ return start;
+ }
+
++static char *usb_dump_iad_descriptor(char *start, char *end,
++ const struct usb_interface_assoc_descriptor *iad)
++{
++ if (start > end)
++ return start;
++ start += sprintf(start, format_iad,
++ iad->bFirstInterface,
++ iad->bInterfaceCount,
++ iad->bFunctionClass,
++ class_decode(iad->bFunctionClass),
++ iad->bFunctionSubClass,
++ iad->bFunctionProtocol);
++ return start;
++}
++
+ /* TBD:
+ * 0. TBDs
+ * 1. marking active interface altsettings (code lists all, but should mark
+@@ -322,6 +342,12 @@
+ if (!config) /* getting these some in 2.3.7; none in 2.3.6 */
+ return start + sprintf(start, "(null Cfg. desc.)\n");
+ start = usb_dump_config_descriptor(start, end, &config->desc, active);
++ for (i = 0; i < USB_MAXIADS; i++) {
++ if (config->intf_assoc[i] == NULL)
++ break;
++ start = usb_dump_iad_descriptor(start, end,
++ config->intf_assoc[i]);
++ }
+ for (i = 0; i < config->desc.bNumInterfaces; i++) {
+ intfc = config->intf_cache[i];
+ interface = config->interface[i];
diff -Nurb linux-2.6.22-570/drivers/usb/core/hub.c linux-2.6.22-590/drivers/usb/core/hub.c
---- linux-2.6.22-570/drivers/usb/core/hub.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/drivers/usb/core/hub.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/drivers/usb/core/hub.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/drivers/usb/core/hub.c 2008-01-29 22:12:32.000000000 -0500
@@ -2831,6 +2831,7 @@
static int hub_thread(void *__unused)
do {
hub_events();
wait_event_interruptible(khubd_wait,
+diff -Nurb linux-2.6.22-570/drivers/usb/core/message.c linux-2.6.22-590/drivers/usb/core/message.c
+--- linux-2.6.22-570/drivers/usb/core/message.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/drivers/usb/core/message.c 2008-01-29 22:12:32.000000000 -0500
+@@ -1409,6 +1409,36 @@
+ .uevent = usb_if_uevent,
+ };
+
++static struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev,
++ struct usb_host_config *config,
++ u8 inum)
++{
++ struct usb_interface_assoc_descriptor *retval = NULL;
++ struct usb_interface_assoc_descriptor *intf_assoc;
++ int first_intf;
++ int last_intf;
++ int i;
++
++ for (i = 0; (i < USB_MAXIADS && config->intf_assoc[i]); i++) {
++ intf_assoc = config->intf_assoc[i];
++ if (intf_assoc->bInterfaceCount == 0)
++ continue;
++
++ first_intf = intf_assoc->bFirstInterface;
++ last_intf = first_intf + (intf_assoc->bInterfaceCount - 1);
++ if (inum >= first_intf && inum <= last_intf) {
++ if (!retval)
++ retval = intf_assoc;
++ else
++ dev_err(&dev->dev, "Interface #%d referenced"
++ " by multiple IADs\n", inum);
++ }
++ }
++
++ return retval;
++}
++
++
+ /*
+ * usb_set_configuration - Makes a particular device setting be current
+ * @dev: the device whose configuration is being updated
+@@ -1555,6 +1585,7 @@
+ intfc = cp->intf_cache[i];
+ intf->altsetting = intfc->altsetting;
+ intf->num_altsetting = intfc->num_altsetting;
++ intf->intf_assoc = find_iad(dev, cp, i);
+ kref_get(&intfc->ref);
+
+ alt = usb_altnum_to_altsetting(intf, 0);
+diff -Nurb linux-2.6.22-570/drivers/usb/core/sysfs.c linux-2.6.22-590/drivers/usb/core/sysfs.c
+--- linux-2.6.22-570/drivers/usb/core/sysfs.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/drivers/usb/core/sysfs.c 2008-01-29 22:12:32.000000000 -0500
+@@ -424,6 +424,25 @@
+ sysfs_remove_group(&dev->kobj, &dev_attr_grp);
+ }
+
++/* Interface Accociation Descriptor fields */
++#define usb_intf_assoc_attr(field, format_string) \
++static ssize_t \
++show_iad_##field (struct device *dev, struct device_attribute *attr, \
++ char *buf) \
++{ \
++ struct usb_interface *intf = to_usb_interface (dev); \
++ \
++ return sprintf (buf, format_string, \
++ intf->intf_assoc->field); \
++} \
++static DEVICE_ATTR(iad_##field, S_IRUGO, show_iad_##field, NULL);
++
++usb_intf_assoc_attr (bFirstInterface, "%02x\n")
++usb_intf_assoc_attr (bInterfaceCount, "%02d\n")
++usb_intf_assoc_attr (bFunctionClass, "%02x\n")
++usb_intf_assoc_attr (bFunctionSubClass, "%02x\n")
++usb_intf_assoc_attr (bFunctionProtocol, "%02x\n")
++
+ /* Interface fields */
+ #define usb_intf_attr(field, format_string) \
+ static ssize_t \
+@@ -487,6 +506,18 @@
+ }
+ static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
+
++static struct attribute *intf_assoc_attrs[] = {
++ &dev_attr_iad_bFirstInterface.attr,
++ &dev_attr_iad_bInterfaceCount.attr,
++ &dev_attr_iad_bFunctionClass.attr,
++ &dev_attr_iad_bFunctionSubClass.attr,
++ &dev_attr_iad_bFunctionProtocol.attr,
++ NULL,
++};
++static struct attribute_group intf_assoc_attr_grp = {
++ .attrs = intf_assoc_attrs,
++};
++
+ static struct attribute *intf_attrs[] = {
+ &dev_attr_bInterfaceNumber.attr,
+ &dev_attr_bAlternateSetting.attr,
+@@ -538,6 +569,8 @@
+ alt->string = usb_cache_string(udev, alt->desc.iInterface);
+ if (alt->string)
+ retval = device_create_file(dev, &dev_attr_interface);
++ if (intf->intf_assoc)
++ retval = sysfs_create_group(&dev->kobj, &intf_assoc_attr_grp);
+ usb_create_intf_ep_files(intf, udev);
+ return 0;
+ }
+@@ -549,4 +582,5 @@
+ usb_remove_intf_ep_files(intf);
+ device_remove_file(dev, &dev_attr_interface);
+ sysfs_remove_group(&dev->kobj, &intf_attr_grp);
++ sysfs_remove_group(&intf->dev.kobj, &intf_assoc_attr_grp);
+ }
diff -Nurb linux-2.6.22-570/drivers/usb/gadget/file_storage.c linux-2.6.22-590/drivers/usb/gadget/file_storage.c
--- linux-2.6.22-570/drivers/usb/gadget/file_storage.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/usb/gadget/file_storage.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/usb/gadget/file_storage.c 2008-01-29 22:12:32.000000000 -0500
@@ -3434,6 +3434,9 @@
allow_signal(SIGKILL);
allow_signal(SIGUSR1);
* that expects a __user pointer and it will work okay. */
diff -Nurb linux-2.6.22-570/drivers/usb/storage/usb.c linux-2.6.22-590/drivers/usb/storage/usb.c
--- linux-2.6.22-570/drivers/usb/storage/usb.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/usb/storage/usb.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/usb/storage/usb.c 2008-01-29 22:12:32.000000000 -0500
@@ -301,8 +301,6 @@
struct us_data *us = (struct us_data *)__us;
struct Scsi_Host *host = us_to_host(us);
printk(KERN_DEBUG "usb-storage: waiting for device "
diff -Nurb linux-2.6.22-570/drivers/video/Kconfig linux-2.6.22-590/drivers/video/Kconfig
--- linux-2.6.22-570/drivers/video/Kconfig 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/video/Kconfig 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/video/Kconfig 2008-01-29 22:12:32.000000000 -0500
@@ -12,6 +12,13 @@
tristate
default n
---help---
diff -Nurb linux-2.6.22-570/drivers/video/Makefile linux-2.6.22-590/drivers/video/Makefile
--- linux-2.6.22-570/drivers/video/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/video/Makefile 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/video/Makefile 2008-01-29 22:12:32.000000000 -0500
@@ -122,3 +122,6 @@
# the test framebuffer is last
+obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o
diff -Nurb linux-2.6.22-570/drivers/video/aty/radeon_base.c linux-2.6.22-590/drivers/video/aty/radeon_base.c
--- linux-2.6.22-570/drivers/video/aty/radeon_base.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/video/aty/radeon_base.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/video/aty/radeon_base.c 2008-01-29 22:12:32.000000000 -0500
@@ -2102,7 +2102,9 @@
}
.size = EDID_LENGTH,
diff -Nurb linux-2.6.22-570/drivers/video/backlight/backlight.c linux-2.6.22-590/drivers/video/backlight/backlight.c
--- linux-2.6.22-570/drivers/video/backlight/backlight.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/video/backlight/backlight.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/video/backlight/backlight.c 2008-01-29 22:12:32.000000000 -0500
@@ -172,7 +172,7 @@
#define DECLARE_ATTR(_name,_mode,_show,_store) \
}
diff -Nurb linux-2.6.22-570/drivers/video/backlight/lcd.c linux-2.6.22-590/drivers/video/backlight/lcd.c
--- linux-2.6.22-570/drivers/video/backlight/lcd.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/video/backlight/lcd.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/video/backlight/lcd.c 2008-01-29 22:12:32.000000000 -0500
@@ -157,7 +157,7 @@
#define DECLARE_ATTR(_name,_mode,_show,_store) \
}
diff -Nurb linux-2.6.22-570/drivers/video/ps3fb.c linux-2.6.22-590/drivers/video/ps3fb.c
--- linux-2.6.22-570/drivers/video/ps3fb.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/video/ps3fb.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/video/ps3fb.c 2008-01-29 22:12:32.000000000 -0500
@@ -812,6 +812,7 @@
static int ps3fbd(void *arg)
set_current_state(TASK_INTERRUPTIBLE);
diff -Nurb linux-2.6.22-570/drivers/w1/slaves/w1_ds2433.c linux-2.6.22-590/drivers/w1/slaves/w1_ds2433.c
--- linux-2.6.22-570/drivers/w1/slaves/w1_ds2433.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/w1/slaves/w1_ds2433.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/w1/slaves/w1_ds2433.c 2008-01-29 22:12:32.000000000 -0500
@@ -91,8 +91,9 @@
}
#endif /* CONFIG_W1_SLAVE_DS2433_CRC */
.read = w1_f23_read_bin,
diff -Nurb linux-2.6.22-570/drivers/w1/slaves/w1_therm.c linux-2.6.22-590/drivers/w1/slaves/w1_therm.c
--- linux-2.6.22-570/drivers/w1/slaves/w1_therm.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/w1/slaves/w1_therm.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/w1/slaves/w1_therm.c 2008-01-29 22:12:32.000000000 -0500
@@ -42,13 +42,13 @@
{}
};
struct w1_master *dev = sl->master;
diff -Nurb linux-2.6.22-570/drivers/w1/w1.c linux-2.6.22-590/drivers/w1/w1.c
--- linux-2.6.22-570/drivers/w1/w1.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/w1/w1.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/w1/w1.c 2008-01-29 22:12:32.000000000 -0500
@@ -105,7 +105,9 @@
return sprintf(buf, "%s\n", sl->name);
}
diff -Nurb linux-2.6.22-570/drivers/zorro/zorro-sysfs.c linux-2.6.22-590/drivers/zorro/zorro-sysfs.c
--- linux-2.6.22-570/drivers/zorro/zorro-sysfs.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/drivers/zorro/zorro-sysfs.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/drivers/zorro/zorro-sysfs.c 2008-01-29 22:12:32.000000000 -0500
@@ -49,8 +49,9 @@
static DEVICE_ATTR(resource, S_IRUGO, zorro_show_resource, NULL);
},
.size = sizeof(struct ConfigDev),
.read = zorro_read_config,
+diff -Nurb linux-2.6.22-570/ed linux-2.6.22-590/ed
+--- linux-2.6.22-570/ed 1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.22-590/ed 2008-01-29 22:12:32.000000000 -0500
+@@ -0,0 +1,6 @@
++vi -o ./fs/proc/proc_misc.c ./fs/proc/proc_misc.c.rej
++vi -o ./fs/proc/array.c ./fs/proc/array.c.rej
++vi -o ./include/linux/sched.h ./include/linux/sched.h.rej
++vi -o ./kernel/time/timekeeping.c ./kernel/time/timekeeping.c.rej
++vi -o ./kernel/timer.c ./kernel/timer.c.rej
++vi -o ./kernel/fork.c ./kernel/fork.c.rej
+diff -Nurb linux-2.6.22-570/edit linux-2.6.22-590/edit
+--- linux-2.6.22-570/edit 1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.22-590/edit 2008-01-29 22:12:32.000000000 -0500
+@@ -0,0 +1,19 @@
++vi -o ./fs/proc/root.c ./fs/proc/root.c.rej
++vi -o ./include/linux/nsproxy.h ./include/linux/nsproxy.h.rej
++vi -o ./include/linux/sched.h ./include/linux/sched.h.rej
++vi -o ./include/net/inet_timewait_sock.h ./include/net/inet_timewait_sock.h.rej
++vi -o ./include/net/route.h ./include/net/route.h.rej
++vi -o ./include/net/sock.h ./include/net/sock.h.rej
++vi -o ./kernel/nsproxy.c ./kernel/nsproxy.c.rej
++vi -o ./lib/Makefile ./lib/Makefile.rej
++vi -o ./net/core/dev.c ./net/core/dev.c.rej
++vi -o ./net/core/rtnetlink.c ./net/core/rtnetlink.c.rej
++vi -o ./net/core/sock.c ./net/core/sock.c.rej
++vi -o ./net/ipv4/af_inet.c ./net/ipv4/af_inet.c.rej
++vi -o ./net/ipv4/inet_connection_sock.c ./net/ipv4/inet_connection_sock.c.rej
++vi -o ./net/ipv4/inet_hashtables.c ./net/ipv4/inet_hashtables.c.rej
++vi -o ./net/ipv4/raw.c ./net/ipv4/raw.c.rej
++vi -o ./net/ipv4/tcp_ipv4.c ./net/ipv4/tcp_ipv4.c.rej
++vi -o ./net/ipv4/udp.c ./net/ipv4/udp.c.rej
++vi -o ./net/ipv6/addrconf.c ./net/ipv6/addrconf.c.rej
++vi -o ./net/unix/af_unix.c ./net/unix/af_unix.c.rej
diff -Nurb linux-2.6.22-570/fs/Kconfig linux-2.6.22-590/fs/Kconfig
--- linux-2.6.22-570/fs/Kconfig 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/Kconfig 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/Kconfig 2008-01-29 22:12:32.000000000 -0500
@@ -1030,6 +1030,41 @@
endmenu
depends on BLOCK && EXPERIMENTAL
diff -Nurb linux-2.6.22-570/fs/Makefile linux-2.6.22-590/fs/Makefile
--- linux-2.6.22-570/fs/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/Makefile 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/Makefile 2008-01-29 22:12:32.000000000 -0500
@@ -19,6 +19,7 @@
obj-y += no-block.o
endif
obj-$(CONFIG_OCFS2_FS) += ocfs2/
obj-$(CONFIG_GFS2_FS) += gfs2/
+obj-$(CONFIG_UNION_FS) += unionfs/
+diff -Nurb linux-2.6.22-570/fs/afs/netdevices.c linux-2.6.22-590/fs/afs/netdevices.c
+--- linux-2.6.22-570/fs/afs/netdevices.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/fs/afs/netdevices.c 2008-01-29 22:12:32.000000000 -0500
+@@ -8,6 +8,7 @@
+ #include <linux/inetdevice.h>
+ #include <linux/netdevice.h>
+ #include <linux/if_arp.h>
++#include <net/net_namespace.h>
+ #include "internal.h"
+
+ /*
+@@ -23,7 +24,7 @@
+ BUG();
+
+ rtnl_lock();
+- dev = __dev_getfirstbyhwtype(ARPHRD_ETHER);
++ dev = __dev_getfirstbyhwtype(&init_net, ARPHRD_ETHER);
+ if (dev) {
+ memcpy(mac, dev->dev_addr, maclen);
+ ret = 0;
+@@ -47,7 +48,7 @@
+ ASSERT(maxbufs > 0);
+
+ rtnl_lock();
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ if (dev->type == ARPHRD_LOOPBACK && !wantloopback)
+ continue;
+ idev = __in_dev_get_rtnl(dev);
diff -Nurb linux-2.6.22-570/fs/buffer.c linux-2.6.22-590/fs/buffer.c
--- linux-2.6.22-570/fs/buffer.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/buffer.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/buffer.c 2008-01-29 22:12:32.000000000 -0500
@@ -982,7 +982,7 @@
struct buffer_head *bh;
get_cpu_var(bh_accounting).nr++;
diff -Nurb linux-2.6.22-570/fs/cifs/cifsfs.c linux-2.6.22-590/fs/cifs/cifsfs.c
--- linux-2.6.22-570/fs/cifs/cifsfs.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/cifs/cifsfs.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/cifs/cifsfs.c 2008-01-29 22:12:32.000000000 -0500
@@ -849,6 +849,7 @@
__u16 netfid;
int rc;
continue;
diff -Nurb linux-2.6.22-570/fs/cifs/connect.c linux-2.6.22-590/fs/cifs/connect.c
--- linux-2.6.22-570/fs/cifs/connect.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/cifs/connect.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/cifs/connect.c 2008-01-29 22:12:32.000000000 -0500
@@ -363,6 +363,7 @@
GFP_KERNEL);
}
while (!kthread_should_stop()) {
if (try_to_freeze())
continue;
+diff -Nurb linux-2.6.22-570/fs/compat_ioctl.c linux-2.6.22-590/fs/compat_ioctl.c
+--- linux-2.6.22-570/fs/compat_ioctl.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/fs/compat_ioctl.c 2008-01-29 22:12:32.000000000 -0500
+@@ -319,22 +319,21 @@
+
+ static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
+ {
+- struct net_device *dev;
+- struct ifreq32 ifr32;
++ struct ifreq __user *uifr;
+ int err;
+
+- if (copy_from_user(&ifr32, compat_ptr(arg), sizeof(ifr32)))
++ uifr = compat_alloc_user_space(sizeof(struct ifreq));
++ if (copy_in_user(uifr, compat_ptr(arg), sizeof(struct ifreq32)));
+ return -EFAULT;
+
+- dev = dev_get_by_index(ifr32.ifr_ifindex);
+- if (!dev)
+- return -ENODEV;
++ err = sys_ioctl(fd, SIOCGIFNAME, (unsigned long)uifr);
++ if (err)
++ return err;
+
+- strlcpy(ifr32.ifr_name, dev->name, sizeof(ifr32.ifr_name));
+- dev_put(dev);
++ if (copy_in_user(compat_ptr(arg), uifr, sizeof(struct ifreq32)))
++ return -EFAULT;
+
+- err = copy_to_user(compat_ptr(arg), &ifr32, sizeof(ifr32));
+- return (err ? -EFAULT : 0);
++ return 0;
+ }
+
+ static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
diff -Nurb linux-2.6.22-570/fs/configfs/configfs_internal.h linux-2.6.22-590/fs/configfs/configfs_internal.h
--- linux-2.6.22-570/fs/configfs/configfs_internal.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/configfs/configfs_internal.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/configfs/configfs_internal.h 2008-01-29 22:12:32.000000000 -0500
@@ -29,6 +29,7 @@
struct configfs_dirent {
struct list_head s_links;
diff -Nurb linux-2.6.22-570/fs/configfs/dir.c linux-2.6.22-590/fs/configfs/dir.c
--- linux-2.6.22-570/fs/configfs/dir.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/configfs/dir.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/configfs/dir.c 2008-01-29 22:12:32.000000000 -0500
@@ -355,6 +355,10 @@
/* Mark that we've taken i_mutex */
sd->s_type |= CONFIGFS_USET_DROPPING;
diff -Nurb linux-2.6.22-570/fs/configfs/file.c linux-2.6.22-590/fs/configfs/file.c
--- linux-2.6.22-570/fs/configfs/file.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/configfs/file.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/configfs/file.c 2008-01-29 22:12:32.000000000 -0500
@@ -27,19 +27,26 @@
#include <linux/fs.h>
#include <linux/module.h>
return 0;
diff -Nurb linux-2.6.22-570/fs/configfs/item.c linux-2.6.22-590/fs/configfs/item.c
--- linux-2.6.22-570/fs/configfs/item.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/configfs/item.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/configfs/item.c 2008-01-29 22:12:32.000000000 -0500
@@ -62,7 +62,6 @@
* dynamically allocated string that @item->ci_name points to.
* Otherwise, use the static @item->ci_namebuf array.
EXPORT_SYMBOL(config_item_get);
diff -Nurb linux-2.6.22-570/fs/drop_caches.c linux-2.6.22-590/fs/drop_caches.c
--- linux-2.6.22-570/fs/drop_caches.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/drop_caches.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/drop_caches.c 2008-01-29 22:12:32.000000000 -0500
@@ -3,6 +3,7 @@
*/
void drop_pagecache(void)
{
diff -Nurb linux-2.6.22-570/fs/ecryptfs/inode.c linux-2.6.22-590/fs/ecryptfs/inode.c
---- linux-2.6.22-570/fs/ecryptfs/inode.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/fs/ecryptfs/inode.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/ecryptfs/inode.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/ecryptfs/inode.c 2008-01-29 22:12:32.000000000 -0500
@@ -280,7 +280,9 @@
int rc = 0;
struct dentry *lower_dir_dentry;
rc = PTR_ERR(lower_dentry);
diff -Nurb linux-2.6.22-570/fs/ecryptfs/main.c linux-2.6.22-590/fs/ecryptfs/main.c
--- linux-2.6.22-570/fs/ecryptfs/main.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ecryptfs/main.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ecryptfs/main.c 2008-01-29 22:12:32.000000000 -0500
@@ -840,8 +840,6 @@
goto out;
}
if (rc) {
printk(KERN_ERR "sysfs registration failed\n");
diff -Nurb linux-2.6.22-570/fs/exec.c linux-2.6.22-590/fs/exec.c
---- linux-2.6.22-570/fs/exec.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/fs/exec.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/exec.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/exec.c 2008-01-29 22:12:32.000000000 -0500
@@ -861,9 +861,9 @@
current->sas_ss_sp = current->sas_ss_size = 0;
name = bprm->filename;
-@@ -894,7 +894,7 @@
+@@ -889,12 +889,12 @@
+
+ if (bprm->e_uid != current->euid || bprm->e_gid != current->egid) {
+ suid_keys(current);
+- current->mm->dumpable = suid_dumpable;
++ set_dumpable(current->mm, suid_dumpable);
+ current->pdeath_signal = 0;
} else if (file_permission(bprm->file, MAY_READ) ||
(bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) {
suid_keys(current);
if (retval < 0)
diff -Nurb linux-2.6.22-570/fs/gfs2/ops_address.c linux-2.6.22-590/fs/gfs2/ops_address.c
--- linux-2.6.22-570/fs/gfs2/ops_address.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/gfs2/ops_address.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/gfs2/ops_address.c 2008-01-29 22:12:32.000000000 -0500
@@ -250,7 +250,7 @@
if (file) {
gf = file->private_data;
gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|LM_FLAG_TRY_1CB, &gh);
diff -Nurb linux-2.6.22-570/fs/gfs2/ops_file.c linux-2.6.22-590/fs/gfs2/ops_file.c
--- linux-2.6.22-570/fs/gfs2/ops_file.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/gfs2/ops_file.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/gfs2/ops_file.c 2008-01-29 22:12:32.000000000 -0500
@@ -364,6 +364,8 @@
else
vma->vm_ops = &gfs2_vm_ops_private;
return error;
diff -Nurb linux-2.6.22-570/fs/gfs2/ops_vm.c linux-2.6.22-590/fs/gfs2/ops_vm.c
--- linux-2.6.22-570/fs/gfs2/ops_vm.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/gfs2/ops_vm.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/gfs2/ops_vm.c 2008-01-29 22:12:32.000000000 -0500
@@ -27,13 +27,13 @@
#include "trans.h"
#include "util.h"
};
diff -Nurb linux-2.6.22-570/fs/inode.c linux-2.6.22-590/fs/inode.c
---- linux-2.6.22-570/fs/inode.c 2008-03-15 10:34:23.000000000 -0400
-+++ linux-2.6.22-590/fs/inode.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/inode.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/inode.c 2008-01-29 22:12:32.000000000 -0500
@@ -149,7 +149,7 @@
mapping->a_ops = &empty_aops;
mapping->host = inode;
{
diff -Nurb linux-2.6.22-570/fs/jbd/journal.c linux-2.6.22-590/fs/jbd/journal.c
--- linux-2.6.22-570/fs/jbd/journal.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/jbd/journal.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/jbd/journal.c 2008-01-29 22:12:32.000000000 -0500
@@ -1710,7 +1710,7 @@
journal_head_cache = kmem_cache_create("journal_head",
sizeof(struct journal_head),
if (jbd_handle_cache == NULL) {
diff -Nurb linux-2.6.22-570/fs/jbd/revoke.c linux-2.6.22-590/fs/jbd/revoke.c
--- linux-2.6.22-570/fs/jbd/revoke.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/jbd/revoke.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/jbd/revoke.c 2008-01-29 22:12:32.000000000 -0500
@@ -169,13 +169,17 @@
{
revoke_record_cache = kmem_cache_create("revoke_record",
revoke_record_cache = NULL;
diff -Nurb linux-2.6.22-570/fs/jffs2/background.c linux-2.6.22-590/fs/jffs2/background.c
--- linux-2.6.22-570/fs/jffs2/background.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/jffs2/background.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/jffs2/background.c 2008-01-29 22:12:32.000000000 -0500
@@ -81,6 +81,7 @@
set_user_nice(current, 10);
diff -Nurb linux-2.6.22-570/fs/lockd/host.c linux-2.6.22-590/fs/lockd/host.c
--- linux-2.6.22-570/fs/lockd/host.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/lockd/host.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/lockd/host.c 2008-01-29 22:12:32.000000000 -0500
@@ -161,15 +161,9 @@
*/
nsm_unmonitor(host);
diff -Nurb linux-2.6.22-570/fs/lockd/mon.c linux-2.6.22-590/fs/lockd/mon.c
--- linux-2.6.22-570/fs/lockd/mon.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/lockd/mon.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/lockd/mon.c 2008-01-29 22:12:32.000000000 -0500
@@ -61,6 +61,7 @@
status);
else
return rpc_create(&args);
diff -Nurb linux-2.6.22-570/fs/lockd/svc.c linux-2.6.22-590/fs/lockd/svc.c
--- linux-2.6.22-570/fs/lockd/svc.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/lockd/svc.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/lockd/svc.c 2008-01-29 22:12:32.000000000 -0500
@@ -25,6 +25,7 @@
#include <linux/smp.h>
#include <linux/smp_lock.h>
unlock_kernel();
module_put_and_exit(0);
diff -Nurb linux-2.6.22-570/fs/namei.c linux-2.6.22-590/fs/namei.c
---- linux-2.6.22-570/fs/namei.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/namei.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/namei.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/namei.c 2008-01-29 22:12:32.000000000 -0500
@@ -1386,7 +1386,8 @@
return 0;
}
EXPORT_SYMBOL(page_put_link);
EXPORT_SYMBOL(page_readlink);
diff -Nurb linux-2.6.22-570/fs/namespace.c linux-2.6.22-590/fs/namespace.c
---- linux-2.6.22-570/fs/namespace.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/namespace.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/namespace.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/namespace.c 2008-01-29 22:12:32.000000000 -0500
@@ -1538,7 +1538,7 @@
new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
struct mnt_namespace *new_ns;
diff -Nurb linux-2.6.22-570/fs/ncpfs/mmap.c linux-2.6.22-590/fs/ncpfs/mmap.c
--- linux-2.6.22-570/fs/ncpfs/mmap.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ncpfs/mmap.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ncpfs/mmap.c 2008-01-29 22:12:32.000000000 -0500
@@ -25,8 +25,8 @@
/*
* Fill in the supplied page for mmap
}
diff -Nurb linux-2.6.22-570/fs/nfs/callback.c linux-2.6.22-590/fs/nfs/callback.c
--- linux-2.6.22-570/fs/nfs/callback.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/nfs/callback.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/nfs/callback.c 2008-01-29 22:12:32.000000000 -0500
@@ -14,6 +14,7 @@
#include <linux/sunrpc/svcsock.h>
#include <linux/nfs_fs.h>
complete(&nfs_callback_info.started);
diff -Nurb linux-2.6.22-570/fs/nfs/client.c linux-2.6.22-590/fs/nfs/client.c
---- linux-2.6.22-570/fs/nfs/client.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/nfs/client.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/nfs/client.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/nfs/client.c 2008-01-29 22:12:32.000000000 -0500
@@ -102,19 +102,10 @@
int nfsversion)
{
diff -Nurb linux-2.6.22-570/fs/nfs/delegation.c linux-2.6.22-590/fs/nfs/delegation.c
--- linux-2.6.22-570/fs/nfs/delegation.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/nfs/delegation.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/nfs/delegation.c 2008-01-29 22:12:32.000000000 -0500
@@ -74,7 +74,7 @@
continue;
get_nfs_open_context(ctx);
put_nfs_open_context(ctx);
diff -Nurb linux-2.6.22-570/fs/nfs/delegation.h linux-2.6.22-590/fs/nfs/delegation.h
--- linux-2.6.22-570/fs/nfs/delegation.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/nfs/delegation.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/nfs/delegation.h 2008-01-29 22:12:32.000000000 -0500
@@ -39,7 +39,7 @@
/* NFSv4 delegation-related procedures */
int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode);
diff -Nurb linux-2.6.22-570/fs/nfs/dir.c linux-2.6.22-590/fs/nfs/dir.c
---- linux-2.6.22-570/fs/nfs/dir.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/nfs/dir.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/nfs/dir.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/nfs/dir.c 2008-01-29 22:12:32.000000000 -0500
@@ -898,14 +898,13 @@
return (nd->intent.open.flags & O_EXCL) != 0;
}
}
diff -Nurb linux-2.6.22-570/fs/nfs/direct.c linux-2.6.22-590/fs/nfs/direct.c
--- linux-2.6.22-570/fs/nfs/direct.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/nfs/direct.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/nfs/direct.c 2008-01-29 22:12:32.000000000 -0500
@@ -266,7 +266,7 @@
static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned long user_addr, size_t count, loff_t pos)
{
retval = generic_write_checks(file, &pos, &count, 0);
if (retval)
diff -Nurb linux-2.6.22-570/fs/nfs/inode.c linux-2.6.22-590/fs/nfs/inode.c
---- linux-2.6.22-570/fs/nfs/inode.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/nfs/inode.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/nfs/inode.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/nfs/inode.c 2008-01-29 22:12:32.000000000 -0500
@@ -466,14 +466,14 @@
ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
nfs4_init_once(nfsi);
diff -Nurb linux-2.6.22-570/fs/nfs/mount_clnt.c linux-2.6.22-590/fs/nfs/mount_clnt.c
--- linux-2.6.22-570/fs/nfs/mount_clnt.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/nfs/mount_clnt.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/nfs/mount_clnt.c 2008-01-29 22:12:32.000000000 -0500
@@ -69,6 +69,7 @@
msg.rpc_proc = &mnt_clnt->cl_procinfo[MNTPROC_MNT];
return rpc_create(&args);
diff -Nurb linux-2.6.22-570/fs/nfs/nfs3proc.c linux-2.6.22-590/fs/nfs/nfs3proc.c
--- linux-2.6.22-570/fs/nfs/nfs3proc.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/nfs/nfs3proc.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/nfs/nfs3proc.c 2008-01-29 22:12:32.000000000 -0500
@@ -335,9 +335,7 @@
* not sure this buys us anything (and I'd have
* to revamp the NFSv3 XDR code) */
if (status != 0)
diff -Nurb linux-2.6.22-570/fs/nfs/nfs4_fs.h linux-2.6.22-590/fs/nfs/nfs4_fs.h
--- linux-2.6.22-570/fs/nfs/nfs4_fs.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/nfs/nfs4_fs.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/nfs/nfs4_fs.h 2008-01-29 22:12:32.000000000 -0500
@@ -165,7 +165,7 @@
extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *);
extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
#endif /* __LINUX_FS_NFS_NFS4_FS.H */
diff -Nurb linux-2.6.22-570/fs/nfs/nfs4proc.c linux-2.6.22-590/fs/nfs/nfs4proc.c
--- linux-2.6.22-570/fs/nfs/nfs4proc.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/nfs/nfs4proc.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/nfs/nfs4proc.c 2008-01-29 22:12:32.000000000 -0500
@@ -214,14 +214,14 @@
}
out:
diff -Nurb linux-2.6.22-570/fs/nfs/nfs4state.c linux-2.6.22-590/fs/nfs/nfs4state.c
--- linux-2.6.22-570/fs/nfs/nfs4state.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/nfs/nfs4state.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/nfs/nfs4state.c 2008-01-29 22:12:32.000000000 -0500
@@ -341,7 +341,7 @@
/*
* Close the current file.
/*
diff -Nurb linux-2.6.22-570/fs/nfs/nfs4xdr.c linux-2.6.22-590/fs/nfs/nfs4xdr.c
--- linux-2.6.22-570/fs/nfs/nfs4xdr.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/nfs/nfs4xdr.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/nfs/nfs4xdr.c 2008-01-29 22:12:32.000000000 -0500
@@ -3269,7 +3269,7 @@
static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
{
dprintk("%s: Bitmap too large! Length = %u\n", __FUNCTION__, bmlen);
diff -Nurb linux-2.6.22-570/fs/nfs/pagelist.c linux-2.6.22-590/fs/nfs/pagelist.c
--- linux-2.6.22-570/fs/nfs/pagelist.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/nfs/pagelist.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/nfs/pagelist.c 2008-01-29 22:12:32.000000000 -0500
@@ -85,9 +85,8 @@
req->wb_offset = offset;
req->wb_pgbase = offset;
return res;
diff -Nurb linux-2.6.22-570/fs/nfs/read.c linux-2.6.22-590/fs/nfs/read.c
--- linux-2.6.22-570/fs/nfs/read.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/nfs/read.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/nfs/read.c 2008-01-29 22:12:32.000000000 -0500
@@ -145,8 +145,8 @@
unlock_page(req->wb_page);
int nfs_readpages(struct file *filp, struct address_space *mapping,
diff -Nurb linux-2.6.22-570/fs/nfs/super.c linux-2.6.22-590/fs/nfs/super.c
---- linux-2.6.22-570/fs/nfs/super.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/nfs/super.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/nfs/super.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/nfs/super.c 2008-01-29 22:12:32.000000000 -0500
@@ -292,6 +292,7 @@
{ NFS_MOUNT_NONLM, ",nolock", "" },
{ NFS_MOUNT_NOACL, ",noacl", "" },
goto out_err_nosb;
diff -Nurb linux-2.6.22-570/fs/nfs/write.c linux-2.6.22-590/fs/nfs/write.c
--- linux-2.6.22-570/fs/nfs/write.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/nfs/write.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/nfs/write.c 2008-01-29 22:12:32.000000000 -0500
@@ -117,7 +117,7 @@
if (PagePrivate(page)) {
req = (struct nfs_page *)page_private(page);
diff -Nurb linux-2.6.22-570/fs/nfsd/nfs4callback.c linux-2.6.22-590/fs/nfsd/nfs4callback.c
--- linux-2.6.22-570/fs/nfsd/nfs4callback.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/nfsd/nfs4callback.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/nfsd/nfs4callback.c 2008-01-29 22:12:32.000000000 -0500
@@ -429,29 +429,23 @@
goto out_err;
}
cb->cb_client = NULL;
diff -Nurb linux-2.6.22-570/fs/nfsd/nfs4state.c linux-2.6.22-590/fs/nfsd/nfs4state.c
--- linux-2.6.22-570/fs/nfsd/nfs4state.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/nfsd/nfs4state.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/nfsd/nfs4state.c 2008-01-29 22:12:32.000000000 -0500
@@ -378,7 +378,6 @@
if (clnt) {
clp->cl_callback.cb_client = NULL;
diff -Nurb linux-2.6.22-570/fs/nfsd/nfssvc.c linux-2.6.22-590/fs/nfsd/nfssvc.c
--- linux-2.6.22-570/fs/nfsd/nfssvc.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/nfsd/nfssvc.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/nfsd/nfssvc.c 2008-01-29 22:12:32.000000000 -0500
@@ -19,6 +19,7 @@
#include <linux/slab.h>
#include <linux/smp.h>
* The main request loop
diff -Nurb linux-2.6.22-570/fs/ocfs2/alloc.c linux-2.6.22-590/fs/ocfs2/alloc.c
--- linux-2.6.22-570/fs/ocfs2/alloc.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/alloc.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/alloc.c 2008-01-29 22:12:32.000000000 -0500
@@ -50,6 +50,8 @@
#include "buffer_head_io.h"
brelse(tc->tc_last_eb_bh);
diff -Nurb linux-2.6.22-570/fs/ocfs2/alloc.h linux-2.6.22-590/fs/ocfs2/alloc.h
--- linux-2.6.22-570/fs/ocfs2/alloc.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/alloc.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/alloc.h 2008-01-29 22:12:32.000000000 -0500
@@ -34,7 +34,13 @@
u32 cpos,
u64 start_blk,
/*
* Helper function to look at the # of clusters in an extent record.
diff -Nurb linux-2.6.22-570/fs/ocfs2/aops.c linux-2.6.22-590/fs/ocfs2/aops.c
---- linux-2.6.22-570/fs/ocfs2/aops.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/aops.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/ocfs2/aops.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/fs/ocfs2/aops.c 2008-01-29 22:12:32.000000000 -0500
@@ -232,7 +232,7 @@
* might now be discovering a truncate that hit on another node.
* block_read_full_page->get_block freaks out if it is asked to read
const struct address_space_operations ocfs2_aops = {
diff -Nurb linux-2.6.22-570/fs/ocfs2/aops.h linux-2.6.22-590/fs/ocfs2/aops.h
--- linux-2.6.22-570/fs/ocfs2/aops.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/aops.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/aops.h 2008-01-29 22:12:32.000000000 -0500
@@ -42,57 +42,22 @@
int (*fn)( handle_t *handle,
struct buffer_head *bh));
#define ocfs2_iocb_is_rw_locked(iocb) \
diff -Nurb linux-2.6.22-570/fs/ocfs2/cluster/heartbeat.c linux-2.6.22-590/fs/ocfs2/cluster/heartbeat.c
--- linux-2.6.22-570/fs/ocfs2/cluster/heartbeat.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/cluster/heartbeat.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/cluster/heartbeat.c 2008-01-29 22:12:32.000000000 -0500
@@ -1335,6 +1335,7 @@
ret = wait_event_interruptible(o2hb_steady_queue,
atomic_read(®->hr_steady_iterations) == 0);
list_del_init(&hc->hc_item);
diff -Nurb linux-2.6.22-570/fs/ocfs2/cluster/heartbeat.h linux-2.6.22-590/fs/ocfs2/cluster/heartbeat.h
--- linux-2.6.22-570/fs/ocfs2/cluster/heartbeat.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/cluster/heartbeat.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/cluster/heartbeat.h 2008-01-29 22:12:32.000000000 -0500
@@ -69,8 +69,10 @@
o2hb_cb_func *func,
void *data,
void o2hb_init(void);
diff -Nurb linux-2.6.22-570/fs/ocfs2/cluster/masklog.c linux-2.6.22-590/fs/ocfs2/cluster/masklog.c
--- linux-2.6.22-570/fs/ocfs2/cluster/masklog.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/cluster/masklog.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/cluster/masklog.c 2008-01-29 22:12:32.000000000 -0500
@@ -74,7 +74,6 @@
#define define_mask(_name) { \
.attr = { \
.mask = ML_##_name, \
diff -Nurb linux-2.6.22-570/fs/ocfs2/cluster/nodemanager.c linux-2.6.22-590/fs/ocfs2/cluster/nodemanager.c
--- linux-2.6.22-570/fs/ocfs2/cluster/nodemanager.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/cluster/nodemanager.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/cluster/nodemanager.c 2008-01-29 22:12:32.000000000 -0500
@@ -900,6 +900,46 @@
},
};
if (ocfs2_table_header)
diff -Nurb linux-2.6.22-570/fs/ocfs2/cluster/nodemanager.h linux-2.6.22-590/fs/ocfs2/cluster/nodemanager.h
--- linux-2.6.22-570/fs/ocfs2/cluster/nodemanager.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/cluster/nodemanager.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/cluster/nodemanager.h 2008-01-29 22:12:32.000000000 -0500
@@ -77,4 +77,9 @@
void o2nm_node_get(struct o2nm_node *node);
void o2nm_node_put(struct o2nm_node *node);
#endif /* O2CLUSTER_NODEMANAGER_H */
diff -Nurb linux-2.6.22-570/fs/ocfs2/cluster/tcp.c linux-2.6.22-590/fs/ocfs2/cluster/tcp.c
--- linux-2.6.22-570/fs/ocfs2/cluster/tcp.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/cluster/tcp.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/cluster/tcp.c 2008-01-29 22:12:32.000000000 -0500
@@ -261,14 +261,12 @@
static void o2net_complete_nodes_nsw(struct o2net_node *nn)
o2net_unregister_hb_callbacks();
diff -Nurb linux-2.6.22-570/fs/ocfs2/dir.c linux-2.6.22-590/fs/ocfs2/dir.c
--- linux-2.6.22-570/fs/ocfs2/dir.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/dir.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/dir.c 2008-01-29 22:12:32.000000000 -0500
@@ -368,7 +368,7 @@
u32 offset = OCFS2_I(dir)->ip_clusters;
if (status < 0) {
diff -Nurb linux-2.6.22-570/fs/ocfs2/dlm/dlmdomain.c linux-2.6.22-590/fs/ocfs2/dlm/dlmdomain.c
--- linux-2.6.22-570/fs/ocfs2/dlm/dlmdomain.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/dlm/dlmdomain.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/dlm/dlmdomain.c 2008-01-29 22:12:32.000000000 -0500
@@ -1128,8 +1128,8 @@
static void dlm_unregister_domain_handlers(struct dlm_ctxt *dlm)
diff -Nurb linux-2.6.22-570/fs/ocfs2/dlm/dlmmaster.c linux-2.6.22-590/fs/ocfs2/dlm/dlmmaster.c
--- linux-2.6.22-570/fs/ocfs2/dlm/dlmmaster.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/dlm/dlmmaster.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/dlm/dlmmaster.c 2008-01-29 22:12:32.000000000 -0500
@@ -192,25 +192,20 @@
static void dlm_dump_mles(struct dlm_ctxt *dlm)
{
mle->type != DLM_MLE_MIGRATION);
diff -Nurb linux-2.6.22-570/fs/ocfs2/dlm/dlmrecovery.c linux-2.6.22-590/fs/ocfs2/dlm/dlmrecovery.c
--- linux-2.6.22-570/fs/ocfs2/dlm/dlmrecovery.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/dlm/dlmrecovery.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/dlm/dlmrecovery.c 2008-01-29 22:12:32.000000000 -0500
@@ -158,8 +158,7 @@
struct dlm_ctxt *dlm =
container_of(work, struct dlm_ctxt, dispatched_work);
list_del_init(&lock->list);
dlm_lock_put(lock);
diff -Nurb linux-2.6.22-570/fs/ocfs2/dlmglue.c linux-2.6.22-590/fs/ocfs2/dlmglue.c
---- linux-2.6.22-570/fs/ocfs2/dlmglue.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/dlmglue.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/ocfs2/dlmglue.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/ocfs2/dlmglue.c 2008-01-29 22:12:32.000000000 -0500
@@ -600,15 +600,13 @@
static void lockres_set_flags(struct ocfs2_lock_res *lockres,
unsigned long newflags)
diff -Nurb linux-2.6.22-570/fs/ocfs2/endian.h linux-2.6.22-590/fs/ocfs2/endian.h
--- linux-2.6.22-570/fs/ocfs2/endian.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/endian.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/endian.h 2008-01-29 22:12:32.000000000 -0500
@@ -32,6 +32,11 @@
*var = cpu_to_le32(le32_to_cpu(*var) + val);
}
*var = cpu_to_le32(le32_to_cpu(*var) & val);
diff -Nurb linux-2.6.22-570/fs/ocfs2/extent_map.c linux-2.6.22-590/fs/ocfs2/extent_map.c
--- linux-2.6.22-570/fs/ocfs2/extent_map.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/extent_map.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/extent_map.c 2008-01-29 22:12:32.000000000 -0500
@@ -109,17 +109,14 @@
*/
void ocfs2_extent_map_trunc(struct inode *inode, unsigned int cpos)
u32 *p_cluster, u32 *num_clusters,
unsigned int *extent_flags)
diff -Nurb linux-2.6.22-570/fs/ocfs2/file.c linux-2.6.22-590/fs/ocfs2/file.c
---- linux-2.6.22-570/fs/ocfs2/file.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/file.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/ocfs2/file.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/ocfs2/file.c 2008-01-29 22:12:32.000000000 -0500
@@ -326,9 +326,6 @@
(unsigned long long)OCFS2_I(inode)->ip_blkno,
(unsigned long long)new_i_size);
static ssize_t __ocfs2_file_splice_write(struct pipe_inode_info *pipe,
diff -Nurb linux-2.6.22-570/fs/ocfs2/file.h linux-2.6.22-590/fs/ocfs2/file.h
--- linux-2.6.22-570/fs/ocfs2/file.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/file.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/file.h 2008-01-29 22:12:32.000000000 -0500
@@ -39,15 +39,16 @@
};
int ocfs2_do_extend_allocation(struct ocfs2_super *osb,
#endif /* OCFS2_FILE_H */
diff -Nurb linux-2.6.22-570/fs/ocfs2/heartbeat.c linux-2.6.22-590/fs/ocfs2/heartbeat.c
--- linux-2.6.22-570/fs/ocfs2/heartbeat.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/heartbeat.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/heartbeat.c 2008-01-29 22:12:32.000000000 -0500
@@ -157,16 +157,16 @@
if (ocfs2_mount_local(osb))
return 0;
mlog_errno(ret);
}
diff -Nurb linux-2.6.22-570/fs/ocfs2/ioctl.c linux-2.6.22-590/fs/ocfs2/ioctl.c
---- linux-2.6.22-570/fs/ocfs2/ioctl.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/ioctl.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/ocfs2/ioctl.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/ocfs2/ioctl.c 2008-01-29 22:12:32.000000000 -0500
@@ -14,6 +14,7 @@
#include "ocfs2.h"
#include "alloc.h"
}
diff -Nurb linux-2.6.22-570/fs/ocfs2/journal.c linux-2.6.22-590/fs/ocfs2/journal.c
--- linux-2.6.22-570/fs/ocfs2/journal.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/journal.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/journal.c 2008-01-29 22:12:32.000000000 -0500
@@ -722,8 +722,7 @@
container_of(work, struct ocfs2_journal, j_recovery_work);
struct ocfs2_super *osb = journal->j_osb;
mlog(0, "Complete recovery for slot %d\n", item->lri_slot);
diff -Nurb linux-2.6.22-570/fs/ocfs2/mmap.c linux-2.6.22-590/fs/ocfs2/mmap.c
--- linux-2.6.22-570/fs/ocfs2/mmap.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/mmap.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/mmap.c 2008-01-29 22:12:32.000000000 -0500
@@ -37,38 +37,48 @@
#include "ocfs2.h"
}
diff -Nurb linux-2.6.22-570/fs/ocfs2/namei.c linux-2.6.22-590/fs/ocfs2/namei.c
---- linux-2.6.22-570/fs/ocfs2/namei.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/namei.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/ocfs2/namei.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/ocfs2/namei.c 2008-01-29 22:12:32.000000000 -0500
@@ -1684,7 +1684,7 @@
u32 offset = 0;
handle, data_ac, NULL,
NULL);
diff -Nurb linux-2.6.22-570/fs/ocfs2/ocfs2.h linux-2.6.22-590/fs/ocfs2/ocfs2.h
---- linux-2.6.22-570/fs/ocfs2/ocfs2.h 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/ocfs2.h 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/ocfs2/ocfs2.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/ocfs2/ocfs2.h 2008-01-29 22:12:32.000000000 -0500
@@ -220,6 +220,7 @@
u16 max_slots;
s16 node_num;
* in parallel so we want the transitions to be atomic. this also
* means that any future flags osb_flags must be protected by spinlock
diff -Nurb linux-2.6.22-570/fs/ocfs2/ocfs2_fs.h linux-2.6.22-590/fs/ocfs2/ocfs2_fs.h
---- linux-2.6.22-570/fs/ocfs2/ocfs2_fs.h 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/ocfs2_fs.h 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/ocfs2/ocfs2_fs.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/ocfs2/ocfs2_fs.h 2008-01-29 22:12:32.000000000 -0500
@@ -88,7 +88,7 @@
#define OCFS2_FEATURE_COMPAT_SUPP OCFS2_FEATURE_COMPAT_BACKUP_SB
#define OCFS2_FEATURE_INCOMPAT_SUPP (OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT \
#define OCFS2_JOURNAL_DIRTY_FL (0x00000001) /* Journal needs recovery */
diff -Nurb linux-2.6.22-570/fs/ocfs2/slot_map.c linux-2.6.22-590/fs/ocfs2/slot_map.c
--- linux-2.6.22-570/fs/ocfs2/slot_map.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/slot_map.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/slot_map.c 2008-01-29 22:12:32.000000000 -0500
@@ -121,17 +121,25 @@
return ret;
}
mlog(ML_ERROR, "no free slots available!\n");
diff -Nurb linux-2.6.22-570/fs/ocfs2/suballoc.c linux-2.6.22-590/fs/ocfs2/suballoc.c
--- linux-2.6.22-570/fs/ocfs2/suballoc.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/suballoc.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/suballoc.c 2008-01-29 22:12:32.000000000 -0500
@@ -98,14 +98,6 @@
u16 chain);
static inline int ocfs2_block_group_reasonably_empty(struct ocfs2_group_desc *bg,
struct buffer_head *bitmap_bh,
diff -Nurb linux-2.6.22-570/fs/ocfs2/suballoc.h linux-2.6.22-590/fs/ocfs2/suballoc.h
--- linux-2.6.22-570/fs/ocfs2/suballoc.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/suballoc.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/suballoc.h 2008-01-29 22:12:32.000000000 -0500
@@ -86,20 +86,29 @@
u32 *cluster_start,
u32 *num_clusters);
u64 bg_blkno)
{
diff -Nurb linux-2.6.22-570/fs/ocfs2/super.c linux-2.6.22-590/fs/ocfs2/super.c
---- linux-2.6.22-570/fs/ocfs2/super.c 2008-03-15 10:34:33.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/super.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/ocfs2/super.c 2008-01-29 22:12:27.000000000 -0500
++++ linux-2.6.22-590/fs/ocfs2/super.c 2008-01-29 22:12:32.000000000 -0500
@@ -82,7 +82,8 @@
MODULE_LICENSE("GPL");
status = 1;
diff -Nurb linux-2.6.22-570/fs/ocfs2/super.h linux-2.6.22-590/fs/ocfs2/super.h
--- linux-2.6.22-570/fs/ocfs2/super.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ocfs2/super.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ocfs2/super.h 2008-01-29 22:12:32.000000000 -0500
@@ -45,4 +45,6 @@
#define ocfs2_abort(sb, fmt, args...) __ocfs2_abort(sb, __PRETTY_FUNCTION__, fmt, ##args)
+
#endif /* OCFS2_SUPER_H */
diff -Nurb linux-2.6.22-570/fs/open.c linux-2.6.22-590/fs/open.c
---- linux-2.6.22-570/fs/open.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/open.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/open.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/open.c 2008-01-29 22:12:32.000000000 -0500
@@ -362,6 +362,92 @@
#endif
* switching the fsuid/fsgid around to the real ones.
diff -Nurb linux-2.6.22-570/fs/partitions/check.c linux-2.6.22-590/fs/partitions/check.c
--- linux-2.6.22-570/fs/partitions/check.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/partitions/check.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/partitions/check.c 2008-01-29 22:12:32.000000000 -0500
@@ -397,7 +397,6 @@
static struct attribute addpartattr = {
.name = "whole_disk",
};
sysfs_create_file(&p->kobj, &addpartattr);
+diff -Nurb linux-2.6.22-570/fs/proc/Makefile linux-2.6.22-590/fs/proc/Makefile
+--- linux-2.6.22-570/fs/proc/Makefile 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/fs/proc/Makefile 2008-01-29 22:12:32.000000000 -0500
+@@ -11,6 +11,7 @@
+ proc_tty.o proc_misc.o
+
+ proc-$(CONFIG_PROC_SYSCTL) += proc_sysctl.o
++proc-$(CONFIG_NET) += proc_net.o
+ proc-$(CONFIG_PROC_KCORE) += kcore.o
+ proc-$(CONFIG_PROC_VMCORE) += vmcore.o
+ proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o
diff -Nurb linux-2.6.22-570/fs/proc/array.c linux-2.6.22-590/fs/proc/array.c
---- linux-2.6.22-570/fs/proc/array.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/proc/array.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/proc/array.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/proc/array.c 2008-01-29 22:12:32.000000000 -0500
@@ -291,6 +291,15 @@
return buffer;
}
start_time = nsec_to_clock_t(start_time);
diff -Nurb linux-2.6.22-570/fs/proc/base.c linux-2.6.22-590/fs/proc/base.c
---- linux-2.6.22-570/fs/proc/base.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/proc/base.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/proc/base.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/proc/base.c 2008-01-29 22:12:32.000000000 -0500
@@ -67,7 +67,7 @@
#include <linux/mount.h>
#include <linux/security.h>
REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust),
#ifdef CONFIG_AUDITSYSCALL
diff -Nurb linux-2.6.22-570/fs/proc/generic.c linux-2.6.22-590/fs/proc/generic.c
---- linux-2.6.22-570/fs/proc/generic.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/proc/generic.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/proc/generic.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/proc/generic.c 2008-01-29 22:12:32.000000000 -0500
@@ -74,7 +74,7 @@
nbytes = MAX_NON_LFS - pos;
while ((nbytes > 0) && !eof) {
diff -Nurb linux-2.6.22-570/fs/proc/internal.h linux-2.6.22-590/fs/proc/internal.h
---- linux-2.6.22-570/fs/proc/internal.h 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/proc/internal.h 2008-03-15 10:35:47.000000000 -0400
-@@ -46,15 +46,13 @@
+--- linux-2.6.22-570/fs/proc/internal.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/proc/internal.h 2008-01-29 22:12:32.000000000 -0500
+@@ -17,6 +17,11 @@
+ #else
+ static inline void proc_sys_init(void) { }
+ #endif
++#ifdef CONFIG_NET
++extern int proc_net_init(void);
++#else
++static inline int proc_net_init(void) { return 0; }
++#endif
+
+ struct vmalloc_info {
+ unsigned long used;
+@@ -46,15 +51,13 @@
extern int proc_tgid_stat(struct task_struct *, char *);
extern int proc_pid_status(struct task_struct *, char *);
extern int proc_pid_statm(struct task_struct *, char *);
void free_proc_entry(struct proc_dir_entry *de);
diff -Nurb linux-2.6.22-570/fs/proc/proc_misc.c linux-2.6.22-590/fs/proc/proc_misc.c
---- linux-2.6.22-570/fs/proc/proc_misc.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/proc/proc_misc.c 2008-03-15 10:35:47.000000000 -0400
-@@ -463,12 +463,14 @@
+--- linux-2.6.22-570/fs/proc/proc_misc.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/proc/proc_misc.c 2008-01-29 22:12:32.000000000 -0500
+@@ -122,6 +122,7 @@
+ cputime_t idletime = cputime_add(init_task.utime, init_task.stime);
+
+ do_posix_clock_monotonic_gettime(&uptime);
++ monotonic_to_bootbased(&uptime);
+ cputime_to_timespec(idletime, &idle);
+ if (vx_flags(VXF_VIRT_UPTIME, 0))
+ vx_vsi_uptime(&uptime, &idle);
+@@ -463,12 +464,14 @@
unsigned long jif;
cputime64_t user, nice, system, idle, iowait, irq, softirq, steal;
u64 sum = 0;
for_each_possible_cpu(i) {
int j;
+diff -Nurb linux-2.6.22-570/fs/proc/proc_net.c linux-2.6.22-590/fs/proc/proc_net.c
+--- linux-2.6.22-570/fs/proc/proc_net.c 1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.22-590/fs/proc/proc_net.c 2008-01-29 22:12:32.000000000 -0500
+@@ -0,0 +1,154 @@
++/*
++ * linux/fs/proc/net.c
++ *
++ * Copyright (C) 2007
++ *
++ * Author: Eric Biederman <ebiederm@xmission.com>
++ *
++ * proc net directory handling functions
++ */
++
++#include <asm/uaccess.h>
++
++#include <linux/errno.h>
++#include <linux/time.h>
++#include <linux/proc_fs.h>
++#include <linux/stat.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/module.h>
++#include <linux/bitops.h>
++#include <linux/smp_lock.h>
++#include <linux/mount.h>
++#include <linux/nsproxy.h>
++#include <net/net_namespace.h>
++
++#include "internal.h"
++
++static struct proc_dir_entry *proc_net_shadow;
++
++static struct dentry *proc_net_shadow_dentry(struct dentry *parent,
++ struct proc_dir_entry *de)
++{
++ struct dentry *shadow = NULL;
++ struct inode *inode;
++ if (!de)
++ goto out;
++ de_get(de);
++ inode = proc_get_inode(parent->d_inode->i_sb, de->low_ino, de);
++ if (!inode)
++ goto out_de_put;
++ shadow = d_alloc_name(parent, de->name);
++ if (!shadow)
++ goto out_iput;
++ shadow->d_op = parent->d_op; /* proc_dentry_operations */
++ d_instantiate(shadow, inode);
++out:
++ return shadow;
++out_iput:
++ iput(inode);
++out_de_put:
++ de_put(de);
++ goto out;
++}
++
++static void *proc_net_follow_link(struct dentry *parent, struct nameidata *nd)
++{
++ struct net *net = current->nsproxy->net_ns;
++ struct dentry *shadow;
++ shadow = proc_net_shadow_dentry(parent, net->proc_net);
++ if (!shadow)
++ return ERR_PTR(-ENOENT);
++
++ dput(nd->dentry);
++ /* My dentry count is 1 and that should be enough as the
++ * shadow dentry is thrown away immediately.
++ */
++ nd->dentry = shadow;
++ return NULL;
++}
++
++static struct dentry *proc_net_lookup(struct inode *dir, struct dentry *dentry,
++ struct nameidata *nd)
++{
++ struct net *net = current->nsproxy->net_ns;
++ struct dentry *shadow;
++
++ shadow = proc_net_shadow_dentry(nd->dentry, net->proc_net);
++ if (!shadow)
++ return ERR_PTR(-ENOENT);
++
++ dput(nd->dentry);
++ nd->dentry = shadow;
++
++ return shadow->d_inode->i_op->lookup(shadow->d_inode, dentry, nd);
++}
++
++static int proc_net_setattr(struct dentry *dentry, struct iattr *iattr)
++{
++ struct net *net = current->nsproxy->net_ns;
++ struct dentry *shadow;
++ int ret;
++
++ shadow = proc_net_shadow_dentry(dentry->d_parent, net->proc_net);
++ if (!shadow)
++ return -ENOENT;
++ ret = shadow->d_inode->i_op->setattr(shadow, iattr);
++ dput(shadow);
++ return ret;
++}
++
++static const struct file_operations proc_net_dir_operations = {
++ .read = generic_read_dir,
++};
++
++static struct inode_operations proc_net_dir_inode_operations = {
++ .follow_link = proc_net_follow_link,
++ .lookup = proc_net_lookup,
++ .setattr = proc_net_setattr,
++};
++
++
++static int proc_net_ns_init(struct net *net)
++{
++ struct proc_dir_entry *netd, *net_statd;
++
++ netd = proc_mkdir("net", &net->proc_net_root);
++ if (!netd)
++ return -EEXIST;
++
++ net_statd = proc_mkdir("stat", netd);
++ if (!net_statd) {
++ remove_proc_entry("net", &net->proc_net_root);
++ return -EEXIST;
++ }
++
++ netd->data = net;
++ net_statd->data = net;
++ net->proc_net_root.data = net;
++ net->proc_net = netd;
++ net->proc_net_stat = net_statd;
++
++ return 0;
++}
++
++static void proc_net_ns_exit(struct net *net)
++{
++ remove_proc_entry("stat", net->proc_net);
++ remove_proc_entry("net", &net->proc_net_root);
++
++}
++
++struct pernet_operations proc_net_ns_ops = {
++ .init = proc_net_ns_init,
++ .exit = proc_net_ns_exit,
++};
++
++int proc_net_init(void)
++{
++ proc_net_shadow = proc_mkdir("net", NULL);
++ proc_net_shadow->proc_iops = &proc_net_dir_inode_operations;
++ proc_net_shadow->proc_fops = &proc_net_dir_operations;
++
++ return register_pernet_subsys(&proc_net_ns_ops);
++}
+diff -Nurb linux-2.6.22-570/fs/proc/root.c linux-2.6.22-590/fs/proc/root.c
+--- linux-2.6.22-570/fs/proc/root.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/proc/root.c 2008-01-29 22:12:32.000000000 -0500
+@@ -21,11 +21,11 @@
+
+ #include "internal.h"
+
+-struct proc_dir_entry *proc_net, *proc_net_stat, *proc_bus, *proc_root_fs, *proc_root_driver;
+ struct proc_dir_entry *proc_virtual;
+
+ extern void proc_vx_init(void);
+
++struct proc_dir_entry *proc_bus, *proc_root_fs, *proc_root_driver;
+ static int proc_get_sb(struct file_system_type *fs_type,
+ int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+ {
+@@ -64,8 +64,8 @@
+ return;
+ }
+ proc_misc_init();
+- proc_net = proc_mkdir("net", NULL);
+- proc_net_stat = proc_mkdir("net/stat", NULL);
++
++ proc_net_init();
+
+ #ifdef CONFIG_SYSVIPC
+ proc_mkdir("sysvipc", NULL);
+@@ -163,7 +163,5 @@
+ EXPORT_SYMBOL(remove_proc_entry);
+ EXPORT_SYMBOL(proc_root);
+ EXPORT_SYMBOL(proc_root_fs);
+-EXPORT_SYMBOL(proc_net);
+-EXPORT_SYMBOL(proc_net_stat);
+ EXPORT_SYMBOL(proc_bus);
+ EXPORT_SYMBOL(proc_root_driver);
diff -Nurb linux-2.6.22-570/fs/proc/task_mmu.c linux-2.6.22-590/fs/proc/task_mmu.c
--- linux-2.6.22-570/fs/proc/task_mmu.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/proc/task_mmu.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/proc/task_mmu.c 2008-01-29 22:12:32.000000000 -0500
@@ -5,6 +5,7 @@
#include <linux/highmem.h>
#include <linux/ptrace.h>
+#endif
diff -Nurb linux-2.6.22-570/fs/ramfs/inode.c linux-2.6.22-590/fs/ramfs/inode.c
--- linux-2.6.22-570/fs/ramfs/inode.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/ramfs/inode.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/ramfs/inode.c 2008-01-29 22:12:32.000000000 -0500
@@ -60,6 +60,7 @@
inode->i_blocks = 0;
inode->i_mapping->a_ops = &ramfs_aops;
default:
diff -Nurb linux-2.6.22-570/fs/revoke.c linux-2.6.22-590/fs/revoke.c
--- linux-2.6.22-570/fs/revoke.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/revoke.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/revoke.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,777 @@
+/*
+ * fs/revoke.c - Invalidate all current open file descriptors of an inode.
+late_initcall(revokefs_init);
diff -Nurb linux-2.6.22-570/fs/revoked_inode.c linux-2.6.22-590/fs/revoked_inode.c
--- linux-2.6.22-570/fs/revoked_inode.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/revoked_inode.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/revoked_inode.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,417 @@
+/*
+ * fs/revoked_inode.c
+ inode->i_mapping->a_ops = &revoked_aops;
+}
diff -Nurb linux-2.6.22-570/fs/splice.c linux-2.6.22-590/fs/splice.c
---- linux-2.6.22-570/fs/splice.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/fs/splice.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/splice.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/fs/splice.c 2008-01-29 22:12:32.000000000 -0500
@@ -28,6 +28,7 @@
#include <linux/module.h>
#include <linux/syscalls.h>
return out->f_op->splice_write(pipe, out, ppos, len, flags);
}
-@@ -954,6 +959,21 @@
+@@ -954,6 +959,10 @@
if (unlikely(ret < 0))
return ret;
-+<<<<<<< HEAD/fs/splice.c
-+=======
+ ret = security_file_permission(in, MAY_READ);
+ if (unlikely(ret < 0))
+ return ret;
+
-+ isize = i_size_read(in->f_mapping->host);
-+ if (unlikely(*ppos >= isize))
-+ return 0;
-+
-+ left = isize - *ppos;
-+ if (unlikely(left < len))
-+ len = left;
-+
-+>>>>>>> /fs/splice.c
return in->f_op->splice_read(in, ppos, pipe, len, flags);
}
-@@ -1272,6 +1292,7 @@
+@@ -1272,6 +1281,7 @@
static long do_vmsplice(struct file *file, const struct iovec __user *iov,
unsigned long nr_segs, unsigned int flags)
{
struct pipe_inode_info *pipe;
struct page *pages[PIPE_BUFFERS];
struct partial_page partial[PIPE_BUFFERS];
-@@ -1290,6 +1311,10 @@
+@@ -1290,6 +1300,10 @@
else if (unlikely(!nr_segs))
return 0;
if (spd.nr_pages <= 0)
diff -Nurb linux-2.6.22-570/fs/stack.c linux-2.6.22-590/fs/stack.c
--- linux-2.6.22-570/fs/stack.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/stack.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/stack.c 2008-01-29 22:12:32.000000000 -0500
@@ -1,8 +1,20 @@
+/*
+ * Copyright (c) 2006-2007 Erez Zadok
void fsstack_copy_attr_all(struct inode *dest, const struct inode *src,
diff -Nurb linux-2.6.22-570/fs/sync.c linux-2.6.22-590/fs/sync.c
--- linux-2.6.22-570/fs/sync.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/sync.c 2008-03-15 10:35:47.000000000 -0400
-@@ -174,6 +174,14 @@
++++ linux-2.6.22-590/fs/sync.c 2008-01-29 22:12:32.000000000 -0500
+@@ -174,6 +174,9 @@
* already-instantiated disk blocks, there are no guarantees here that the data
* will be available after a crash.
*/
+/* It would be nice if people remember that not all the world's an i386
+ when they introduce new system calls */
-+asmlinkage long sys_sync_file_range2(int fd, unsigned int flags,
-+ loff_t offset, loff_t nbytes)
-+{
-+ return sys_sync_file_range(fd, offset, nbytes, flags);
-+}
+
asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes,
unsigned int flags)
{
diff -Nurb linux-2.6.22-570/fs/sysfs/bin.c linux-2.6.22-590/fs/sysfs/bin.c
--- linux-2.6.22-570/fs/sysfs/bin.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/sysfs/bin.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/sysfs/bin.c 2008-01-29 22:12:32.000000000 -0500
@@ -20,29 +20,41 @@
#include "sysfs.h"
void sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr)
{
- if (sysfs_hash_and_remove(kobj->dentry, attr->attr.name) < 0) {
-+ if (sysfs_hash_and_remove(kobj->sd, attr->attr.name) < 0) {
++ if (sysfs_hash_and_remove(kobj, kobj->sd, attr->attr.name) < 0) {
printk(KERN_ERR "%s: "
"bad dentry or inode or no such file: \"%s\"\n",
__FUNCTION__, attr->attr.name);
diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c
--- linux-2.6.22-570/fs/sysfs/dir.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/sysfs/dir.c 2008-03-15 10:35:47.000000000 -0400
-@@ -9,21 +9,337 @@
++++ linux-2.6.22-590/fs/sysfs/dir.c 2008-01-29 22:12:32.000000000 -0500
+@@ -9,21 +9,442 @@
#include <linux/module.h>
#include <linux/kobject.h>
#include <linux/namei.h>
-DECLARE_RWSEM(sysfs_rename_sem);
-spinlock_t sysfs_lock = SPIN_LOCK_UNLOCKED;
++static void sysfs_prune_shadow_sd(struct sysfs_dirent *sd);
++
+DEFINE_MUTEX(sysfs_mutex);
+spinlock_t sysfs_assoc_lock = SPIN_LOCK_UNLOCKED;
+
+static spinlock_t sysfs_ino_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_IDA(sysfs_ino_ida);
+
++static struct sysfs_dirent *find_shadow_sd(struct sysfs_dirent *parent_sd, const void *target)
++{
++ /* Find the shadow directory for the specified tag */
++ struct sysfs_dirent *sd;
++
++ for (sd = parent_sd->s_children; sd; sd = sd->s_sibling) {
++ if (sd->s_name != target)
++ continue;
++ break;
++ }
++ return sd;
++}
++
++static const void *find_shadow_tag(struct kobject *kobj)
++{
++ /* Find the tag the current kobj is cached with */
++ return kobj->sd->s_parent->s_name;
++}
++
+/**
+ * sysfs_link_sibling - link sysfs_dirent into sibling list
+ * @sd: sysfs_dirent of interest
+ * Locking:
+ * mutex_lock(sysfs_mutex)
+ */
++
++/**
++ * sysfs_unlink_sibling - unlink sysfs_dirent from sibling list
++ * @sd: sysfs_dirent of interest
++ *
++ * Unlink @sd from its sibling list which starts from
++ * sd->s_parent->s_children.
++ *
++ * Locking:
++ * mutex_lock(sysfs_mutex)
++ */
++
+void sysfs_link_sibling(struct sysfs_dirent *sd)
+{
+ struct sysfs_dirent *parent_sd = sd->s_parent;
+ sd->s_sibling = parent_sd->s_children;
+ parent_sd->s_children = sd;
+}
++/**
++ * sysfs_get_dentry - get dentry for the given sysfs_dirent
++ * @sd: sysfs_dirent of interest
++ *
++ * Get dentry for @sd. Dentry is looked up if currently not
++ * present. This function climbs sysfs_dirent tree till it
++ * reaches a sysfs_dirent with valid dentry attached and descends
++ * down from there looking up dentry for each step.
++ *
++ * LOCKING:
++ * Kernel thread context (may sleep)
++ *
++ * RETURNS:
++ * Pointer to found dentry on success, ERR_PTR() value on error.
++ */
++struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd)
++{
++ struct sysfs_dirent *cur;
++ struct dentry *parent_dentry, *dentry;
++ int i, depth;
++
++ /* Find the first parent which has valid s_dentry and get the
++ * dentry.
++ */
++ mutex_lock(&sysfs_mutex);
++ restart0:
++ spin_lock(&sysfs_assoc_lock);
++ restart1:
++ spin_lock(&dcache_lock);
++
++ dentry = NULL;
++ depth = 0;
++ cur = sd;
++ while (!cur->s_dentry || !cur->s_dentry->d_inode) {
++ if (cur->s_flags & SYSFS_FLAG_REMOVED) {
++ dentry = ERR_PTR(-ENOENT);
++ depth = 0;
++ break;
++ }
++ cur = cur->s_parent;
++ depth++;
++ }
++ if (!IS_ERR(dentry))
++ dentry = dget_locked(cur->s_dentry);
++
++ spin_unlock(&dcache_lock);
++ spin_unlock(&sysfs_assoc_lock);
++
++ /* from the found dentry, look up depth times */
++ while (depth--) {
++ /* find and get depth'th ancestor */
++ for (cur = sd, i = 0; cur && i < depth; i++)
++ cur = cur->s_parent;
++
++ /* This can happen if tree structure was modified due
++ * to move/rename. Restart.
++ */
++ if (i != depth) {
++ dput(dentry);
++ goto restart0;
++ }
++
++ sysfs_get(cur);
++
++ mutex_unlock(&sysfs_mutex);
++
++ /* look it up */
++ parent_dentry = dentry;
++ dentry = lookup_one_len_kern(cur->s_name, parent_dentry,
++ strlen(cur->s_name));
++ dput(parent_dentry);
++
++ if (IS_ERR(dentry)) {
++ sysfs_put(cur);
++ return dentry;
++ }
++
++ mutex_lock(&sysfs_mutex);
++ spin_lock(&sysfs_assoc_lock);
++
++ /* This, again, can happen if tree structure has
++ * changed and we looked up the wrong thing. Restart.
++ */
++ if (cur->s_dentry != dentry) {
++ dput(dentry);
++ sysfs_put(cur);
++ goto restart1;
++ }
++
++ spin_unlock(&sysfs_assoc_lock);
++
++ sysfs_put(cur);
++ }
++
++ mutex_unlock(&sysfs_mutex);
++ return dentry;
++}
++
++/**
++ * sysfs_link_sibling - link sysfs_dirent into sibling list
++ * @sd: sysfs_dirent of interest
++ *
++ * Link @sd into its sibling list which starts from
++ * sd->s_parent->s_children.
++ *
++ * Locking:
++ * mutex_lock(sd->s_parent->dentry->d_inode->i_mutex)
++ */
+
+/**
+ * sysfs_unlink_sibling - unlink sysfs_dirent from sibling list
+ * sd->s_parent->s_children.
+ *
+ * Locking:
-+ * mutex_lock(sysfs_mutex)
++ * mutex_lock(sd->s_parent->dentry->d_inode->i_mutex)
+ */
+void sysfs_unlink_sibling(struct sysfs_dirent *sd)
+{
+ * RETURNS:
+ * Pointer to found dentry on success, ERR_PTR() value on error.
+ */
-+struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd)
-+{
-+ struct sysfs_dirent *cur;
-+ struct dentry *parent_dentry, *dentry;
-+ int i, depth;
-+
-+ /* Find the first parent which has valid s_dentry and get the
-+ * dentry.
-+ */
-+ mutex_lock(&sysfs_mutex);
-+ restart0:
-+ spin_lock(&sysfs_assoc_lock);
-+ restart1:
-+ spin_lock(&dcache_lock);
-+
-+ dentry = NULL;
-+ depth = 0;
-+ cur = sd;
-+ while (!cur->s_dentry || !cur->s_dentry->d_inode) {
-+ if (cur->s_flags & SYSFS_FLAG_REMOVED) {
-+ dentry = ERR_PTR(-ENOENT);
-+ depth = 0;
-+ break;
-+ }
-+ cur = cur->s_parent;
-+ depth++;
-+ }
-+ if (!IS_ERR(dentry))
-+ dentry = dget_locked(cur->s_dentry);
-+
-+ spin_unlock(&dcache_lock);
-+ spin_unlock(&sysfs_assoc_lock);
-+
-+ /* from the found dentry, look up depth times */
-+ while (depth--) {
-+ /* find and get depth'th ancestor */
-+ for (cur = sd, i = 0; cur && i < depth; i++)
-+ cur = cur->s_parent;
-+
-+ /* This can happen if tree structure was modified due
-+ * to move/rename. Restart.
-+ */
-+ if (i != depth) {
-+ dput(dentry);
-+ goto restart0;
-+ }
-+
-+ sysfs_get(cur);
-+
-+ mutex_unlock(&sysfs_mutex);
-+
-+ /* look it up */
-+ parent_dentry = dentry;
-+ dentry = lookup_one_len_kern(cur->s_name, parent_dentry,
-+ strlen(cur->s_name));
-+ dput(parent_dentry);
-+
-+ if (IS_ERR(dentry)) {
-+ sysfs_put(cur);
-+ return dentry;
-+ }
-+
-+ mutex_lock(&sysfs_mutex);
-+ spin_lock(&sysfs_assoc_lock);
-+
-+ /* This, again, can happen if tree structure has
-+ * changed and we looked up the wrong thing. Restart.
-+ */
-+ if (cur->s_dentry != dentry) {
-+ dput(dentry);
-+ sysfs_put(cur);
-+ goto restart1;
-+ }
-+
-+ spin_unlock(&sysfs_assoc_lock);
-+
-+ sysfs_put(cur);
-+ }
-+
-+ mutex_unlock(&sysfs_mutex);
-+ return dentry;
-+}
+
+/**
+ * sysfs_get_active - get an active reference to sysfs_dirent
+ * RETURNS:
+ * Pointer to @sd on success, NULL on failure.
+ */
-+struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
-+{
-+ if (unlikely(!sd))
-+ return NULL;
-+
-+ while (1) {
-+ int v, t;
-+
-+ v = atomic_read(&sd->s_active);
-+ if (unlikely(v < 0))
-+ return NULL;
-+
-+ t = atomic_cmpxchg(&sd->s_active, v, v + 1);
-+ if (likely(t == v))
-+ return sd;
-+ if (t < 0)
-+ return NULL;
-+
-+ cpu_relax();
-+ }
-+}
-+
+/**
+ * sysfs_put_active - put an active reference to sysfs_dirent
+ * @sd: sysfs_dirent to put an active reference to
+ sd->s_sibling = NULL;
+}
+
++/**
++ * sysfs_get_active - get an active reference to sysfs_dirent
++ * @sd: sysfs_dirent to get an active reference to
++ *
++ * Get an active reference of @sd. This function is noop if @sd
++ * is NULL.
++ *
++ * RETURNS:
++ * Pointer to @sd on success, NULL on failure.
++ */
++struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
++{
++ if (unlikely(!sd))
++ return NULL;
++
++ while (1) {
++ int v, t;
++
++ v = atomic_read(&sd->s_active);
++ if (unlikely(v < 0))
++ return NULL;
++
++ t = atomic_cmpxchg(&sd->s_active, v, v + 1);
++ if (likely(t == v))
++ return sd;
++ if (t < 0)
++ return NULL;
++
++ cpu_relax();
++ }
++}
++/**
++ * sysfs_put_active - put an active reference to sysfs_dirent
++ * @sd: sysfs_dirent to put an active reference to
++ *
++ * Put an active reference to @sd. This function is noop if @sd
++ * is NULL.
++ */
++
++/**
++ * sysfs_get_active_two - get active references to sysfs_dirent and parent
++ * @sd: sysfs_dirent of interest
++ *
++ * Get active reference to @sd and its parent. Parent's active
++ * reference is grabbed first. This function is noop if @sd is
++ * NULL.
++ *
++ * RETURNS:
++ * Pointer to @sd on success, NULL on failure.
++ */
++
++/**
++ * sysfs_put_active_two - put active references to sysfs_dirent and parent
++ * @sd: sysfs_dirent of interest
++ *
++ * Put active references to @sd and its parent. This function is
++ * noop if @sd is NULL.
++ */
++
++/**
++ * sysfs_deactivate - deactivate sysfs_dirent
++ * @sd: sysfs_dirent to deactivate
++ *
++ * Deny new active references and drain existing ones. s_active
++ * will be unlocked when the sysfs_dirent is released.
++ */
++
+static int sysfs_alloc_ino(ino_t *pino)
+{
+ int ino, rc;
+ if (sysfs_type(sd) & SYSFS_COPY_NAME)
+ kfree(sd->s_name);
+ kfree(sd->s_iattr);
-+ sysfs_free_ino(sd->s_ino);
++ if (sysfs_type(sd) != SYSFS_SHADOW_DIR)
++ sysfs_free_ino(sd->s_ino);
+ kmem_cache_free(sysfs_dir_cachep, sd);
+
+ sd = parent_sd;
/* The dentry might have been deleted or another
* lookup could have happened updating sd->s_dentry to
-@@ -32,7 +348,7 @@
+@@ -32,7 +453,7 @@
*/
if (sd->s_dentry == dentry)
sd->s_dentry = NULL;
sysfs_put(sd);
}
iput(inode);
-@@ -42,260 +358,402 @@
+@@ -42,344 +463,594 @@
.d_iput = sysfs_d_iput,
};
+ sd->s_dentry = dentry;
+ spin_unlock(&sysfs_assoc_lock);
+
++ if (dentry->d_flags & DCACHE_UNHASHED)
+ d_rehash(dentry);
}
- else
- return -EEXIST;
- }
-- }
+ memset(acxt, 0, sizeof(*acxt));
+ acxt->parent_sd = parent_sd;
-
-- return 0;
++
+ /* Lookup parent inode. inode initialization and I_NEW
+ * clearing are protected by sysfs_mutex. By grabbing it and
+ * looking up with _nowait variant, inode state can be
+ mutex_unlock(&sysfs_mutex);
+ mutex_lock(&inode->i_mutex);
+ mutex_lock(&sysfs_mutex);
-+ }
+ }
+ } else
+ iput(inode);
- }
++}
+- return 0;
+/**
+ * sysfs_add_one - add sysfs_dirent to parent
+ * @acxt: addrm context to use
+ inc_nlink(acxt->parent_inode);
+
+ acxt->cnt++;
-+}
+ }
--static struct sysfs_dirent *
--__sysfs_make_dirent(struct dentry *dentry, void *element, mode_t mode, int type)
+/**
+ * sysfs_remove_one - remove sysfs_dirent from parent
+ * @acxt: addrm context to use
+ * Determined by sysfs_addrm_start().
+ */
+void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
- {
-- struct sysfs_dirent * sd;
++{
+ BUG_ON(sd->s_sibling || (sd->s_flags & SYSFS_FLAG_REMOVED));
-
-- sd = __sysfs_new_dirent(element);
-- if (!sd)
-- goto out;
++
+ sd->s_flags |= SYSFS_FLAG_REMOVED;
+ sd->s_sibling = acxt->removed;
+ acxt->removed = sd;
-
-- sd->s_mode = mode;
-- sd->s_type = type;
-- sd->s_dentry = dentry;
-- if (dentry) {
-- dentry->d_fsdata = sysfs_get(sd);
-- dentry->d_op = &sysfs_dentry_ops;
-- }
++
+ if (sysfs_type(sd) == SYSFS_DIR && acxt->parent_inode)
+ drop_nlink(acxt->parent_inode);
-
--out:
-- return sd;
++
+ acxt->cnt++;
- }
++}
--int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry,
-- void * element, umode_t mode, int type)
+-static struct sysfs_dirent *
+-__sysfs_make_dirent(struct dentry *dentry, void *element, mode_t mode, int type)
+/**
+ * sysfs_drop_dentry - drop dentry for the specified sysfs_dirent
+ * @sd: target sysfs_dirent
+ */
+static void sysfs_drop_dentry(struct sysfs_dirent *sd)
{
-- struct sysfs_dirent *sd;
+- struct sysfs_dirent * sd;
+ struct dentry *dentry = NULL;
+ struct inode *inode;
-- sd = __sysfs_make_dirent(dentry, element, mode, type);
-- __sysfs_list_dirent(parent_sd, sd);
+- sd = __sysfs_new_dirent(element);
+- if (!sd)
+- goto out;
+ /* We're not holding a reference to ->s_dentry dentry but the
+ * field will stay valid as long as sysfs_assoc_lock is held.
+ */
+ spin_lock(&sysfs_assoc_lock);
+ spin_lock(&dcache_lock);
-- return sd ? 0 : -ENOMEM;
+- sd->s_mode = mode;
+- sd->s_type = type;
+- sd->s_dentry = dentry;
+- if (dentry) {
+- dentry->d_fsdata = sysfs_get(sd);
+- dentry->d_op = &sysfs_dentry_ops;
+- }
+ /* drop dentry if it's there and dput() didn't kill it yet */
+ if (sd->s_dentry && sd->s_dentry->d_inode) {
+ dentry = dget_locked(sd->s_dentry);
+ spin_unlock(&dcache_lock);
+ spin_unlock(&sysfs_assoc_lock);
+
-+ /* dentries for shadowed inodes are pinned, unpin */
-+ if (dentry && sysfs_is_shadowed_inode(dentry->d_inode))
++ /* dentries for shadowed directories are pinned, unpin */
++ if ((sysfs_type(sd) == SYSFS_SHADOW_DIR) ||
++ (sd->s_flags & SYSFS_FLAG_SHADOWED))
+ dput(dentry);
+ dput(dentry);
-+
+
+-out:
+- return sd;
+ /* adjust nlink and update timestamp */
+ inode = ilookup(sysfs_sb, sd->s_ino);
+ if (inode) {
+ }
}
--static int init_dir(struct inode * inode)
+-int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry,
+- void * element, umode_t mode, int type)
++/**
++ * sysfs_drop_dentry - drop dentry for the specified sysfs_dirent
++ * @sd: target sysfs_dirent
++ *
++ * Drop dentry for @sd. @sd must have been unlinked from its
++ * parent on entry to this function such that it can't be looked
++ * up anymore.
++ *
++ * @sd->s_dentry which is protected with sysfs_assoc_lock points
++ * to the currently associated dentry but we're not holding a
++ * reference to it and racing with dput(). Grab dcache_lock and
++ * verify dentry before dropping it. If @sd->s_dentry is NULL or
++ * dput() beats us, no need to bother.
++ */
++
++
+/**
+ * sysfs_addrm_finish - finish up sysfs_dirent add/remove
+ * @acxt: addrm context to finish up
+ */
+int sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
{
-- inode->i_op = &sysfs_dir_inode_operations;
-- inode->i_fop = &sysfs_dir_operations;
+- struct sysfs_dirent *sd;
+ /* release resources acquired by sysfs_addrm_start() */
+ mutex_unlock(&sysfs_mutex);
+ if (acxt->parent_inode) {
+ if (acxt->cnt)
+ inode->i_ctime = inode->i_mtime = CURRENT_TIME;
-- /* directory inodes start off with i_nlink == 2 (for "." entry) */
-- inc_nlink(inode);
-- return 0;
+- sd = __sysfs_make_dirent(dentry, element, mode, type);
+- __sysfs_list_dirent(parent_sd, sd);
+ mutex_unlock(&inode->i_mutex);
+ iput(inode);
+ }
-+
+
+- return sd ? 0 : -ENOMEM;
+ /* kill removed sysfs_dirents */
+ while (acxt->removed) {
+ struct sysfs_dirent *sd = acxt->removed;
+ acxt->removed = sd->s_sibling;
+ sd->s_sibling = NULL;
+
++ sysfs_prune_shadow_sd(sd->s_parent);
+ sysfs_drop_dentry(sd);
+ sysfs_deactivate(sd);
+ sysfs_put(sd);
+ return acxt->cnt;
}
--static int init_file(struct inode * inode)
+-static int init_dir(struct inode * inode)
+/**
+ * sysfs_find_dirent - find sysfs_dirent with the given name
+ * @parent_sd: sysfs_dirent to search under
+struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
+ const unsigned char *name)
{
-- inode->i_size = PAGE_SIZE;
-- inode->i_fop = &sysfs_file_operations;
-- return 0;
+- inode->i_op = &sysfs_dir_inode_operations;
+- inode->i_fop = &sysfs_dir_operations;
+ struct sysfs_dirent *sd;
-+
+
+- /* directory inodes start off with i_nlink == 2 (for "." entry) */
+- inc_nlink(inode);
+- return 0;
+ for (sd = parent_sd->s_children; sd; sd = sd->s_sibling)
+ if (sysfs_type(sd) && !strcmp(sd->s_name, name))
+ return sd;
+ return NULL;
}
--static int init_symlink(struct inode * inode)
+-static int init_file(struct inode * inode)
+/**
+ * sysfs_get_dirent - find and get sysfs_dirent with the given name
+ * @parent_sd: sysfs_dirent to search under
+struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
+ const unsigned char *name)
{
-- inode->i_op = &sysfs_symlink_inode_operations;
+- inode->i_size = PAGE_SIZE;
+- inode->i_fop = &sysfs_file_operations;
- return 0;
+-}
+ struct sysfs_dirent *sd;
-+
+
+-static int init_symlink(struct inode * inode)
+-{
+- inode->i_op = &sysfs_symlink_inode_operations;
+- return 0;
+ mutex_lock(&sysfs_mutex);
+ sd = sysfs_find_dirent(parent_sd, name);
+ sysfs_get(sd);
umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
+ struct sysfs_addrm_cxt acxt;
+ struct sysfs_dirent *sd;
++ int err;
- mutex_lock(&p->d_inode->i_mutex);
- *d = lookup_one_len(n, p, strlen(n));
- inc_nlink(p->d_inode);
- (*d)->d_op = &sysfs_dentry_ops;
- d_rehash(*d);
+- }
+ /* allocate */
+ sd = sysfs_new_dirent(name, mode, SYSFS_DIR);
+ if (!sd)
+
+ /* link in */
+ sysfs_addrm_start(&acxt, parent_sd);
-+ if (!sysfs_find_dirent(parent_sd, name)) {
++ err = -ENOENT;
++ if (!sysfs_resolve_for_create(kobj, &acxt.parent_sd))
++ goto addrm_finish;
++
++ err = -EEXIST;
++ if (!sysfs_find_dirent(acxt.parent_sd, name)) {
+ sysfs_add_one(&acxt, sd);
+ sysfs_link_sibling(sd);
- }
++ err = 0;
++ }
++addrm_finish:
+ if (sysfs_addrm_finish(&acxt)) {
+ *p_sd = sd;
+ return 0;
- error = PTR_ERR(*d);
- mutex_unlock(&p->d_inode->i_mutex);
- return error;
-+ return -EEXIST;
++ return err;
}
-
* sysfs_create_dir - create a directory for an object.
* @kobj: object we're creating directory for.
- * @shadow_parent: parent parent object.
-+ * @shadow_parent: parent object.
*/
-
-int sysfs_create_dir(struct kobject * kobj, struct dentry *shadow_parent)
-+int sysfs_create_dir(struct kobject *kobj,
-+ struct sysfs_dirent *shadow_parent_sd)
++int sysfs_create_dir(struct kobject * kobj)
{
- struct dentry * dentry = NULL;
- struct dentry * parent;
- if (shadow_parent)
- parent = shadow_parent;
-+ if (shadow_parent_sd)
-+ parent_sd = shadow_parent_sd;
- else if (kobj->parent)
+- else if (kobj->parent)
- parent = kobj->parent->dentry;
++ if (kobj->parent)
+ parent_sd = kobj->parent->sd;
else if (sysfs_mount && sysfs_mount->mnt_sb)
- parent = sysfs_mount->mnt_sb->s_root;
+ error = create_dir(kobj, parent_sd, kobject_name(kobj), &sd);
if (!error)
- kobj->dentry = dentry;
-- return error;
--}
--
++ kobj->sd = sd;
+ return error;
+ }
+
-/* attaches attribute's sysfs_dirent to the dentry corresponding to the
- * attribute file
- */
-static int sysfs_attach_attr(struct sysfs_dirent * sd, struct dentry * dentry)
--{
++static int sysfs_count_nlink(struct sysfs_dirent *sd)
+ {
- struct attribute * attr = NULL;
- struct bin_attribute * bin_attr = NULL;
- int (* init) (struct inode *) = NULL;
- int error = 0;
--
++ struct sysfs_dirent *child;
++ int nr = 0;
+
- if (sd->s_type & SYSFS_KOBJ_BIN_ATTR) {
- bin_attr = sd->s_element;
- attr = &bin_attr->attr;
- attr = sd->s_element;
- init = init_file;
- }
--
++ for (child = sd->s_children; child; child = child->s_sibling)
++ if (sysfs_type(child) == SYSFS_DIR)
++ nr++;
++ return nr + 2;
++}
+
- dentry->d_fsdata = sysfs_get(sd);
- /* protect sd->s_dentry against sysfs_d_iput */
- spin_lock(&sysfs_lock);
- error = sysfs_create(dentry, (attr->mode & S_IALLUGO) | S_IFREG, init);
- if (error) {
- sysfs_put(sd);
-+ kobj->sd = sd;
- return error;
-- }
--
-- if (bin_attr) {
-- dentry->d_inode->i_size = bin_attr->size;
-- dentry->d_inode->i_fop = &bin_fops;
+- return error;
- }
-- dentry->d_op = &sysfs_dentry_ops;
-- d_rehash(dentry);
--
-- return 0;
- }
-
--static int sysfs_attach_link(struct sysfs_dirent * sd, struct dentry * dentry)
-+static int sysfs_count_nlink(struct sysfs_dirent *sd)
- {
-- int err = 0;
-+ struct sysfs_dirent *child;
-+ int nr = 0;
-
-- dentry->d_fsdata = sysfs_get(sd);
-- /* protect sd->s_dentry against sysfs_d_iput */
-- spin_lock(&sysfs_lock);
-- sd->s_dentry = dentry;
-- spin_unlock(&sysfs_lock);
-- err = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink);
-- if (!err) {
-- dentry->d_op = &sysfs_dentry_ops;
-- d_rehash(dentry);
-- } else
-- sysfs_put(sd);
--
-- return err;
-+ for (child = sd->s_children; child; child = child->s_sibling)
-+ if (sysfs_type(child) == SYSFS_DIR)
-+ nr++;
-+ return nr + 2;
- }
-
- static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
-@@ -303,24 +761,60 @@
- {
- struct sysfs_dirent * parent_sd = dentry->d_parent->d_fsdata;
- struct sysfs_dirent * sd;
-- int err = 0;
++static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
++ struct nameidata *nd)
++{
++ struct sysfs_dirent * parent_sd = dentry->d_parent->d_fsdata;
++ struct sysfs_dirent * sd;
+ struct bin_attribute *bin_attr;
+ struct inode *inode;
+ int found = 0;
-- list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
-- if (sd->s_type & SYSFS_NOT_PINNED) {
-- const unsigned char * name = sysfs_get_name(sd);
+- if (bin_attr) {
+- dentry->d_inode->i_size = bin_attr->size;
+- dentry->d_inode->i_fop = &bin_fops;
+ for (sd = parent_sd->s_children; sd; sd = sd->s_sibling) {
+ if (sysfs_type(sd) &&
+ !strcmp(sd->s_name, dentry->d_name.name)) {
+ found = 1;
+ break;
+ }
-+ }
+ }
+- dentry->d_op = &sysfs_dentry_ops;
+- d_rehash(dentry);
-- if (strcmp(name, dentry->d_name.name))
-- continue;
+- return 0;
+-}
+ /* no such entry */
+ if (!found)
+ return NULL;
-- if (sd->s_type & SYSFS_KOBJ_LINK)
-- err = sysfs_attach_link(sd, dentry);
-- else
-- err = sysfs_attach_attr(sd, dentry);
+-static int sysfs_attach_link(struct sysfs_dirent * sd, struct dentry * dentry)
+-{
+- int err = 0;
+ /* attach dentry and inode */
+ inode = sysfs_get_inode(sd);
+ if (!inode)
+ inode->i_op = &sysfs_dir_inode_operations;
+ inode->i_fop = &sysfs_dir_operations;
+ inode->i_nlink = sysfs_count_nlink(sd);
- break;
++ break;
+ case SYSFS_KOBJ_ATTR:
+ inode->i_size = PAGE_SIZE;
+ inode->i_fop = &sysfs_file_operations;
+ break;
+ default:
+ BUG();
- }
- }
++ }
++ }
-- return ERR_PTR(err);
+- dentry->d_fsdata = sysfs_get(sd);
+- /* protect sd->s_dentry against sysfs_d_iput */
+- spin_lock(&sysfs_lock);
+- sd->s_dentry = dentry;
+- spin_unlock(&sysfs_lock);
+- err = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink);
+- if (!err) {
+- dentry->d_op = &sysfs_dentry_ops;
+- d_rehash(dentry);
+- } else
+- sysfs_put(sd);
+ sysfs_instantiate(dentry, inode);
+ sysfs_attach_dentry(sd, dentry);
-+
+
+- return err;
+ mutex_unlock(&sysfs_mutex);
+
+ return NULL;
}
+-static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
+- struct nameidata *nd)
++static void *sysfs_shadow_follow_link(struct dentry *dentry, struct nameidata *nd)
+ {
+- struct sysfs_dirent * parent_sd = dentry->d_parent->d_fsdata;
+- struct sysfs_dirent * sd;
+- int err = 0;
++ struct sysfs_dirent *sd;
++ struct dentry *dest;
+
+- list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
+- if (sd->s_type & SYSFS_NOT_PINNED) {
+- const unsigned char * name = sysfs_get_name(sd);
++ sd = dentry->d_fsdata;
++ dest = NULL;
++ if (sd->s_flags & SYSFS_FLAG_SHADOWED) {
++ const struct shadow_dir_operations *shadow_ops;
++ const void *tag;
+
+- if (strcmp(name, dentry->d_name.name))
+- continue;
++ mutex_lock(&sysfs_mutex);
+
+- if (sd->s_type & SYSFS_KOBJ_LINK)
+- err = sysfs_attach_link(sd, dentry);
+- else
+- err = sysfs_attach_attr(sd, dentry);
+- break;
+- }
++ shadow_ops = dentry->d_inode->i_private;
++ tag = shadow_ops->current_tag();
++
++ sd = find_shadow_sd(sd, tag);
++ if (sd)
++ dest = sd->s_dentry;
++ dget(dest);
++
++ mutex_unlock(&sysfs_mutex);
+ }
++ if (!dest)
++ dest = dget(dentry);
++ dput(nd->dentry);
++ nd->dentry = dest;
+
+- return ERR_PTR(err);
++ return NULL;
+ }
+
++
const struct inode_operations sysfs_dir_inode_operations = {
-@@ -328,58 +822,46 @@
+ .lookup = sysfs_lookup,
.setattr = sysfs_setattr,
++ .follow_link = sysfs_shadow_follow_link,
};
-static void remove_dir(struct dentry * d)
-+static void remove_dir(struct sysfs_dirent *sd)
++static void __remove_dir(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
{
- struct dentry * parent = dget(d->d_parent);
- struct sysfs_dirent * sd;
-+ struct sysfs_addrm_cxt acxt;
++ sysfs_unlink_sibling(sd);
++ sysfs_remove_one(acxt, sd);
++}
- mutex_lock(&parent->d_inode->i_mutex);
- d_delete(d);
- sysfs_put(sd);
- if (d->d_inode)
- simple_rmdir(parent->d_inode,d);
--
++static void remove_dir(struct sysfs_dirent *sd)
++{
++ struct sysfs_addrm_cxt acxt;
+
- pr_debug(" o %s removing done (%d)\n",d->d_name.name,
- atomic_read(&d->d_count));
--
-- mutex_unlock(&parent->d_inode->i_mutex);
-- dput(parent);
+ sysfs_addrm_start(&acxt, sd->s_parent);
-+ sysfs_unlink_sibling(sd);
-+ sysfs_remove_one(&acxt, sd);
++ __remove_dir(&acxt, sd);
+ sysfs_addrm_finish(&acxt);
++}
+
+- mutex_unlock(&parent->d_inode->i_mutex);
+- dput(parent);
++void sysfs_remove_subdir(struct sysfs_dirent *sd)
++{
++ remove_dir(sd);
}
-void sysfs_remove_subdir(struct dentry * d)
-+void sysfs_remove_subdir(struct sysfs_dirent *sd)
++static void sysfs_empty_dir(struct sysfs_addrm_cxt *acxt,
++ struct sysfs_dirent *dir_sd)
{
- remove_dir(d);
-+ remove_dir(sd);
++ struct sysfs_dirent **pos;
++
++ pos = &dir_sd->s_children;
++ while (*pos) {
++ struct sysfs_dirent *sd = *pos;
++
++ if (sysfs_type(sd) && sysfs_type(sd) != SYSFS_DIR) {
++ *pos = sd->s_sibling;
++ sd->s_sibling = NULL;
++ sysfs_remove_one(acxt, sd);
++ } else
++ pos = &(*pos)->s_sibling;
++ }
}
++static void sysfs_remove_shadows(struct sysfs_addrm_cxt * acxt,
++ struct sysfs_dirent *dir_sd)
++{
++ struct sysfs_dirent **pos;
++
++ pos = &dir_sd->s_children;
++ while (*pos) {
++ struct sysfs_dirent *sd = *pos;
++
++ sysfs_empty_dir(acxt, sd);
++ __remove_dir(acxt, sd);
++ }
++}
-static void __sysfs_remove_dir(struct dentry *dentry)
+static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd)
- struct sysfs_dirent * parent_sd;
- struct sysfs_dirent * sd, * tmp;
+ struct sysfs_addrm_cxt acxt;
-+ struct sysfs_dirent **pos;
- dget(dentry);
- if (!dentry)
- list_del_init(&sd->s_sibling);
- sysfs_drop_dentry(sd, dentry);
- sysfs_put(sd);
+- }
+- mutex_unlock(&dentry->d_inode->i_mutex);
+ pr_debug("sysfs %s: removing dir\n", dir_sd->s_name);
+ sysfs_addrm_start(&acxt, dir_sd);
-+ pos = &dir_sd->s_children;
-+ while (*pos) {
-+ struct sysfs_dirent *sd = *pos;
-+
-+ if (sysfs_type(sd) && sysfs_type(sd) != SYSFS_DIR) {
-+ *pos = sd->s_sibling;
-+ sd->s_sibling = NULL;
-+ sysfs_remove_one(&acxt, sd);
-+ } else
-+ pos = &(*pos)->s_sibling;
- }
-- mutex_unlock(&dentry->d_inode->i_mutex);
++ if (sysfs_type(dir_sd) == SYSFS_DIR)
++ sysfs_empty_dir(&acxt, dir_sd);
++ else
++ sysfs_remove_shadows(&acxt, dir_sd);
+ sysfs_addrm_finish(&acxt);
- remove_dir(dentry);
}
/**
-@@ -393,102 +875,166 @@
+@@ -393,102 +1064,154 @@
void sysfs_remove_dir(struct kobject * kobj)
{
}
-int sysfs_rename_dir(struct kobject * kobj, struct dentry *new_parent,
-+int sysfs_rename_dir(struct kobject *kobj, struct sysfs_dirent *new_parent_sd,
- const char *new_name)
+- const char *new_name)
++int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
{
- int error = 0;
- struct dentry * new_dentry;
-+ struct sysfs_dirent *sd = kobj->sd;
-+ struct dentry *new_parent = NULL;
-+ struct dentry *old_dentry = NULL, *new_dentry = NULL;
-+ const char *dup_name = NULL;
++ struct dentry *old_dentry, *new_dentry, *parent;
++ struct sysfs_addrm_cxt acxt;
++ struct sysfs_dirent *sd;
++ const char *dup_name;
+ int error;
- if (!new_parent)
- return -EFAULT;
-+ /* get dentries */
-+ old_dentry = sysfs_get_dentry(sd);
-+ if (IS_ERR(old_dentry)) {
-+ error = PTR_ERR(old_dentry);
-+ goto out_dput;
-+ }
-+
-+ new_parent = sysfs_get_dentry(new_parent_sd);
-+ if (IS_ERR(new_parent)) {
-+ error = PTR_ERR(new_parent);
-+ goto out_dput;
-+ }
++ dup_name = NULL;
++ new_dentry = NULL;
- down_write(&sysfs_rename_sem);
-+ /* lock new_parent and get dentry for new name */
- mutex_lock(&new_parent->d_inode->i_mutex);
+- mutex_lock(&new_parent->d_inode->i_mutex);
++ sd = kobj->sd;
++ sysfs_addrm_start(&acxt, sd->s_parent);
++ error = -ENOENT;
++ if (!sysfs_resolve_for_create(kobj, &acxt.parent_sd))
++ goto addrm_finish;
++
++ error = -EEXIST;
++ if (sysfs_find_dirent(acxt.parent_sd, new_name))
++ goto addrm_finish;
- new_dentry = lookup_one_len(new_name, new_parent, strlen(new_name));
+- new_dentry = lookup_one_len(new_name, new_parent, strlen(new_name));
- if (!IS_ERR(new_dentry)) {
- /* By allowing two different directories with the
- * same d_parent we allow this routine to move
- * between different shadows of the same directory
-+ if (IS_ERR(new_dentry)) {
-+ error = PTR_ERR(new_dentry);
-+ goto out_unlock;
-+ }
-+
-+ /* By allowing two different directories with the same
-+ * d_parent we allow this routine to move between different
-+ * shadows of the same directory
- */
+- */
- if (kobj->dentry->d_parent->d_inode != new_parent->d_inode)
- return -EINVAL;
- else if (new_dentry->d_parent->d_inode != new_parent->d_inode)
-- error = -EINVAL;
+ error = -EINVAL;
- else if (new_dentry == kobj->dentry)
++ if ((sd->s_parent == acxt.parent_sd) &&
++ (strcmp(new_name, sd->s_name) == 0))
++ goto addrm_finish;
++
++ old_dentry = sd->s_dentry;
++ parent = acxt.parent_sd->s_dentry;
++ if (old_dentry) {
++ old_dentry = sd->s_dentry;
++ parent = acxt.parent_sd->s_dentry;
++ new_dentry = lookup_one_len(new_name, parent, strlen(new_name));
++ if (IS_ERR(new_dentry)) {
++ error = PTR_ERR(new_dentry);
++ goto addrm_finish;
++ }
++
error = -EINVAL;
- else if (!new_dentry->d_inode) {
-+ if (old_dentry->d_parent->d_inode != new_parent->d_inode ||
-+ new_dentry->d_parent->d_inode != new_parent->d_inode ||
-+ old_dentry == new_dentry)
-+ goto out_unlock;
-+
-+ error = -EEXIST;
-+ if (new_dentry->d_inode)
-+ goto out_unlock;
++ if (old_dentry == new_dentry)
++ goto addrm_finish;
++ }
+
+ /* rename kobject and sysfs_dirent */
+ error = -ENOMEM;
+ new_name = dup_name = kstrdup(new_name, GFP_KERNEL);
+ if (!new_name)
-+ goto out_drop;
++ goto addrm_finish;
+
error = kobject_set_name(kobj, "%s", new_name);
- if (!error) {
- struct sysfs_dirent *sd, *parent_sd;
+ if (error)
-+ goto out_drop;
-+
-+ dup_name = sd->s_name;
-+ sd->s_name = new_name;
++ goto addrm_finish;
-+ /* move under the new parent */
- d_add(new_dentry, NULL);
+- d_add(new_dentry, NULL);
- d_move(kobj->dentry, new_dentry);
-+ d_move(sd->s_dentry, new_dentry);
++ dup_name = sd->s_name;
++ sd->s_name = new_name;
- sd = kobj->dentry->d_fsdata;
- parent_sd = new_parent->d_fsdata;
-+ mutex_lock(&sysfs_mutex);
++ /* move under the new parent */
++ sysfs_unlink_sibling(sd);
++ sysfs_get(acxt.parent_sd);
++ sysfs_put(sd->s_parent);
++ sd->s_parent = acxt.parent_sd;
++ sysfs_link_sibling(sd);
- list_del_init(&sd->s_sibling);
- list_add(&sd->s_sibling, &parent_sd->s_children);
- }
- else
-+ sysfs_unlink_sibling(sd);
-+ sysfs_get(new_parent_sd);
-+ sysfs_put(sd->s_parent);
-+ sd->s_parent = new_parent_sd;
-+ sysfs_link_sibling(sd);
-+
-+ mutex_unlock(&sysfs_mutex);
-+
-+ error = 0;
-+ goto out_unlock;
-+
-+ out_drop:
- d_drop(new_dentry);
+- d_drop(new_dentry);
- } else
- error = -EEXIST;
- dput(new_dentry);
-- }
-+ out_unlock:
- mutex_unlock(&new_parent->d_inode->i_mutex);
++ if (new_dentry) {
++ d_add(new_dentry, NULL);
++ d_move(old_dentry, new_dentry);
+ }
+- mutex_unlock(&new_parent->d_inode->i_mutex);
- up_write(&sysfs_rename_sem);
--
-+ out_dput:
++ error = 0;
++addrm_finish:
++ sysfs_addrm_finish(&acxt);
+
+ kfree(dup_name);
-+ dput(new_parent);
-+ dput(old_dentry);
+ dput(new_dentry);
return error;
}
+ goto out_dput;
+ }
+ old_parent = sd->s_parent->s_dentry;
-
-- if (old_parent_dentry->d_inode == new_parent_dentry->d_inode)
-- return 0; /* nothing to move */
++
+ new_parent = sysfs_get_dentry(new_parent_sd);
+ if (IS_ERR(new_parent)) {
+ error = PTR_ERR(new_parent);
+ goto out_dput;
+ }
-+
+
+- if (old_parent_dentry->d_inode == new_parent_dentry->d_inode)
+- return 0; /* nothing to move */
+ if (old_parent->d_inode == new_parent->d_inode) {
+ error = 0;
+ goto out_dput; /* nothing to move */
+ sysfs_put(sd->s_parent);
+ sd->s_parent = new_parent_sd;
+ sysfs_link_sibling(sd);
-
-+ mutex_unlock(&sysfs_mutex);
+
++ mutex_unlock(&sysfs_mutex);
+
+ out_unlock:
+ mutex_unlock(&new_parent->d_inode->i_mutex);
+ mutex_unlock(&old_parent->d_inode->i_mutex);
return error;
}
-@@ -496,23 +1042,27 @@
+@@ -496,23 +1219,27 @@
{
struct dentry * dentry = file->f_path.dentry;
struct sysfs_dirent * parent_sd = dentry->d_fsdata;
release_sysfs_dirent(cursor);
-@@ -530,7 +1080,7 @@
+@@ -530,7 +1257,7 @@
struct dentry *dentry = filp->f_path.dentry;
struct sysfs_dirent * parent_sd = dentry->d_fsdata;
struct sysfs_dirent *cursor = filp->private_data;
ino_t ino;
int i = filp->f_pos;
-@@ -543,38 +1093,52 @@
+@@ -543,38 +1270,55 @@
i++;
/* fallthrough */
case 1:
i++;
/* fallthrough */
default:
-+ mutex_lock(&sysfs_mutex);
++ /* If I am the shadow master return nothing. */
++ if (parent_sd->s_flags & SYSFS_FLAG_SHADOWED)
++ return 0;
+
++ mutex_lock(&sysfs_mutex);
+ pos = &parent_sd->s_children;
+ while (*pos != cursor)
+ pos = &(*pos)->s_sibling;
}
return 0;
}
-@@ -583,7 +1147,6 @@
+@@ -583,7 +1327,6 @@
{
struct dentry * dentry = file->f_path.dentry;
switch (origin) {
case 1:
offset += file->f_pos;
-@@ -591,31 +1154,35 @@
+@@ -591,127 +1334,224 @@
if (offset >= 0)
break;
default:
return offset;
}
-@@ -628,12 +1195,20 @@
- int sysfs_make_shadowed_dir(struct kobject *kobj,
- void * (*follow_link)(struct dentry *, struct nameidata *))
++const struct file_operations sysfs_dir_operations = {
++ .open = sysfs_dir_open,
++ .release = sysfs_dir_close,
++ .llseek = sysfs_dir_lseek,
++ .read = generic_read_dir,
++ .readdir = sysfs_readdir,
++};
+
+-/**
+- * sysfs_make_shadowed_dir - Setup so a directory can be shadowed
+- * @kobj: object we're creating shadow of.
+- */
+
+-int sysfs_make_shadowed_dir(struct kobject *kobj,
+- void * (*follow_link)(struct dentry *, struct nameidata *))
++static void sysfs_prune_shadow_sd(struct sysfs_dirent *sd)
{
-+ struct dentry *dentry;
- struct inode *inode;
- struct inode_operations *i_op;
+- struct inode *inode;
+- struct inode_operations *i_op;
++ struct sysfs_addrm_cxt acxt;
- inode = kobj->dentry->d_inode;
- if (inode->i_op != &sysfs_dir_inode_operations)
-+ /* get dentry for @kobj->sd, dentry of a shadowed dir is pinned */
-+ dentry = sysfs_get_dentry(kobj->sd);
-+ if (IS_ERR(dentry))
-+ return PTR_ERR(dentry);
-+
-+ inode = dentry->d_inode;
-+ if (inode->i_op != &sysfs_dir_inode_operations) {
-+ dput(dentry);
- return -EINVAL;
-+ }
+- return -EINVAL;
++ /* If a shadow directory goes empty remove it. */
++ if (sysfs_type(sd) != SYSFS_SHADOW_DIR)
++ return;
- i_op = kmalloc(sizeof(*i_op), GFP_KERNEL);
- if (!i_op)
-@@ -658,54 +1233,72 @@
- * directory.
- */
+- i_op = kmalloc(sizeof(*i_op), GFP_KERNEL);
+- if (!i_op)
+- return -ENOMEM;
++ if (sd->s_children)
++ return;
+
+- memcpy(i_op, &sysfs_dir_inode_operations, sizeof(*i_op));
+- i_op->follow_link = follow_link;
++ sysfs_addrm_start(&acxt, sd->s_parent);
+
+- /* Locking of inode->i_op?
+- * Since setting i_op is a single word write and they
+- * are atomic we should be ok here.
+- */
+- inode->i_op = i_op;
+- return 0;
+-}
++ if (sd->s_flags & SYSFS_FLAG_REMOVED)
++ goto addrm_finish;
+
+-/**
+- * sysfs_create_shadow_dir - create a shadow directory for an object.
+- * @kobj: object we're creating directory for.
+- *
+- * sysfs_make_shadowed_dir must already have been called on this
+- * directory.
+- */
++ if (sd->s_children)
++ goto addrm_finish;
-struct dentry *sysfs_create_shadow_dir(struct kobject *kobj)
-+struct sysfs_dirent *sysfs_create_shadow_dir(struct kobject *kobj)
++ __remove_dir(&acxt, sd);
++addrm_finish:
++ sysfs_addrm_finish(&acxt);
++}
++
++static struct sysfs_dirent *add_shadow_sd(struct sysfs_dirent *parent_sd, const void *tag)
{
- struct sysfs_dirent *sd;
- struct dentry *parent, *dir, *shadow;
-+ struct sysfs_dirent *parent_sd = kobj->sd->s_parent;
-+ struct dentry *dir, *parent, *shadow;
++ struct sysfs_dirent *sd = NULL;
++ struct dentry *dir, *shadow;
struct inode *inode;
-+ struct sysfs_dirent *sd;
-+ struct sysfs_addrm_cxt acxt;
- dir = kobj->dentry;
-- inode = dir->d_inode;
-+ dir = sysfs_get_dentry(kobj->sd);
-+ if (IS_ERR(dir)) {
-+ sd = (void *)dir;
-+ goto out;
-+ }
- parent = dir->d_parent;
++ dir = parent_sd->s_dentry;
+ inode = dir->d_inode;
+- parent = dir->d_parent;
- shadow = ERR_PTR(-EINVAL);
-+
-+ inode = dir->d_inode;
-+ sd = ERR_PTR(-EINVAL);
- if (!sysfs_is_shadowed_inode(inode))
+- if (!sysfs_is_shadowed_inode(inode))
- goto out;
-+ goto out_dput;
- shadow = d_alloc(parent, &dir->d_name);
+- shadow = d_alloc(parent, &dir->d_name);
++ shadow = d_alloc(dir->d_parent, &dir->d_name);
if (!shadow)
- goto nomem;
+- goto nomem;
++ goto out;
++
++ /* Since the shadow directory is reachable make it look
++ * like it is actually hashed.
++ */
++ shadow->d_hash.pprev = &shadow->d_hash.next;
++ shadow->d_hash.next = NULL;
++ shadow->d_flags &= ~DCACHE_UNHASHED;
- sd = __sysfs_make_dirent(shadow, kobj, inode->i_mode, SYSFS_DIR);
-+ sd = sysfs_new_dirent("_SHADOW_", inode->i_mode, SYSFS_DIR);
++ sd = sysfs_new_dirent(tag, parent_sd->s_mode, SYSFS_SHADOW_DIR);
if (!sd)
- goto nomem;
-+ sd->s_elem.dir.kobj = kobj;
+- goto nomem;
++ goto error;
-+ sysfs_addrm_start(&acxt, parent_sd);
-+
-+ /* add but don't link into children list */
-+ sysfs_add_one(&acxt, sd);
-+
-+ /* attach and instantiate dentry */
-+ sysfs_attach_dentry(sd, shadow);
- d_instantiate(shadow, igrab(inode));
+- d_instantiate(shadow, igrab(inode));
- inc_nlink(inode);
- inc_nlink(parent->d_inode);
- shadow->d_op = &sysfs_dentry_ops;
-+ inc_nlink(inode); /* tj: synchronization? */
-+
-+ sysfs_addrm_finish(&acxt);
++ sd->s_elem.dir.kobj = parent_sd->s_elem.dir.kobj;
++ sd->s_parent = sysfs_get(parent_sd);
- dget(shadow); /* Extra count - pin the dentry in core */
+- dget(shadow); /* Extra count - pin the dentry in core */
++ /* Use the inode number of the parent we are shadowing */
++ sysfs_free_ino(sd->s_ino);
++ sd->s_ino = parent_sd->s_ino;
--out:
++ inc_nlink(inode);
++ inc_nlink(dir->d_parent->d_inode);
++
++ sysfs_link_sibling(sd);
++ __iget(inode);
++ sysfs_instantiate(shadow, inode);
++ sysfs_attach_dentry(sd, shadow);
+ out:
- return shadow;
-nomem:
-+ goto out_dput;
-+
-+ nomem:
++ return sd;
++error:
dput(shadow);
- shadow = ERR_PTR(-ENOMEM);
-- goto out;
-+ sd = ERR_PTR(-ENOMEM);
-+ out_dput:
-+ dput(dir);
-+ out:
-+ return sd;
+ goto out;
}
++int sysfs_resolve_for_create(struct kobject *kobj,
++ struct sysfs_dirent **parent_sd)
++{
++ const struct shadow_dir_operations *shadow_ops;
++ struct sysfs_dirent *sd, *shadow_sd;
++
++ sd = *parent_sd;
++ if (sysfs_type(sd) == SYSFS_SHADOW_DIR)
++ sd = sd->s_parent;
++
++ if (sd->s_flags & SYSFS_FLAG_SHADOWED) {
++ const void *tag;
++
++ shadow_ops = sd->s_dentry->d_inode->i_private;
++ tag = shadow_ops->kobject_tag(kobj);
++
++ shadow_sd = find_shadow_sd(sd, tag);
++ if (!shadow_sd)
++ shadow_sd = add_shadow_sd(sd, tag);
++ sd = shadow_sd;
++ }
++ if (sd) {
++ *parent_sd = sd;
++ return 1;
++ }
++ return 0;
++}
++
++int sysfs_resolve_for_remove(struct kobject *kobj,
++ struct sysfs_dirent **parent_sd)
++{
++ struct sysfs_dirent *sd;
++ /* If dentry is a shadow directory find the shadow that is
++ * stored under the same tag as kobj. This allows removal
++ * of dirents to function properly even if the value of
++ * kobject_tag() has changed since we initially created
++ * the dirents assoctated with kobj.
++ */
++
++ sd = *parent_sd;
++ if (sysfs_type(sd) == SYSFS_SHADOW_DIR)
++ sd = sd->s_parent;
++ if (sd->s_flags & SYSFS_FLAG_SHADOWED) {
++ const void *tag;
++
++ tag = find_shadow_tag(kobj);
++ sd = find_shadow_sd(sd, tag);
++ }
++ if (sd) {
++ *parent_sd = sd;
++ return 1;
++ }
++ return 0;
++}
++
/**
- * sysfs_remove_shadow_dir - remove an object's directory.
+- * sysfs_remove_shadow_dir - remove an object's directory.
- * @shadow: dentry of shadow directory
-+ * @shadow_sd: sysfs_dirent of shadow directory
++ * sysfs_enable_shadowing - Automatically create shadows of a directory
++ * @kobj: object to automatically shadow
*
- * The only thing special about this is that we remove any files in
- * the directory before we remove the directory, and we've inlined
- * what used to be sysfs_rmdir() below, instead of calling separately.
+- * The only thing special about this is that we remove any files in
+- * the directory before we remove the directory, and we've inlined
+- * what used to be sysfs_rmdir() below, instead of calling separately.
++ * Once shadowing has been enabled on a directory the contents
++ * of the directory become dependent upon context.
++ *
++ * shadow_ops->current_tag() returns the context for the current
++ * process.
++ *
++ * shadow_ops->kobject_tag() returns the context that a given kobj
++ * resides in.
++ *
++ * Using those methods the sysfs code on shadowed directories
++ * carefully stores the files so that when we lookup files
++ * we get the proper answer for our context.
++ *
++ * If the context of a kobject is changed it is expected that
++ * the kobject will be renamed so the appopriate sysfs data structures
++ * can be updated.
*/
-
+-
-void sysfs_remove_shadow_dir(struct dentry *shadow)
-+void sysfs_remove_shadow_dir(struct sysfs_dirent *shadow_sd)
++int sysfs_enable_shadowing(struct kobject *kobj,
++ const struct shadow_dir_operations *shadow_ops)
{
- __sysfs_remove_dir(shadow);
-+ __sysfs_remove_dir(shadow_sd);
++ struct sysfs_dirent *sd;
++ struct dentry *dentry;
++ int err;
++
++ /* Find the dentry for the shadowed directory and
++ * increase it's count.
++ */
++ err = -ENOENT;
++ sd = kobj->sd;
++ dentry = sysfs_get_dentry(sd);
++ if (!dentry)
++ goto out;
++
++ mutex_lock(&sysfs_mutex);
++ err = -EINVAL;
++ /* We can only enable shadowing on empty directories
++ * where shadowing is not already enabled.
++ */
++ if (!sd->s_children && (sysfs_type(sd) == SYSFS_DIR) &&
++ !(sd->s_flags & SYSFS_FLAG_REMOVED) &&
++ !(sd->s_flags & SYSFS_FLAG_SHADOWED)) {
++ sd->s_flags |= SYSFS_FLAG_SHADOWED;
++ dentry->d_inode->i_private = (void *)shadow_ops;
++ err = 0;
++ }
++ mutex_unlock(&sysfs_mutex);
++out:
++ if (err)
++ dput(dentry);
++ return err;
}
- const struct file_operations sysfs_dir_operations = {
+-const struct file_operations sysfs_dir_operations = {
+- .open = sysfs_dir_open,
+- .release = sysfs_dir_close,
+- .llseek = sysfs_dir_lseek,
+- .read = generic_read_dir,
+- .readdir = sysfs_readdir,
+-};
diff -Nurb linux-2.6.22-570/fs/sysfs/file.c linux-2.6.22-590/fs/sysfs/file.c
---- linux-2.6.22-570/fs/sysfs/file.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/fs/sysfs/file.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/sysfs/file.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/fs/sysfs/file.c 2008-01-29 22:12:32.000000000 -0500
@@ -50,29 +50,15 @@
.store = subsys_attr_store,
};
+ struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj;
struct sysfs_ops * ops = buffer->ops;
+ int rc;
-
-- return ops->store(kobj,attr,buffer->page,count);
++
+ /* need attr_sd for attr and ops, its parent for kobj */
+ if (!sysfs_get_active_two(attr_sd))
+ return -ENODEV;
+ rc = ops->store(kobj, attr_sd->s_elem.attr.attr, buffer->page, count);
+
+ sysfs_put_active_two(attr_sd);
-+
+
+- return ops->store(kobj,attr,buffer->page,count);
+ return rc;
}
-@@ -231,37 +229,26 @@
+@@ -231,37 +229,29 @@
ssize_t len;
down(&buffer->sem);
+ struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+ struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj;
struct sysfs_buffer * buffer;
++
struct sysfs_ops * ops = NULL;
- int error = 0;
--
++ int error;
+
- if (!kobj || !attr)
- goto Einval;
-+ int error;
- /* Grab the module reference for this attribute if we have one */
- if (!try_module_get(attr->owner)) {
- error = -ENODEV;
- goto Done;
- }
-+ /* need attr_sd for attr and ops, its parent for kobj */
++ /* need attr_sr for attr and ops, its parent for kobj */
++
+ if (!sysfs_get_active_two(attr_sd))
+ return -ENODEV;
/* if the kobject has no ktype, then we assume that it is a subsystem
* itself, and use ops for it.
-@@ -277,7 +264,7 @@
+@@ -277,20 +267,7 @@
* or the subsystem have no operations.
*/
if (!ops)
- goto Eaccess;
+-
+- /* make sure we have a collection to add our buffers to */
+- mutex_lock(&inode->i_mutex);
+- if (!(set = inode->i_private)) {
+- if (!(set = inode->i_private = kmalloc(sizeof(struct sysfs_buffer_collection), GFP_KERNEL))) {
+- mutex_unlock(&inode->i_mutex);
+- error = -ENOMEM;
+- goto Done;
+- } else {
+- INIT_LIST_HEAD(&set->associates);
+- }
+- }
+- mutex_unlock(&inode->i_mutex);
+ goto err_out;
- /* make sure we have a collection to add our buffers to */
- mutex_lock(&inode->i_mutex);
-@@ -299,7 +286,7 @@
+ /* File needs write support.
+ * The inode's perms must say it's ok,
+@@ -299,7 +276,7 @@
if (file->f_mode & FMODE_WRITE) {
if (!(inode->i_mode & S_IWUGO) || !ops->store)
}
-@@ -309,48 +296,38 @@
+@@ -309,48 +286,38 @@
*/
if (file->f_mode & FMODE_READ) {
if (!(inode->i_mode & S_IRUGO) || !ops->show)
if (buffer) {
if (buffer->page)
-@@ -377,57 +354,43 @@
+@@ -377,57 +344,43 @@
static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
{
struct sysfs_buffer * buffer = filp->private_data;
- struct kobject * kobj = to_kobj(filp->f_path.dentry->d_parent);
- struct sysfs_dirent * sd = filp->f_path.dentry->d_fsdata;
- int res = 0;
+-
+- poll_wait(filp, &kobj->poll, wait);
+ struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata;
+ struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj;
-- poll_wait(filp, &kobj->poll, wait);
-+ /* need parent for the kobj, grab both */
-+ if (!sysfs_get_active_two(attr_sd))
-+ goto trigger;
-
- if (buffer->event != atomic_read(&sd->s_event)) {
- res = POLLERR|POLLPRI;
- buffer->needs_read_fill = 1;
- }
--
++ /* need parent for the kobj, grab both */
++ if (!sysfs_get_active_two(attr_sd))
++ goto trigger;
+
- return res;
-}
+ poll_wait(filp, &kobj->poll, wait);
}
EXPORT_SYMBOL_GPL(sysfs_notify);
-@@ -441,19 +404,30 @@
+@@ -441,19 +394,30 @@
};
}
-@@ -465,9 +439,9 @@
+@@ -465,9 +429,9 @@
int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)
{
}
-@@ -481,16 +455,16 @@
+@@ -481,16 +445,16 @@
int sysfs_add_file_to_group(struct kobject *kobj,
const struct attribute *attr, const char *group)
{
return error;
}
EXPORT_SYMBOL_GPL(sysfs_add_file_to_group);
-@@ -503,30 +477,31 @@
+@@ -503,30 +467,31 @@
*/
int sysfs_update_file(struct kobject * kobj, const struct attribute * attr)
{
}
-@@ -539,30 +514,34 @@
+@@ -539,30 +504,34 @@
*/
int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode)
{
}
EXPORT_SYMBOL_GPL(sysfs_chmod_file);
-@@ -577,7 +556,7 @@
+@@ -577,7 +546,7 @@
void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
{
- sysfs_hash_and_remove(kobj->dentry, attr->name);
-+ sysfs_hash_and_remove(kobj->sd, attr->name);
++ sysfs_hash_and_remove(kobj, kobj->sd, attr->name);
}
-@@ -590,12 +569,12 @@
+@@ -590,12 +559,12 @@
void sysfs_remove_file_from_group(struct kobject *kobj,
const struct attribute *attr, const char *group)
{
- dput(dir);
+ dir_sd = sysfs_get_dirent(kobj->sd, group);
+ if (dir_sd) {
-+ sysfs_hash_and_remove(dir_sd, attr->name);
++ sysfs_hash_and_remove(kobj, dir_sd, attr->name);
+ sysfs_put(dir_sd);
}
}
EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group);
diff -Nurb linux-2.6.22-570/fs/sysfs/group.c linux-2.6.22-590/fs/sysfs/group.c
--- linux-2.6.22-570/fs/sysfs/group.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/sysfs/group.c 2008-03-15 10:35:47.000000000 -0400
-@@ -18,26 +18,25 @@
++++ linux-2.6.22-590/fs/sysfs/group.c 2008-01-29 22:12:32.000000000 -0500
+@@ -13,31 +13,29 @@
+ #include <linux/dcache.h>
+ #include <linux/namei.h>
+ #include <linux/err.h>
+-#include <linux/fs.h>
+ #include <asm/semaphore.h>
#include "sysfs.h"
-static void remove_files(struct dentry * dir,
- const struct attribute_group * grp)
-+static void remove_files(struct sysfs_dirent *dir_sd,
++static void remove_files(struct kobject *kobj, struct sysfs_dirent *dir_sd,
+ const struct attribute_group *grp)
{
struct attribute *const* attr;
for (attr = grp->attrs; *attr; attr++)
- sysfs_hash_and_remove(dir,(*attr)->name);
-+ sysfs_hash_and_remove(dir_sd, (*attr)->name);
++ sysfs_hash_and_remove(kobj, dir_sd, (*attr)->name);
}
-static int create_files(struct dentry * dir,
- const struct attribute_group * grp)
-+static int create_files(struct sysfs_dirent *dir_sd,
++static int create_files(struct kobject *kobj, struct sysfs_dirent *dir_sd,
+ const struct attribute_group *grp)
{
struct attribute *const* attr;
+ error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR);
if (error)
- remove_files(dir,grp);
-+ remove_files(dir_sd, grp);
++ remove_files(kobj, dir_sd, grp);
return error;
}
-@@ -45,44 +44,44 @@
+@@ -45,44 +43,44 @@
int sysfs_create_group(struct kobject * kobj,
const struct attribute_group * grp)
{
- if ((error = create_files(dir,grp))) {
+ sd = kobj->sd;
+ sysfs_get(sd);
-+ error = create_files(sd, grp);
++ error = create_files(kobj, sd, grp);
+ if (error) {
if (grp->name)
- sysfs_remove_subdir(dir);
+ sd = sysfs_get(dir_sd);
- remove_files(dir,grp);
-+ remove_files(sd, grp);
++ remove_files(kobj, sd, grp);
if (grp->name)
- sysfs_remove_subdir(dir);
- /* release the ref. taken in this routine */
diff -Nurb linux-2.6.22-570/fs/sysfs/inode.c linux-2.6.22-590/fs/sysfs/inode.c
--- linux-2.6.22-570/fs/sysfs/inode.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/sysfs/inode.c 2008-03-15 10:35:47.000000000 -0400
-@@ -133,10 +133,8 @@
++++ linux-2.6.22-590/fs/sysfs/inode.c 2008-01-29 22:12:32.000000000 -0500
+@@ -34,16 +34,6 @@
+ .setattr = sysfs_setattr,
+ };
+
+-void sysfs_delete_inode(struct inode *inode)
+-{
+- /* Free the shadowed directory inode operations */
+- if (sysfs_is_shadowed_inode(inode)) {
+- kfree(inode->i_op);
+- inode->i_op = NULL;
+- }
+- return generic_delete_inode(inode);
+-}
+-
+ int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
+ {
+ struct inode * inode = dentry->d_inode;
+@@ -133,10 +123,8 @@
*/
static struct lock_class_key sysfs_inode_imutex_key;
inode->i_blocks = 0;
inode->i_mapping->a_ops = &sysfs_aops;
inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
-@@ -151,169 +149,78 @@
+@@ -151,169 +139,81 @@
*/
set_inode_attr(inode, sd->s_iattr);
} else
- set_default_inode_attr(inode, mode);
- }
- return inode;
-+ set_default_inode_attr(inode, sd->s_mode);
- }
-
+-}
+-
-int sysfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *))
-{
- int error = 0;
- iput(inode);
- Done:
- return error;
--}
--
++ set_default_inode_attr(inode, sd->s_mode);
+ }
+
-/*
- * Get the name for corresponding element represented by the given sysfs_dirent
+/**
{
- struct dentry *dentry = NULL;
- struct inode *inode;
--
++ BUG_ON(!dentry || dentry->d_inode);
+
- /* We're not holding a reference to ->s_dentry dentry but the
- * field will stay valid as long as sysfs_lock is held.
- */
- spin_lock(&sysfs_lock);
- spin_lock(&dcache_lock);
-+ BUG_ON(!dentry || dentry->d_inode);
++ if (inode->i_state & I_NEW)
++ unlock_new_inode(inode);
- /* dget dentry if it's still alive */
- if (sd->s_dentry && sd->s_dentry->d_inode)
- spin_unlock(&dentry->d_lock);
- spin_unlock(&dcache_lock);
- }
-+ if (inode->i_state & I_NEW)
-+ unlock_new_inode(inode);
-
+-
- dput(dentry);
- }
+ d_instantiate(dentry, inode);
}
-int sysfs_hash_and_remove(struct dentry * dir, const char * name)
-+int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name)
++int sysfs_hash_and_remove(struct kobject *kobj, struct sysfs_dirent *dir_sd, const char *name)
{
- struct sysfs_dirent * sd;
- struct sysfs_dirent * parent_sd;
- if (dir->d_inode == NULL)
- /* no inode means this hasn't been made visible yet */
- return -ENOENT;
-+ sysfs_addrm_start(&acxt, dir_sd);
-+
-+ for (pos = &dir_sd->s_children; *pos; pos = &(*pos)->s_sibling) {
-+ sd = *pos;
- parent_sd = dir->d_fsdata;
- mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
- list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
- if (!sd->s_element)
++ sysfs_addrm_start(&acxt, dir_sd);
++ if (!sysfs_resolve_for_remove(kobj, &acxt.parent_sd))
++ goto addrm_finish;
++
++ for (pos = &acxt.parent_sd->s_children; *pos; pos = &(*pos)->s_sibling) {
++ sd = *pos;
++
+ if (!sysfs_type(sd))
continue;
- if (!strcmp(sysfs_get_name(sd), name)) {
}
}
- mutex_unlock(&dir->d_inode->i_mutex);
-
+-
- return found ? 0 : -ENOENT;
++addrm_finish:
+ if (sysfs_addrm_finish(&acxt))
+ return 0;
+ return -ENOENT;
}
diff -Nurb linux-2.6.22-570/fs/sysfs/mount.c linux-2.6.22-590/fs/sysfs/mount.c
---- linux-2.6.22-570/fs/sysfs/mount.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/sysfs/mount.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/sysfs/mount.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/sysfs/mount.c 2008-01-29 22:12:32.000000000 -0500
@@ -17,28 +17,18 @@
struct super_block * sysfs_sb = NULL;
struct kmem_cache *sysfs_dir_cachep;
-
static const struct super_operations sysfs_ops = {
.statfs = simple_statfs,
- .drop_inode = sysfs_delete_inode,
+- .drop_inode = sysfs_delete_inode,
- .clear_inode = sysfs_clear_inode,
++ .drop_inode = generic_delete_inode,
};
-static struct sysfs_dirent sysfs_root = {
root = d_alloc_root(inode);
if (!root) {
+@@ -69,6 +60,7 @@
+ iput(inode);
+ return -ENOMEM;
+ }
++ sysfs_root.s_dentry = root;
+ root->d_fsdata = &sysfs_root;
+ sb->s_root = root;
+ return 0;
diff -Nurb linux-2.6.22-570/fs/sysfs/symlink.c linux-2.6.22-590/fs/sysfs/symlink.c
--- linux-2.6.22-570/fs/sysfs/symlink.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/sysfs/symlink.c 2008-03-15 10:35:47.000000000 -0400
-@@ -11,71 +11,39 @@
++++ linux-2.6.22-590/fs/sysfs/symlink.c 2008-01-29 22:12:32.000000000 -0500
+@@ -11,71 +11,49 @@
#include "sysfs.h"
int depth = 0;
- do { depth++; } while ((p = p->parent));
+
-+ for (; sd->s_parent; sd = sd->s_parent)
++ for (; sd->s_parent; sd = sd->s_parent) {
++ if (sysfs_type(sd) == SYSFS_SHADOW_DIR)
++ continue;
+ depth++;
++ }
+
return depth;
}
- p = p->parent;
- } while (p);
+
-+ for (; sd->s_parent; sd = sd->s_parent)
++ for (; sd->s_parent; sd = sd->s_parent) {
++ if (sysfs_type(sd) == SYSFS_SHADOW_DIR)
++ continue;
+ length += strlen(sd->s_name) + 1;
++ }
+
return length;
}
{
- struct kobject * p;
-
++ int cur;
--length;
- for (p = kobj; p; p = p->parent) {
- int cur = strlen(kobject_name(p));
+ for (; sd->s_parent; sd = sd->s_parent) {
-+ int cur = strlen(sd->s_name);
++ if (sysfs_type(sd) == SYSFS_SHADOW_DIR)
++ continue;
++
++ cur = strlen(sd->s_name);
/* back up enough to print this bus id with '/' */
length -= cur;
/**
* sysfs_create_link - create symlink between two objects.
* @kobj: object whose directory we're creating the link in.
-@@ -84,24 +52,57 @@
+@@ -84,29 +62,80 @@
*/
int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name)
{
+ sd->s_elem.symlink.target_sd = target_sd;
+
+ sysfs_addrm_start(&acxt, parent_sd);
++ if (!sysfs_resolve_for_create(target, &acxt.parent_sd))
++ goto addrm_finish;
+
-+ if (!sysfs_find_dirent(parent_sd, name)) {
++ if (!sysfs_find_dirent(acxt.parent_sd, name)) {
+ sysfs_add_one(&acxt, sd);
+ sysfs_link_sibling(sd);
+ }
- if (!dentry)
- return -EFAULT;
++addrm_finish:
+ if (sysfs_addrm_finish(&acxt))
+ return 0;
return error;
}
-@@ -114,17 +115,17 @@
+
+ /**
++ * sysfs_delete_link - remove symlink in object's directory.
++ * @kobj: object we're acting for.
++ * @targ: object we're pointing to.
++ * @name: name of the symlink to remove.
++ *
++ * Unlike sysfs_remove_link sysfs_delete_link has enough information
++ * to successfully delete symlinks in shadow directories.
++ */
++void sysfs_delete_link(struct kobject *kobj, struct kobject *targ,
++ const char *name)
++{
++ sysfs_hash_and_remove(targ, kobj->sd, name);
++}
++
++/**
+ * sysfs_remove_link - remove symlink in object's directory.
+ * @kobj: object we're acting for.
+ * @name: name of the symlink to remove.
+@@ -114,17 +143,33 @@
void sysfs_remove_link(struct kobject * kobj, const char * name)
{
- sysfs_hash_and_remove(kobj->dentry,name);
-+ sysfs_hash_and_remove(kobj->sd, name);
++ sysfs_hash_and_remove(kobj, kobj->sd, name);
}
-static int sysfs_get_target_path(struct kobject * kobj, struct kobject * target,
- char *path)
++/**
++ * sysfs_rename_link - rename symlink in object's directory.
++ * @kobj: object we're acting for.
++ * @targ: object we're pointing to.
++ * @old: previous name of the symlink.
++ * @new: new name of the symlink.
++ *
++ * A helper function for the common rename symlink idiom.
++ */
++int sysfs_rename_link(struct kobject *kobj, struct kobject *targ,
++ const char *old, const char *new)
++{
++ sysfs_delete_link(kobj, targ, old);
++ return sysfs_create_link(kobj, targ, new);
++}
++
+static int sysfs_get_target_path(struct sysfs_dirent * parent_sd,
+ struct sysfs_dirent * target_sd, char *path)
{
if (size > PATH_MAX)
return -ENAMETOOLONG;
-@@ -133,7 +134,7 @@
+@@ -133,7 +178,7 @@
for (s = path; depth--; s += 3)
strcpy(s,"../");
pr_debug("%s: path = '%s'\n", __FUNCTION__, path);
return 0;
-@@ -141,27 +142,16 @@
+@@ -141,27 +186,16 @@
static int sysfs_getlink(struct dentry *dentry, char * path)
{
- kobject_put(kobj);
- return -EINVAL;
- }
--
-- down_read(&sysfs_rename_sem);
-- error = sysfs_get_target_path(kobj, target_kobj, path);
-- up_read(&sysfs_rename_sem);
+ struct sysfs_dirent *sd = dentry->d_fsdata;
+ struct sysfs_dirent *parent_sd = sd->s_parent;
+ struct sysfs_dirent *target_sd = sd->s_elem.symlink.target_sd;
+ mutex_lock(&sysfs_mutex);
+ error = sysfs_get_target_path(parent_sd, target_sd, path);
+ mutex_unlock(&sysfs_mutex);
-
+
+- down_read(&sysfs_rename_sem);
+- error = sysfs_get_target_path(kobj, target_kobj, path);
+- up_read(&sysfs_rename_sem);
+-
- kobject_put(kobj);
- kobject_put(target_kobj);
return error;
static void *sysfs_follow_link(struct dentry *dentry, struct nameidata *nd)
diff -Nurb linux-2.6.22-570/fs/sysfs/sysfs.h linux-2.6.22-590/fs/sysfs/sysfs.h
--- linux-2.6.22-570/fs/sysfs/sysfs.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/sysfs/sysfs.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/sysfs/sysfs.h 2008-01-29 22:12:32.000000000 -0500
@@ -1,9 +1,40 @@
+struct sysfs_elem_dir {
+ struct kobject * kobj;
umode_t s_mode;
ino_t s_ino;
struct dentry * s_dentry;
-@@ -11,30 +42,60 @@
+@@ -11,30 +42,77 @@
atomic_t s_event;
};
+ struct sysfs_dirent *removed;
+ int cnt;
+};
++
++/*
++ * A sysfs file which deletes another file when written to need to
++ * write lock the s_active of the victim while its s_active is read
++ * locked for the write operation. Tell lockdep that this is okay.
++ */
++enum sysfs_s_active_class
++{
++ SYSFS_S_ACTIVE_NORMAL, /* file r/w access, etc - default */
++ SYSFS_S_ACTIVE_DEACTIVATE, /* file deactivation */
++};
+
extern struct vfsmount * sysfs_mount;
+extern struct sysfs_dirent sysfs_root;
-extern void sysfs_delete_inode(struct inode *inode);
-extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *);
-extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
+-
+-extern int sysfs_dirent_exist(struct sysfs_dirent *, const unsigned char *);
+-extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *,
+- umode_t, int);
+-
+-extern int sysfs_add_file(struct dentry *, const struct attribute *, int);
+-extern int sysfs_hash_and_remove(struct dentry * dir, const char * name);
+extern struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd);
+extern void sysfs_link_sibling(struct sysfs_dirent *sd);
+extern void sysfs_unlink_sibling(struct sysfs_dirent *sd);
++
++extern int sysfs_resolve_for_create(struct kobject *kobj,
++ struct sysfs_dirent **parent_sd);
++extern int sysfs_resolve_for_remove(struct kobject *kobj,
++ struct sysfs_dirent **parent_sd);
++
+extern struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd);
+extern void sysfs_put_active(struct sysfs_dirent *sd);
+extern struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd);
+extern void sysfs_remove_one(struct sysfs_addrm_cxt *acxt,
+ struct sysfs_dirent *sd);
+extern int sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt);
-
--extern int sysfs_dirent_exist(struct sysfs_dirent *, const unsigned char *);
--extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *,
-- umode_t, int);
--
--extern int sysfs_add_file(struct dentry *, const struct attribute *, int);
--extern int sysfs_hash_and_remove(struct dentry * dir, const char * name);
-+extern void sysfs_delete_inode(struct inode *inode);
++
+extern void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode);
+extern struct inode * sysfs_get_inode(struct sysfs_dirent *sd);
+extern void sysfs_instantiate(struct dentry *dentry, struct inode *inode);
+
+extern int sysfs_add_file(struct sysfs_dirent *dir_sd,
+ const struct attribute *attr, int type);
-+extern int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name);
++extern int sysfs_hash_and_remove(struct kobject *kobj,
++ struct sysfs_dirent *dir_sd, const char *name);
extern struct sysfs_dirent *sysfs_find(struct sysfs_dirent *dir, const char * name);
-extern int sysfs_create_subdir(struct kobject *, const char *, struct dentry **);
extern struct super_block * sysfs_sb;
extern const struct file_operations sysfs_dir_operations;
extern const struct file_operations sysfs_file_operations;
-@@ -42,73 +103,9 @@
+@@ -42,73 +120,9 @@
extern const struct inode_operations sysfs_dir_inode_operations;
extern const struct inode_operations sysfs_symlink_inode_operations;
}
static inline struct sysfs_dirent * sysfs_get(struct sysfs_dirent * sd)
-@@ -122,7 +119,7 @@
+@@ -122,11 +136,6 @@
static inline void sysfs_put(struct sysfs_dirent * sd)
{
+ if (sd && atomic_dec_and_test(&sd->s_count))
release_sysfs_dirent(sd);
}
-
+-
+-static inline int sysfs_is_shadowed_inode(struct inode *inode)
+-{
+- return S_ISDIR(inode->i_mode) && inode->i_op->follow_link;
+-}
diff -Nurb linux-2.6.22-570/fs/unionfs/Makefile linux-2.6.22-590/fs/unionfs/Makefile
--- linux-2.6.22-570/fs/unionfs/Makefile 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/Makefile 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/Makefile 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,7 @@
+obj-$(CONFIG_UNION_FS) += unionfs.o
+
+unionfs-$(CONFIG_UNION_FS_XATTR) += xattr.o
diff -Nurb linux-2.6.22-570/fs/unionfs/commonfops.c linux-2.6.22-590/fs/unionfs/commonfops.c
--- linux-2.6.22-570/fs/unionfs/commonfops.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/commonfops.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/commonfops.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,748 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+}
diff -Nurb linux-2.6.22-570/fs/unionfs/copyup.c linux-2.6.22-590/fs/unionfs/copyup.c
--- linux-2.6.22-570/fs/unionfs/copyup.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/copyup.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/copyup.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,806 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+}
diff -Nurb linux-2.6.22-570/fs/unionfs/dentry.c linux-2.6.22-590/fs/unionfs/dentry.c
--- linux-2.6.22-570/fs/unionfs/dentry.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/dentry.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/dentry.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+};
diff -Nurb linux-2.6.22-570/fs/unionfs/dirfops.c linux-2.6.22-590/fs/unionfs/dirfops.c
--- linux-2.6.22-570/fs/unionfs/dirfops.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/dirfops.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/dirfops.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+};
diff -Nurb linux-2.6.22-570/fs/unionfs/dirhelper.c linux-2.6.22-590/fs/unionfs/dirhelper.c
--- linux-2.6.22-570/fs/unionfs/dirhelper.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/dirhelper.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/dirhelper.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+}
diff -Nurb linux-2.6.22-570/fs/unionfs/fanout.h linux-2.6.22-590/fs/unionfs/fanout.h
--- linux-2.6.22-570/fs/unionfs/fanout.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/fanout.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/fanout.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+#endif /* _FANOUT_H */
diff -Nurb linux-2.6.22-570/fs/unionfs/file.c linux-2.6.22-590/fs/unionfs/file.c
--- linux-2.6.22-570/fs/unionfs/file.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/file.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/file.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+};
diff -Nurb linux-2.6.22-570/fs/unionfs/inode.c linux-2.6.22-590/fs/unionfs/inode.c
--- linux-2.6.22-570/fs/unionfs/inode.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/inode.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/inode.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,1138 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+};
diff -Nurb linux-2.6.22-570/fs/unionfs/lookup.c linux-2.6.22-590/fs/unionfs/lookup.c
--- linux-2.6.22-570/fs/unionfs/lookup.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/lookup.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/lookup.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+}
diff -Nurb linux-2.6.22-570/fs/unionfs/main.c linux-2.6.22-590/fs/unionfs/main.c
--- linux-2.6.22-570/fs/unionfs/main.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/main.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/main.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,729 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+module_exit(exit_unionfs_fs);
diff -Nurb linux-2.6.22-570/fs/unionfs/mmap.c linux-2.6.22-590/fs/unionfs/mmap.c
--- linux-2.6.22-570/fs/unionfs/mmap.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/mmap.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/mmap.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,348 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+};
diff -Nurb linux-2.6.22-570/fs/unionfs/rdstate.c linux-2.6.22-590/fs/unionfs/rdstate.c
--- linux-2.6.22-570/fs/unionfs/rdstate.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/rdstate.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/rdstate.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+}
diff -Nurb linux-2.6.22-570/fs/unionfs/rename.c linux-2.6.22-590/fs/unionfs/rename.c
--- linux-2.6.22-570/fs/unionfs/rename.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/rename.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/rename.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,477 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+}
diff -Nurb linux-2.6.22-570/fs/unionfs/sioq.c linux-2.6.22-590/fs/unionfs/sioq.c
--- linux-2.6.22-570/fs/unionfs/sioq.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/sioq.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/sioq.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+}
diff -Nurb linux-2.6.22-570/fs/unionfs/sioq.h linux-2.6.22-590/fs/unionfs/sioq.h
--- linux-2.6.22-570/fs/unionfs/sioq.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/sioq.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/sioq.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+#endif /* _SIOQ_H */
diff -Nurb linux-2.6.22-570/fs/unionfs/subr.c linux-2.6.22-590/fs/unionfs/subr.c
--- linux-2.6.22-570/fs/unionfs/subr.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/subr.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/subr.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+}
diff -Nurb linux-2.6.22-570/fs/unionfs/super.c linux-2.6.22-590/fs/unionfs/super.c
--- linux-2.6.22-570/fs/unionfs/super.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/super.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/super.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,1002 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+};
diff -Nurb linux-2.6.22-570/fs/unionfs/union.h linux-2.6.22-590/fs/unionfs/union.h
--- linux-2.6.22-570/fs/unionfs/union.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/union.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/union.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,467 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+#endif /* not _UNION_H_ */
diff -Nurb linux-2.6.22-570/fs/unionfs/unlink.c linux-2.6.22-590/fs/unionfs/unlink.c
--- linux-2.6.22-570/fs/unionfs/unlink.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/unlink.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/unlink.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+}
diff -Nurb linux-2.6.22-570/fs/unionfs/xattr.c linux-2.6.22-590/fs/unionfs/xattr.c
--- linux-2.6.22-570/fs/unionfs/xattr.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/fs/unionfs/xattr.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/unionfs/xattr.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+}
diff -Nurb linux-2.6.22-570/fs/xfs/linux-2.6/xfs_file.c linux-2.6.22-590/fs/xfs/linux-2.6/xfs_file.c
--- linux-2.6.22-570/fs/xfs/linux-2.6/xfs_file.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/fs/xfs/linux-2.6/xfs_file.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/fs/xfs/linux-2.6/xfs_file.c 2008-01-29 22:12:32.000000000 -0500
@@ -246,18 +246,19 @@
#ifdef CONFIG_XFS_DMAPI
.mprotect = xfs_vm_mprotect,
#endif
diff -Nurb linux-2.6.22-570/fs/xfs/linux-2.6/xfs_super.c linux-2.6.22-590/fs/xfs/linux-2.6/xfs_super.c
---- linux-2.6.22-570/fs/xfs/linux-2.6/xfs_super.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/fs/xfs/linux-2.6/xfs_super.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/fs/xfs/linux-2.6/xfs_super.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/fs/xfs/linux-2.6/xfs_super.c 2008-01-29 22:12:32.000000000 -0500
@@ -570,6 +570,7 @@
bhv_vfs_sync_work_t *work, *n;
LIST_HEAD (tmp);
timeleft = schedule_timeout_interruptible(timeleft);
diff -Nurb linux-2.6.22-570/include/acpi/acmacros.h linux-2.6.22-590/include/acpi/acmacros.h
--- linux-2.6.22-570/include/acpi/acmacros.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/acpi/acmacros.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/acpi/acmacros.h 2008-01-29 22:12:32.000000000 -0500
@@ -486,6 +486,8 @@
#define ACPI_FUNCTION_NAME(name)
#endif
#define ACPI_DEBUG_EXEC(a) a
diff -Nurb linux-2.6.22-570/include/acpi/acoutput.h linux-2.6.22-590/include/acpi/acoutput.h
--- linux-2.6.22-570/include/acpi/acoutput.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/acpi/acoutput.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/acpi/acoutput.h 2008-01-29 22:12:32.000000000 -0500
@@ -178,8 +178,8 @@
/* Defaults for debug_level, debug and normal */
#endif /* __ACOUTPUT_H__ */
diff -Nurb linux-2.6.22-570/include/acpi/platform/acenv.h linux-2.6.22-590/include/acpi/platform/acenv.h
--- linux-2.6.22-570/include/acpi/platform/acenv.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/acpi/platform/acenv.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/acpi/platform/acenv.h 2008-01-29 22:12:32.000000000 -0500
@@ -136,7 +136,7 @@
/*! [Begin] no source code translation */
#elif defined(_AED_EFI)
diff -Nurb linux-2.6.22-570/include/acpi/platform/aclinux.h linux-2.6.22-590/include/acpi/platform/aclinux.h
--- linux-2.6.22-570/include/acpi/platform/aclinux.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/acpi/platform/aclinux.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/acpi/platform/aclinux.h 2008-01-29 22:12:32.000000000 -0500
@@ -91,7 +91,10 @@
#define ACPI_USE_NATIVE_DIVIDE
#endif
#endif /* __KERNEL__ */
diff -Nurb linux-2.6.22-570/include/acpi/processor.h linux-2.6.22-590/include/acpi/processor.h
---- linux-2.6.22-570/include/acpi/processor.h 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/include/acpi/processor.h 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/include/acpi/processor.h 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/include/acpi/processor.h 2008-01-29 22:12:32.000000000 -0500
@@ -21,6 +21,8 @@
#define ACPI_PSD_REV0_REVISION 0 /* Support for _PSD as in ACPI 3.0 */
#define ACPI_PSD_REV0_ENTRIES 5
diff -Nurb linux-2.6.22-570/include/asm-alpha/page.h linux-2.6.22-590/include/asm-alpha/page.h
--- linux-2.6.22-570/include/asm-alpha/page.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-alpha/page.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-alpha/page.h 2008-01-29 22:12:32.000000000 -0500
@@ -17,7 +17,8 @@
extern void clear_page(void *page);
#define clear_user_page(page, vaddr, pg) clear_page(page)
extern void copy_page(void * _to, void * _from);
diff -Nurb linux-2.6.22-570/include/asm-arm/arch-iop13xx/adma.h linux-2.6.22-590/include/asm-arm/arch-iop13xx/adma.h
--- linux-2.6.22-570/include/asm-arm/arch-iop13xx/adma.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/asm-arm/arch-iop13xx/adma.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-arm/arch-iop13xx/adma.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,544 @@
+/*
+ * Copyright(c) 2006, Intel Corporation.
+#endif /* _ADMA_H */
diff -Nurb linux-2.6.22-570/include/asm-arm/arch-iop13xx/iop13xx.h linux-2.6.22-590/include/asm-arm/arch-iop13xx/iop13xx.h
--- linux-2.6.22-570/include/asm-arm/arch-iop13xx/iop13xx.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-arm/arch-iop13xx/iop13xx.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-arm/arch-iop13xx/iop13xx.h 2008-01-29 22:12:32.000000000 -0500
@@ -166,12 +166,22 @@
#define IOP13XX_INIT_I2C_1 (1 << 1)
#define IOP13XX_INIT_I2C_2 (1 << 2)
#define IOP13XX_XBG_BECSR IOP13XX_REG_ADDR32(0x178c)
diff -Nurb linux-2.6.22-570/include/asm-arm/arch-iop32x/adma.h linux-2.6.22-590/include/asm-arm/arch-iop32x/adma.h
--- linux-2.6.22-570/include/asm-arm/arch-iop32x/adma.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/asm-arm/arch-iop32x/adma.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-arm/arch-iop32x/adma.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,5 @@
+#ifndef IOP32X_ADMA_H
+#define IOP32X_ADMA_H
+
diff -Nurb linux-2.6.22-570/include/asm-arm/arch-iop33x/adma.h linux-2.6.22-590/include/asm-arm/arch-iop33x/adma.h
--- linux-2.6.22-570/include/asm-arm/arch-iop33x/adma.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/asm-arm/arch-iop33x/adma.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-arm/arch-iop33x/adma.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,5 @@
+#ifndef IOP33X_ADMA_H
+#define IOP33X_ADMA_H
+
diff -Nurb linux-2.6.22-570/include/asm-arm/hardware/iop3xx-adma.h linux-2.6.22-590/include/asm-arm/hardware/iop3xx-adma.h
--- linux-2.6.22-570/include/asm-arm/hardware/iop3xx-adma.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/asm-arm/hardware/iop3xx-adma.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-arm/hardware/iop3xx-adma.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,891 @@
+/*
+ * Copyright © 2006, Intel Corporation.
+#endif /* _ADMA_H */
diff -Nurb linux-2.6.22-570/include/asm-arm/hardware/iop3xx.h linux-2.6.22-590/include/asm-arm/hardware/iop3xx.h
--- linux-2.6.22-570/include/asm-arm/hardware/iop3xx.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-arm/hardware/iop3xx.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-arm/hardware/iop3xx.h 2008-01-29 22:12:32.000000000 -0500
@@ -144,24 +144,9 @@
#define IOP3XX_IAR (volatile u32 *)IOP3XX_REG_ADDR(0x0380)
diff -Nurb linux-2.6.22-570/include/asm-arm/hardware/iop_adma.h linux-2.6.22-590/include/asm-arm/hardware/iop_adma.h
--- linux-2.6.22-570/include/asm-arm/hardware/iop_adma.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/asm-arm/hardware/iop_adma.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-arm/hardware/iop_adma.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,120 @@
+/*
+ * Copyright © 2006, Intel Corporation.
+#endif
diff -Nurb linux-2.6.22-570/include/asm-arm/kgdb.h linux-2.6.22-590/include/asm-arm/kgdb.h
--- linux-2.6.22-570/include/asm-arm/kgdb.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/asm-arm/kgdb.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-arm/kgdb.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,103 @@
+/*
+ * include/asm-arm/kgdb.h
+#endif /* __ASM_KGDB_H__ */
diff -Nurb linux-2.6.22-570/include/asm-arm/system.h linux-2.6.22-590/include/asm-arm/system.h
--- linux-2.6.22-570/include/asm-arm/system.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-arm/system.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-arm/system.h 2008-01-29 22:12:32.000000000 -0500
@@ -360,6 +360,41 @@
extern void disable_hlt(void);
extern void enable_hlt(void);
#define arch_align_stack(x) (x)
diff -Nurb linux-2.6.22-570/include/asm-cris/page.h linux-2.6.22-590/include/asm-cris/page.h
--- linux-2.6.22-570/include/asm-cris/page.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-cris/page.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-cris/page.h 2008-01-29 22:12:32.000000000 -0500
@@ -20,7 +20,8 @@
#define clear_user_page(page, vaddr, pg) clear_page(page)
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
/*
diff -Nurb linux-2.6.22-570/include/asm-generic/kgdb.h linux-2.6.22-590/include/asm-generic/kgdb.h
--- linux-2.6.22-570/include/asm-generic/kgdb.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/asm-generic/kgdb.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-generic/kgdb.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,100 @@
+/*
+ * include/asm-generic/kgdb.h
+#endif /* __ASM_GENERIC_KGDB_H__ */
diff -Nurb linux-2.6.22-570/include/asm-generic/vmlinux.lds.h linux-2.6.22-590/include/asm-generic/vmlinux.lds.h
--- linux-2.6.22-570/include/asm-generic/vmlinux.lds.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-generic/vmlinux.lds.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-generic/vmlinux.lds.h 2008-01-29 22:12:32.000000000 -0500
@@ -127,6 +127,8 @@
*(__ksymtab_strings) \
} \
the beginning of the section so we begin them at 0. */
diff -Nurb linux-2.6.22-570/include/asm-h8300/page.h linux-2.6.22-590/include/asm-h8300/page.h
--- linux-2.6.22-570/include/asm-h8300/page.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-h8300/page.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-h8300/page.h 2008-01-29 22:12:32.000000000 -0500
@@ -22,7 +22,8 @@
#define clear_user_page(page, vaddr, pg) clear_page(page)
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
/*
diff -Nurb linux-2.6.22-570/include/asm-i386/kdebug.h linux-2.6.22-590/include/asm-i386/kdebug.h
--- linux-2.6.22-570/include/asm-i386/kdebug.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-i386/kdebug.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-i386/kdebug.h 2008-01-29 22:12:32.000000000 -0500
@@ -28,6 +28,7 @@
DIE_CALL,
DIE_NMI_IPI,
#endif
diff -Nurb linux-2.6.22-570/include/asm-i386/kgdb.h linux-2.6.22-590/include/asm-i386/kgdb.h
--- linux-2.6.22-570/include/asm-i386/kgdb.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/asm-i386/kgdb.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-i386/kgdb.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,51 @@
+#ifdef __KERNEL__
+#ifndef _ASM_KGDB_H_
+#endif /* __KERNEL__ */
diff -Nurb linux-2.6.22-570/include/asm-i386/page.h linux-2.6.22-590/include/asm-i386/page.h
--- linux-2.6.22-570/include/asm-i386/page.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-i386/page.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-i386/page.h 2008-01-29 22:12:32.000000000 -0500
@@ -34,7 +34,8 @@
#define clear_user_page(page, vaddr, pg) clear_page(page)
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
/*
diff -Nurb linux-2.6.22-570/include/asm-i386/unistd.h linux-2.6.22-590/include/asm-i386/unistd.h
--- linux-2.6.22-570/include/asm-i386/unistd.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-i386/unistd.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-i386/unistd.h 2008-01-29 22:12:32.000000000 -0500
@@ -329,10 +329,13 @@
#define __NR_signalfd 321
#define __NR_timerfd 322
#define __ARCH_WANT_OLD_READDIR
diff -Nurb linux-2.6.22-570/include/asm-i386/unwind.h linux-2.6.22-590/include/asm-i386/unwind.h
--- linux-2.6.22-570/include/asm-i386/unwind.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-i386/unwind.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-i386/unwind.h 2008-01-29 22:12:32.000000000 -0500
@@ -1,6 +1,95 @@
#ifndef _ASM_I386_UNWIND_H
#define _ASM_I386_UNWIND_H
#endif /* _ASM_I386_UNWIND_H */
diff -Nurb linux-2.6.22-570/include/asm-ia64/kdebug.h linux-2.6.22-590/include/asm-ia64/kdebug.h
--- linux-2.6.22-570/include/asm-ia64/kdebug.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-ia64/kdebug.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-ia64/kdebug.h 2008-01-29 22:12:32.000000000 -0500
@@ -69,6 +69,7 @@
DIE_KDEBUG_LEAVE,
DIE_KDUMP_ENTER,
#endif
diff -Nurb linux-2.6.22-570/include/asm-ia64/kgdb.h linux-2.6.22-590/include/asm-ia64/kgdb.h
--- linux-2.6.22-570/include/asm-ia64/kgdb.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/asm-ia64/kgdb.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-ia64/kgdb.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,37 @@
+#ifdef __KERNEL__
+#ifndef _ASM_KGDB_H_
+#endif /* __KERNEL__ */
diff -Nurb linux-2.6.22-570/include/asm-ia64/page.h linux-2.6.22-590/include/asm-ia64/page.h
--- linux-2.6.22-570/include/asm-ia64/page.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-ia64/page.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-ia64/page.h 2008-01-29 22:12:32.000000000 -0500
@@ -87,9 +87,10 @@
} while (0)
page; \
diff -Nurb linux-2.6.22-570/include/asm-ia64/processor.h linux-2.6.22-590/include/asm-ia64/processor.h
--- linux-2.6.22-570/include/asm-ia64/processor.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-ia64/processor.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-ia64/processor.h 2008-01-29 22:12:32.000000000 -0500
@@ -295,9 +295,9 @@
regs->ar_bspstore = current->thread.rbs_bot; \
regs->ar_fpsr = FPSR_DEFAULT; \
* uid/privileges. \
diff -Nurb linux-2.6.22-570/include/asm-m32r/page.h linux-2.6.22-590/include/asm-m32r/page.h
--- linux-2.6.22-570/include/asm-m32r/page.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-m32r/page.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-m32r/page.h 2008-01-29 22:12:32.000000000 -0500
@@ -15,7 +15,8 @@
#define clear_user_page(page, vaddr, pg) clear_page(page)
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
/*
diff -Nurb linux-2.6.22-570/include/asm-m68knommu/page.h linux-2.6.22-590/include/asm-m68knommu/page.h
--- linux-2.6.22-570/include/asm-m68knommu/page.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-m68knommu/page.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-m68knommu/page.h 2008-01-29 22:12:32.000000000 -0500
@@ -22,7 +22,8 @@
#define clear_user_page(page, vaddr, pg) clear_page(page)
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
/*
diff -Nurb linux-2.6.22-570/include/asm-mips/asmmacro-32.h linux-2.6.22-590/include/asm-mips/asmmacro-32.h
--- linux-2.6.22-570/include/asm-mips/asmmacro-32.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-mips/asmmacro-32.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-mips/asmmacro-32.h 2008-01-29 22:12:32.000000000 -0500
@@ -11,6 +11,28 @@
#include <asm/regdef.h>
#include <asm/fpregdef.h>
lwc1 $f0, THREAD_FPR0(\thread)
diff -Nurb linux-2.6.22-570/include/asm-mips/asmmacro-64.h linux-2.6.22-590/include/asm-mips/asmmacro-64.h
--- linux-2.6.22-570/include/asm-mips/asmmacro-64.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-mips/asmmacro-64.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-mips/asmmacro-64.h 2008-01-29 22:12:32.000000000 -0500
@@ -12,6 +12,7 @@
#include <asm/regdef.h>
#include <asm/fpregdef.h>
LONG_S s1, THREAD_REG17(\thread)
diff -Nurb linux-2.6.22-570/include/asm-mips/kdebug.h linux-2.6.22-590/include/asm-mips/kdebug.h
--- linux-2.6.22-570/include/asm-mips/kdebug.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-mips/kdebug.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-mips/kdebug.h 2008-01-29 22:12:32.000000000 -0500
@@ -1 +1,30 @@
-#include <asm-generic/kdebug.h>
+/*
+#endif /* _MIPS_KDEBUG_H */
diff -Nurb linux-2.6.22-570/include/asm-mips/kgdb.h linux-2.6.22-590/include/asm-mips/kgdb.h
--- linux-2.6.22-570/include/asm-mips/kgdb.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/asm-mips/kgdb.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-mips/kgdb.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,41 @@
+#ifdef __KERNEL__
+#ifndef _ASM_KGDB_H_
+#endif /* __KERNEL__ */
diff -Nurb linux-2.6.22-570/include/asm-mips/ptrace.h linux-2.6.22-590/include/asm-mips/ptrace.h
--- linux-2.6.22-570/include/asm-mips/ptrace.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-mips/ptrace.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-mips/ptrace.h 2008-01-29 22:12:32.000000000 -0500
@@ -28,7 +28,7 @@
* system call/exception. As usual the registers k0/k1 aren't being saved.
*/
#endif
diff -Nurb linux-2.6.22-570/include/asm-powerpc/cputable.h linux-2.6.22-590/include/asm-powerpc/cputable.h
--- linux-2.6.22-570/include/asm-powerpc/cputable.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-powerpc/cputable.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-powerpc/cputable.h 2008-01-29 22:12:32.000000000 -0500
@@ -111,7 +111,7 @@
/* CPU kernel features */
#ifdef __powerpc64__
diff -Nurb linux-2.6.22-570/include/asm-powerpc/floppy.h linux-2.6.22-590/include/asm-powerpc/floppy.h
--- linux-2.6.22-570/include/asm-powerpc/floppy.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-powerpc/floppy.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-powerpc/floppy.h 2008-01-29 22:12:32.000000000 -0500
@@ -29,7 +29,7 @@
#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL);
prev_addr = addr;
diff -Nurb linux-2.6.22-570/include/asm-powerpc/io.h linux-2.6.22-590/include/asm-powerpc/io.h
--- linux-2.6.22-570/include/asm-powerpc/io.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-powerpc/io.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-powerpc/io.h 2008-01-29 22:12:32.000000000 -0500
@@ -607,9 +607,9 @@
*
* * iounmap undoes such a mapping and can be hooked
#define mmio_read32be(addr) readl_be(addr)
diff -Nurb linux-2.6.22-570/include/asm-powerpc/kgdb.h linux-2.6.22-590/include/asm-powerpc/kgdb.h
--- linux-2.6.22-570/include/asm-powerpc/kgdb.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/asm-powerpc/kgdb.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-powerpc/kgdb.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,75 @@
+/*
+ * include/asm-powerpc/kgdb.h
+#endif /* __KERNEL__ */
diff -Nurb linux-2.6.22-570/include/asm-powerpc/lppaca.h linux-2.6.22-590/include/asm-powerpc/lppaca.h
--- linux-2.6.22-570/include/asm-powerpc/lppaca.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-powerpc/lppaca.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-powerpc/lppaca.h 2008-01-29 22:12:32.000000000 -0500
@@ -98,7 +98,7 @@
u64 saved_gpr5; // Saved GPR5 x30-x37
volatile u32 saved_decr; // Saved Decr Value x3C-x3F
diff -Nurb linux-2.6.22-570/include/asm-powerpc/mmu-hash32.h linux-2.6.22-590/include/asm-powerpc/mmu-hash32.h
--- linux-2.6.22-570/include/asm-powerpc/mmu-hash32.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/asm-powerpc/mmu-hash32.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-powerpc/mmu-hash32.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,91 @@
+#ifndef _ASM_POWERPC_MMU_HASH32_H_
+#define _ASM_POWERPC_MMU_HASH32_H_
+#endif /* _ASM_POWERPC_MMU_HASH32_H_ */
diff -Nurb linux-2.6.22-570/include/asm-powerpc/mmu-hash64.h linux-2.6.22-590/include/asm-powerpc/mmu-hash64.h
--- linux-2.6.22-570/include/asm-powerpc/mmu-hash64.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-powerpc/mmu-hash64.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-powerpc/mmu-hash64.h 2008-01-29 22:12:32.000000000 -0500
@@ -103,12 +103,12 @@
#ifndef __ASSEMBLY__
diff -Nurb linux-2.6.22-570/include/asm-powerpc/mmu.h linux-2.6.22-590/include/asm-powerpc/mmu.h
--- linux-2.6.22-570/include/asm-powerpc/mmu.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-powerpc/mmu.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-powerpc/mmu.h 2008-01-29 22:12:32.000000000 -0500
@@ -5,6 +5,9 @@
#ifdef CONFIG_PPC64
/* 64-bit classic hash table MMU */
# include <asm/mmu-44x.h>
diff -Nurb linux-2.6.22-570/include/asm-powerpc/pci-bridge.h linux-2.6.22-590/include/asm-powerpc/pci-bridge.h
--- linux-2.6.22-570/include/asm-powerpc/pci-bridge.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-powerpc/pci-bridge.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-powerpc/pci-bridge.h 2008-01-29 22:12:32.000000000 -0500
@@ -31,6 +31,7 @@
int last_busno;
#define PCI_PROBE_NORMAL 0 /* Do normal PCI probing */
diff -Nurb linux-2.6.22-570/include/asm-powerpc/pci.h linux-2.6.22-590/include/asm-powerpc/pci.h
--- linux-2.6.22-570/include/asm-powerpc/pci.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-powerpc/pci.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-powerpc/pci.h 2008-01-29 22:12:32.000000000 -0500
@@ -220,10 +220,6 @@
return root;
}
diff -Nurb linux-2.6.22-570/include/asm-powerpc/pgtable-ppc32.h linux-2.6.22-590/include/asm-powerpc/pgtable-ppc32.h
--- linux-2.6.22-570/include/asm-powerpc/pgtable-ppc32.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-powerpc/pgtable-ppc32.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-powerpc/pgtable-ppc32.h 2008-01-29 22:12:32.000000000 -0500
@@ -6,11 +6,7 @@
#ifndef __ASSEMBLY__
#include <linux/sched.h>
*/
diff -Nurb linux-2.6.22-570/include/asm-powerpc/pgtable-ppc64.h linux-2.6.22-590/include/asm-powerpc/pgtable-ppc64.h
--- linux-2.6.22-570/include/asm-powerpc/pgtable-ppc64.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-powerpc/pgtable-ppc64.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-powerpc/pgtable-ppc64.h 2008-01-29 22:12:32.000000000 -0500
@@ -7,11 +7,7 @@
#ifndef __ASSEMBLY__
/*
diff -Nurb linux-2.6.22-570/include/asm-powerpc/pgtable.h linux-2.6.22-590/include/asm-powerpc/pgtable.h
--- linux-2.6.22-570/include/asm-powerpc/pgtable.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-powerpc/pgtable.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-powerpc/pgtable.h 2008-01-29 22:12:32.000000000 -0500
@@ -2,6 +2,13 @@
#define _ASM_POWERPC_PGTABLE_H
#ifdef __KERNEL__
diff -Nurb linux-2.6.22-570/include/asm-powerpc/ppc-pci.h linux-2.6.22-590/include/asm-powerpc/ppc-pci.h
--- linux-2.6.22-570/include/asm-powerpc/ppc-pci.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-powerpc/ppc-pci.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-powerpc/ppc-pci.h 2008-01-29 22:12:32.000000000 -0500
@@ -26,7 +26,7 @@
extern void find_and_init_phbs(void);
#else /* CONFIG_PCI */
diff -Nurb linux-2.6.22-570/include/asm-powerpc/ptrace.h linux-2.6.22-590/include/asm-powerpc/ptrace.h
--- linux-2.6.22-570/include/asm-powerpc/ptrace.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-powerpc/ptrace.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-powerpc/ptrace.h 2008-01-29 22:12:32.000000000 -0500
@@ -92,6 +92,11 @@
set_thread_flag(TIF_NOERROR); \
} while(0)
#define PPC_PTRACE_GETFPREGS 0x97 /* Get FPRs 0 - 31 */
diff -Nurb linux-2.6.22-570/include/asm-powerpc/syscalls.h linux-2.6.22-590/include/asm-powerpc/syscalls.h
--- linux-2.6.22-570/include/asm-powerpc/syscalls.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-powerpc/syscalls.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-powerpc/syscalls.h 2008-01-29 22:12:32.000000000 -0500
@@ -43,16 +43,9 @@
asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset,
#endif /* __KERNEL__ */
#endif /* __ASM_POWERPC_SYSCALLS_H */
diff -Nurb linux-2.6.22-570/include/asm-powerpc/systbl.h linux-2.6.22-590/include/asm-powerpc/systbl.h
---- linux-2.6.22-570/include/asm-powerpc/systbl.h 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/include/asm-powerpc/systbl.h 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/include/asm-powerpc/systbl.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/asm-powerpc/systbl.h 2008-01-29 22:12:32.000000000 -0500
@@ -312,3 +312,4 @@
COMPAT_SYS_SPU(timerfd)
SYSCALL_SPU(eventfd)
+COMPAT_SYS(fallocate)
diff -Nurb linux-2.6.22-570/include/asm-powerpc/thread_info.h linux-2.6.22-590/include/asm-powerpc/thread_info.h
--- linux-2.6.22-570/include/asm-powerpc/thread_info.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-powerpc/thread_info.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-powerpc/thread_info.h 2008-01-29 22:12:32.000000000 -0500
@@ -113,8 +113,8 @@
#define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling
TIF_NEED_RESCHED */
#define _TIF_USER_WORK_MASK (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
diff -Nurb linux-2.6.22-570/include/asm-powerpc/tlbflush.h linux-2.6.22-590/include/asm-powerpc/tlbflush.h
--- linux-2.6.22-570/include/asm-powerpc/tlbflush.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-powerpc/tlbflush.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-powerpc/tlbflush.h 2008-01-29 22:12:32.000000000 -0500
@@ -155,6 +155,11 @@
{
}
/*
diff -Nurb linux-2.6.22-570/include/asm-powerpc/unistd.h linux-2.6.22-590/include/asm-powerpc/unistd.h
---- linux-2.6.22-570/include/asm-powerpc/unistd.h 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/include/asm-powerpc/unistd.h 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/include/asm-powerpc/unistd.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/asm-powerpc/unistd.h 2008-01-29 22:12:32.000000000 -0500
@@ -331,10 +331,11 @@
#define __NR_timerfd 306
#define __NR_eventfd 307
#define NR_syscalls __NR_syscalls
diff -Nurb linux-2.6.22-570/include/asm-ppc/kgdb.h linux-2.6.22-590/include/asm-ppc/kgdb.h
--- linux-2.6.22-570/include/asm-ppc/kgdb.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-ppc/kgdb.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-ppc/kgdb.h 2008-01-29 22:12:32.000000000 -0500
@@ -1,57 +1,18 @@
-/*
- * kgdb.h: Defines and declarations for serial line source level
#endif /* __KERNEL__ */
diff -Nurb linux-2.6.22-570/include/asm-ppc/machdep.h linux-2.6.22-590/include/asm-ppc/machdep.h
--- linux-2.6.22-570/include/asm-ppc/machdep.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-ppc/machdep.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-ppc/machdep.h 2008-01-29 22:12:32.000000000 -0500
@@ -72,9 +72,7 @@
unsigned long (*find_end_of_memory)(void);
void (*setup_io_mappings)(void);
void (*nvram_write_val)(int addr, unsigned char val);
diff -Nurb linux-2.6.22-570/include/asm-ppc/mv64x60.h linux-2.6.22-590/include/asm-ppc/mv64x60.h
--- linux-2.6.22-570/include/asm-ppc/mv64x60.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-ppc/mv64x60.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-ppc/mv64x60.h 2008-01-29 22:12:32.000000000 -0500
@@ -348,6 +348,8 @@
void mv64x60_progress_init(u32 base);
gt64260_32bit_windows[MV64x60_32BIT_WIN_COUNT];
diff -Nurb linux-2.6.22-570/include/asm-ppc/mv64x60_defs.h linux-2.6.22-590/include/asm-ppc/mv64x60_defs.h
--- linux-2.6.22-570/include/asm-ppc/mv64x60_defs.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-ppc/mv64x60_defs.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-ppc/mv64x60_defs.h 2008-01-29 22:12:32.000000000 -0500
@@ -57,7 +57,8 @@
#define MV64x60_IRQ_I2C 37
#define MV64x60_IRQ_BRG 39
#define MV64x60_IRQ_P0_GPP_8_15 57
diff -Nurb linux-2.6.22-570/include/asm-s390/page.h linux-2.6.22-590/include/asm-s390/page.h
--- linux-2.6.22-570/include/asm-s390/page.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-s390/page.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-s390/page.h 2008-01-29 22:12:32.000000000 -0500
@@ -64,7 +64,8 @@
#define clear_user_page(page, vaddr, pg) clear_page(page)
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
/*
diff -Nurb linux-2.6.22-570/include/asm-sh/kgdb.h linux-2.6.22-590/include/asm-sh/kgdb.h
--- linux-2.6.22-570/include/asm-sh/kgdb.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-sh/kgdb.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-sh/kgdb.h 2008-01-29 22:12:32.000000000 -0500
@@ -2,78 +2,41 @@
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
#endif
diff -Nurb linux-2.6.22-570/include/asm-sh/system.h linux-2.6.22-590/include/asm-sh/system.h
--- linux-2.6.22-570/include/asm-sh/system.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-sh/system.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-sh/system.h 2008-01-29 22:12:32.000000000 -0500
@@ -264,6 +264,45 @@
#define instruction_size(insn) (2)
#endif
*/
diff -Nurb linux-2.6.22-570/include/asm-um/thread_info.h linux-2.6.22-590/include/asm-um/thread_info.h
--- linux-2.6.22-570/include/asm-um/thread_info.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-um/thread_info.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-um/thread_info.h 2008-01-29 22:12:32.000000000 -0500
@@ -52,10 +52,21 @@
return ti;
}
diff -Nurb linux-2.6.22-570/include/asm-x86_64/kdebug.h linux-2.6.22-590/include/asm-x86_64/kdebug.h
--- linux-2.6.22-570/include/asm-x86_64/kdebug.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-x86_64/kdebug.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-x86_64/kdebug.h 2008-01-29 22:12:32.000000000 -0500
@@ -23,6 +23,7 @@
DIE_CALL,
DIE_NMI_IPI,
extern void printk_address(unsigned long address);
diff -Nurb linux-2.6.22-570/include/asm-x86_64/kgdb.h linux-2.6.22-590/include/asm-x86_64/kgdb.h
--- linux-2.6.22-570/include/asm-x86_64/kgdb.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/asm-x86_64/kgdb.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-x86_64/kgdb.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,52 @@
+#ifdef __KERNEL__
+#ifndef _ASM_KGDB_H_
+#endif /* __KERNEL__ */
diff -Nurb linux-2.6.22-570/include/asm-x86_64/page.h linux-2.6.22-590/include/asm-x86_64/page.h
--- linux-2.6.22-570/include/asm-x86_64/page.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-x86_64/page.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-x86_64/page.h 2008-01-29 22:12:32.000000000 -0500
@@ -48,7 +48,8 @@
#define clear_user_page(page, vaddr, pg) clear_page(page)
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
* These are used to make use of C type-checking..
diff -Nurb linux-2.6.22-570/include/asm-x86_64/proto.h linux-2.6.22-590/include/asm-x86_64/proto.h
--- linux-2.6.22-570/include/asm-x86_64/proto.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-x86_64/proto.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-x86_64/proto.h 2008-01-29 22:12:32.000000000 -0500
@@ -75,8 +75,6 @@
extern void early_quirks(void);
extern void check_efer(void);
extern unsigned long table_start, table_end;
diff -Nurb linux-2.6.22-570/include/asm-x86_64/system.h linux-2.6.22-590/include/asm-x86_64/system.h
--- linux-2.6.22-570/include/asm-x86_64/system.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-x86_64/system.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-x86_64/system.h 2008-01-29 22:12:32.000000000 -0500
@@ -22,7 +22,9 @@
/* Save restore flags to clear handle leaking NT */
: [next] "S" (next), [prev] "D" (prev), \
[threadrsp] "i" (offsetof(struct task_struct, thread.rsp)), \
diff -Nurb linux-2.6.22-570/include/asm-x86_64/unistd.h linux-2.6.22-590/include/asm-x86_64/unistd.h
---- linux-2.6.22-570/include/asm-x86_64/unistd.h 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/include/asm-x86_64/unistd.h 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/include/asm-x86_64/unistd.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/asm-x86_64/unistd.h 2008-01-29 22:12:32.000000000 -0500
@@ -630,6 +630,8 @@
__SYSCALL(__NR_timerfd, sys_timerfd)
#define __NR_eventfd 284
#define __ARCH_WANT_OLD_READDIR
diff -Nurb linux-2.6.22-570/include/asm-x86_64/unwind.h linux-2.6.22-590/include/asm-x86_64/unwind.h
--- linux-2.6.22-570/include/asm-x86_64/unwind.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/asm-x86_64/unwind.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/asm-x86_64/unwind.h 2008-01-29 22:12:32.000000000 -0500
@@ -1,6 +1,100 @@
#ifndef _ASM_X86_64_UNWIND_H
#define _ASM_X86_64_UNWIND_H
+
#endif /* _ASM_X86_64_UNWIND_H */
diff -Nurb linux-2.6.22-570/include/linux/Kbuild linux-2.6.22-590/include/linux/Kbuild
---- linux-2.6.22-570/include/linux/Kbuild 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/include/linux/Kbuild 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/include/linux/Kbuild 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/linux/Kbuild 2008-01-29 22:12:32.000000000 -0500
@@ -91,7 +91,6 @@
header-y += in_route.h
header-y += ioctl.h
header-y += irda.h
diff -Nurb linux-2.6.22-570/include/linux/acpi.h linux-2.6.22-590/include/linux/acpi.h
--- linux-2.6.22-570/include/linux/acpi.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/acpi.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/acpi.h 2008-01-29 22:12:32.000000000 -0500
@@ -206,11 +206,8 @@
{
return max_cstate;
static inline void acpi_set_cstate_limit(unsigned int new_limit) { return; }
diff -Nurb linux-2.6.22-570/include/linux/async_tx.h linux-2.6.22-590/include/linux/async_tx.h
--- linux-2.6.22-570/include/linux/async_tx.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/linux/async_tx.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/async_tx.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,156 @@
+/*
+ * Copyright © 2006, Intel Corporation.
+#endif /* _ASYNC_TX_H_ */
diff -Nurb linux-2.6.22-570/include/linux/configfs.h linux-2.6.22-590/include/linux/configfs.h
--- linux-2.6.22-570/include/linux/configfs.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/configfs.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/configfs.h 2008-01-29 22:12:32.000000000 -0500
@@ -75,7 +75,6 @@
extern void config_item_init_type_name(struct config_item *item,
const char *name,
#endif /* _CONFIGFS_H_ */
diff -Nurb linux-2.6.22-570/include/linux/container.h linux-2.6.22-590/include/linux/container.h
--- linux-2.6.22-570/include/linux/container.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/linux/container.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/container.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,295 @@
+#ifndef _LINUX_CONTAINER_H
+#define _LINUX_CONTAINER_H
+#endif /* _LINUX_CONTAINER_H */
diff -Nurb linux-2.6.22-570/include/linux/container_subsys.h linux-2.6.22-590/include/linux/container_subsys.h
--- linux-2.6.22-570/include/linux/container_subsys.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/linux/container_subsys.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/container_subsys.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,32 @@
+/* Add subsystem definitions of the form SUBSYS(<name>) in this
+ * file. Surround each one by a line of comment markers so that
+/* */
diff -Nurb linux-2.6.22-570/include/linux/cpu_acct.h linux-2.6.22-590/include/linux/cpu_acct.h
--- linux-2.6.22-570/include/linux/cpu_acct.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/linux/cpu_acct.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/cpu_acct.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,14 @@
+
+#ifndef _LINUX_CPU_ACCT_H
+#endif
diff -Nurb linux-2.6.22-570/include/linux/cpuidle.h linux-2.6.22-590/include/linux/cpuidle.h
--- linux-2.6.22-570/include/linux/cpuidle.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/linux/cpuidle.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/cpuidle.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,189 @@
+/*
+ * cpuidle.h - a generic framework for CPU idle power management
+#endif /* _LINUX_CPUIDLE_H */
diff -Nurb linux-2.6.22-570/include/linux/cpuset.h linux-2.6.22-590/include/linux/cpuset.h
--- linux-2.6.22-570/include/linux/cpuset.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/cpuset.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/cpuset.h 2008-01-29 22:12:32.000000000 -0500
@@ -11,6 +11,7 @@
#include <linux/sched.h>
#include <linux/cpumask.h>
#endif /* _LINUX_CPUSET_H */
diff -Nurb linux-2.6.22-570/include/linux/device.h linux-2.6.22-590/include/linux/device.h
--- linux-2.6.22-570/include/linux/device.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/device.h 2008-03-15 10:35:47.000000000 -0400
-@@ -238,7 +238,6 @@
++++ linux-2.6.22-590/include/linux/device.h 2008-01-29 22:12:32.000000000 -0500
+@@ -200,6 +200,8 @@
+
+ int (*suspend)(struct device *, pm_message_t state);
+ int (*resume)(struct device *);
++
++ const struct shadow_dir_operations *shadow_ops;
+ };
+
+ extern int __must_check class_register(struct class *);
+@@ -238,7 +240,6 @@
* @devt: for internal use by the driver core only.
* @node: for internal use by the driver core only.
* @kobj: for internal use by the driver core only.
* @groups: optional additional groups to be created
* @dev: if set, a symlink to the struct device is created in the sysfs
* directory for this struct class device.
-@@ -263,8 +262,6 @@
+@@ -263,8 +264,6 @@
struct kobject kobj;
struct class * class; /* required */
dev_t devt; /* dev_t, creates the sysfs "dev" */
struct device * dev; /* not necessary, but nice to have */
void * class_data; /* class-specific data */
struct class_device *parent; /* parent of this child device, if there is one */
-@@ -419,8 +416,6 @@
+@@ -419,8 +418,6 @@
struct device_type *type;
unsigned is_registered:1;
unsigned uevent_suppress:1;
* its driver.
diff -Nurb linux-2.6.22-570/include/linux/dmaengine.h linux-2.6.22-590/include/linux/dmaengine.h
--- linux-2.6.22-570/include/linux/dmaengine.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/dmaengine.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/dmaengine.h 2008-01-29 22:12:32.000000000 -0500
@@ -21,29 +21,40 @@
#ifndef DMAENGINE_H
#define DMAENGINE_H
#endif /* DMAENGINE_H */
diff -Nurb linux-2.6.22-570/include/linux/etherdevice.h linux-2.6.22-590/include/linux/etherdevice.h
--- linux-2.6.22-570/include/linux/etherdevice.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/etherdevice.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/etherdevice.h 2008-01-29 22:12:32.000000000 -0500
@@ -40,12 +40,6 @@
struct hh_cache *hh);
* is_zero_ether_addr - Determine if give Ethernet address is all zeros.
diff -Nurb linux-2.6.22-570/include/linux/freezer.h linux-2.6.22-590/include/linux/freezer.h
--- linux-2.6.22-570/include/linux/freezer.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/freezer.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/freezer.h 2008-01-29 22:12:32.000000000 -0500
@@ -115,6 +115,14 @@
return !!(p->flags & PF_FREEZER_SKIP);
}
+static inline void set_freezable(void) {}
#endif
diff -Nurb linux-2.6.22-570/include/linux/fs.h linux-2.6.22-590/include/linux/fs.h
---- linux-2.6.22-570/include/linux/fs.h 2008-03-15 10:34:29.000000000 -0400
-+++ linux-2.6.22-590/include/linux/fs.h 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/include/linux/fs.h 2008-01-29 22:12:26.000000000 -0500
++++ linux-2.6.22-590/include/linux/fs.h 2008-01-29 22:12:32.000000000 -0500
@@ -283,6 +283,17 @@
#define SYNC_FILE_RANGE_WRITE 2
#define SYNC_FILE_RANGE_WAIT_AFTER 4
#endif /* _LINUX_FS_H */
diff -Nurb linux-2.6.22-570/include/linux/fs_stack.h linux-2.6.22-590/include/linux/fs_stack.h
--- linux-2.6.22-570/include/linux/fs_stack.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/fs_stack.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/fs_stack.h 2008-01-29 22:12:32.000000000 -0500
@@ -1,7 +1,19 @@
+/*
+ * Copyright (c) 2006-2007 Erez Zadok
static inline void fsstack_copy_attr_atime(struct inode *dest,
diff -Nurb linux-2.6.22-570/include/linux/gfp.h linux-2.6.22-590/include/linux/gfp.h
--- linux-2.6.22-570/include/linux/gfp.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/gfp.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/gfp.h 2008-01-29 22:12:32.000000000 -0500
@@ -30,6 +30,9 @@
* cannot handle allocation failures.
*
* it. The alloc_page*() variants return 'struct page *' and as such
diff -Nurb linux-2.6.22-570/include/linux/highmem.h linux-2.6.22-590/include/linux/highmem.h
--- linux-2.6.22-570/include/linux/highmem.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/highmem.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/highmem.h 2008-01-29 22:12:32.000000000 -0500
@@ -73,10 +73,27 @@
}
void *kaddr = kmap_atomic(page, KM_USER0);
diff -Nurb linux-2.6.22-570/include/linux/hugetlb.h linux-2.6.22-590/include/linux/hugetlb.h
--- linux-2.6.22-570/include/linux/hugetlb.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/hugetlb.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/hugetlb.h 2008-01-29 22:12:32.000000000 -0500
@@ -15,6 +15,7 @@
}
extern const unsigned long hugetlb_zero, hugetlb_infinity;
extern int sysctl_hugetlb_shm_group;
+diff -Nurb linux-2.6.22-570/include/linux/idr.h linux-2.6.22-590/include/linux/idr.h
+--- linux-2.6.22-570/include/linux/idr.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/linux/idr.h 2008-01-29 22:12:32.000000000 -0500
+@@ -83,4 +83,33 @@
+ void idr_destroy(struct idr *idp);
+ void idr_init(struct idr *idp);
+
++
++/*
++ * IDA - IDR based id allocator, use when translation from id to
++ * pointer isn't necessary.
++ */
++#define IDA_CHUNK_SIZE 128 /* 128 bytes per chunk */
++#define IDA_BITMAP_LONGS (128 / sizeof(long) - 1)
++#define IDA_BITMAP_BITS (IDA_BITMAP_LONGS * sizeof(long) * 8)
++
++struct ida_bitmap {
++ long nr_busy;
++ unsigned long bitmap[IDA_BITMAP_LONGS];
++};
++
++struct ida {
++ struct idr idr;
++ struct ida_bitmap *free_bitmap;
++};
++
++#define IDA_INIT(name) { .idr = IDR_INIT(name), .free_bitmap = NULL, }
++#define DEFINE_IDA(name) struct ida name = IDA_INIT(name)
++
++int ida_pre_get(struct ida *ida, gfp_t gfp_mask);
++int ida_get_new_above(struct ida *ida, int starting_id, int *p_id);
++int ida_get_new(struct ida *ida, int *p_id);
++void ida_remove(struct ida *ida, int id);
++void ida_destroy(struct ida *ida);
++void ida_init(struct ida *ida);
++
+ #endif /* __IDR_H__ */
+diff -Nurb linux-2.6.22-570/include/linux/if_bridge.h linux-2.6.22-590/include/linux/if_bridge.h
+--- linux-2.6.22-570/include/linux/if_bridge.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/linux/if_bridge.h 2008-01-29 22:12:32.000000000 -0500
+@@ -104,7 +104,7 @@
+
+ #include <linux/netdevice.h>
+
+-extern void brioctl_set(int (*ioctl_hook)(unsigned int, void __user *));
++extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
+ extern struct sk_buff *(*br_handle_frame_hook)(struct net_bridge_port *p,
+ struct sk_buff *skb);
+ extern int (*br_should_route_hook)(struct sk_buff **pskb);
diff -Nurb linux-2.6.22-570/include/linux/if_link.h linux-2.6.22-590/include/linux/if_link.h
--- linux-2.6.22-570/include/linux/if_link.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/if_link.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/if_link.h 2008-01-29 22:12:32.000000000 -0500
@@ -76,6 +76,8 @@
#define IFLA_WEIGHT IFLA_WEIGHT
IFLA_OPERSTATE,
+};
+
#endif /* _LINUX_IF_LINK_H */
+diff -Nurb linux-2.6.22-570/include/linux/if_pppox.h linux-2.6.22-590/include/linux/if_pppox.h
+--- linux-2.6.22-570/include/linux/if_pppox.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/linux/if_pppox.h 2008-01-29 22:12:32.000000000 -0500
+@@ -160,7 +160,7 @@
+ struct module;
+
+ struct pppox_proto {
+- int (*create)(struct socket *sock);
++ int (*create)(struct net *net, struct socket *sock);
+ int (*ioctl)(struct socket *sock, unsigned int cmd,
+ unsigned long arg);
+ struct module *owner;
diff -Nurb linux-2.6.22-570/include/linux/if_tun.h linux-2.6.22-590/include/linux/if_tun.h
--- linux-2.6.22-570/include/linux/if_tun.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/if_tun.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/if_tun.h 2008-01-29 22:12:32.000000000 -0500
@@ -36,6 +36,7 @@
unsigned long flags;
int attached;
#define IFF_TUN 0x0001
diff -Nurb linux-2.6.22-570/include/linux/if_vlan.h linux-2.6.22-590/include/linux/if_vlan.h
--- linux-2.6.22-570/include/linux/if_vlan.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/if_vlan.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/if_vlan.h 2008-01-29 22:12:32.000000000 -0500
+@@ -62,7 +62,7 @@
+ #define VLAN_VID_MASK 0xfff
+
+ /* found in socket.c */
+-extern void vlan_ioctl_set(int (*hook)(void __user *));
++extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *));
+
+ #define VLAN_NAME "vlan"
+
@@ -99,7 +99,7 @@
}
enum vlan_name_types {
VLAN_NAME_TYPE_PLUS_VID, /* Name will look like: vlan0005 */
VLAN_NAME_TYPE_RAW_PLUS_VID, /* name will look like: eth1.0005 */
+diff -Nurb linux-2.6.22-570/include/linux/inetdevice.h linux-2.6.22-590/include/linux/inetdevice.h
+--- linux-2.6.22-570/include/linux/inetdevice.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/linux/inetdevice.h 2008-01-29 22:12:32.000000000 -0500
+@@ -17,8 +17,6 @@
+ DECLARE_BITMAP(state, __NET_IPV4_CONF_MAX - 1);
+ };
+
+-extern struct ipv4_devconf ipv4_devconf;
+-
+ struct in_device
+ {
+ struct net_device *dev;
+@@ -44,7 +42,7 @@
+ };
+
+ #define IPV4_DEVCONF(cnf, attr) ((cnf).data[NET_IPV4_CONF_ ## attr - 1])
+-#define IPV4_DEVCONF_ALL(attr) IPV4_DEVCONF(ipv4_devconf, attr)
++#define IPV4_DEVCONF_ALL(net, attr) IPV4_DEVCONF(*((net)->ipv4_devconf), attr)
+
+ static inline int ipv4_devconf_get(struct in_device *in_dev, int index)
+ {
+@@ -71,14 +69,14 @@
+ ipv4_devconf_set((in_dev), NET_IPV4_CONF_ ## attr, (val))
+
+ #define IN_DEV_ANDCONF(in_dev, attr) \
+- (IPV4_DEVCONF_ALL(attr) && IN_DEV_CONF_GET((in_dev), attr))
++ (IPV4_DEVCONF_ALL((in_dev)->dev->nd_net, attr) && IN_DEV_CONF_GET((in_dev), attr))
+ #define IN_DEV_ORCONF(in_dev, attr) \
+- (IPV4_DEVCONF_ALL(attr) || IN_DEV_CONF_GET((in_dev), attr))
++ (IPV4_DEVCONF_ALL((in_dev)->dev->nd_net, attr) || IN_DEV_CONF_GET((in_dev), attr))
+ #define IN_DEV_MAXCONF(in_dev, attr) \
+- (max(IPV4_DEVCONF_ALL(attr), IN_DEV_CONF_GET((in_dev), attr)))
++ (max(IPV4_DEVCONF_ALL((in_dev)->dev->nd_net, attr), IN_DEV_CONF_GET((in_dev), attr)))
+
+ #define IN_DEV_FORWARD(in_dev) IN_DEV_CONF_GET((in_dev), FORWARDING)
+-#define IN_DEV_MFORWARD(in_dev) (IPV4_DEVCONF_ALL(MC_FORWARDING) && \
++#define IN_DEV_MFORWARD(in_dev) (IPV4_DEVCONF_ALL((in_dev)->dev->nd_net, MC_FORWARDING) && \
+ IPV4_DEVCONF((in_dev)->cnf, \
+ MC_FORWARDING))
+ #define IN_DEV_RPFILTER(in_dev) IN_DEV_ANDCONF((in_dev), RP_FILTER)
+@@ -127,15 +125,15 @@
+ extern int register_inetaddr_notifier(struct notifier_block *nb);
+ extern int unregister_inetaddr_notifier(struct notifier_block *nb);
+
+-extern struct net_device *ip_dev_find(__be32 addr);
++extern struct net_device *ip_dev_find(struct net *net, __be32 addr);
+ extern int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b);
+-extern int devinet_ioctl(unsigned int cmd, void __user *);
++extern int devinet_ioctl(struct net *net, unsigned int cmd, void __user *);
+ extern void devinet_init(void);
+-extern struct in_device *inetdev_by_index(int);
++extern struct in_device *inetdev_by_index(struct net *, int);
+ extern __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope);
+-extern __be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope);
++extern __be32 inet_confirm_addr(struct net *net, const struct net_device *dev, __be32 dst, __be32 local, int scope);
+ extern struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix, __be32 mask);
+-extern void inet_forward_change(void);
++extern void inet_forward_change(struct net *net);
+
+ static __inline__ int inet_ifa_match(__be32 addr, struct in_ifaddr *ifa)
+ {
diff -Nurb linux-2.6.22-570/include/linux/init_task.h linux-2.6.22-590/include/linux/init_task.h
---- linux-2.6.22-570/include/linux/init_task.h 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/include/linux/init_task.h 2008-03-15 10:35:47.000000000 -0400
-@@ -8,6 +8,7 @@
+--- linux-2.6.22-570/include/linux/init_task.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/linux/init_task.h 2008-01-29 22:12:32.000000000 -0500
+@@ -8,6 +8,8 @@
#include <linux/lockdep.h>
#include <linux/ipc.h>
#include <linux/pid_namespace.h>
+#include <linux/user_namespace.h>
++#include <net/net_namespace.h>
#define INIT_FDTABLE \
{ \
-@@ -78,6 +79,7 @@
+@@ -77,7 +79,9 @@
+ .nslock = __SPIN_LOCK_UNLOCKED(nsproxy.nslock), \
.uts_ns = &init_uts_ns, \
.mnt_ns = NULL, \
++ .net_ns = &init_net, \
INIT_IPC_NS(ipc_ns) \
+ .user_ns = &init_user_ns, \
}
#define INIT_SIGHAND(sighand) { \
diff -Nurb linux-2.6.22-570/include/linux/io.h linux-2.6.22-590/include/linux/io.h
--- linux-2.6.22-570/include/linux/io.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/io.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/io.h 2008-01-29 22:12:32.000000000 -0500
@@ -63,32 +63,7 @@
void __iomem * devm_ioremap_nocache(struct device *dev, unsigned long offset,
unsigned long size);
-#endif /* _LINUX_IP_MP_ALG_H */
-
diff -Nurb linux-2.6.22-570/include/linux/ipc.h linux-2.6.22-590/include/linux/ipc.h
---- linux-2.6.22-570/include/linux/ipc.h 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/include/linux/ipc.h 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/include/linux/ipc.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/linux/ipc.h 2008-01-29 22:12:32.000000000 -0500
@@ -93,6 +93,7 @@
#ifdef CONFIG_SYSVIPC
-
diff -Nurb linux-2.6.22-570/include/linux/ipv6.h linux-2.6.22-590/include/linux/ipv6.h
--- linux-2.6.22-570/include/linux/ipv6.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/ipv6.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/ipv6.h 2008-01-29 22:12:32.000000000 -0500
@@ -247,7 +247,7 @@
__u16 lastopt;
__u32 nhoff;
diff -Nurb linux-2.6.22-570/include/linux/kgdb.h linux-2.6.22-590/include/linux/kgdb.h
--- linux-2.6.22-570/include/linux/kgdb.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/linux/kgdb.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/kgdb.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,291 @@
+/*
+ * include/linux/kgdb.h
+#endif /* __KERNEL__ */
diff -Nurb linux-2.6.22-570/include/linux/kmod.h linux-2.6.22-590/include/linux/kmod.h
--- linux-2.6.22-570/include/linux/kmod.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/kmod.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/kmod.h 2008-01-29 22:12:32.000000000 -0500
@@ -36,13 +36,57 @@
#define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x)))
extern void usermodehelper_init(void);
diff -Nurb linux-2.6.22-570/include/linux/kobject.h linux-2.6.22-590/include/linux/kobject.h
--- linux-2.6.22-570/include/linux/kobject.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/kobject.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/kobject.h 2008-01-29 22:12:32.000000000 -0500
@@ -55,7 +55,7 @@
struct kobject * parent;
struct kset * kset;
wait_queue_head_t poll;
};
-@@ -71,12 +71,13 @@
+@@ -71,13 +71,9 @@
extern void kobject_cleanup(struct kobject *);
extern int __must_check kobject_add(struct kobject *);
-extern int __must_check kobject_shadow_add(struct kobject *, struct dentry *);
-+extern int __must_check kobject_shadow_add(struct kobject *kobj,
-+ struct sysfs_dirent *shadow_parent);
extern void kobject_del(struct kobject *);
extern int __must_check kobject_rename(struct kobject *, const char *new_name);
- extern int __must_check kobject_shadow_rename(struct kobject *kobj,
+-extern int __must_check kobject_shadow_rename(struct kobject *kobj,
- struct dentry *new_parent,
-+ struct sysfs_dirent *new_parent,
- const char *new_name);
+- const char *new_name);
extern int __must_check kobject_move(struct kobject *, struct kobject *);
+ extern int __must_check kobject_register(struct kobject *);
diff -Nurb linux-2.6.22-570/include/linux/ktime.h linux-2.6.22-590/include/linux/ktime.h
--- linux-2.6.22-570/include/linux/ktime.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/ktime.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/ktime.h 2008-01-29 22:12:32.000000000 -0500
@@ -279,6 +279,16 @@
return (s64) tv.tv_sec * USEC_PER_SEC + tv.tv_usec;
}
* The resolution of the clocks. The resolution value is returned in
* the clock_getres() system call to give application programmers an
diff -Nurb linux-2.6.22-570/include/linux/magic.h linux-2.6.22-590/include/linux/magic.h
---- linux-2.6.22-570/include/linux/magic.h 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/include/linux/magic.h 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/include/linux/magic.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/linux/magic.h 2008-01-29 22:12:32.000000000 -0500
@@ -36,8 +36,12 @@
#define REISERFS_SUPER_MAGIC_STRING "ReIsErFs"
#define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"
#endif /* __LINUX_MAGIC_H__ */
diff -Nurb linux-2.6.22-570/include/linux/mempolicy.h linux-2.6.22-590/include/linux/mempolicy.h
--- linux-2.6.22-570/include/linux/mempolicy.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/mempolicy.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/mempolicy.h 2008-01-29 22:12:32.000000000 -0500
@@ -148,18 +148,10 @@
const nodemask_t *new);
extern void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new);
static inline int do_migrate_pages(struct mm_struct *mm,
diff -Nurb linux-2.6.22-570/include/linux/mm.h linux-2.6.22-590/include/linux/mm.h
--- linux-2.6.22-570/include/linux/mm.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/mm.h 2008-03-15 10:35:47.000000000 -0400
-@@ -170,6 +170,13 @@
++++ linux-2.6.22-590/include/linux/mm.h 2008-01-29 22:12:32.000000000 -0500
+@@ -42,6 +42,8 @@
+
+ #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
+
++#define VM_REVOKED 0x20000000 /* Mapping has been revoked */
++
+ /*
+ * Linux kernel virtual memory manager primitives.
+ * The idea being to have a "virtual" mm in the same way
+@@ -170,6 +172,13 @@
#define VM_INSERTPAGE 0x02000000 /* The vma has had "vm_insert_page()" done on it */
#define VM_ALWAYSDUMP 0x04000000 /* Always include in core dumps */
#ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
#define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
#endif
-@@ -192,6 +199,25 @@
+@@ -192,6 +201,25 @@
*/
extern pgprot_t protection_map[16];
/*
* These are the virtual MM functions - opening of an area, closing and
-@@ -201,9 +227,15 @@
+@@ -201,9 +229,15 @@
struct vm_operations_struct {
void (*open)(struct vm_area_struct * area);
void (*close)(struct vm_area_struct * area);
/* notification that a previously read-only page is about to become
* writable, if an error is returned it will cause a SIGBUS */
-@@ -656,7 +688,6 @@
+@@ -656,7 +690,6 @@
*/
#define NOPAGE_SIGBUS (NULL)
#define NOPAGE_OOM ((struct page *) (-1))
/*
* Error return values for the *_nopfn functions
-@@ -744,6 +775,16 @@
+@@ -744,6 +777,16 @@
struct vm_area_struct *start_vma, unsigned long start_addr,
unsigned long end_addr, unsigned long *nr_accounted,
struct zap_details *);
void free_pgd_range(struct mmu_gather **tlb, unsigned long addr,
unsigned long end, unsigned long floor, unsigned long ceiling);
void free_pgtables(struct mmu_gather **tlb, struct vm_area_struct *start_vma,
-@@ -1058,6 +1099,7 @@
+@@ -1058,6 +1101,7 @@
extern int insert_vm_struct(struct mm_struct *, struct vm_area_struct *);
extern void __vma_link_rb(struct mm_struct *, struct vm_area_struct *,
struct rb_node **, struct rb_node *);
extern void unlink_file_vma(struct vm_area_struct *);
extern struct vm_area_struct *copy_vma(struct vm_area_struct **,
unsigned long addr, unsigned long len, pgoff_t pgoff);
-@@ -1097,9 +1139,11 @@
+@@ -1097,9 +1141,11 @@
loff_t lstart, loff_t lend);
/* generic vm_area_ops exported for stackable file systems */
/* mm/page-writeback.c */
int write_one_page(struct page *page, int wait);
-@@ -1199,6 +1243,7 @@
+@@ -1199,6 +1245,7 @@
void __user *, size_t *, loff_t *);
unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask,
unsigned long lru_pages);
diff -Nurb linux-2.6.22-570/include/linux/mmc/card.h linux-2.6.22-590/include/linux/mmc/card.h
--- linux-2.6.22-570/include/linux/mmc/card.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/mmc/card.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/mmc/card.h 2008-01-29 22:12:32.000000000 -0500
@@ -72,6 +72,7 @@
#define MMC_STATE_READONLY (1<<1) /* card is read-only */
#define MMC_STATE_HIGHSPEED (1<<2) /* card is in high speed mode */
#define mmc_card_id(c) ((c)->dev.bus_id)
diff -Nurb linux-2.6.22-570/include/linux/mmc/mmc.h linux-2.6.22-590/include/linux/mmc/mmc.h
--- linux-2.6.22-570/include/linux/mmc/mmc.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/mmc/mmc.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/mmc/mmc.h 2008-01-29 22:12:32.000000000 -0500
@@ -253,5 +253,13 @@
#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */
#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */
diff -Nurb linux-2.6.22-570/include/linux/mmzone.h linux-2.6.22-590/include/linux/mmzone.h
--- linux-2.6.22-570/include/linux/mmzone.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/mmzone.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/mmzone.h 2008-01-29 22:12:32.000000000 -0500
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/seqlock.h>
#ifdef CONFIG_SPARSEMEM_EXTREME
diff -Nurb linux-2.6.22-570/include/linux/mnt_namespace.h linux-2.6.22-590/include/linux/mnt_namespace.h
--- linux-2.6.22-570/include/linux/mnt_namespace.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/mnt_namespace.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/mnt_namespace.h 2008-01-29 22:12:32.000000000 -0500
@@ -14,7 +14,7 @@
int event;
};
diff -Nurb linux-2.6.22-570/include/linux/module.h linux-2.6.22-590/include/linux/module.h
--- linux-2.6.22-570/include/linux/module.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/module.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/module.h 2008-01-29 22:12:32.000000000 -0500
@@ -227,8 +227,17 @@
MODULE_STATE_LIVE,
MODULE_STATE_COMING,
struct module_param_attrs *param_attrs;
diff -Nurb linux-2.6.22-570/include/linux/namei.h linux-2.6.22-590/include/linux/namei.h
--- linux-2.6.22-570/include/linux/namei.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/namei.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/namei.h 2008-01-29 22:12:32.000000000 -0500
@@ -3,6 +3,7 @@
#include <linux/dcache.h>
+}
+
#endif /* _LINUX_NAMEI_H */
+diff -Nurb linux-2.6.22-570/include/linux/net.h linux-2.6.22-590/include/linux/net.h
+--- linux-2.6.22-570/include/linux/net.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/linux/net.h 2008-01-29 22:12:32.000000000 -0500
+@@ -23,6 +23,7 @@
+
+ struct poll_table_struct;
+ struct inode;
++struct net;
+
+ #define NPROTO 34 /* should be enough for now.. */
+
+@@ -170,7 +171,7 @@
+
+ struct net_proto_family {
+ int family;
+- int (*create)(struct socket *sock, int protocol);
++ int (*create)(struct net *net, struct socket *sock, int protocol);
+ struct module *owner;
+ };
+
diff -Nurb linux-2.6.22-570/include/linux/netdevice.h linux-2.6.22-590/include/linux/netdevice.h
---- linux-2.6.22-570/include/linux/netdevice.h 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/include/linux/netdevice.h 2008-03-15 10:35:47.000000000 -0400
-@@ -314,9 +314,10 @@
+--- linux-2.6.22-570/include/linux/netdevice.h 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/include/linux/netdevice.h 2008-01-29 22:12:32.000000000 -0500
+@@ -39,6 +39,7 @@
+ #include <linux/percpu.h>
+ #include <linux/dmaengine.h>
+
++struct net;
+ struct vlan_group;
+ struct ethtool_ops;
+ struct netpoll_info;
+@@ -314,9 +315,10 @@
/* Net device features */
unsigned long features;
#define NETIF_F_SG 1 /* Scatter/gather IO. */
#define NETIF_F_HIGHDMA 32 /* Can DMA to high memory. */
#define NETIF_F_FRAGLIST 64 /* Scatter/gather IO. */
#define NETIF_F_HW_VLAN_TX 128 /* Transmit VLAN hw acceleration */
-@@ -338,8 +339,11 @@
+@@ -325,6 +327,7 @@
+ #define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */
+ #define NETIF_F_GSO 2048 /* Enable software GSO. */
+ #define NETIF_F_LLTX 4096 /* LockLess TX */
++#define NETIF_F_NETNS_LOCAL 8192 /* Does not change network namespaces */
+
+ /* Segmentation offload features */
+ #define NETIF_F_GSO_SHIFT 16
+@@ -338,8 +341,11 @@
/* List of features with software fallbacks. */
#define NETIF_F_GSO_SOFTWARE (NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6)
struct net_device *next_sched;
-@@ -540,13 +544,16 @@
+@@ -533,6 +539,9 @@
+ void (*poll_controller)(struct net_device *dev);
+ #endif
+
++ /* Network namespace this network device is inside */
++ struct net *nd_net;
++
+ /* bridge stuff */
+ struct net_bridge_port *br_port;
+
+@@ -540,13 +549,16 @@
struct device dev;
/* space for optional statistics and wireless sysfs groups */
struct attribute_group *sysfs_groups[3];
{
return (char *)dev + ((sizeof(struct net_device)
+ NETDEV_ALIGN_CONST)
+@@ -576,45 +588,48 @@
+ #include <linux/interrupt.h>
+ #include <linux/notifier.h>
+
+-extern struct net_device loopback_dev; /* The loopback */
+-extern struct list_head dev_base_head; /* All devices */
+ extern rwlock_t dev_base_lock; /* Device list lock */
+
+-#define for_each_netdev(d) \
+- list_for_each_entry(d, &dev_base_head, dev_list)
+-#define for_each_netdev_safe(d, n) \
+- list_for_each_entry_safe(d, n, &dev_base_head, dev_list)
+-#define for_each_netdev_continue(d) \
+- list_for_each_entry_continue(d, &dev_base_head, dev_list)
+-#define net_device_entry(lh) list_entry(lh, struct net_device, dev_list)
+-
+-static inline struct net_device *next_net_device(struct net_device *dev)
+-{
+- struct list_head *lh;
+
+- lh = dev->dev_list.next;
+- return lh == &dev_base_head ? NULL : net_device_entry(lh);
+-}
++#define for_each_netdev(net, d) \
++ list_for_each_entry(d, &(net)->dev_base_head, dev_list)
++#define for_each_netdev_safe(net, d, n) \
++ list_for_each_entry_safe(d, n, &(net)->dev_base_head, dev_list)
++#define for_each_netdev_continue(net, d) \
++ list_for_each_entry_continue(d, &(net)->dev_base_head, dev_list)
++#define net_device_entry(lh) list_entry(lh, struct net_device, dev_list)
+
+-static inline struct net_device *first_net_device(void)
+-{
+- return list_empty(&dev_base_head) ? NULL :
+- net_device_entry(dev_base_head.next);
+-}
++#define next_net_device(d) \
++({ \
++ struct net_device *dev = d; \
++ struct list_head *lh; \
++ struct net *net; \
++ \
++ net = dev->nd_net; \
++ lh = dev->dev_list.next; \
++ lh == &net->dev_base_head ? NULL : net_device_entry(lh); \
++})
++
++#define first_net_device(N) \
++({ \
++ struct net *NET = (N); \
++ list_empty(&NET->dev_base_head) ? NULL : \
++ net_device_entry(NET->dev_base_head.next); \
++})
+
+ extern int netdev_boot_setup_check(struct net_device *dev);
+ extern unsigned long netdev_boot_base(const char *prefix, int unit);
+-extern struct net_device *dev_getbyhwaddr(unsigned short type, char *hwaddr);
+-extern struct net_device *dev_getfirstbyhwtype(unsigned short type);
+-extern struct net_device *__dev_getfirstbyhwtype(unsigned short type);
++extern struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, char *hwaddr);
++extern struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type);
++extern struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type);
+ extern void dev_add_pack(struct packet_type *pt);
+ extern void dev_remove_pack(struct packet_type *pt);
+ extern void __dev_remove_pack(struct packet_type *pt);
+
+-extern struct net_device *dev_get_by_flags(unsigned short flags,
++extern struct net_device *dev_get_by_flags(struct net *net, unsigned short flags,
+ unsigned short mask);
+-extern struct net_device *dev_get_by_name(const char *name);
+-extern struct net_device *__dev_get_by_name(const char *name);
++extern struct net_device *dev_get_by_name(struct net *net, const char *name);
++extern struct net_device *__dev_get_by_name(struct net *net, const char *name);
+ extern int dev_alloc_name(struct net_device *dev, const char *name);
+ extern int dev_open(struct net_device *dev);
+ extern int dev_close(struct net_device *dev);
+@@ -625,9 +640,9 @@
+ extern void synchronize_net(void);
+ extern int register_netdevice_notifier(struct notifier_block *nb);
+ extern int unregister_netdevice_notifier(struct notifier_block *nb);
+-extern int call_netdevice_notifiers(unsigned long val, void *v);
+-extern struct net_device *dev_get_by_index(int ifindex);
+-extern struct net_device *__dev_get_by_index(int ifindex);
++extern int call_netdevice_notifiers(unsigned long val, struct net_device *dev);
++extern struct net_device *dev_get_by_index(struct net *net, int ifindex);
++extern struct net_device *__dev_get_by_index(struct net *net, int ifindex);
+ extern int dev_restart(struct net_device *dev);
+ #ifdef CONFIG_NETPOLL_TRAP
+ extern int netpoll_trap(void);
+@@ -732,11 +747,13 @@
+ #define HAVE_NETIF_RECEIVE_SKB 1
+ extern int netif_receive_skb(struct sk_buff *skb);
+ extern int dev_valid_name(const char *name);
+-extern int dev_ioctl(unsigned int cmd, void __user *);
+-extern int dev_ethtool(struct ifreq *);
++extern int dev_ioctl(struct net *net, unsigned int cmd, void __user *);
++extern int dev_ethtool(struct net *net, struct ifreq *);
+ extern unsigned dev_get_flags(const struct net_device *);
+ extern int dev_change_flags(struct net_device *, unsigned);
+ extern int dev_change_name(struct net_device *, char *);
++extern int dev_change_net_namespace(struct net_device *,
++ struct net *, const char *);
+ extern int dev_set_mtu(struct net_device *, int);
+ extern int dev_set_mac_address(struct net_device *,
+ struct sockaddr *);
+@@ -1006,7 +1023,7 @@
+ extern void netdev_state_change(struct net_device *dev);
+ extern void netdev_features_change(struct net_device *dev);
+ /* Load a device via the kmod */
+-extern void dev_load(const char *name);
++extern void dev_load(struct net *net, const char *name);
+ extern void dev_mcast_init(void);
+ extern int netdev_max_backlog;
+ extern int weight_p;
+diff -Nurb linux-2.6.22-570/include/linux/netfilter/x_tables.h linux-2.6.22-590/include/linux/netfilter/x_tables.h
+--- linux-2.6.22-570/include/linux/netfilter/x_tables.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/linux/netfilter/x_tables.h 2008-01-29 22:12:32.000000000 -0500
+@@ -289,7 +289,7 @@
+ unsigned int size, const char *table, unsigned int hook,
+ unsigned short proto, int inv_proto);
+
+-extern int xt_register_table(struct xt_table *table,
++extern int xt_register_table(struct net *net, struct xt_table *table,
+ struct xt_table_info *bootstrap,
+ struct xt_table_info *newinfo);
+ extern void *xt_unregister_table(struct xt_table *table);
+@@ -306,7 +306,7 @@
+ extern int xt_find_revision(int af, const char *name, u8 revision, int target,
+ int *err);
+
+-extern struct xt_table *xt_find_table_lock(int af, const char *name);
++extern struct xt_table *xt_find_table_lock(struct net *net, int af, const char *name);
+ extern void xt_table_unlock(struct xt_table *t);
+
+ extern int xt_proto_init(int af);
+diff -Nurb linux-2.6.22-570/include/linux/netfilter.h linux-2.6.22-590/include/linux/netfilter.h
+--- linux-2.6.22-570/include/linux/netfilter.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/linux/netfilter.h 2008-01-29 22:12:32.000000000 -0500
+@@ -362,11 +362,6 @@
+ #endif
+ }
+
+-#ifdef CONFIG_PROC_FS
+-#include <linux/proc_fs.h>
+-extern struct proc_dir_entry *proc_net_netfilter;
+-#endif
+-
+ #else /* !CONFIG_NETFILTER */
+ #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
+ #define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb)
+diff -Nurb linux-2.6.22-570/include/linux/netfilter_ipv4/ip_tables.h linux-2.6.22-590/include/linux/netfilter_ipv4/ip_tables.h
+--- linux-2.6.22-570/include/linux/netfilter_ipv4/ip_tables.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/linux/netfilter_ipv4/ip_tables.h 2008-01-29 22:12:32.000000000 -0500
+@@ -292,7 +292,7 @@
+ #include <linux/init.h>
+ extern void ipt_init(void) __init;
+
+-extern int ipt_register_table(struct xt_table *table,
++extern int ipt_register_table(struct net *net, struct xt_table *table,
+ const struct ipt_replace *repl);
+ extern void ipt_unregister_table(struct xt_table *table);
+
+diff -Nurb linux-2.6.22-570/include/linux/netfilter_ipv4.h linux-2.6.22-590/include/linux/netfilter_ipv4.h
+--- linux-2.6.22-570/include/linux/netfilter_ipv4.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/linux/netfilter_ipv4.h 2008-01-29 22:12:32.000000000 -0500
+@@ -75,7 +75,7 @@
+ #define SO_ORIGINAL_DST 80
+
+ #ifdef __KERNEL__
+-extern int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type);
++extern int ip_route_me_harder(struct net *net, struct sk_buff **pskb, unsigned addr_type);
+ extern int ip_xfrm_me_harder(struct sk_buff **pskb);
+ extern __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
+ unsigned int dataoff, u_int8_t protocol);
diff -Nurb linux-2.6.22-570/include/linux/netlink.h linux-2.6.22-590/include/linux/netlink.h
---- linux-2.6.22-570/include/linux/netlink.h 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/include/linux/netlink.h 2008-03-15 10:35:47.000000000 -0400
-@@ -21,7 +21,7 @@
+--- linux-2.6.22-570/include/linux/netlink.h 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/include/linux/netlink.h 2008-01-29 22:12:32.000000000 -0500
+@@ -21,12 +21,14 @@
#define NETLINK_DNRTMSG 14 /* DECnet routing messages */
#define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages to userspace */
#define NETLINK_GENERIC 16
#define NETLINK_SCSITRANSPORT 18 /* SCSI Transports */
#define NETLINK_ECRYPTFS 19
+ #define MAX_LINKS 32
+
++struct net;
++
+ struct sockaddr_nl
+ {
+ sa_family_t nl_family; /* AF_NETLINK */
+@@ -157,7 +159,8 @@
+ #define NETLINK_CREDS(skb) (&NETLINK_CB((skb)).creds)
+
+
+-extern struct sock *netlink_kernel_create(int unit, unsigned int groups,
++extern struct sock *netlink_kernel_create(struct net *net,
++ int unit,unsigned int groups,
+ void (*input)(struct sock *sk, int len),
+ struct mutex *cb_mutex,
+ struct module *module);
+@@ -204,6 +207,7 @@
+
+ struct netlink_notify
+ {
++ struct net *net;
+ int pid;
+ int protocol;
+ };
diff -Nurb linux-2.6.22-570/include/linux/netpoll.h linux-2.6.22-590/include/linux/netpoll.h
--- linux-2.6.22-570/include/linux/netpoll.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/netpoll.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/netpoll.h 2008-01-29 22:12:32.000000000 -0500
@@ -16,7 +16,7 @@
struct net_device *dev;
char dev_name[IFNAMSIZ];
u16 local_port, remote_port;
diff -Nurb linux-2.6.22-570/include/linux/nfs4.h linux-2.6.22-590/include/linux/nfs4.h
--- linux-2.6.22-570/include/linux/nfs4.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/nfs4.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/nfs4.h 2008-01-29 22:12:32.000000000 -0500
@@ -15,6 +15,7 @@
#include <linux/types.h>
#define NFS4_FHSIZE 128
diff -Nurb linux-2.6.22-570/include/linux/nfs4_mount.h linux-2.6.22-590/include/linux/nfs4_mount.h
--- linux-2.6.22-570/include/linux/nfs4_mount.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/nfs4_mount.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/nfs4_mount.h 2008-01-29 22:12:32.000000000 -0500
@@ -65,6 +65,7 @@
#define NFS4_MOUNT_NOCTO 0x0010 /* 1 */
#define NFS4_MOUNT_NOAC 0x0020 /* 1 */
#endif
diff -Nurb linux-2.6.22-570/include/linux/nfs_fs.h linux-2.6.22-590/include/linux/nfs_fs.h
--- linux-2.6.22-570/include/linux/nfs_fs.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/nfs_fs.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/nfs_fs.h 2008-01-29 22:12:32.000000000 -0500
@@ -30,7 +30,9 @@
#ifdef __KERNEL__
/* Open contexts for shared mmap writes */
diff -Nurb linux-2.6.22-570/include/linux/nfs_fs_sb.h linux-2.6.22-590/include/linux/nfs_fs_sb.h
--- linux-2.6.22-570/include/linux/nfs_fs_sb.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/nfs_fs_sb.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/nfs_fs_sb.h 2008-01-29 22:12:32.000000000 -0500
@@ -16,7 +16,6 @@
#define NFS_CS_INITING 1 /* busy initialising */
int cl_nfsversion; /* NFS protocol version */
#define NFS_CS_IDMAP 2 /* - idmap started */
#define NFS_CS_RENEWD 3 /* - renewd started */
diff -Nurb linux-2.6.22-570/include/linux/nfs_mount.h linux-2.6.22-590/include/linux/nfs_mount.h
---- linux-2.6.22-570/include/linux/nfs_mount.h 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/include/linux/nfs_mount.h 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/include/linux/nfs_mount.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/linux/nfs_mount.h 2008-01-29 22:12:32.000000000 -0500
@@ -62,6 +62,7 @@
#define NFS_MOUNT_STRICTLOCK 0x1000 /* reserved for NFSv4 */
#define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 */
diff -Nurb linux-2.6.22-570/include/linux/nfs_page.h linux-2.6.22-590/include/linux/nfs_page.h
--- linux-2.6.22-570/include/linux/nfs_page.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/nfs_page.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/nfs_page.h 2008-01-29 22:12:32.000000000 -0500
@@ -16,12 +16,13 @@
#include <linux/sunrpc/auth.h>
#include <linux/nfs_xdr.h>
static inline struct nfs_page *
diff -Nurb linux-2.6.22-570/include/linux/nfs_xdr.h linux-2.6.22-590/include/linux/nfs_xdr.h
--- linux-2.6.22-570/include/linux/nfs_xdr.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/nfs_xdr.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/nfs_xdr.h 2008-01-29 22:12:32.000000000 -0500
@@ -144,6 +144,7 @@
nfs4_stateid delegation;
__u32 do_recall;
/*
diff -Nurb linux-2.6.22-570/include/linux/nsproxy.h linux-2.6.22-590/include/linux/nsproxy.h
---- linux-2.6.22-570/include/linux/nsproxy.h 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/include/linux/nsproxy.h 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/include/linux/nsproxy.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/linux/nsproxy.h 2008-01-29 22:12:32.000000000 -0500
@@ -10,6 +10,12 @@
struct ipc_namespace;
struct pid_namespace;
/*
* A structure to contain pointers to all per-process
* namespaces - fs (mount), uts, network, sysvipc, etc.
-@@ -29,6 +35,7 @@
+@@ -29,10 +35,12 @@
struct ipc_namespace *ipc_ns;
struct mnt_namespace *mnt_ns;
struct pid_namespace *pid_ns;
+ struct user_namespace *user_ns;
++ struct net *net_ns;
};
extern struct nsproxy init_nsproxy;
+-int copy_namespaces(int flags, struct task_struct *tsk);
++int copy_namespaces(unsigned long flags, struct task_struct *tsk);
+ struct nsproxy *copy_nsproxy(struct nsproxy *orig);
+ void get_task_namespaces(struct task_struct *tsk);
+ void free_nsproxy(struct nsproxy *ns);
diff -Nurb linux-2.6.22-570/include/linux/pageblock-flags.h linux-2.6.22-590/include/linux/pageblock-flags.h
--- linux-2.6.22-570/include/linux/pageblock-flags.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/linux/pageblock-flags.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/pageblock-flags.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,52 @@
+/*
+ * Macros for manipulating and testing flags related to a
+
+#endif /* PAGEBLOCK_FLAGS_H */
diff -Nurb linux-2.6.22-570/include/linux/pci_ids.h linux-2.6.22-590/include/linux/pci_ids.h
---- linux-2.6.22-570/include/linux/pci_ids.h 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/include/linux/pci_ids.h 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/include/linux/pci_ids.h 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/include/linux/pci_ids.h 2008-01-29 22:12:32.000000000 -0500
@@ -2003,6 +2003,7 @@
#define PCI_VENDOR_ID_ENE 0x1524
#define PCI_DEVICE_ID_ENE_1410 0x1410
diff -Nurb linux-2.6.22-570/include/linux/pid_namespace.h linux-2.6.22-590/include/linux/pid_namespace.h
--- linux-2.6.22-570/include/linux/pid_namespace.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/pid_namespace.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/pid_namespace.h 2008-01-29 22:12:32.000000000 -0500
@@ -29,7 +29,7 @@
kref_get(&ns->kref);
}
static inline void put_pid_ns(struct pid_namespace *ns)
diff -Nurb linux-2.6.22-570/include/linux/pnp.h linux-2.6.22-590/include/linux/pnp.h
--- linux-2.6.22-570/include/linux/pnp.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/pnp.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/pnp.h 2008-01-29 22:12:32.000000000 -0500
@@ -335,6 +335,10 @@
int (*set)(struct pnp_dev *dev, struct pnp_resource_table *res);
int (*disable)(struct pnp_dev *dev);
struct device dev; /* link to driver model */
diff -Nurb linux-2.6.22-570/include/linux/prctl.h linux-2.6.22-590/include/linux/prctl.h
--- linux-2.6.22-570/include/linux/prctl.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/prctl.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/prctl.h 2008-01-29 22:12:32.000000000 -0500
@@ -59,4 +59,8 @@
# define PR_ENDIAN_LITTLE 1 /* True little endian mode */
# define PR_ENDIAN_PPC_LITTLE 2 /* "PowerPC" pseudo little endian */
+
#endif /* _LINUX_PRCTL_H */
diff -Nurb linux-2.6.22-570/include/linux/proc_fs.h linux-2.6.22-590/include/linux/proc_fs.h
---- linux-2.6.22-570/include/linux/proc_fs.h 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/include/linux/proc_fs.h 2008-03-15 10:35:47.000000000 -0400
-@@ -105,7 +105,6 @@
+--- linux-2.6.22-570/include/linux/proc_fs.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/linux/proc_fs.h 2008-01-29 22:12:32.000000000 -0500
+@@ -86,8 +86,6 @@
+
+ extern struct proc_dir_entry proc_root;
+ extern struct proc_dir_entry *proc_root_fs;
+-extern struct proc_dir_entry *proc_net;
+-extern struct proc_dir_entry *proc_net_stat;
+ extern struct proc_dir_entry *proc_bus;
+ extern struct proc_dir_entry *proc_root_driver;
+ extern struct proc_dir_entry *proc_root_kcore;
+@@ -105,7 +103,6 @@
unsigned long task_vsize(struct mm_struct *);
int task_statm(struct mm_struct *, int *, int *, int *, int *);
char *task_mem(struct mm_struct *, char *);
struct proc_dir_entry *de_get(struct proc_dir_entry *de);
void de_put(struct proc_dir_entry *de);
+@@ -113,6 +110,10 @@
+ extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
+ struct proc_dir_entry *parent);
+ extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
++static inline void remove_proc_pde(struct proc_dir_entry *pde)
++{
++ return remove_proc_entry(pde->name, pde->parent);
++}
+
+ extern struct vfsmount *proc_mnt;
+ extern int proc_fill_super(struct super_block *,void *,int);
+@@ -182,42 +183,18 @@
+ return res;
+ }
+
+-static inline struct proc_dir_entry *proc_net_create(const char *name,
+- mode_t mode, get_info_t *get_info)
+-{
+- return create_proc_info_entry(name,mode,proc_net,get_info);
+-}
+-
+-static inline struct proc_dir_entry *proc_net_fops_create(const char *name,
+- mode_t mode, const struct file_operations *fops)
+-{
+- struct proc_dir_entry *res = create_proc_entry(name, mode, proc_net);
+- if (res)
+- res->proc_fops = fops;
+- return res;
+-}
+-
+-static inline void proc_net_remove(const char *name)
+-{
+- remove_proc_entry(name,proc_net);
+-}
+-
+ #else
+
+ #define proc_root_driver NULL
+-#define proc_net NULL
+ #define proc_bus NULL
+
+-#define proc_net_fops_create(name, mode, fops) ({ (void)(mode), NULL; })
+-#define proc_net_create(name, mode, info) ({ (void)(mode), NULL; })
+-static inline void proc_net_remove(const char *name) {}
+-
+ static inline void proc_flush_task(struct task_struct *task) { }
+
+ static inline struct proc_dir_entry *create_proc_entry(const char *name,
+ mode_t mode, struct proc_dir_entry *parent) { return NULL; }
+
+ #define remove_proc_entry(name, parent) do {} while (0)
++#define remove_proc_pde(PDE) do {} while (0)
+
+ static inline struct proc_dir_entry *proc_symlink(const char *name,
+ struct proc_dir_entry *parent,const char *dest) {return NULL;}
diff -Nurb linux-2.6.22-570/include/linux/raid/raid5.h linux-2.6.22-590/include/linux/raid/raid5.h
--- linux-2.6.22-570/include/linux/raid/raid5.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/raid/raid5.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/raid/raid5.h 2008-01-29 22:12:32.000000000 -0500
@@ -116,13 +116,46 @@
* attach a request to an active stripe (add_stripe_bh())
* lockdev attach-buffer unlockdev
* To improve write throughput, we need to delay the handling of some
diff -Nurb linux-2.6.22-570/include/linux/raid/xor.h linux-2.6.22-590/include/linux/raid/xor.h
--- linux-2.6.22-570/include/linux/raid/xor.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/raid/xor.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/raid/xor.h 2008-01-29 22:12:32.000000000 -0500
@@ -3,9 +3,10 @@
#include <linux/raid/md.h>
struct xor_block_template *next;
diff -Nurb linux-2.6.22-570/include/linux/reboot.h linux-2.6.22-590/include/linux/reboot.h
--- linux-2.6.22-570/include/linux/reboot.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/reboot.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/reboot.h 2008-01-29 22:12:32.000000000 -0500
@@ -67,6 +67,11 @@
void ctrl_alt_del(void);
*/
diff -Nurb linux-2.6.22-570/include/linux/revoked_fs_i.h linux-2.6.22-590/include/linux/revoked_fs_i.h
--- linux-2.6.22-570/include/linux/revoked_fs_i.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/linux/revoked_fs_i.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/revoked_fs_i.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,18 @@
+#ifndef _LINUX_REVOKED_FS_I_H
+#define _LINUX_REVOKED_FS_I_H
+#endif
diff -Nurb linux-2.6.22-570/include/linux/rtnetlink.h linux-2.6.22-590/include/linux/rtnetlink.h
--- linux-2.6.22-570/include/linux/rtnetlink.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/rtnetlink.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/rtnetlink.h 2008-01-29 22:12:32.000000000 -0500
@@ -261,7 +261,7 @@
RTA_FLOW,
RTA_CACHEINFO,
RTA_TABLE,
__RTA_MAX
};
-@@ -570,10 +570,16 @@
+@@ -570,15 +570,21 @@
}
extern int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len);
#define rtattr_parse_nested(tb, max, rta) \
rtattr_parse((tb), (max), RTA_DATA((rta)), RTA_PAYLOAD((rta)))
+-extern int rtnetlink_send(struct sk_buff *skb, u32 pid, u32 group, int echo);
+-extern int rtnl_unicast(struct sk_buff *skb, u32 pid);
+-extern int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group,
+#define rtattr_parse_nested_compat(tb, max, rta, data, len) \
+({ data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
+ __rtattr_parse_nested_compat(tb, max, rta, len); })
+
- extern int rtnetlink_send(struct sk_buff *skb, u32 pid, u32 group, int echo);
- extern int rtnl_unicast(struct sk_buff *skb, u32 pid);
- extern int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group,
++extern int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, u32 group, int echo);
++extern int rtnl_unicast(struct sk_buff *skb, struct net *net, u32 pid);
++extern int rtnl_notify(struct sk_buff *skb, struct net *net, u32 pid, u32 group,
+ struct nlmsghdr *nlh, gfp_t flags);
+-extern void rtnl_set_sk_err(u32 group, int error);
++extern void rtnl_set_sk_err(struct net *net, u32 group, int error);
+ extern int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics);
+ extern int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst,
+ u32 id, u32 ts, u32 tsage, long expires,
@@ -638,6 +644,18 @@
({ (start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
(skb)->len; })
({ if (start) \
skb_trim(skb, (unsigned char *) (start) - (skb)->data); \
diff -Nurb linux-2.6.22-570/include/linux/sched.h linux-2.6.22-590/include/linux/sched.h
---- linux-2.6.22-570/include/linux/sched.h 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/include/linux/sched.h 2008-03-15 10:35:47.000000000 -0400
-@@ -26,6 +26,7 @@
+--- linux-2.6.22-570/include/linux/sched.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/linux/sched.h 2008-01-29 22:12:32.000000000 -0500
+@@ -26,7 +26,9 @@
#define CLONE_STOPPED 0x02000000 /* Start in stopped state */
#define CLONE_NEWUTS 0x04000000 /* New utsname group? */
#define CLONE_NEWIPC 0x08000000 /* New ipcs */
-+#define CLONE_NEWUSER 0x10000000 /* New user namespace */
++#define CLONE_NEWUSER 0x20000000 /* New user namespace */
#define CLONE_KTHREAD 0x10000000 /* clone a kernel thread */
++#define CLONE_NEWNET 0x40000000 /* New network namespace */
/*
-@@ -266,6 +267,7 @@
+ * Scheduling policies
+@@ -266,6 +268,7 @@
asmlinkage void schedule(void);
struct nsproxy;
/* Maximum number of active map areas.. This is a random (large) number */
#define DEFAULT_MAX_MAP_COUNT 65536
-@@ -325,6 +327,27 @@
+@@ -325,6 +328,27 @@
(mm)->hiwater_vm = (mm)->total_vm; \
} while (0)
struct mm_struct {
struct vm_area_struct * mmap; /* list of VMAs */
struct rb_root mm_rb;
-@@ -383,7 +406,7 @@
+@@ -383,7 +407,7 @@
unsigned int token_priority;
unsigned int last_interval;
/* coredumping support */
int core_waiters;
-@@ -757,9 +780,6 @@
+@@ -757,9 +781,6 @@
#endif
};
/*
* Maximum cache size the migration-costs auto-tuning code will
* search from:
-@@ -770,8 +790,6 @@
+@@ -770,8 +791,6 @@
struct io_context; /* See blkdev.h */
#define NGROUPS_SMALL 32
#define NGROUPS_PER_BLOCK ((int)(PAGE_SIZE / sizeof(gid_t)))
struct group_info {
-@@ -912,7 +930,7 @@
+@@ -912,7 +931,7 @@
unsigned int rt_priority;
cputime_t utime, stime;
unsigned long nvcsw, nivcsw; /* context switch counts */
/* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
unsigned long min_flt, maj_flt;
-@@ -1067,11 +1085,16 @@
+@@ -1067,11 +1086,16 @@
short il_next;
#endif
#ifdef CONFIG_CPUSETS
struct robust_list_head __user *robust_list;
#ifdef CONFIG_COMPAT
struct compat_robust_list_head __user *compat_robust_list;
-@@ -1514,7 +1537,8 @@
+@@ -1514,7 +1538,8 @@
/*
* Protects ->fs, ->files, ->mm, ->group_info, ->comm, keyring
* subscriptions and synchronises with wait4(). Also used in procfs. Also
* It must not be nested with write_lock_irq(&tasklist_lock),
diff -Nurb linux-2.6.22-570/include/linux/seccomp.h linux-2.6.22-590/include/linux/seccomp.h
--- linux-2.6.22-570/include/linux/seccomp.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/seccomp.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/seccomp.h 2008-01-29 22:12:32.000000000 -0500
@@ -4,8 +4,6 @@
#ifdef CONFIG_SECCOMP
#endif /* _LINUX_SECCOMP_H */
diff -Nurb linux-2.6.22-570/include/linux/security.h linux-2.6.22-590/include/linux/security.h
--- linux-2.6.22-570/include/linux/security.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/security.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/security.h 2008-01-29 22:12:32.000000000 -0500
@@ -71,6 +71,7 @@
extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb);
extern int cap_netlink_recv(struct sk_buff *skb, int cap);
}
diff -Nurb linux-2.6.22-570/include/linux/serial_8250.h linux-2.6.22-590/include/linux/serial_8250.h
--- linux-2.6.22-570/include/linux/serial_8250.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/serial_8250.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/serial_8250.h 2008-01-29 22:12:32.000000000 -0500
@@ -57,6 +57,7 @@
int serial8250_register_port(struct uart_port *);
diff -Nurb linux-2.6.22-570/include/linux/signal.h linux-2.6.22-590/include/linux/signal.h
--- linux-2.6.22-570/include/linux/signal.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/signal.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/signal.h 2008-01-29 22:12:32.000000000 -0500
@@ -238,12 +238,15 @@
extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
extern long do_sigpending(void __user *, unsigned long);
* In POSIX a signal is sent either to a specific thread (Linux task)
* or to the process as a whole (Linux thread group). How the signal
diff -Nurb linux-2.6.22-570/include/linux/skbuff.h linux-2.6.22-590/include/linux/skbuff.h
---- linux-2.6.22-570/include/linux/skbuff.h 2008-03-15 10:34:27.000000000 -0400
-+++ linux-2.6.22-590/include/linux/skbuff.h 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/include/linux/skbuff.h 2008-01-29 22:12:24.000000000 -0500
++++ linux-2.6.22-590/include/linux/skbuff.h 2008-01-29 22:12:32.000000000 -0500
@@ -147,8 +147,8 @@
/* We divide dataref into two halves. The higher 16 bits hold references
* @headroom: needed headroom
diff -Nurb linux-2.6.22-570/include/linux/slab.h linux-2.6.22-590/include/linux/slab.h
--- linux-2.6.22-570/include/linux/slab.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/slab.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/slab.h 2008-01-29 22:12:32.000000000 -0500
@@ -26,12 +26,14 @@
#define SLAB_HWCACHE_ALIGN 0x00002000UL /* Align objs on cache lines */
#define SLAB_CACHE_DMA 0x00004000UL /* Use GFP_DMA memory */
/*
* struct kmem_cache related prototypes
*/
+diff -Nurb linux-2.6.22-570/include/linux/socket.h linux-2.6.22-590/include/linux/socket.h
+--- linux-2.6.22-570/include/linux/socket.h 2008-01-29 22:12:24.000000000 -0500
++++ linux-2.6.22-590/include/linux/socket.h 2008-01-29 22:12:32.000000000 -0500
+@@ -24,7 +24,6 @@
+ #include <linux/types.h> /* pid_t */
+ #include <linux/compiler.h> /* __user */
+
+-extern int sysctl_somaxconn;
+ #ifdef CONFIG_PROC_FS
+ struct seq_file;
+ extern void socket_seq_show(struct seq_file *seq);
diff -Nurb linux-2.6.22-570/include/linux/string.h linux-2.6.22-590/include/linux/string.h
--- linux-2.6.22-570/include/linux/string.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/string.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/string.h 2008-01-29 22:12:32.000000000 -0500
@@ -105,8 +105,12 @@
#endif
}
#endif
diff -Nurb linux-2.6.22-570/include/linux/sunrpc/auth.h linux-2.6.22-590/include/linux/sunrpc/auth.h
---- linux-2.6.22-570/include/linux/sunrpc/auth.h 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/include/linux/sunrpc/auth.h 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/include/linux/sunrpc/auth.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/linux/sunrpc/auth.h 2008-01-29 22:12:32.000000000 -0500
@@ -16,6 +16,7 @@
#include <linux/sunrpc/xdr.h>
struct rpc_cred * get_rpccred(struct rpc_cred *cred)
diff -Nurb linux-2.6.22-570/include/linux/sunrpc/auth_gss.h linux-2.6.22-590/include/linux/sunrpc/auth_gss.h
--- linux-2.6.22-570/include/linux/sunrpc/auth_gss.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/sunrpc/auth_gss.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/sunrpc/auth_gss.h 2008-01-29 22:12:32.000000000 -0500
@@ -85,11 +85,6 @@
struct gss_upcall_msg *gc_upcall;
};
#endif /* _LINUX_SUNRPC_AUTH_GSS_H */
diff -Nurb linux-2.6.22-570/include/linux/sunrpc/clnt.h linux-2.6.22-590/include/linux/sunrpc/clnt.h
---- linux-2.6.22-570/include/linux/sunrpc/clnt.h 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/include/linux/sunrpc/clnt.h 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/include/linux/sunrpc/clnt.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/linux/sunrpc/clnt.h 2008-01-29 22:12:32.000000000 -0500
@@ -24,8 +24,10 @@
* The high-level client handle
*/
diff -Nurb linux-2.6.22-570/include/linux/sunrpc/gss_api.h linux-2.6.22-590/include/linux/sunrpc/gss_api.h
--- linux-2.6.22-570/include/linux/sunrpc/gss_api.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/sunrpc/gss_api.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/sunrpc/gss_api.h 2008-01-29 22:12:32.000000000 -0500
@@ -77,7 +77,7 @@
struct module *gm_owner;
struct xdr_netobj gm_oid;
struct pf_desc * gm_pfs;
diff -Nurb linux-2.6.22-570/include/linux/sunrpc/rpc_pipe_fs.h linux-2.6.22-590/include/linux/sunrpc/rpc_pipe_fs.h
--- linux-2.6.22-570/include/linux/sunrpc/rpc_pipe_fs.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/sunrpc/rpc_pipe_fs.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/sunrpc/rpc_pipe_fs.h 2008-01-29 22:12:32.000000000 -0500
@@ -23,9 +23,11 @@
void *private;
struct list_head pipe;
int flags;
diff -Nurb linux-2.6.22-570/include/linux/sunrpc/sched.h linux-2.6.22-590/include/linux/sunrpc/sched.h
--- linux-2.6.22-570/include/linux/sunrpc/sched.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/sunrpc/sched.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/sunrpc/sched.h 2008-01-29 22:12:32.000000000 -0500
@@ -110,11 +110,6 @@
if (!list_empty(head) && \
((task=list_entry((head)->next, struct rpc_task, u.tk_wait.list)),1))
struct rpc_call_ops {
diff -Nurb linux-2.6.22-570/include/linux/syscalls.h linux-2.6.22-590/include/linux/syscalls.h
---- linux-2.6.22-570/include/linux/syscalls.h 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/include/linux/syscalls.h 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/include/linux/syscalls.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/linux/syscalls.h 2008-01-29 22:12:32.000000000 -0500
@@ -110,6 +110,9 @@
asmlinkage long sys_capset(cap_user_header_t header,
const cap_user_data_t data);
+
#endif
diff -Nurb linux-2.6.22-570/include/linux/sysctl.h linux-2.6.22-590/include/linux/sysctl.h
---- linux-2.6.22-570/include/linux/sysctl.h 2008-03-15 10:34:26.000000000 -0400
-+++ linux-2.6.22-590/include/linux/sysctl.h 2008-03-15 10:35:47.000000000 -0400
-@@ -166,6 +166,7 @@
+--- linux-2.6.22-570/include/linux/sysctl.h 2008-01-29 22:12:23.000000000 -0500
++++ linux-2.6.22-590/include/linux/sysctl.h 2008-01-29 22:12:32.000000000 -0500
+@@ -31,6 +31,7 @@
+
+ struct file;
+ struct completion;
++struct net;
+
+ #define CTL_MAXNAME 10 /* how many path components do we allow in a
+ call to sysctl? In other words, what is
+@@ -166,6 +167,7 @@
KERN_MAX_LOCK_DEPTH=74,
KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
};
-@@ -208,6 +209,7 @@
+@@ -208,6 +210,7 @@
VM_PANIC_ON_OOM=33, /* panic at out-of-memory */
VM_VDSO_ENABLED=34, /* map VDSO into new processes? */
VM_MIN_SLAB=35, /* Percent pages ignored by zone reclaim */
/* s390 vm cmm sysctls */
VM_CMM_PAGES=1111,
-@@ -843,6 +845,9 @@
+@@ -843,6 +846,9 @@
};
/* CTL_DEBUG names: */
/* CTL_DEV names: */
enum {
+@@ -980,6 +986,7 @@
+ void __user *oldval, size_t __user *oldlenp,
+ void __user *newval, size_t newlen);
+
++extern ctl_handler sysctl_data;
+ extern ctl_handler sysctl_string;
+ extern ctl_handler sysctl_intvec;
+ extern ctl_handler sysctl_jiffies;
+@@ -1056,6 +1063,12 @@
+
+ void unregister_sysctl_table(struct ctl_table_header * table);
+
++#ifdef CONFIG_NET
++extern struct ctl_table_header *register_net_sysctl_table(struct net *net, struct ctl_table *table);
++extern void unregister_net_sysctl_table(struct ctl_table_header *header);
++extern ctl_table net_root_table[];
++#endif
++
+ #else /* __KERNEL__ */
+
+ #endif /* __KERNEL__ */
diff -Nurb linux-2.6.22-570/include/linux/sysdev.h linux-2.6.22-590/include/linux/sysdev.h
--- linux-2.6.22-570/include/linux/sysdev.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/sysdev.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/sysdev.h 2008-01-29 22:12:32.000000000 -0500
@@ -101,8 +101,7 @@
#define _SYSDEV_ATTR(_name,_mode,_show,_store) \
.store = _store, \
}
diff -Nurb linux-2.6.22-570/include/linux/sysfs.h linux-2.6.22-590/include/linux/sysfs.h
---- linux-2.6.22-570/include/linux/sysfs.h 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/include/linux/sysfs.h 2008-03-15 10:35:47.000000000 -0400
-@@ -21,7 +21,12 @@
+--- linux-2.6.22-570/include/linux/sysfs.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/linux/sysfs.h 2008-01-29 22:12:32.000000000 -0500
+@@ -19,9 +19,11 @@
+
+ struct kobject;
struct module;
- struct nameidata;
- struct dentry;
-+struct sysfs_dirent;
+-struct nameidata;
+-struct dentry;
+/* FIXME
+ * The *owner field is no longer used, but leave around
struct attribute {
const char * name;
struct module * owner;
-@@ -41,13 +46,13 @@
+@@ -41,13 +43,13 @@
*/
#define __ATTR(_name,_mode,_show,_store) { \
.show = _name##_show, \
}
-@@ -61,8 +66,10 @@
+@@ -61,8 +63,10 @@
struct attribute attr;
size_t size;
void *private;
int (*mmap)(struct kobject *, struct bin_attribute *attr,
struct vm_area_struct *vma);
};
-@@ -72,12 +79,16 @@
+@@ -72,12 +76,23 @@
ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
};
++struct shadow_dir_operations {
++ const void *(*current_tag)(void);
++ const void *(*kobject_tag)(struct kobject *kobj);
++};
++
+#define SYSFS_TYPE_MASK 0x00ff
#define SYSFS_ROOT 0x0001
#define SYSFS_DIR 0x0002
#define SYSFS_KOBJ_BIN_ATTR 0x0008
#define SYSFS_KOBJ_LINK 0x0020
-#define SYSFS_NOT_PINNED (SYSFS_KOBJ_ATTR | SYSFS_KOBJ_BIN_ATTR | SYSFS_KOBJ_LINK)
++#define SYSFS_SHADOW_DIR 0x0040
+#define SYSFS_COPY_NAME (SYSFS_DIR | SYSFS_KOBJ_LINK)
+
+#define SYSFS_FLAG_MASK ~SYSFS_TYPE_MASK
+#define SYSFS_FLAG_REMOVED 0x0100
++#define SYSFS_FLAG_SHADOWED 0x0200
#ifdef CONFIG_SYSFS
-@@ -85,13 +96,14 @@
+@@ -85,13 +100,13 @@
void (*func)(void *), void *data, struct module *owner);
extern int __must_check
-sysfs_create_dir(struct kobject *, struct dentry *);
-+sysfs_create_dir(struct kobject *kobj, struct sysfs_dirent *shadow_parent_sd);
++sysfs_create_dir(struct kobject *);
extern void
sysfs_remove_dir(struct kobject *);
extern int __must_check
-sysfs_rename_dir(struct kobject *, struct dentry *, const char *new_name);
-+sysfs_rename_dir(struct kobject *kobj, struct sysfs_dirent *new_parent_sd,
-+ const char *new_name);
++sysfs_rename_dir(struct kobject *kobj, const char *new_name);
extern int __must_check
sysfs_move_dir(struct kobject *, struct kobject *);
-@@ -131,8 +143,8 @@
+@@ -114,6 +129,13 @@
+ extern void
+ sysfs_remove_link(struct kobject *, const char * name);
- extern int sysfs_make_shadowed_dir(struct kobject *kobj,
- void * (*follow_link)(struct dentry *, struct nameidata *));
++extern int
++sysfs_rename_link(struct kobject *kobj, struct kobject *target,
++ const char *old_name, const char *new_name);
++
++extern void
++sysfs_delete_link(struct kobject *dir, struct kobject *targ, const char *name);
++
+ int __must_check sysfs_create_bin_file(struct kobject *kobj,
+ struct bin_attribute *attr);
+ void sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr);
+@@ -128,11 +150,7 @@
+
+ void sysfs_notify(struct kobject * k, char *dir, char *attr);
+
+-
+-extern int sysfs_make_shadowed_dir(struct kobject *kobj,
+- void * (*follow_link)(struct dentry *, struct nameidata *));
-extern struct dentry *sysfs_create_shadow_dir(struct kobject *kobj);
-extern void sysfs_remove_shadow_dir(struct dentry *dir);
-+extern struct sysfs_dirent *sysfs_create_shadow_dir(struct kobject *kobj);
-+extern void sysfs_remove_shadow_dir(struct sysfs_dirent *shadow_sd);
++int sysfs_enable_shadowing(struct kobject *, const struct shadow_dir_operations *);
extern int __must_check sysfs_init(void);
-@@ -144,7 +156,8 @@
+@@ -144,7 +162,7 @@
return -ENOSYS;
}
-static inline int sysfs_create_dir(struct kobject * k, struct dentry *shadow)
-+static inline int sysfs_create_dir(struct kobject *kobj,
-+ struct sysfs_dirent *shadow_parent_sd)
++static inline int sysfs_create_dir(struct kobject * kobj)
{
return 0;
}
-@@ -154,8 +167,8 @@
+@@ -154,9 +172,7 @@
;
}
-static inline int sysfs_rename_dir(struct kobject * k,
- struct dentry *new_parent,
-+static inline int sysfs_rename_dir(struct kobject *kobj,
-+ struct sysfs_dirent *new_parent_sd,
- const char *new_name)
+- const char *new_name)
++static inline int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
+ {
+ return 0;
+ }
+@@ -195,6 +211,17 @@
+ ;
+ }
+
++static inline int
++sysfs_rename_link(struct kobject * k, struct kobject *t,
++ const char *old_name, const char * new_name)
++{
++ return 0;
++}
++
++static inline void
++sysfs_delete_link(struct kobject *k, struct kobject *t, const char *name)
++{
++}
+
+ static inline int sysfs_create_bin_file(struct kobject * k, struct bin_attribute * a)
+ {
+@@ -231,8 +258,8 @@
+ {
+ }
+
+-static inline int sysfs_make_shadowed_dir(struct kobject *kobj,
+- void * (*follow_link)(struct dentry *, struct nameidata *))
++static inline int sysfs_enable_shadowing(struct kobject *kobj,
++ const struct shadow_dir_operations *shadow_ops)
{
return 0;
+ }
diff -Nurb linux-2.6.22-570/include/linux/taskstats.h linux-2.6.22-590/include/linux/taskstats.h
--- linux-2.6.22-570/include/linux/taskstats.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/taskstats.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/taskstats.h 2008-01-29 22:12:32.000000000 -0500
@@ -31,7 +31,7 @@
*/
diff -Nurb linux-2.6.22-570/include/linux/tick.h linux-2.6.22-590/include/linux/tick.h
--- linux-2.6.22-570/include/linux/tick.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/tick.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/tick.h 2008-01-29 22:12:32.000000000 -0500
@@ -40,6 +40,7 @@
* @idle_sleeps: Number of idle calls, where the sched tick was stopped
* @idle_entrytime: Time when the idle call was entered
# endif /* !NO_HZ */
#endif
+diff -Nurb linux-2.6.22-570/include/linux/time.h linux-2.6.22-590/include/linux/time.h
+--- linux-2.6.22-570/include/linux/time.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/linux/time.h 2008-01-29 22:12:32.000000000 -0500
+@@ -116,6 +116,8 @@
+ extern unsigned int alarm_setitimer(unsigned int seconds);
+ extern int do_getitimer(int which, struct itimerval *value);
+ extern void getnstimeofday(struct timespec *tv);
++extern void getboottime(struct timespec *ts);
++extern void monotonic_to_bootbased(struct timespec *ts);
+
+ extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
+ extern int timekeeping_is_continuous(void);
diff -Nurb linux-2.6.22-570/include/linux/union_fs.h linux-2.6.22-590/include/linux/union_fs.h
--- linux-2.6.22-570/include/linux/union_fs.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/linux/union_fs.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/union_fs.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2003-2007 Erez Zadok
+
diff -Nurb linux-2.6.22-570/include/linux/unwind.h linux-2.6.22-590/include/linux/unwind.h
--- linux-2.6.22-570/include/linux/unwind.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/unwind.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/unwind.h 2008-01-29 22:12:32.000000000 -0500
@@ -14,6 +14,63 @@
struct module;
+#endif
+
#endif /* _LINUX_UNWIND_H */
+diff -Nurb linux-2.6.22-570/include/linux/usb.h linux-2.6.22-590/include/linux/usb.h
+--- linux-2.6.22-570/include/linux/usb.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/linux/usb.h 2008-01-29 22:12:32.000000000 -0500
+@@ -146,6 +146,10 @@
+ * active alternate setting */
+ unsigned num_altsetting; /* number of alternate settings */
+
++ /* If there is an interface association descriptor then it will list
++ * the associated interfaces */
++ struct usb_interface_assoc_descriptor *intf_assoc;
++
+ int minor; /* minor number this interface is
+ * bound to */
+ enum usb_interface_condition condition; /* state of binding */
+@@ -175,6 +179,7 @@
+
+ /* this maximum is arbitrary */
+ #define USB_MAXINTERFACES 32
++#define USB_MAXIADS USB_MAXINTERFACES/2
+
+ /**
+ * struct usb_interface_cache - long-term representation of a device interface
+@@ -245,6 +250,11 @@
+ struct usb_config_descriptor desc;
+
+ char *string; /* iConfiguration string, if present */
++
++ /* List of any Interface Association Descriptors in this
++ * configuration. */
++ struct usb_interface_assoc_descriptor *intf_assoc[USB_MAXIADS];
++
+ /* the interfaces associated with this configuration,
+ * stored in no particular order */
+ struct usb_interface *interface[USB_MAXINTERFACES];
diff -Nurb linux-2.6.22-570/include/linux/user_namespace.h linux-2.6.22-590/include/linux/user_namespace.h
--- linux-2.6.22-570/include/linux/user_namespace.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/include/linux/user_namespace.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/user_namespace.h 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,61 @@
+#ifndef _LINUX_USER_NAMESPACE_H
+#define _LINUX_USER_NAMESPACE_H
+#endif /* _LINUX_USER_H */
diff -Nurb linux-2.6.22-570/include/linux/utsname.h linux-2.6.22-590/include/linux/utsname.h
--- linux-2.6.22-570/include/linux/utsname.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/utsname.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/utsname.h 2008-01-29 22:12:32.000000000 -0500
@@ -48,26 +48,14 @@
kref_get(&ns->kref);
}
return ¤t->nsproxy->uts_ns->name;
diff -Nurb linux-2.6.22-570/include/linux/vmalloc.h linux-2.6.22-590/include/linux/vmalloc.h
--- linux-2.6.22-570/include/linux/vmalloc.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/linux/vmalloc.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/linux/vmalloc.h 2008-01-29 22:12:32.000000000 -0500
@@ -65,9 +65,10 @@
unsigned long flags, int node,
gfp_t gfp_mask);
/*
* Internals. Dont't use..
diff -Nurb linux-2.6.22-570/include/net/addrconf.h linux-2.6.22-590/include/net/addrconf.h
---- linux-2.6.22-570/include/net/addrconf.h 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/include/net/addrconf.h 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/include/net/addrconf.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/net/addrconf.h 2008-01-29 22:12:32.000000000 -0500
@@ -61,7 +61,7 @@
extern int ipv6_chk_addr(struct in6_addr *addr,
struct net_device *dev,
extern int ipv6_chk_home_addr(struct in6_addr *addr);
#endif
extern struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr,
+diff -Nurb linux-2.6.22-570/include/net/af_unix.h linux-2.6.22-590/include/net/af_unix.h
+--- linux-2.6.22-570/include/net/af_unix.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/net/af_unix.h 2008-01-29 22:12:32.000000000 -0500
+@@ -91,12 +91,11 @@
+ #define unix_sk(__sk) ((struct unix_sock *)__sk)
+
+ #ifdef CONFIG_SYSCTL
+-extern int sysctl_unix_max_dgram_qlen;
+-extern void unix_sysctl_register(void);
+-extern void unix_sysctl_unregister(void);
++extern void unix_sysctl_register(struct net *net);
++extern void unix_sysctl_unregister(struct net *net);
+ #else
+-static inline void unix_sysctl_register(void) {}
+-static inline void unix_sysctl_unregister(void) {}
++static inline void unix_sysctl_register(struct net *net) {}
++static inline void unix_sysctl_unregister(struct net *net) {}
+ #endif
+ #endif
+ #endif
+diff -Nurb linux-2.6.22-570/include/net/arp.h linux-2.6.22-590/include/net/arp.h
+--- linux-2.6.22-570/include/net/arp.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/net/arp.h 2008-01-29 22:12:32.000000000 -0500
+@@ -11,7 +11,7 @@
+
+ extern void arp_init(void);
+ extern int arp_find(unsigned char *haddr, struct sk_buff *skb);
+-extern int arp_ioctl(unsigned int cmd, void __user *arg);
++extern int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg);
+ extern void arp_send(int type, int ptype, __be32 dest_ip,
+ struct net_device *dev, __be32 src_ip,
+ unsigned char *dest_hw, unsigned char *src_hw, unsigned char *th);
diff -Nurb linux-2.6.22-570/include/net/dst.h linux-2.6.22-590/include/net/dst.h
--- linux-2.6.22-570/include/net/dst.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/net/dst.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/net/dst.h 2008-01-29 22:12:32.000000000 -0500
@@ -47,7 +47,6 @@
#define DST_NOXFRM 2
#define DST_NOPOLICY 4
unsigned long expires;
unsigned short header_len; /* more space at head required */
+diff -Nurb linux-2.6.22-570/include/net/fib_rules.h linux-2.6.22-590/include/net/fib_rules.h
+--- linux-2.6.22-570/include/net/fib_rules.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/net/fib_rules.h 2008-01-29 22:12:32.000000000 -0500
+@@ -56,12 +56,12 @@
+ int (*fill)(struct fib_rule *, struct sk_buff *,
+ struct nlmsghdr *,
+ struct fib_rule_hdr *);
+- u32 (*default_pref)(void);
++ u32 (*default_pref)(struct fib_rules_ops *ops);
+ size_t (*nlmsg_payload)(struct fib_rule *);
+
+ /* Called after modifications to the rules set, must flush
+ * the route cache if one exists. */
+- void (*flush_cache)(void);
++ void (*flush_cache)(struct fib_rules_ops *ops);
+
+ int nlgroup;
+ const struct nla_policy *policy;
+@@ -101,8 +101,8 @@
+ return frh->table;
+ }
+
+-extern int fib_rules_register(struct fib_rules_ops *);
+-extern int fib_rules_unregister(struct fib_rules_ops *);
++extern int fib_rules_register(struct net *net, struct fib_rules_ops *);
++extern int fib_rules_unregister(struct net *net, struct fib_rules_ops *);
+
+ extern int fib_rules_lookup(struct fib_rules_ops *,
+ struct flowi *, int flags,
diff -Nurb linux-2.6.22-570/include/net/flow.h linux-2.6.22-590/include/net/flow.h
--- linux-2.6.22-570/include/net/flow.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/net/flow.h 2008-03-15 10:35:47.000000000 -0400
-@@ -67,20 +67,16 @@
++++ linux-2.6.22-590/include/net/flow.h 2008-01-29 22:12:32.000000000 -0500
+@@ -8,9 +8,11 @@
+ #define _NET_FLOW_H
+
+ #include <linux/in6.h>
++#include <net/net_namespace.h>
+ #include <asm/atomic.h>
+
+ struct flowi {
++ struct net *fl_net;
+ int oif;
+ int iif;
+ __u32 mark;
+@@ -67,20 +69,16 @@
__be32 spi;
__u32 secid; /* used by xfrm; see secid.txt */
} __attribute__((__aligned__(BITS_PER_LONG/8)));
+diff -Nurb linux-2.6.22-570/include/net/inet6_hashtables.h linux-2.6.22-590/include/net/inet6_hashtables.h
+--- linux-2.6.22-570/include/net/inet6_hashtables.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/net/inet6_hashtables.h 2008-01-29 22:12:32.000000000 -0500
+@@ -62,31 +62,31 @@
+ const __be16 sport,
+ const struct in6_addr *daddr,
+ const u16 hnum,
+- const int dif);
++ const int dif, struct net *net);
+
+ extern struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
+ const struct in6_addr *daddr,
+ const unsigned short hnum,
+- const int dif);
++ const int dif, struct net *net);
+
+ static inline struct sock *__inet6_lookup(struct inet_hashinfo *hashinfo,
+ const struct in6_addr *saddr,
+ const __be16 sport,
+ const struct in6_addr *daddr,
+ const u16 hnum,
+- const int dif)
++ const int dif, struct net *net)
+ {
+ struct sock *sk = __inet6_lookup_established(hashinfo, saddr, sport,
+- daddr, hnum, dif);
++ daddr, hnum, dif, net);
+ if (sk)
+ return sk;
+
+- return inet6_lookup_listener(hashinfo, daddr, hnum, dif);
++ return inet6_lookup_listener(hashinfo, daddr, hnum, dif, net);
+ }
+
+ extern struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
+ const struct in6_addr *saddr, const __be16 sport,
+ const struct in6_addr *daddr, const __be16 dport,
+- const int dif);
++ const int dif, struct net *net);
+ #endif /* defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) */
+ #endif /* _INET6_HASHTABLES_H */
+diff -Nurb linux-2.6.22-570/include/net/inet_hashtables.h linux-2.6.22-590/include/net/inet_hashtables.h
+--- linux-2.6.22-570/include/net/inet_hashtables.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/net/inet_hashtables.h 2008-01-29 22:12:32.000000000 -0500
+@@ -75,6 +75,7 @@
+ * ports are created in O(1) time? I thought so. ;-) -DaveM
+ */
+ struct inet_bind_bucket {
++ struct net *net;
+ unsigned short port;
+ signed short fastreuse;
+ struct hlist_node node;
+@@ -138,34 +139,35 @@
+ extern struct inet_bind_bucket *
+ inet_bind_bucket_create(struct kmem_cache *cachep,
+ struct inet_bind_hashbucket *head,
++ struct net *net,
+ const unsigned short snum);
+ extern void inet_bind_bucket_destroy(struct kmem_cache *cachep,
+ struct inet_bind_bucket *tb);
+
+-static inline int inet_bhashfn(const __u16 lport, const int bhash_size)
++static inline int inet_bhashfn(struct net *net, const __u16 lport, const int bhash_size)
+ {
+- return lport & (bhash_size - 1);
++ return (((unsigned long)net) ^ lport) & (bhash_size - 1);
+ }
+
+ extern void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb,
+ const unsigned short snum);
+
+ /* These can have wildcards, don't try too hard. */
+-static inline int inet_lhashfn(const unsigned short num)
++static inline int inet_lhashfn(struct net *net, const unsigned short num)
+ {
+- return num & (INET_LHTABLE_SIZE - 1);
++ return (((unsigned long)net) ^ num) & (INET_LHTABLE_SIZE - 1);
+ }
+
+ static inline int inet_sk_listen_hashfn(const struct sock *sk)
+ {
+- return inet_lhashfn(inet_sk(sk)->num);
++ return inet_lhashfn(sk->sk_net, inet_sk(sk)->num);
+ }
+
+ /* Caller must disable local BH processing. */
+ static inline void __inet_inherit_port(struct inet_hashinfo *table,
+ struct sock *sk, struct sock *child)
+ {
+- const int bhash = inet_bhashfn(inet_sk(child)->num, table->bhash_size);
++ const int bhash = inet_bhashfn(sk->sk_net, inet_sk(child)->num, table->bhash_size);
+ struct inet_bind_hashbucket *head = &table->bhash[bhash];
+ struct inet_bind_bucket *tb;
+
+@@ -274,12 +276,13 @@
+ extern struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
+ const __be32 daddr,
+ const unsigned short hnum,
+- const int dif);
++ const int dif, struct net *net);
+
+ static inline struct sock *inet_lookup_listener(struct inet_hashinfo *hashinfo,
+- __be32 daddr, __be16 dport, int dif)
++ __be32 daddr, __be16 dport,
++ int dif, struct net *net)
+ {
+- return __inet_lookup_listener(hashinfo, daddr, ntohs(dport), dif);
++ return __inet_lookup_listener(hashinfo, daddr, ntohs(dport), dif, net);
+ }
+
+ /* Socket demux engine toys. */
+@@ -313,30 +316,34 @@
+ (((__force __u64)(__be32)(__daddr)) << 32) | \
+ ((__force __u64)(__be32)(__saddr)));
+ #endif /* __BIG_ENDIAN */
+-#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
++#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif, __net)\
+ (((__sk)->sk_hash == (__hash)) && \
+ ((*((__addrpair *)&(inet_sk(__sk)->daddr))) == (__cookie)) && \
+ ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \
+- (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
+-#define INET_TW_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
++ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))) && \
++ ((__sk)->sk_net == __net))
++#define INET_TW_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif, __net)\
+ (((__sk)->sk_hash == (__hash)) && \
+ ((*((__addrpair *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) && \
+ ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \
+- (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
++ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))) && \
++ ((__sk)->sk_net == __net))
+ #else /* 32-bit arch */
+ #define INET_ADDR_COOKIE(__name, __saddr, __daddr)
+-#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif) \
++#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif, __net) \
+ (((__sk)->sk_hash == (__hash)) && \
+ (inet_sk(__sk)->daddr == (__saddr)) && \
+ (inet_sk(__sk)->rcv_saddr == (__daddr)) && \
+ ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \
+- (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
+-#define INET_TW_MATCH(__sk, __hash,__cookie, __saddr, __daddr, __ports, __dif) \
++ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))) && \
++ ((__sk)->sk_net == __net))
++#define INET_TW_MATCH(__sk, __hash,__cookie, __saddr, __daddr, __ports, __dif, __net) \
+ (((__sk)->sk_hash == (__hash)) && \
+ (inet_twsk(__sk)->tw_daddr == (__saddr)) && \
+ (inet_twsk(__sk)->tw_rcv_saddr == (__daddr)) && \
+ ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \
+- (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
++ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))) && \
++ ((__sk)->sk_net == __net))
+ #endif /* 64-bit arch */
+
+ /*
+@@ -349,7 +356,7 @@
+ __inet_lookup_established(struct inet_hashinfo *hashinfo,
+ const __be32 saddr, const __be16 sport,
+ const __be32 daddr, const u16 hnum,
+- const int dif)
++ const int dif, struct net *net)
+ {
+ INET_ADDR_COOKIE(acookie, saddr, daddr)
+ const __portpair ports = INET_COMBINED_PORTS(sport, hnum);
+@@ -358,19 +365,19 @@
+ /* Optimize here for direct hit, only listening connections can
+ * have wildcards anyways.
+ */
+- unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport);
++ unsigned int hash = inet_ehashfn(net, daddr, hnum, saddr, sport);
+ struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);
+
+ prefetch(head->chain.first);
+ read_lock(&head->lock);
+ sk_for_each(sk, node, &head->chain) {
+- if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
++ if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif, net))
+ goto hit; /* You sunk my battleship! */
+ }
+
+ /* Must check for a TIME_WAIT'er before going to listener hash. */
+ sk_for_each(sk, node, &head->twchain) {
+- if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
++ if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif, net))
+ goto hit;
+ }
+ sk = NULL;
+@@ -386,32 +393,32 @@
+ inet_lookup_established(struct inet_hashinfo *hashinfo,
+ const __be32 saddr, const __be16 sport,
+ const __be32 daddr, const __be16 dport,
+- const int dif)
++ const int dif, struct net *net)
+ {
+ return __inet_lookup_established(hashinfo, saddr, sport, daddr,
+- ntohs(dport), dif);
++ ntohs(dport), dif, net);
+ }
+
+ static inline struct sock *__inet_lookup(struct inet_hashinfo *hashinfo,
+ const __be32 saddr, const __be16 sport,
+ const __be32 daddr, const __be16 dport,
+- const int dif)
++ const int dif, struct net *net)
+ {
+ u16 hnum = ntohs(dport);
+ struct sock *sk = __inet_lookup_established(hashinfo, saddr, sport, daddr,
+- hnum, dif);
+- return sk ? : __inet_lookup_listener(hashinfo, daddr, hnum, dif);
++ hnum, dif, net);
++ return sk ? : __inet_lookup_listener(hashinfo, daddr, hnum, dif, net);
+ }
+
+ static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo,
+ const __be32 saddr, const __be16 sport,
+ const __be32 daddr, const __be16 dport,
+- const int dif)
++ const int dif, struct net *net)
+ {
+ struct sock *sk;
+
+ local_bh_disable();
+- sk = __inet_lookup(hashinfo, saddr, sport, daddr, dport, dif);
++ sk = __inet_lookup(hashinfo, saddr, sport, daddr, dport, dif, net);
+ local_bh_enable();
+
+ return sk;
+diff -Nurb linux-2.6.22-570/include/net/inet_sock.h linux-2.6.22-590/include/net/inet_sock.h
+--- linux-2.6.22-570/include/net/inet_sock.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/net/inet_sock.h 2008-01-29 22:12:32.000000000 -0500
+@@ -171,10 +171,12 @@
+ extern u32 inet_ehash_secret;
+ extern void build_ehash_secret(void);
+
+-static inline unsigned int inet_ehashfn(const __be32 laddr, const __u16 lport,
++static inline unsigned int inet_ehashfn(struct net *net,
++ const __be32 laddr, const __u16 lport,
+ const __be32 faddr, const __be16 fport)
+ {
+- return jhash_2words((__force __u32) laddr ^ (__force __u32) faddr,
++ return jhash_2words((__force __u32) laddr ^ (__force __u32) faddr ^
++ (__force __u32) ((unsigned long)net),
+ ((__u32) lport) << 16 | (__force __u32)fport,
+ inet_ehash_secret);
+ }
+@@ -187,7 +189,7 @@
+ const __be32 faddr = inet->daddr;
+ const __be16 fport = inet->dport;
+
+- return inet_ehashfn(laddr, lport, faddr, fport);
++ return inet_ehashfn(sk->sk_net, laddr, lport, faddr, fport);
+ }
+
+ #endif /* _INET_SOCK_H */
+diff -Nurb linux-2.6.22-570/include/net/inet_timewait_sock.h linux-2.6.22-590/include/net/inet_timewait_sock.h
+--- linux-2.6.22-570/include/net/inet_timewait_sock.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/net/inet_timewait_sock.h 2008-01-29 22:12:32.000000000 -0500
+@@ -115,6 +115,7 @@
+ #define tw_refcnt __tw_common.skc_refcnt
+ #define tw_hash __tw_common.skc_hash
+ #define tw_prot __tw_common.skc_prot
++#define tw_net __tw_common.skc_net
+ #define tw_xid __tw_common.skc_xid
+ #define tw_vx_info __tw_common.skc_vx_info
+ #define tw_nid __tw_common.skc_nid
+diff -Nurb linux-2.6.22-570/include/net/inetpeer.h linux-2.6.22-590/include/net/inetpeer.h
+--- linux-2.6.22-570/include/net/inetpeer.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/net/inetpeer.h 2008-01-29 22:12:32.000000000 -0500
+@@ -15,6 +15,8 @@
+ #include <linux/spinlock.h>
+ #include <asm/atomic.h>
+
++struct net;
++
+ struct inet_peer
+ {
+ /* group together avl_left,avl_right,v4daddr to speedup lookups */
+@@ -22,7 +24,11 @@
+ __be32 v4daddr; /* peer's address */
+ __u16 avl_height;
+ __u16 ip_id_count; /* IP ID for the next packet */
+- struct inet_peer *unused_next, **unused_prevp;
++ union {
++ struct inet_peer *unused_next;
++ struct net *net;
++ } u;
++ struct inet_peer **unused_prevp;
+ __u32 dtime; /* the time of last use of not
+ * referenced entries */
+ atomic_t refcnt;
+@@ -34,7 +40,7 @@
+ void inet_initpeers(void) __init;
+
+ /* can be called with or without local BH being disabled */
+-struct inet_peer *inet_getpeer(__be32 daddr, int create);
++struct inet_peer *inet_getpeer(struct net *net, __be32 daddr, int create);
+
+ /* can be called from BH context or outside */
+ extern void inet_putpeer(struct inet_peer *p);
+diff -Nurb linux-2.6.22-570/include/net/ip.h linux-2.6.22-590/include/net/ip.h
+--- linux-2.6.22-570/include/net/ip.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/net/ip.h 2008-01-29 22:12:32.000000000 -0500
+@@ -149,13 +149,6 @@
+ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg,
+ unsigned int len);
+
+-struct ipv4_config
+-{
+- int log_martians;
+- int no_pmtu_disc;
+-};
+-
+-extern struct ipv4_config ipv4_config;
+ DECLARE_SNMP_STAT(struct ipstats_mib, ip_statistics);
+ #define IP_INC_STATS(field) SNMP_INC_STATS(ip_statistics, field)
+ #define IP_INC_STATS_BH(field) SNMP_INC_STATS_BH(ip_statistics, field)
+@@ -171,27 +164,6 @@
+ extern int snmp_mib_init(void *ptr[2], size_t mibsize, size_t mibalign);
+ extern void snmp_mib_free(void *ptr[2]);
+
+-extern int sysctl_local_port_range[2];
+-extern int sysctl_ip_default_ttl;
+-extern int sysctl_ip_nonlocal_bind;
+-
+-/* From ip_fragment.c */
+-extern int sysctl_ipfrag_high_thresh;
+-extern int sysctl_ipfrag_low_thresh;
+-extern int sysctl_ipfrag_time;
+-extern int sysctl_ipfrag_secret_interval;
+-extern int sysctl_ipfrag_max_dist;
+-
+-/* From inetpeer.c */
+-extern int inet_peer_threshold;
+-extern int inet_peer_minttl;
+-extern int inet_peer_maxttl;
+-extern int inet_peer_gc_mintime;
+-extern int inet_peer_gc_maxtime;
+-
+-/* From ip_output.c */
+-extern int sysctl_ip_dynaddr;
+-
+ extern void ipfrag_init(void);
+
+ #ifdef CONFIG_INET
+@@ -332,8 +304,6 @@
+ };
+
+ struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user);
+-extern int ip_frag_nqueues;
+-extern atomic_t ip_frag_mem;
+
+ /*
+ * Functions provided by ip_forward.c
+@@ -392,5 +362,6 @@
+ #endif
+
+ extern struct ctl_table ipv4_table[];
++extern struct ctl_table multi_ipv4_table[];
+
+ #endif /* _IP_H */
diff -Nurb linux-2.6.22-570/include/net/ip_fib.h linux-2.6.22-590/include/net/ip_fib.h
--- linux-2.6.22-570/include/net/ip_fib.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/net/ip_fib.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/net/ip_fib.h 2008-01-29 22:12:32.000000000 -0500
@@ -39,7 +39,6 @@
int fc_mx_len;
int fc_mp_len;
u32 fc_nlflags;
struct nl_info fc_nlinfo;
};
-@@ -86,9 +85,6 @@
- #ifdef CONFIG_IP_ROUTE_MULTIPATH
- int fib_power;
+@@ -89,6 +88,7 @@
+ #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
+ u32 fib_mp_alg;
#endif
--#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-- u32 fib_mp_alg;
--#endif
++ struct net * fib_net;
struct fib_nh fib_nh[0];
#define fib_dev fib_nh[0].nh_dev
};
-@@ -103,10 +99,6 @@
+@@ -103,10 +103,6 @@
unsigned char nh_sel;
unsigned char type;
unsigned char scope;
struct fib_info *fi;
#ifdef CONFIG_IP_MULTIPLE_TABLES
struct fib_rule *r;
-@@ -145,14 +137,6 @@
+@@ -145,14 +141,6 @@
#define FIB_RES_DEV(res) (FIB_RES_NH(res).nh_dev)
#define FIB_RES_OIF(res) (FIB_RES_NH(res).nh_oif)
struct fib_table {
struct hlist_node tb_hlist;
u32 tb_id;
+@@ -171,43 +159,43 @@
+
+ #ifndef CONFIG_IP_MULTIPLE_TABLES
+
+-extern struct fib_table *ip_fib_local_table;
+-extern struct fib_table *ip_fib_main_table;
+-
+-static inline struct fib_table *fib_get_table(u32 id)
++static inline struct fib_table *fib_get_table(struct net *net, u32 id)
+ {
+ if (id != RT_TABLE_LOCAL)
+- return ip_fib_main_table;
+- return ip_fib_local_table;
++ return net->ip_fib_main_table;
++ return net->ip_fib_local_table;
+ }
+
+-static inline struct fib_table *fib_new_table(u32 id)
++static inline struct fib_table *fib_new_table(struct net *net, u32 id)
+ {
+- return fib_get_table(id);
++ return fib_get_table(net, id);
+ }
+
+ static inline int fib_lookup(const struct flowi *flp, struct fib_result *res)
+ {
+- if (ip_fib_local_table->tb_lookup(ip_fib_local_table, flp, res) &&
+- ip_fib_main_table->tb_lookup(ip_fib_main_table, flp, res))
++ struct net *net = flp->fl_net;
++ struct fib_table *local_table = net->ip_fib_local_table;
++ struct fib_table *main_table = net->ip_fib_main_table;
++ if (local_table->tb_lookup(local_table, flp, res) &&
++ main_table->tb_lookup(main_table, flp, res))
+ return -ENETUNREACH;
+ return 0;
+ }
+
+ static inline void fib_select_default(const struct flowi *flp, struct fib_result *res)
+ {
++ struct net *net = flp->fl_net;
++ struct fib_table *main_table = net->ip_fib_main_table;
+ if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
+- ip_fib_main_table->tb_select_default(ip_fib_main_table, flp, res);
++ main_table->tb_select_default(main_table, flp, res);
+ }
+
+ #else /* CONFIG_IP_MULTIPLE_TABLES */
+-#define ip_fib_local_table fib_get_table(RT_TABLE_LOCAL)
+-#define ip_fib_main_table fib_get_table(RT_TABLE_MAIN)
+
+ extern int fib_lookup(struct flowi *flp, struct fib_result *res);
+
+-extern struct fib_table *fib_new_table(u32 id);
+-extern struct fib_table *fib_get_table(u32 id);
++extern struct fib_table *fib_new_table(struct net *net, u32 id);
++extern struct fib_table *fib_get_table(struct net *net, u32 id);
+ extern void fib_select_default(const struct flowi *flp, struct fib_result *res);
+
+ #endif /* CONFIG_IP_MULTIPLE_TABLES */
+@@ -223,15 +211,17 @@
+
+ /* Exported by fib_semantics.c */
+ extern int ip_fib_check_default(__be32 gw, struct net_device *dev);
+-extern int fib_sync_down(__be32 local, struct net_device *dev, int force);
++extern int fib_sync_down(struct net *net, __be32 local, struct net_device *dev, int force);
+ extern int fib_sync_up(struct net_device *dev);
+ extern __be32 __fib_res_prefsrc(struct fib_result *res);
+
+ /* Exported by fib_hash.c */
+ extern struct fib_table *fib_hash_init(u32 id);
++extern void fib_hash_exit(struct fib_table *tb);
+
+ #ifdef CONFIG_IP_MULTIPLE_TABLES
+-extern void __init fib4_rules_init(void);
++extern void fib4_rules_init(struct net * net);
++extern void fib4_rules_exit(struct net * net);
+
+ #ifdef CONFIG_NET_CLS_ROUTE
+ extern u32 fib_rules_tclass(struct fib_result *res);
+@@ -274,8 +264,11 @@
+ }
+
+ #ifdef CONFIG_PROC_FS
+-extern int fib_proc_init(void);
+-extern void fib_proc_exit(void);
++extern int fib_proc_init(struct net * net);
++extern void fib_proc_exit(struct net * net);
+ #endif
+
++extern int fib_info_init(struct net *net);
++extern void fib_info_exit(struct net *net);
++
+ #endif /* _NET_FIB_H */
diff -Nurb linux-2.6.22-570/include/net/ip_mp_alg.h linux-2.6.22-590/include/net/ip_mp_alg.h
--- linux-2.6.22-570/include/net/ip_mp_alg.h 2007-07-08 19:32:17.000000000 -0400
+++ linux-2.6.22-590/include/net/ip_mp_alg.h 1969-12-31 19:00:00.000000000 -0500
-}
-
-#endif /* _NET_IP_MP_ALG_H */
+diff -Nurb linux-2.6.22-570/include/net/llc_conn.h linux-2.6.22-590/include/net/llc_conn.h
+--- linux-2.6.22-570/include/net/llc_conn.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/net/llc_conn.h 2008-01-29 22:12:32.000000000 -0500
+@@ -93,7 +93,7 @@
+ return skb->cb[sizeof(skb->cb) - 1];
+ }
+
+-extern struct sock *llc_sk_alloc(int family, gfp_t priority,
++extern struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority,
+ struct proto *prot);
+ extern void llc_sk_free(struct sock *sk);
+
diff -Nurb linux-2.6.22-570/include/net/mip6.h linux-2.6.22-590/include/net/mip6.h
--- linux-2.6.22-570/include/net/mip6.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/net/mip6.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/net/mip6.h 2008-01-29 22:12:32.000000000 -0500
@@ -54,8 +54,4 @@
#define IP6_MH_TYPE_BERROR 7 /* Binding Error */
#define IP6_MH_TYPE_MAX IP6_MH_TYPE_BERROR
-extern int mip6_mh_filter(struct sock *sk, struct sk_buff *skb);
-
#endif
+diff -Nurb linux-2.6.22-570/include/net/neighbour.h linux-2.6.22-590/include/net/neighbour.h
+--- linux-2.6.22-570/include/net/neighbour.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/net/neighbour.h 2008-01-29 22:12:32.000000000 -0500
+@@ -34,6 +34,7 @@
+
+ struct neigh_parms
+ {
++ struct net *net;
+ struct net_device *dev;
+ struct neigh_parms *next;
+ int (*neigh_setup)(struct neighbour *);
+@@ -126,6 +127,7 @@
+ struct pneigh_entry
+ {
+ struct pneigh_entry *next;
++ struct net *net;
+ struct net_device *dev;
+ u8 flags;
+ u8 key[0];
+@@ -187,6 +189,7 @@
+ const void *pkey,
+ struct net_device *dev);
+ extern struct neighbour * neigh_lookup_nodev(struct neigh_table *tbl,
++ struct net *net,
+ const void *pkey);
+ extern struct neighbour * neigh_create(struct neigh_table *tbl,
+ const void *pkey,
+@@ -205,21 +208,24 @@
+ struct net_device *dev);
+
+ extern struct neigh_parms *neigh_parms_alloc(struct net_device *dev, struct neigh_table *tbl);
++extern struct neigh_parms *neigh_parms_alloc_default(struct neigh_table *tbl, struct net *net);
+ extern void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms);
+ extern void neigh_parms_destroy(struct neigh_parms *parms);
+ extern unsigned long neigh_rand_reach_time(unsigned long base);
+
+ extern void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
+ struct sk_buff *skb);
+-extern struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl, const void *key, struct net_device *dev, int creat);
+-extern int pneigh_delete(struct neigh_table *tbl, const void *key, struct net_device *dev);
++extern struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev, int creat);
++extern int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev);
+
+ extern void neigh_app_ns(struct neighbour *n);
+ extern void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void *), void *cookie);
+ extern void __neigh_for_each_release(struct neigh_table *tbl, int (*cb)(struct neighbour *));
+ extern void pneigh_for_each(struct neigh_table *tbl, void (*cb)(struct pneigh_entry *));
+
+-struct neigh_seq_state {
++struct neigh_seq_state
++{
++ struct net *net;
+ struct neigh_table *tbl;
+ void *(*neigh_sub_iter)(struct neigh_seq_state *state,
+ struct neighbour *n, loff_t *pos);
+diff -Nurb linux-2.6.22-570/include/net/net_namespace.h linux-2.6.22-590/include/net/net_namespace.h
+--- linux-2.6.22-570/include/net/net_namespace.h 1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.22-590/include/net/net_namespace.h 2008-01-29 22:12:32.000000000 -0500
+@@ -0,0 +1,236 @@
++/*
++ * Operations on the network namespace
++ */
++#ifndef __NET_NET_NAMESPACE_H
++#define __NET_NET_NAMESPACE_H
++
++#include <asm/atomic.h>
++#include <linux/workqueue.h>
++#include <linux/list.h>
++#include <linux/proc_fs.h>
++#include <linux/sysctl.h>
++#include <linux/netdevice.h>
++#include <linux/timer.h>
++
++struct sock;
++struct xt_af_pernet;
++struct ipv4_devconf;
++struct neigh_parms;
++struct inet_peer;
++struct xt_table;
++struct net {
++ atomic_t count; /* To decided when the network namespace
++ * should go
++ */
++ atomic_t use_count; /* For references we destroy on demand */
++ struct list_head list; /* list of network namespace structures */
++ struct work_struct work; /* work struct for freeing */
++
++#ifdef CONFIG_PROC_FS
++ struct proc_dir_entry *proc_net;
++ struct proc_dir_entry *proc_net_stat;
++ struct proc_dir_entry proc_net_root;
++# ifdef CONFIG_NETFILTER
++ struct proc_dir_entry *proc_net_netfilter;
++# endif
++#endif
++#ifdef CONFIG_SYSCTL
++ struct ctl_table_header net_table_header;
++#endif
++ struct net_device loopback_dev; /* The loopback */
++ struct list_head dev_base_head; /* All devices */
++
++ struct hlist_head *dev_name_head;
++ struct hlist_head *dev_index_head;
++
++ struct sock * rtnl; /* rtnetlink socket */
++
++
++ /* core netfilter */
++ struct xt_af_pernet * xtn;
++
++ /* core fib_rules */
++ struct list_head rules_ops;
++ spinlock_t rules_mod_lock;
++
++#ifdef CONFIG_XFRM
++ u32 sysctl_xfrm_aevent_etime;
++ u32 sysctl_xfrm_aevent_rseqth;
++ int sysctl_xfrm_larval_drop;
++ u32 sysctl_xfrm_acq_expires;
++#endif /* CONFIG_XFRM */
++
++ int sysctl_somaxconn;
++
++#ifdef CONFIG_PACKET
++ /* List of all packet sockets. */
++ rwlock_t packet_sklist_lock;
++ struct hlist_head packet_sklist;
++#endif /* CONFIG_PACKET */
++#ifdef CONFIG_UNIX
++ int sysctl_unix_max_dgram_qlen;
++ void * unix_sysctl;
++#endif /* CONFIG_UNIX */
++#ifdef CONFIG_IP_MULTIPLE_TABLES
++ void * fib4_table;
++#endif /* CONFIG_IP_MULTIPLE_TABLES */
++#ifdef CONFIG_IP_FIB_HASH
++ int fn_hash_last_dflt;
++#endif
++#ifdef CONFIG_IP_FIB_TRIE
++ int trie_last_dflt;
++#endif
++#ifndef CONFIG_IP_MULTIPLE_TABLES
++ struct fib_table *ip_fib_local_table;
++ struct fib_table *ip_fib_main_table;
++#endif
++ struct hlist_head *ip_fib_table_hash;
++ struct sock *nlfl;
++
++ /* fib_semantics */
++ struct hlist_head *fib_info_hash;
++ struct hlist_head *fib_info_laddrhash;
++ unsigned int fib_info_hash_size;
++ unsigned int fib_info_cnt;
++ struct hlist_head *fib_info_devhash;
++
++ /* af_inet.c */
++ int sysctl_ip_nonlocal_bind; /* __read_mostly */
++ int sysctl_ip_default_ttl; /* __read_mostly */
++ int sysctl_ipfrag_high_thresh;
++ int sysctl_ipfrag_low_thresh;
++ int sysctl_ipfrag_time;
++ int sysctl_ipfrag_secret_interval;
++ int sysctl_ipfrag_max_dist;
++ int sysctl_ipv4_no_pmtu_disc;
++ int sysctl_local_port_range[2];
++ int sysctl_ip_dynaddr;
++ int sysctl_tcp_timestamps; /* __read_mostly */
++ int sysctl_tcp_window_scaling; /* __read_mostly */
++ /* inetpeer.c */
++ int inet_peer_threshold;
++ int inet_peer_minttl;
++ int inet_peer_maxttl;
++ int inet_peer_gc_mintime;
++ int inet_peer_gc_maxtime;
++
++ /* devinet */
++ struct ipv4_devconf *ipv4_devconf;
++ struct ipv4_devconf *ipv4_devconf_dflt;
++
++ /* arp.c */
++ struct neigh_parms *arp_neigh_parms_default;
++
++ /* icmp.c */
++ struct socket **__icmp_socket;
++
++ /* inetpeer.c */
++ struct inet_peer *peer_root;
++ int peer_total;
++ struct inet_peer *inet_peer_unused_head;
++ struct inet_peer **inet_peer_unused_tailp;
++ struct timer_list peer_periodic_timer;
++
++ /* ip_fragment.c */
++ struct hlist_head *ipq_hash;
++ u32 ipfrag_hash_rnd;
++ struct list_head ipq_lru_list;
++ int ip_frag_nqueues;
++ atomic_t ip_frag_mem;
++ struct timer_list ipfrag_secret_timer;
++
++ /* udp.c */
++ int udp_port_rover;
++
++ /* iptable_filter.c */
++ struct xt_table *ip_packet_filter;
++};
++
++extern struct net init_net;
++extern struct list_head net_namespace_list;
++
++extern struct net *copy_net_ns(unsigned long flags, struct net *net_ns);
++extern void __put_net(struct net *net);
++
++static inline struct net *get_net(struct net *net)
++{
++ atomic_inc(&net->count);
++ return net;
++}
++
++static inline void put_net(struct net *net)
++{
++ if (atomic_dec_and_test(&net->count))
++ __put_net(net);
++}
++
++static inline struct net *hold_net(struct net *net)
++{
++ atomic_inc(&net->use_count);
++ return net;
++}
++
++static inline void release_net(struct net *net)
++{
++ atomic_dec(&net->use_count);
++}
++
++extern void net_lock(void);
++extern void net_unlock(void);
++
++#define for_each_net(VAR) \
++ list_for_each_entry(VAR, &net_namespace_list, list)
++
++
++struct pernet_operations {
++ struct list_head list;
++ int (*init)(struct net *net);
++ void (*exit)(struct net *net);
++};
++
++extern int register_pernet_subsys(struct pernet_operations *);
++extern void unregister_pernet_subsys(struct pernet_operations *);
++extern int register_pernet_device(struct pernet_operations *);
++extern void unregister_pernet_device(struct pernet_operations *);
++
++#ifdef CONFIG_PROC_FS
++static inline struct net *PDE_NET(struct proc_dir_entry *pde)
++{
++ return pde->parent->data;
++}
++
++static inline struct net *PROC_NET(const struct inode *inode)
++{
++ return PDE_NET(PDE(inode));
++}
++
++static inline struct proc_dir_entry *proc_net_create(struct net *net,
++ const char *name, mode_t mode, get_info_t *get_info)
++{
++ return create_proc_info_entry(name,mode, net->proc_net, get_info);
++}
++
++static inline struct proc_dir_entry *proc_net_fops_create(struct net *net,
++ const char *name, mode_t mode, const struct file_operations *fops)
++{
++ struct proc_dir_entry *res =
++ create_proc_entry(name, mode, net->proc_net);
++ if (res)
++ res->proc_fops = fops;
++ return res;
++}
++
++static inline void proc_net_remove(struct net *net, const char *name)
++{
++ remove_proc_entry(name, net->proc_net);
++}
++
++#else
++
++#define proc_net_fops_create(net, name, mode, fops) ({ (void)(mode), NULL; })
++#define proc_net_create(net, name, mode, info) ({ (void)(mode), NULL; })
++static inline void proc_net_remove(struct net *net, const char *name) {}
++
++#endif /* CONFIG_PROC_FS */
++
++#endif /* __NET_NET_NAMESPACE_H */
diff -Nurb linux-2.6.22-570/include/net/netlink.h linux-2.6.22-590/include/net/netlink.h
--- linux-2.6.22-570/include/net/netlink.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/net/netlink.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/net/netlink.h 2008-01-29 22:12:32.000000000 -0500
@@ -118,6 +118,9 @@
* Nested Attributes Construction:
* nla_nest_start(skb, type) start a nested attribute
* All other Exact length of attribute payload
*
* Example:
-@@ -733,6 +739,39 @@
+@@ -212,6 +218,7 @@
+ struct nl_info {
+ struct nlmsghdr *nlh;
+ u32 pid;
++ struct net *net;
+ };
+
+ extern void netlink_run_queue(struct sock *sk, unsigned int *qlen,
+@@ -733,6 +740,39 @@
{
return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
}
/**
* nla_put_u8 - Add a u16 netlink attribute to a socket buffer
* @skb: socket buffer to add attribute to
-@@ -965,6 +1004,51 @@
+@@ -965,6 +1005,51 @@
}
/**
* nla_nest_cancel - Cancel nesting of attributes
* @skb: socket buffer the message is stored in
* @start: container attribute
+diff -Nurb linux-2.6.22-570/include/net/pkt_cls.h linux-2.6.22-590/include/net/pkt_cls.h
+--- linux-2.6.22-570/include/net/pkt_cls.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/net/pkt_cls.h 2008-01-29 22:12:32.000000000 -0500
+@@ -2,6 +2,7 @@
+ #define __NET_PKT_CLS_H
+
+ #include <linux/pkt_cls.h>
++#include <net/net_namespace.h>
+ #include <net/sch_generic.h>
+ #include <net/act_api.h>
+
+@@ -357,7 +358,7 @@
+ if (indev[0]) {
+ if (!skb->iif)
+ return 0;
+- dev = __dev_get_by_index(skb->iif);
++ dev = __dev_get_by_index(&init_net, skb->iif);
+ if (!dev || strcmp(indev, dev->name))
+ return 0;
+ }
+diff -Nurb linux-2.6.22-570/include/net/protocol.h linux-2.6.22-590/include/net/protocol.h
+--- linux-2.6.22-570/include/net/protocol.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/net/protocol.h 2008-01-29 22:12:32.000000000 -0500
+@@ -86,6 +86,7 @@
+ #define INET_PROTOSW_REUSE 0x01 /* Are ports automatically reusable? */
+ #define INET_PROTOSW_PERMANENT 0x02 /* Permanent protocols are unremovable. */
+ #define INET_PROTOSW_ICSK 0x04 /* Is this an inet_connection_sock? */
++#define INET_PROTOSW_NETNS 0x08 /* Multiple namespaces support? */
+
+ extern struct net_protocol *inet_protocol_base;
+ extern struct net_protocol *inet_protos[MAX_INET_PROTOS];
+diff -Nurb linux-2.6.22-570/include/net/raw.h linux-2.6.22-590/include/net/raw.h
+--- linux-2.6.22-570/include/net/raw.h 2008-01-29 22:12:24.000000000 -0500
++++ linux-2.6.22-590/include/net/raw.h 2008-01-29 22:12:32.000000000 -0500
+@@ -34,7 +34,7 @@
+ extern rwlock_t raw_v4_lock;
+
+
+-extern struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
++extern struct sock *__raw_v4_lookup(struct net *net, struct sock *sk, unsigned short num,
+ __be32 raddr, __be32 laddr,
+ int dif, int tag);
+
diff -Nurb linux-2.6.22-570/include/net/rawv6.h linux-2.6.22-590/include/net/rawv6.h
--- linux-2.6.22-570/include/net/rawv6.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/net/rawv6.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/net/rawv6.h 2008-01-29 22:12:32.000000000 -0500
@@ -3,6 +3,8 @@
#ifdef __KERNEL__
#endif
diff -Nurb linux-2.6.22-570/include/net/route.h linux-2.6.22-590/include/net/route.h
---- linux-2.6.22-570/include/net/route.h 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/include/net/route.h 2008-03-15 10:35:47.000000000 -0400
-@@ -66,7 +66,6 @@
+--- linux-2.6.22-570/include/net/route.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/net/route.h 2008-01-29 22:12:32.000000000 -0500
+@@ -27,6 +27,7 @@
+ #include <net/dst.h>
+ #include <net/inetpeer.h>
+ #include <net/flow.h>
++#include <net/sock.h>
+ #include <net/inet_sock.h>
+ #include <linux/in_route.h>
+ #include <linux/rtnetlink.h>
+@@ -66,7 +67,6 @@
unsigned rt_flags;
__u16 rt_type;
__be32 rt_dst; /* Path destination */
__be32 rt_src; /* Path source */
+@@ -123,9 +123,9 @@
+ extern unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu);
+ extern void ip_rt_send_redirect(struct sk_buff *skb);
+
+-extern unsigned inet_addr_type(__be32 addr);
++extern unsigned inet_addr_type(struct net *net, __be32 addr);
+ extern void ip_rt_multicast_event(struct in_device *);
+-extern int ip_rt_ioctl(unsigned int cmd, void __user *arg);
++extern int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg);
+ extern void ip_rt_get_source(u8 *src, struct rtable *rt);
+ extern int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb);
+
+@@ -154,7 +154,8 @@
+ __be16 sport, __be16 dport, struct sock *sk,
+ int flags)
+ {
+- struct flowi fl = { .oif = oif,
++ struct flowi fl = { .fl_net = sk->sk_net,
++ .oif = oif,
+ .nl_u = { .ip4_u = { .daddr = dst,
+ .saddr = src,
+ .tos = tos } },
+@@ -199,6 +200,7 @@
+ struct flowi fl;
+
+ memcpy(&fl, &(*rp)->fl, sizeof(fl));
++ fl.fl_net = sk->sk_net;
+ fl.fl_ip_sport = sport;
+ fl.fl_ip_dport = dport;
+ fl.proto = protocol;
diff -Nurb linux-2.6.22-570/include/net/rtnetlink.h linux-2.6.22-590/include/net/rtnetlink.h
--- linux-2.6.22-570/include/net/rtnetlink.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/net/rtnetlink.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/net/rtnetlink.h 2008-01-29 22:12:32.000000000 -0500
@@ -22,4 +22,62 @@
return AF_UNSPEC;
}
+#define MODULE_ALIAS_RTNL_LINK(kind) MODULE_ALIAS("rtnl-link-" kind)
+
#endif
+diff -Nurb linux-2.6.22-570/include/net/sock.h linux-2.6.22-590/include/net/sock.h
+--- linux-2.6.22-570/include/net/sock.h 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/include/net/sock.h 2008-01-29 22:12:32.000000000 -0500
+@@ -55,6 +55,7 @@
+ #include <asm/atomic.h>
+ #include <net/dst.h>
+ #include <net/checksum.h>
++#include <net/net_namespace.h>
+
+ /*
+ * This structure really needs to be cleaned up.
+@@ -105,6 +106,7 @@
+ * @skc_refcnt: reference count
+ * @skc_hash: hash value used with various protocol lookup tables
+ * @skc_prot: protocol handlers inside a network family
++ * @skc_net: reference to the network namespace of this socket
+ *
+ * This is the minimal network layer representation of sockets, the header
+ * for struct sock and struct inet_timewait_sock.
+@@ -119,6 +121,7 @@
+ atomic_t skc_refcnt;
+ unsigned int skc_hash;
+ struct proto *skc_prot;
++ struct net *skc_net;
+ xid_t skc_xid;
+ struct vx_info *skc_vx_info;
+ nid_t skc_nid;
+@@ -199,6 +202,7 @@
+ #define sk_refcnt __sk_common.skc_refcnt
+ #define sk_hash __sk_common.skc_hash
+ #define sk_prot __sk_common.skc_prot
++#define sk_net __sk_common.skc_net
+ #define sk_xid __sk_common.skc_xid
+ #define sk_vx_info __sk_common.skc_vx_info
+ #define sk_nid __sk_common.skc_nid
+@@ -781,7 +785,7 @@
+ SINGLE_DEPTH_NESTING)
+ #define bh_unlock_sock(__sk) spin_unlock(&((__sk)->sk_lock.slock))
+
+-extern struct sock *sk_alloc(int family,
++extern struct sock *sk_alloc(struct net *net, int family,
+ gfp_t priority,
+ struct proto *prot, int zero_it);
+ extern void sk_free(struct sock *sk);
+@@ -1010,6 +1014,7 @@
+ #endif
+
+ memcpy(nsk, osk, osk->sk_prot->obj_size);
++ get_net(nsk->sk_net);
+ #ifdef CONFIG_SECURITY_NETWORK
+ nsk->sk_security = sptr;
+ security_sk_clone(osk, nsk);
+@@ -1373,6 +1378,7 @@
+
+ #ifdef CONFIG_SYSCTL
+ extern struct ctl_table core_table[];
++extern struct ctl_table multi_core_table[];
+ #endif
+
+ extern int sysctl_optmem_max;
+diff -Nurb linux-2.6.22-570/include/net/tcp.h linux-2.6.22-590/include/net/tcp.h
+--- linux-2.6.22-570/include/net/tcp.h 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/include/net/tcp.h 2008-01-29 22:12:32.000000000 -0500
+@@ -191,8 +191,6 @@
+ extern struct inet_timewait_death_row tcp_death_row;
+
+ /* sysctl variables for tcp */
+-extern int sysctl_tcp_timestamps;
+-extern int sysctl_tcp_window_scaling;
+ extern int sysctl_tcp_sack;
+ extern int sysctl_tcp_fin_timeout;
+ extern int sysctl_tcp_keepalive_time;
+@@ -1293,6 +1291,7 @@
+ };
+
+ struct tcp_iter_state {
++ struct net *net;
+ sa_family_t family;
+ enum tcp_seq_states state;
+ struct sock *syn_wait_sk;
+@@ -1300,8 +1299,8 @@
+ struct seq_operations seq_ops;
+ };
+
+-extern int tcp_proc_register(struct tcp_seq_afinfo *afinfo);
+-extern void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo);
++extern int tcp_proc_register(struct net *net, struct tcp_seq_afinfo *afinfo);
++extern void tcp_proc_unregister(struct net *net, struct tcp_seq_afinfo *afinfo);
+
+ extern struct request_sock_ops tcp_request_sock_ops;
+
diff -Nurb linux-2.6.22-570/include/net/tipc/tipc_port.h linux-2.6.22-590/include/net/tipc/tipc_port.h
--- linux-2.6.22-570/include/net/tipc/tipc_port.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/net/tipc/tipc_port.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/net/tipc/tipc_port.h 2008-01-29 22:12:32.000000000 -0500
@@ -1,8 +1,8 @@
/*
* include/net/tipc/tipc_port.h: Include file for privileged access to TIPC ports
u32 ref;
struct tipc_msg phdr;
};
+diff -Nurb linux-2.6.22-570/include/net/udp.h linux-2.6.22-590/include/net/udp.h
+--- linux-2.6.22-570/include/net/udp.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/net/udp.h 2008-01-29 22:12:32.000000000 -0500
+@@ -160,6 +160,7 @@
+ };
+
+ struct udp_iter_state {
++ struct net *net;
+ sa_family_t family;
+ struct hlist_head *hashtable;
+ int bucket;
+@@ -167,8 +168,8 @@
+ };
+
+ #ifdef CONFIG_PROC_FS
+-extern int udp_proc_register(struct udp_seq_afinfo *afinfo);
+-extern void udp_proc_unregister(struct udp_seq_afinfo *afinfo);
++extern int udp_proc_register(struct net *net, struct udp_seq_afinfo *afinfo);
++extern void udp_proc_unregister(struct net *net, struct udp_seq_afinfo *afinfo);
+
+ extern int udp4_proc_init(void);
+ extern void udp4_proc_exit(void);
+diff -Nurb linux-2.6.22-570/include/net/wext.h linux-2.6.22-590/include/net/wext.h
+--- linux-2.6.22-570/include/net/wext.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/include/net/wext.h 2008-01-29 22:12:32.000000000 -0500
+@@ -5,16 +5,23 @@
+ * wireless extensions interface to the core code
+ */
+
++struct net;
++
+ #ifdef CONFIG_WIRELESS_EXT
+-extern int wext_proc_init(void);
+-extern int wext_handle_ioctl(struct ifreq *ifr, unsigned int cmd,
++extern int wext_proc_init(struct net *net);
++extern void wext_proc_exit(struct net *net);
++extern int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd,
+ void __user *arg);
+ #else
+-static inline int wext_proc_init(void)
++static inline int wext_proc_init(struct net *net)
+ {
+ return 0;
+ }
+-static inline int wext_handle_ioctl(struct ifreq *ifr, unsigned int cmd,
++static inline void wext_proc_exit(struct net *net)
++{
++ return;
++}
++static inline int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd,
+ void __user *arg)
+ {
+ return -EINVAL;
diff -Nurb linux-2.6.22-570/include/net/xfrm.h linux-2.6.22-590/include/net/xfrm.h
---- linux-2.6.22-570/include/net/xfrm.h 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/include/net/xfrm.h 2008-03-15 10:35:47.000000000 -0400
-@@ -19,9 +19,19 @@
+--- linux-2.6.22-570/include/net/xfrm.h 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/include/net/xfrm.h 2008-01-29 22:12:32.000000000 -0500
+@@ -19,13 +19,21 @@
#include <net/ipv6.h>
#include <net/ip6_fib.h>
+ MODULE_ALIAS("xfrm-type-" __stringify(family) "-" __stringify(proto))
extern struct sock *xfrm_nl;
- extern u32 sysctl_xfrm_aevent_etime;
-@@ -509,11 +519,9 @@
+-extern u32 sysctl_xfrm_aevent_etime;
+-extern u32 sysctl_xfrm_aevent_rseqth;
+
+ extern struct mutex xfrm_cfg_mutex;
+
+@@ -509,11 +517,9 @@
case IPPROTO_ICMPV6:
port = htons(fl->fl_icmp_type);
break;
}
diff -Nurb linux-2.6.22-570/include/scsi/iscsi_if.h linux-2.6.22-590/include/scsi/iscsi_if.h
--- linux-2.6.22-570/include/scsi/iscsi_if.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/scsi/iscsi_if.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/scsi/iscsi_if.h 2008-01-29 22:12:32.000000000 -0500
@@ -48,6 +48,7 @@
ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT = UEVENT_BASE + 14,
* These flags describes reason of stop_conn() call
diff -Nurb linux-2.6.22-570/include/scsi/libiscsi.h linux-2.6.22-590/include/scsi/libiscsi.h
--- linux-2.6.22-570/include/scsi/libiscsi.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/scsi/libiscsi.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/scsi/libiscsi.h 2008-01-29 22:12:32.000000000 -0500
@@ -48,9 +48,8 @@
#define debug_scsi(fmt...)
#endif
extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *,
diff -Nurb linux-2.6.22-570/include/scsi/scsi_cmnd.h linux-2.6.22-590/include/scsi/scsi_cmnd.h
--- linux-2.6.22-570/include/scsi/scsi_cmnd.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/scsi/scsi_cmnd.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/scsi/scsi_cmnd.h 2008-01-29 22:12:32.000000000 -0500
@@ -135,4 +135,24 @@
extern struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *, gfp_t);
extern void scsi_free_sgtable(struct scatterlist *, int);
#endif /* _SCSI_SCSI_CMND_H */
diff -Nurb linux-2.6.22-570/include/scsi/scsi_device.h linux-2.6.22-590/include/scsi/scsi_device.h
--- linux-2.6.22-570/include/scsi/scsi_device.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/scsi/scsi_device.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/scsi/scsi_device.h 2008-01-29 22:12:32.000000000 -0500
@@ -287,6 +287,7 @@
extern void scsi_target_unblock(struct device *);
extern void scsi_remove_target(struct device *);
extern int scsi_is_target_device(const struct device *);
diff -Nurb linux-2.6.22-570/include/scsi/scsi_host.h linux-2.6.22-590/include/scsi/scsi_host.h
--- linux-2.6.22-570/include/scsi/scsi_host.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/scsi/scsi_host.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/scsi/scsi_host.h 2008-01-29 22:12:32.000000000 -0500
@@ -339,12 +339,6 @@
enum scsi_eh_timer_return (* eh_timed_out)(struct scsi_cmnd *);
diff -Nurb linux-2.6.22-570/include/scsi/scsi_transport_fc.h linux-2.6.22-590/include/scsi/scsi_transport_fc.h
--- linux-2.6.22-570/include/scsi/scsi_transport_fc.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/scsi/scsi_transport_fc.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/scsi/scsi_transport_fc.h 2008-01-29 22:12:32.000000000 -0500
@@ -19,7 +19,7 @@
*
* ========
#endif /* SCSI_TRANSPORT_FC_H */
diff -Nurb linux-2.6.22-570/include/scsi/scsi_transport_iscsi.h linux-2.6.22-590/include/scsi/scsi_transport_iscsi.h
--- linux-2.6.22-570/include/scsi/scsi_transport_iscsi.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/include/scsi/scsi_transport_iscsi.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/include/scsi/scsi_transport_iscsi.h 2008-01-29 22:12:32.000000000 -0500
@@ -79,7 +79,8 @@
char *name;
unsigned int caps;
};
diff -Nurb linux-2.6.22-570/init/Kconfig linux-2.6.22-590/init/Kconfig
---- linux-2.6.22-570/init/Kconfig 2008-03-15 10:34:28.000000000 -0400
-+++ linux-2.6.22-590/init/Kconfig 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/init/Kconfig 2008-01-29 22:12:25.000000000 -0500
++++ linux-2.6.22-590/init/Kconfig 2008-01-29 22:12:32.000000000 -0500
@@ -120,15 +120,6 @@
section 6.4 of the Linux Programmer's Guide, available from
<http://www.tldp.org/guides.html>.
config MODULES
diff -Nurb linux-2.6.22-570/init/do_mounts_initrd.c linux-2.6.22-590/init/do_mounts_initrd.c
--- linux-2.6.22-570/init/do_mounts_initrd.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/init/do_mounts_initrd.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/init/do_mounts_initrd.c 2008-01-29 22:12:32.000000000 -0500
@@ -56,12 +56,9 @@
sys_chroot(".");
/* move initrd to rootfs' /old */
sys_fchdir(old_fd);
diff -Nurb linux-2.6.22-570/init/main.c linux-2.6.22-590/init/main.c
---- linux-2.6.22-570/init/main.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/init/main.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/init/main.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/init/main.c 2008-01-29 22:12:32.000000000 -0500
@@ -39,6 +39,7 @@
#include <linux/writeback.h>
#include <linux/cpu.h>
taskstats_init_early();
delayacct_init();
diff -Nurb linux-2.6.22-570/ipc/msg.c linux-2.6.22-590/ipc/msg.c
---- linux-2.6.22-570/ipc/msg.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/ipc/msg.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/ipc/msg.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/ipc/msg.c 2008-01-29 22:12:32.000000000 -0500
@@ -88,7 +88,7 @@
static int sysvipc_msg_proc_show(struct seq_file *s, void *it);
#endif
void __init msg_init(void)
{
diff -Nurb linux-2.6.22-570/ipc/sem.c linux-2.6.22-590/ipc/sem.c
---- linux-2.6.22-570/ipc/sem.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/ipc/sem.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/ipc/sem.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/ipc/sem.c 2008-01-29 22:12:32.000000000 -0500
@@ -123,7 +123,7 @@
#define sc_semopm sem_ctls[2]
#define sc_semmni sem_ctls[3]
void __init sem_init (void)
{
diff -Nurb linux-2.6.22-570/ipc/shm.c linux-2.6.22-590/ipc/shm.c
---- linux-2.6.22-570/ipc/shm.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/ipc/shm.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/ipc/shm.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/ipc/shm.c 2008-01-29 22:12:32.000000000 -0500
@@ -79,7 +79,7 @@
static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
#endif
.set_policy = shm_set_policy,
.get_policy = shm_get_policy,
diff -Nurb linux-2.6.22-570/ipc/util.c linux-2.6.22-590/ipc/util.c
---- linux-2.6.22-570/ipc/util.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/ipc/util.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/ipc/util.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/ipc/util.c 2008-01-29 22:12:32.000000000 -0500
@@ -52,7 +52,6 @@
},
};
diff -Nurb linux-2.6.22-570/ipc/util.h linux-2.6.22-590/ipc/util.h
--- linux-2.6.22-570/ipc/util.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/ipc/util.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/ipc/util.h 2008-01-29 22:12:32.000000000 -0500
@@ -41,12 +41,8 @@
};
void __init ipc_init_proc_interface(const char *path, const char *header,
int ids, int (*show)(struct seq_file *, void *));
diff -Nurb linux-2.6.22-570/kernel/Makefile linux-2.6.22-590/kernel/Makefile
---- linux-2.6.22-570/kernel/Makefile 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/kernel/Makefile 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/kernel/Makefile 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/kernel/Makefile 2008-01-29 22:12:32.000000000 -0500
@@ -4,11 +4,12 @@
obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
diff -Nurb linux-2.6.22-570/kernel/audit.c linux-2.6.22-590/kernel/audit.c
--- linux-2.6.22-570/kernel/audit.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/kernel/audit.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/kernel/audit.c 2008-01-29 22:12:32.000000000 -0500
@@ -391,6 +391,7 @@
{
struct sk_buff *skb;
while (!kthread_should_stop()) {
skb = skb_dequeue(&audit_skb_queue);
wake_up(&audit_backlog_wait);
+@@ -794,8 +795,8 @@
+
+ printk(KERN_INFO "audit: initializing netlink socket (%s)\n",
+ audit_default ? "enabled" : "disabled");
+- audit_sock = netlink_kernel_create(NETLINK_AUDIT, 0, audit_receive,
+- NULL, THIS_MODULE);
++ audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, 0,
++ audit_receive, NULL, THIS_MODULE);
+ if (!audit_sock)
+ audit_panic("cannot initialize netlink socket");
+ else
diff -Nurb linux-2.6.22-570/kernel/auditsc.c linux-2.6.22-590/kernel/auditsc.c
---- linux-2.6.22-570/kernel/auditsc.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/kernel/auditsc.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/kernel/auditsc.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/kernel/auditsc.c 2008-01-29 22:12:32.000000000 -0500
@@ -1500,6 +1500,7 @@
context->names[idx].ino = (unsigned long)-1;
}
* auditsc_get_stamp - get local copies of audit_context values
diff -Nurb linux-2.6.22-570/kernel/container.c linux-2.6.22-590/kernel/container.c
--- linux-2.6.22-570/kernel/container.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/kernel/container.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/kernel/container.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,2545 @@
+/*
+ * kernel/container.c
+ }
+
+ /* Create the container directory, which also creates the container */
-+ ret = vfs_mkdir(inode, dentry, S_IFDIR | 0755);
++ ret = vfs_mkdir(inode, dentry, S_IFDIR | 0755, NULL);
+ child = __d_cont(dentry);
+ dput(dentry);
+ if (ret) {
+}
diff -Nurb linux-2.6.22-570/kernel/container_debug.c linux-2.6.22-590/kernel/container_debug.c
--- linux-2.6.22-570/kernel/container_debug.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/kernel/container_debug.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/kernel/container_debug.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,89 @@
+/*
+ * kernel/ccontainer_debug.c - Example container subsystem that
+};
diff -Nurb linux-2.6.22-570/kernel/cpu_acct.c linux-2.6.22-590/kernel/cpu_acct.c
--- linux-2.6.22-570/kernel/cpu_acct.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/kernel/cpu_acct.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/kernel/cpu_acct.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,185 @@
+/*
+ * kernel/cpu_acct.c - CPU accounting container subsystem
+};
diff -Nurb linux-2.6.22-570/kernel/cpuset.c linux-2.6.22-590/kernel/cpuset.c
--- linux-2.6.22-570/kernel/cpuset.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/kernel/cpuset.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/kernel/cpuset.c 2008-01-29 22:12:32.000000000 -0500
@@ -5,6 +5,7 @@
*
* Copyright (C) 2003 BULL SA.
/* Display task cpus_allowed, mems_allowed in /proc/<pid>/status file. */
char *cpuset_task_status_allowed(struct task_struct *task, char *buffer)
diff -Nurb linux-2.6.22-570/kernel/exit.c linux-2.6.22-590/kernel/exit.c
---- linux-2.6.22-570/kernel/exit.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/kernel/exit.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/kernel/exit.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/kernel/exit.c 2008-01-29 22:12:32.000000000 -0500
@@ -31,7 +31,8 @@
#include <linux/mempolicy.h>
#include <linux/taskstats_kern.h>
if (group_dead && tsk->signal->leader)
diff -Nurb linux-2.6.22-570/kernel/fork.c linux-2.6.22-590/kernel/fork.c
---- linux-2.6.22-570/kernel/fork.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/kernel/fork.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/kernel/fork.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/kernel/fork.c 2008-01-29 22:12:32.000000000 -0500
@@ -29,7 +29,7 @@
#include <linux/nsproxy.h>
#include <linux/capability.h>
{
int retval;
struct task_struct *p = NULL;
-++ int container_callbacks_done = 0;
++ int container_callbacks_done = 0;
struct vx_info *vxi;
struct nx_info *nxi;
if ((err = unshare_thread(unshare_flags)))
diff -Nurb linux-2.6.22-570/kernel/kgdb.c linux-2.6.22-590/kernel/kgdb.c
--- linux-2.6.22-570/kernel/kgdb.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/kernel/kgdb.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/kernel/kgdb.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,1866 @@
+/*
+ * kernel/kgdb.c
+early_param("kgdbwait", opt_kgdb_enter);
diff -Nurb linux-2.6.22-570/kernel/kmod.c linux-2.6.22-590/kernel/kmod.c
--- linux-2.6.22-570/kernel/kmod.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/kernel/kmod.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/kernel/kmod.c 2008-01-29 22:12:32.000000000 -0500
@@ -119,9 +119,10 @@
char **argv;
char **envp;
diff -Nurb linux-2.6.22-570/kernel/module.c linux-2.6.22-590/kernel/module.c
--- linux-2.6.22-570/kernel/module.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/kernel/module.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/kernel/module.c 2008-01-29 22:12:32.000000000 -0500
@@ -67,6 +67,7 @@
/* List of modules, protected by module_mutex AND modlist_lock */
static DEFINE_MUTEX(module_mutex);
printk(KERN_ERR "%s: module is now stuck!\n",
diff -Nurb linux-2.6.22-570/kernel/ns_container.c linux-2.6.22-590/kernel/ns_container.c
--- linux-2.6.22-570/kernel/ns_container.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/kernel/ns_container.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/kernel/ns_container.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,99 @@
+/*
+ * ns_container.c - namespace container subsystem
+ .subsys_id = ns_subsys_id,
+};
diff -Nurb linux-2.6.22-570/kernel/nsproxy.c linux-2.6.22-590/kernel/nsproxy.c
---- linux-2.6.22-570/kernel/nsproxy.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/kernel/nsproxy.c 2008-03-15 10:35:47.000000000 -0400
-@@ -23,6 +23,8 @@
+--- linux-2.6.22-570/kernel/nsproxy.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/kernel/nsproxy.c 2008-01-29 22:12:32.000000000 -0500
+@@ -19,10 +19,13 @@
+ #include <linux/init_task.h>
+ #include <linux/mnt_namespace.h>
+ #include <linux/utsname.h>
++#include <net/net_namespace.h>
+ #include <linux/pid_namespace.h>
#include <linux/vserver/global.h>
#include <linux/vserver/debug.h>
struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);
void get_task_namespaces(struct task_struct *tsk)
-@@ -83,8 +85,15 @@
+@@ -58,6 +61,7 @@
+ struct fs_struct *new_fs)
+ {
+ struct nsproxy *new_nsp;
++ int err = -ENOMEM;
+
+ vxdprintk(VXD_CBIT(space, 4),
+ "unshare_namespaces(0x%08x,%p,%p)",
+@@ -83,8 +87,24 @@
if (IS_ERR(new_nsp->pid_ns))
goto out_pid;
-+ new_nsp->user_ns = copy_user_ns(flags, tsk->nsproxy->user_ns);
++ new_nsp->user_ns = copy_user_ns(flags, orig->user_ns);
+ if (IS_ERR(new_nsp->user_ns))
+ goto out_user;
++
++ new_nsp->net_ns = copy_net_ns(flags, orig->net_ns);
++ if (IS_ERR(new_nsp->net_ns))
++ goto out_net;
+
return new_nsp;
++out_net:
++ if (new_nsp->user_ns)
++ put_user_ns(new_nsp->user_ns);
++ if (new_nsp->net_ns)
++ put_net(new_nsp->net_ns);
+out_user:
+ if (new_nsp->pid_ns)
+ put_pid_ns(new_nsp->pid_ns);
out_pid:
if (new_nsp->ipc_ns)
put_ipc_ns(new_nsp->ipc_ns);
-@@ -95,11 +104,11 @@
+@@ -95,11 +115,11 @@
if (new_nsp->mnt_ns)
put_mnt_ns(new_nsp->mnt_ns);
out_ns:
struct fs_struct *new_fs)
{
return unshare_namespaces(flags, tsk->nsproxy, new_fs);
-@@ -130,7 +139,7 @@
+@@ -130,7 +150,7 @@
* called from clone. This now handles copy for nsproxy and all
* namespaces therein.
*/
{
struct nsproxy *old_ns = tsk->nsproxy;
struct nsproxy *new_ns = NULL;
-@@ -144,7 +153,7 @@
+@@ -144,9 +164,15 @@
get_nsproxy(old_ns);
- if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC)))
-+ if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER)))
++ if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER | CLONE_NEWNET)))
return 0;
++ #ifndef CONFIG_NET_NS
++ if (unshare_flags & CLONE_NEWNET)
++ return -EINVAL;
++ #endif
++
++
if (!capable(CAP_SYS_ADMIN)) {
-@@ -158,7 +167,14 @@
+ err = -EPERM;
+ goto out;
+@@ -158,7 +184,14 @@
goto out;
}
out:
put_nsproxy(old_ns);
vxdprintk(VXD_CBIT(space, 3),
-@@ -194,25 +210,33 @@
+@@ -194,25 +227,37 @@
"unshare_nsproxy_namespaces(0x%08lx,[%p])",
unshare_flags, current->nsproxy);
- if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC)))
+ if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
-+ CLONE_NEWUSER)))
++ CLONE_NEWUSER | CLONE_NEWNET)))
return 0;
-#ifndef CONFIG_IPC_NS
-
-#ifndef CONFIG_UTS_NS
- if (unshare_flags & CLONE_NEWUTS)
-- return -EINVAL;
--#endif
++#ifndef CONFIG_NET_NS
++ if (unshare_flags & CLONE_NEWNET)
+ return -EINVAL;
+ #endif
-
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
+}
+
+module_init(nsproxy_cache_init);
+diff -Nurb linux-2.6.22-570/kernel/nsproxy.c.orig linux-2.6.22-590/kernel/nsproxy.c.orig
+--- linux-2.6.22-570/kernel/nsproxy.c.orig 1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.22-590/kernel/nsproxy.c.orig 2008-01-29 22:12:32.000000000 -0500
+@@ -0,0 +1,264 @@
++/*
++ * Copyright (C) 2006 IBM Corporation
++ *
++ * Author: Serge Hallyn <serue@us.ibm.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation, version 2 of the
++ * License.
++ *
++ * Jun 2006 - namespaces support
++ * OpenVZ, SWsoft Inc.
++ * Pavel Emelianov <xemul@openvz.org>
++ */
++
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/nsproxy.h>
++#include <linux/init_task.h>
++#include <linux/mnt_namespace.h>
++#include <linux/utsname.h>
++#include <net/net_namespace.h>
++#include <linux/pid_namespace.h>
++#include <linux/vserver/global.h>
++#include <linux/vserver/debug.h>
++
++static struct kmem_cache *nsproxy_cachep;
++
++struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);
++
++void get_task_namespaces(struct task_struct *tsk)
++{
++ struct nsproxy *ns = tsk->nsproxy;
++ if (ns) {
++ get_nsproxy(ns);
++ }
++}
++
++/*
++ * creates a copy of "orig" with refcount 1.
++ */
++static inline struct nsproxy *clone_nsproxy(struct nsproxy *orig)
++{
++ struct nsproxy *ns;
++
++ ns = kmemdup(orig, sizeof(struct nsproxy), GFP_KERNEL);
++ if (ns)
++ atomic_set(&ns->count, 1);
++ vxdprintk(VXD_CBIT(space, 2), "clone_nsproxy(%p[%u] = %p[1]",
++ orig, atomic_read(&orig->count), ns);
++ atomic_inc(&vs_global_nsproxy);
++ return ns;
++}
++
++/*
++ * Create new nsproxy and all of its the associated namespaces.
++ * Return the newly created nsproxy. Do not attach this to the task,
++ * leave it to the caller to do proper locking and attach it to task.
++ */
++static struct nsproxy *unshare_namespaces(int flags, struct nsproxy *orig,
++ struct fs_struct *new_fs)
++{
++ struct nsproxy *new_nsp;
++ int err = -ENOMEM;
++
++ vxdprintk(VXD_CBIT(space, 4),
++ "unshare_namespaces(0x%08x,%p,%p)",
++ flags, orig, new_fs);
++
++ new_nsp = clone_nsproxy(orig);
++ if (!new_nsp)
++ return ERR_PTR(-ENOMEM);
++
++ new_nsp->mnt_ns = copy_mnt_ns(flags, orig->mnt_ns, new_fs);
++ if (IS_ERR(new_nsp->mnt_ns))
++ goto out_ns;
++
++ new_nsp->uts_ns = copy_utsname(flags, orig->uts_ns);
++ if (IS_ERR(new_nsp->uts_ns))
++ goto out_uts;
++
++ new_nsp->ipc_ns = copy_ipcs(flags, orig->ipc_ns);
++ if (IS_ERR(new_nsp->ipc_ns))
++ goto out_ipc;
++
++ new_nsp->pid_ns = copy_pid_ns(flags, orig->pid_ns);
++ if (IS_ERR(new_nsp->pid_ns))
++ goto out_pid;
++
++ new_nsp->user_ns = copy_user_ns(flags, orig->user_ns);
++ if (IS_ERR(new_nsp->user_ns))
++ goto out_user;
++
++ new_nsp->net_ns = copy_net_ns(flags, orig->net_ns);
++ if (IS_ERR(new_nsp->net_ns))
++ goto out_net;
++
++ return new_nsp;
++
++out_net:
++ if (new_nsp->user_ns)
++ put_user_ns(new_nsp->user_ns);
++ if (new_nsp->net_ns)
++ put_net(new_nsp->net_ns);
++out_user:
++ if (new_nsp->pid_ns)
++ put_pid_ns(new_nsp->pid_ns);
++out_pid:
++ if (new_nsp->ipc_ns)
++ put_ipc_ns(new_nsp->ipc_ns);
++out_ipc:
++ if (new_nsp->uts_ns)
++ put_uts_ns(new_nsp->uts_ns);
++out_uts:
++ if (new_nsp->mnt_ns)
++ put_mnt_ns(new_nsp->mnt_ns);
++out_ns:
++ kmem_cache_free(nsproxy_cachep, new_nsp);
++ return ERR_PTR(err);
++}
++
++static struct nsproxy *create_new_namespaces(unsigned long flags, struct task_struct *tsk,
++ struct fs_struct *new_fs)
++{
++ return unshare_namespaces(flags, tsk->nsproxy, new_fs);
++}
++
++/*
++ * copies the nsproxy, setting refcount to 1, and grabbing a
++ * reference to all contained namespaces.
++ */
++struct nsproxy *copy_nsproxy(struct nsproxy *orig)
++{
++ struct nsproxy *ns = clone_nsproxy(orig);
++
++ if (ns) {
++ if (ns->mnt_ns)
++ get_mnt_ns(ns->mnt_ns);
++ if (ns->uts_ns)
++ get_uts_ns(ns->uts_ns);
++ if (ns->ipc_ns)
++ get_ipc_ns(ns->ipc_ns);
++ if (ns->pid_ns)
++ get_pid_ns(ns->pid_ns);
++ }
++ return ns;
++}
++
++/*
++ * called from clone. This now handles copy for nsproxy and all
++ * namespaces therein.
++ */
++int copy_namespaces(unsigned long flags, struct task_struct *tsk)
++{
++ struct nsproxy *old_ns = tsk->nsproxy;
++ struct nsproxy *new_ns = NULL;
++ int err = 0;
++
++ vxdprintk(VXD_CBIT(space, 7), "copy_namespaces(0x%08x,%p[%p])",
++ flags, tsk, old_ns);
++
++ if (!old_ns)
++ return 0;
++
++ get_nsproxy(old_ns);
++ return 0;
++
++ if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER | CLONE_NEWNET)))
++ return 0;
++
++ #ifndef CONFIG_NET_NS
++ if (unshare_flags & CLONE_NEWNET)
++ return -EINVAL;
++ #endif
++
++
++ if (!capable(CAP_SYS_ADMIN)) {
++ err = -EPERM;
++ goto out;
++ }
++
++ new_ns = create_new_namespaces(flags, tsk, tsk->fs);
++ if (IS_ERR(new_ns)) {
++ err = PTR_ERR(new_ns);
++ goto out;
++ }
++
++ err = ns_container_clone(tsk);
++ if (err) {
++ put_nsproxy(new_ns);
++ goto out;
++ }
++
++ tsk->nsproxy = new_ns;
++
++out:
++ put_nsproxy(old_ns);
++ vxdprintk(VXD_CBIT(space, 3),
++ "copy_namespaces(0x%08x,%p[%p]) = %d [%p]",
++ flags, tsk, old_ns, err, new_ns);
++ return err;
++}
++
++void free_nsproxy(struct nsproxy *ns)
++{
++ if (ns->mnt_ns)
++ put_mnt_ns(ns->mnt_ns);
++ if (ns->uts_ns)
++ put_uts_ns(ns->uts_ns);
++ if (ns->ipc_ns)
++ put_ipc_ns(ns->ipc_ns);
++ if (ns->pid_ns)
++ put_pid_ns(ns->pid_ns);
++ atomic_dec(&vs_global_nsproxy);
++ kfree(ns);
++}
++
++/*
++ * Called from unshare. Unshare all the namespaces part of nsproxy.
++ * On success, returns the new nsproxy.
++ */
++int unshare_nsproxy_namespaces(unsigned long unshare_flags,
++ struct nsproxy **new_nsp, struct fs_struct *new_fs)
++{
++ int err = 0;
++
++ vxdprintk(VXD_CBIT(space, 4),
++ "unshare_nsproxy_namespaces(0x%08lx,[%p])",
++ unshare_flags, current->nsproxy);
++
++ if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
++ CLONE_NEWUSER | CLONE_NEWNET)))
++ return 0;
++
++#ifndef CONFIG_NET_NS
++ if (unshare_flags & CLONE_NEWNET)
++ return -EINVAL;
++#endif
++ if (!capable(CAP_SYS_ADMIN))
++ return -EPERM;
++
++ *new_nsp = create_new_namespaces(unshare_flags, current,
++ new_fs ? new_fs : current->fs);
++ if (IS_ERR(*new_nsp)) {
++ err = PTR_ERR(*new_nsp);
++ goto out;
++ }
++
++ err = ns_container_clone(current);
++ if (err)
++ put_nsproxy(*new_nsp);
++
++out:
++ return err;
++}
++
++static int __init nsproxy_cache_init(void)
++{
++ nsproxy_cachep = kmem_cache_create("nsproxy", sizeof(struct nsproxy),
++ 0, SLAB_PANIC, NULL, NULL);
++ return 0;
++}
++
++module_init(nsproxy_cache_init);
diff -Nurb linux-2.6.22-570/kernel/params.c linux-2.6.22-590/kernel/params.c
---- linux-2.6.22-570/kernel/params.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/kernel/params.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/kernel/params.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/kernel/params.c 2008-01-29 22:12:32.000000000 -0500
@@ -491,7 +491,6 @@
pattr->mattr.show = param_attr_show;
pattr->mattr.store = param_attr_store;
*(gattr++) = &(pattr++)->mattr.attr;
}
diff -Nurb linux-2.6.22-570/kernel/pid.c linux-2.6.22-590/kernel/pid.c
---- linux-2.6.22-570/kernel/pid.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/kernel/pid.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/kernel/pid.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/kernel/pid.c 2008-01-29 22:12:32.000000000 -0500
@@ -379,7 +379,7 @@
}
EXPORT_SYMBOL_GPL(find_get_pid);
BUG_ON(!old_ns);
get_pid_ns(old_ns);
diff -Nurb linux-2.6.22-570/kernel/ptrace.c linux-2.6.22-590/kernel/ptrace.c
---- linux-2.6.22-570/kernel/ptrace.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/kernel/ptrace.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/kernel/ptrace.c 2008-01-29 22:12:20.000000000 -0500
++++ linux-2.6.22-590/kernel/ptrace.c 2008-01-29 22:12:32.000000000 -0500
@@ -143,7 +143,7 @@
return -EPERM;
smp_rmb();
if (!vx_check(task->xid, VS_ADMIN_P|VS_IDENT))
diff -Nurb linux-2.6.22-570/kernel/rcutorture.c linux-2.6.22-590/kernel/rcutorture.c
--- linux-2.6.22-570/kernel/rcutorture.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/kernel/rcutorture.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/kernel/rcutorture.c 2008-01-29 22:12:32.000000000 -0500
@@ -40,6 +40,7 @@
#include <linux/moduleparam.h>
#include <linux/percpu.h>
idx = cur_ops->readlock();
diff -Nurb linux-2.6.22-570/kernel/rtmutex-tester.c linux-2.6.22-590/kernel/rtmutex-tester.c
--- linux-2.6.22-570/kernel/rtmutex-tester.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/kernel/rtmutex-tester.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/kernel/rtmutex-tester.c 2008-01-29 22:12:32.000000000 -0500
@@ -260,6 +260,7 @@
int ret;
for(;;) {
diff -Nurb linux-2.6.22-570/kernel/sched.c linux-2.6.22-590/kernel/sched.c
---- linux-2.6.22-570/kernel/sched.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/kernel/sched.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/kernel/sched.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/kernel/sched.c 2008-01-29 22:12:32.000000000 -0500
@@ -51,8 +51,10 @@
#include <linux/times.h>
#include <linux/tsacct_kern.h>
if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
diff -Nurb linux-2.6.22-570/kernel/seccomp.c linux-2.6.22-590/kernel/seccomp.c
--- linux-2.6.22-570/kernel/seccomp.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/kernel/seccomp.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/kernel/seccomp.c 2008-01-29 22:12:32.000000000 -0500
@@ -10,6 +10,7 @@
#include <linux/sched.h>
+ return ret;
+}
diff -Nurb linux-2.6.22-570/kernel/signal.c linux-2.6.22-590/kernel/signal.c
---- linux-2.6.22-570/kernel/signal.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/kernel/signal.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/kernel/signal.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/kernel/signal.c 2008-01-29 22:12:32.000000000 -0500
@@ -257,6 +257,16 @@
}
}
/* Notify the system that a driver wants to block all signals for this
* process, and wants to be notified if any signals at all were to be
diff -Nurb linux-2.6.22-570/kernel/softirq.c linux-2.6.22-590/kernel/softirq.c
---- linux-2.6.22-570/kernel/softirq.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/kernel/softirq.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/kernel/softirq.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/kernel/softirq.c 2008-01-29 22:12:32.000000000 -0500
@@ -14,6 +14,7 @@
#include <linux/notifier.h>
#include <linux/percpu.h>
diff -Nurb linux-2.6.22-570/kernel/softlockup.c linux-2.6.22-590/kernel/softlockup.c
--- linux-2.6.22-570/kernel/softlockup.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/kernel/softlockup.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/kernel/softlockup.c 2008-01-29 22:12:32.000000000 -0500
@@ -10,9 +10,11 @@
#include <linux/cpu.h>
#include <linux/init.h>
/* initialize timestamp */
touch_softlockup_watchdog();
diff -Nurb linux-2.6.22-570/kernel/sys.c linux-2.6.22-590/kernel/sys.c
---- linux-2.6.22-570/kernel/sys.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/kernel/sys.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/kernel/sys.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/kernel/sys.c 2008-01-29 22:12:32.000000000 -0500
@@ -31,6 +31,7 @@
#include <linux/cn_proc.h>
#include <linux/getcpu.h>
+}
+EXPORT_SYMBOL_GPL(orderly_poweroff);
diff -Nurb linux-2.6.22-570/kernel/sysctl.c linux-2.6.22-590/kernel/sysctl.c
---- linux-2.6.22-570/kernel/sysctl.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/kernel/sysctl.c 2008-03-15 10:35:47.000000000 -0400
-@@ -45,13 +45,12 @@
+--- linux-2.6.22-570/kernel/sysctl.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/kernel/sysctl.c 2008-01-29 22:12:32.000000000 -0500
+@@ -45,13 +45,13 @@
#include <linux/syscalls.h>
#include <linux/nfs_fs.h>
#include <linux/acpi.h>
+#include <linux/reboot.h>
+#include <linux/fs.h>
++#include <net/net_namespace.h>
#include <asm/uaccess.h>
#include <asm/processor.h>
#ifdef CONFIG_X86
#include <asm/nmi.h>
#include <asm/stacktrace.h>
-@@ -203,7 +202,10 @@
+@@ -140,6 +140,10 @@
+ void __user *buffer, size_t *lenp, loff_t *ppos);
+ #endif
+
++#ifdef CONFIG_NET
++static void sysctl_net_init(struct net *net);
++#endif
++
+ static ctl_table root_table[];
+ static struct ctl_table_header root_table_header =
+ { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) };
+@@ -203,7 +207,10 @@
.mode = 0555,
.child = dev_table,
},
{ .ctl_name = 0 }
};
-@@ -217,6 +219,15 @@
+@@ -217,6 +224,15 @@
.proc_handler = &proc_dointvec,
},
{
.ctl_name = KERN_CORE_USES_PID,
.procname = "core_uses_pid",
.data = &core_uses_pid,
-@@ -625,7 +636,20 @@
+@@ -625,7 +641,20 @@
.proc_handler = &proc_dointvec,
},
#endif
{ .ctl_name = 0 }
};
-@@ -744,6 +768,14 @@
+@@ -744,6 +773,14 @@
.mode = 0644,
.proc_handler = &proc_dointvec,
},
#endif
{
.ctl_name = VM_LOWMEM_RESERVE_RATIO,
-@@ -892,6 +924,10 @@
+@@ -892,6 +929,10 @@
.extra1 = &zero,
},
#endif
{ .ctl_name = 0 }
};
-@@ -1032,10 +1068,28 @@
+@@ -1032,10 +1073,28 @@
.child = binfmt_misc_table,
},
#endif
{ .ctl_name = 0 }
};
+@@ -1097,6 +1156,11 @@
+ {
+ struct ctl_table_header *head;
+ struct list_head *tmp;
++ struct net *net = current->nsproxy->net_ns;
++
++ if (!net->net_table_header.ctl_table)
++ sysctl_net_init(net);
++
+ spin_lock(&sysctl_lock);
+ if (prev) {
+ tmp = &prev->ctl_entry;
+@@ -1114,6 +1178,10 @@
+ next:
+ tmp = tmp->next;
+ if (tmp == &root_table_header.ctl_entry)
++#ifdef CONFIG_NET
++ tmp = &net->net_table_header.ctl_entry;
++ else if (tmp == &net->net_table_header.ctl_entry)
++#endif
+ break;
+ }
+ spin_unlock(&sysctl_lock);
+@@ -1229,7 +1297,6 @@
+ void __user *newval, size_t newlen)
+ {
+ int op = 0, rc;
+- size_t len;
+
+ if (oldval)
+ op |= 004;
+@@ -1250,25 +1317,10 @@
+ /* If there is no strategy routine, or if the strategy returns
+ * zero, proceed with automatic r/w */
+ if (table->data && table->maxlen) {
+- if (oldval && oldlenp) {
+- if (get_user(len, oldlenp))
+- return -EFAULT;
+- if (len) {
+- if (len > table->maxlen)
+- len = table->maxlen;
+- if(copy_to_user(oldval, table->data, len))
+- return -EFAULT;
+- if(put_user(len, oldlenp))
+- return -EFAULT;
+- }
+- }
+- if (newval && newlen) {
+- len = newlen;
+- if (len > table->maxlen)
+- len = table->maxlen;
+- if(copy_from_user(table->data, newval, len))
+- return -EFAULT;
+- }
++ rc = sysctl_data(table, name, nlen, oldval, oldlenp,
++ newval, newlen);
++ if (rc < 0)
++ return rc;
+ }
+ return 0;
+ }
+@@ -1359,7 +1411,8 @@
+ * This routine returns %NULL on a failure to register, and a pointer
+ * to the table header on success.
+ */
+-struct ctl_table_header *register_sysctl_table(ctl_table * table)
++static struct ctl_table_header *__register_sysctl_table(
++ struct ctl_table_header *root, ctl_table * table)
+ {
+ struct ctl_table_header *tmp;
+ tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL);
+@@ -1371,11 +1424,16 @@
+ tmp->unregistering = NULL;
+ sysctl_set_parent(NULL, table);
+ spin_lock(&sysctl_lock);
+- list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
++ list_add_tail(&tmp->ctl_entry, &root->ctl_entry);
+ spin_unlock(&sysctl_lock);
+ return tmp;
+ }
+
++struct ctl_table_header *register_sysctl_table(ctl_table *table)
++{
++ return __register_sysctl_table(&root_table_header, table);
++}
++
+ /**
+ * unregister_sysctl_table - unregister a sysctl table hierarchy
+ * @header: the header returned from register_sysctl_table
+@@ -1392,6 +1450,92 @@
+ kfree(header);
+ }
+
++#ifdef CONFIG_NET
++
++static void *fixup_table_addr(void *addr,
++ const char *start, size_t size, const char *new)
++{
++ char *ptr = addr;
++ if ((ptr >= start) && (ptr < (start + size)))
++ ptr += new - start;
++ return ptr;
++}
++
++static void table_fixup(struct ctl_table *table,
++ const void *start, size_t size, const void *new)
++{
++ for (; table->ctl_name || table->procname; table++) {
++ table->data = fixup_table_addr(table->data, start, size, new);
++ table->extra1 = fixup_table_addr(table->extra1, start, size, new);
++ table->extra2 = fixup_table_addr(table->extra2, start, size, new);
++
++ /* Whee recursive functions on the kernel stack */
++ if (table->child)
++ table_fixup(table->child, start, size, new);
++ }
++}
++
++static unsigned count_table_entries(struct ctl_table *table)
++{
++ unsigned entries = 0;
++ for (; table->ctl_name || table->procname; table++) {
++ entries += 1;
++
++ if (table->child)
++ entries += count_table_entries(table->child);
++ }
++ entries += 1; /* Null terminating entry */
++ return entries;
++}
++
++static struct ctl_table *copy_table_entries(
++ struct ctl_table *dest, struct ctl_table *src)
++{
++ struct ctl_table *table = dest;
++ for (; src->ctl_name || src->procname; src++) {
++ *dest++ = *table;
++ }
++ dest++; /* Null terminating entry */
++ for (; table->ctl_name || table->procname; table++) {
++ if (table->child)
++ dest = copy_table_entries(dest, table->child);
++ }
++ return dest;
++}
++
++static void sysctl_net_init(struct net *net)
++{
++ unsigned entries;
++ struct ctl_table *table;
++
++ entries = count_table_entries(net_root_table);
++ table = kzalloc(GFP_KERNEL, sizeof(*table)*entries);
++ /* FIXME free table... */
++
++ copy_table_entries(table, net_root_table);
++ table_fixup(table, &init_net, sizeof(init_net), net);
++
++ net->net_table_header.ctl_table = table;
++ INIT_LIST_HEAD(&net->net_table_header.ctl_entry);
++}
++
++struct ctl_table_header *register_net_sysctl_table(struct net *net, struct ctl_table *table)
++{
++ if (!net->net_table_header.ctl_table)
++ sysctl_net_init(net);
++ table_fixup(table, &init_net, sizeof(init_net), net);
++ return __register_sysctl_table(&net->net_table_header, table);
++}
++EXPORT_SYMBOL_GPL(register_net_sysctl_table);
++
++void unregister_net_sysctl_table(struct ctl_table_header *header)
++{
++ return unregister_sysctl_table(header);
++}
++EXPORT_SYMBOL_GPL(unregister_net_sysctl_table);
++#endif
++
++
+ #else /* !CONFIG_SYSCTL */
+ struct ctl_table_header *register_sysctl_table(ctl_table * table)
+ {
+@@ -2167,6 +2311,40 @@
+ * General sysctl support routines
+ */
+
++/* The generic sysctl data routine (used if no strategy routine supplied) */
++int sysctl_data(ctl_table *table, int __user *name, int nlen,
++ void __user *oldval, size_t __user *oldlenp,
++ void __user *newval, size_t newlen)
++{
++ size_t len;
++
++ /* Get out of I don't have a variable */
++ if (!table->data || !table->maxlen)
++ return -ENOTDIR;
++
++ if (oldval && oldlenp) {
++ if (get_user(len, oldlenp))
++ return -EFAULT;
++ if (len) {
++ if (len > table->maxlen)
++ len = table->maxlen;
++ if (copy_to_user(oldval, table->data, len))
++ return -EFAULT;
++ if (put_user(len, oldlenp))
++ return -EFAULT;
++ }
++ }
++
++ if (newval && newlen) {
++ if (newlen > table->maxlen)
++ newlen = table->maxlen;
++
++ if (copy_from_user(table->data, newval, newlen))
++ return -EFAULT;
++ }
++ return 1;
++}
++
+ /* The generic string strategy routine: */
+ int sysctl_string(ctl_table *table, int __user *name, int nlen,
+ void __user *oldval, size_t __user *oldlenp,
+@@ -2355,6 +2533,13 @@
+ return -ENOSYS;
+ }
+
++int sysctl_data(ctl_table *table, int __user *name, int nlen,
++ void __user *oldval, size_t __user *oldlenp,
++ void __user *newval, size_t newlen)
++{
++ return -ENOSYS;
++}
++
+ int sysctl_string(ctl_table *table, int __user *name, int nlen,
+ void __user *oldval, size_t __user *oldlenp,
+ void __user *newval, size_t newlen)
+@@ -2402,4 +2587,5 @@
+ EXPORT_SYMBOL(sysctl_jiffies);
+ EXPORT_SYMBOL(sysctl_ms_jiffies);
+ EXPORT_SYMBOL(sysctl_string);
++EXPORT_SYMBOL(sysctl_data);
+ EXPORT_SYMBOL(unregister_sysctl_table);
diff -Nurb linux-2.6.22-570/kernel/taskstats.c linux-2.6.22-590/kernel/taskstats.c
--- linux-2.6.22-570/kernel/taskstats.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/kernel/taskstats.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/kernel/taskstats.c 2008-01-29 22:12:32.000000000 -0500
@@ -196,6 +196,8 @@
/* fill in basic acct fields */
unlock_task_sighand(first, &flags);
diff -Nurb linux-2.6.22-570/kernel/time/tick-sched.c linux-2.6.22-590/kernel/time/tick-sched.c
--- linux-2.6.22-570/kernel/time/tick-sched.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/kernel/time/tick-sched.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/kernel/time/tick-sched.c 2008-01-29 22:12:32.000000000 -0500
@@ -153,6 +153,7 @@
unsigned long seq, last_jiffies, next_jiffies, delta_jiffies, flags;
struct tick_sched *ts;
* nohz_restart_sched_tick - restart the idle tick from the idle task
*
* Restart the idle tick when the CPU is woken up from idle
+diff -Nurb linux-2.6.22-570/kernel/time/timekeeping.c linux-2.6.22-590/kernel/time/timekeeping.c
+--- linux-2.6.22-570/kernel/time/timekeeping.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/kernel/time/timekeeping.c 2008-01-29 22:12:32.000000000 -0500
+@@ -39,7 +39,7 @@
+ */
+ struct timespec xtime __attribute__ ((aligned (16)));
+ struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
+-
++static unsigned long total_sleep_time;
+ EXPORT_SYMBOL(xtime);
+
+
+@@ -251,6 +251,7 @@
+ xtime.tv_nsec = 0;
+ set_normalized_timespec(&wall_to_monotonic,
+ -xtime.tv_sec, -xtime.tv_nsec);
++ total_sleep_time = 0;
+
+ write_sequnlock_irqrestore(&xtime_lock, flags);
+ }
+@@ -282,6 +283,7 @@
+
+ xtime.tv_sec += sleep_length;
+ wall_to_monotonic.tv_sec -= sleep_length;
++ total_sleep_time += sleep_length;
+ }
+ /* re-base the last cycle value */
+ clock->cycle_last = clocksource_read(clock);
+@@ -476,3 +478,34 @@
+ change_clocksource();
+ update_vsyscall(&xtime, clock);
+ }
++
++/**
++ * getboottime - Return the real time of system boot.
++ * @ts: pointer to the timespec to be set
++ *
++ * Returns the time of day in a timespec.
++ *
++ * This is based on the wall_to_monotonic offset and the total suspend
++ * time. Calls to settimeofday will affect the value returned (which
++ * basically means that however wrong your real time clock is at boot time,
++ * you get the right time here).
++ */
++void getboottime(struct timespec *ts)
++{
++ set_normalized_timespec(ts,
++ - (wall_to_monotonic.tv_sec + total_sleep_time),
++ - wall_to_monotonic.tv_nsec);
++}
++
++EXPORT_SYMBOL(getboottime);
++
++/**
++ * monotonic_to_bootbased - Convert the monotonic time to boot based.
++ * @ts: pointer to the timespec to be converted
++ */
++void monotonic_to_bootbased(struct timespec *ts)
++{
++ ts->tv_sec += total_sleep_time;
++}
++
++EXPORT_SYMBOL(monotonic_to_bootbased);
diff -Nurb linux-2.6.22-570/kernel/timer.c linux-2.6.22-590/kernel/timer.c
---- linux-2.6.22-570/kernel/timer.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/kernel/timer.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/kernel/timer.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/kernel/timer.c 2008-01-29 22:12:32.000000000 -0500
@@ -36,6 +36,7 @@
#include <linux/delay.h>
#include <linux/tick.h>
softlockup_tick();
}
+@@ -1125,6 +1130,7 @@
+ getnstimeofday(&tp);
+ tp.tv_sec += wall_to_monotonic.tv_sec;
+ tp.tv_nsec += wall_to_monotonic.tv_nsec;
++ monotonic_to_bootbased(&tp);
+ if (tp.tv_nsec - NSEC_PER_SEC >= 0) {
+ tp.tv_nsec = tp.tv_nsec - NSEC_PER_SEC;
+ tp.tv_sec++;
diff -Nurb linux-2.6.22-570/kernel/unwind.c linux-2.6.22-590/kernel/unwind.c
--- linux-2.6.22-570/kernel/unwind.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/kernel/unwind.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/kernel/unwind.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,1288 @@
+/*
+ * Copyright (C) 2002-2006 Novell, Inc.
+EXPORT_SYMBOL(unwind_init_running);
+
diff -Nurb linux-2.6.22-570/kernel/user.c linux-2.6.22-590/kernel/user.c
---- linux-2.6.22-570/kernel/user.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/kernel/user.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/kernel/user.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/kernel/user.c 2008-01-31 12:21:39.000000000 -0500
@@ -14,17 +14,17 @@
#include <linux/bitops.h>
#include <linux/key.h>
#define UIDHASH_MASK (UIDHASH_SZ - 1)
#define __uidhashfn(xid,uid) ((((uid) >> UIDHASH_BITS) + ((uid)^(xid))) & UIDHASH_MASK)
-#define uidhashentry(xid,uid) (uidhash_table + __uidhashfn((xid),(uid)))
-+#define uidhashentry(ns, uid) ((ns)->uidhash_table + __uidhashfn((uid)))
++#define uidhashentry( xid, uid) (uidhash_table + __uidhashfn(xid, uid))
static struct kmem_cache *uid_cachep;
static struct list_head uidhash_table[UIDHASH_SZ];
-@@ -94,9 +94,10 @@
- {
- struct user_struct *ret;
- unsigned long flags;
-+ struct user_namespace *ns = current->nsproxy->user_ns;
-
- spin_lock_irqsave(&uidhash_lock, flags);
-- ret = uid_hash_find(xid, uid, uidhashentry(xid, uid));
-+ ret = uid_hash_find(uid, uidhashentry(ns, uid));
- spin_unlock_irqrestore(&uidhash_lock, flags);
- return ret;
- }
-@@ -120,9 +121,9 @@
- }
- }
+@@ -122,6 +122,7 @@
--struct user_struct * alloc_uid(xid_t xid, uid_t uid)
-+struct user_struct * alloc_uid(struct user_namespace *ns, uid_t uid)
+ struct user_struct * alloc_uid(xid_t xid, uid_t uid)
{
-- struct list_head *hashent = uidhashentry(xid, uid);
-+ struct list_head *hashent = uidhashentry(ns, uid);
++ struct user_namespace *ns = current->nsproxy->user_ns;
+ struct list_head *hashent = uidhashentry(xid, uid);
struct user_struct *up;
- spin_lock_irq(&uidhash_lock);
-@@ -212,11 +213,11 @@
- 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
-
- for(n = 0; n < UIDHASH_SZ; ++n)
-- INIT_LIST_HEAD(uidhash_table + n);
-+ INIT_LIST_HEAD(init_user_ns.uidhash_table + n);
+@@ -216,7 +217,7 @@
/* Insert the root user immediately (init already runs as root) */
spin_lock_irq(&uidhash_lock);
- uid_hash_insert(&root_user, uidhashentry(0,0));
-+ uid_hash_insert(&root_user, uidhashentry(&init_user_ns, 0));
++ uid_hash_insert(&root_user, uidhashentry( 0, 0));
spin_unlock_irq(&uidhash_lock);
return 0;
+diff -Nurb linux-2.6.22-570/kernel/user.c.orig linux-2.6.22-590/kernel/user.c.orig
+--- linux-2.6.22-570/kernel/user.c.orig 1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.22-590/kernel/user.c.orig 2008-01-29 22:12:32.000000000 -0500
+@@ -0,0 +1,227 @@
++/*
++ * The "user cache".
++ *
++ * (C) Copyright 1991-2000 Linus Torvalds
++ *
++ * We have a per-user structure to keep track of how many
++ * processes, files etc the user has claimed, in order to be
++ * able to have per-user limits for system resources.
++ */
++
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/bitops.h>
++#include <linux/key.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/user_namespace.h>
++
++/*
++ * UID task count cache, to get fast user lookup in "alloc_uid"
++ * when changing user ID's (ie setuid() and friends).
++ */
++
++#define UIDHASH_MASK (UIDHASH_SZ - 1)
++#define __uidhashfn(xid,uid) ((((uid) >> UIDHASH_BITS) + ((uid)^(xid))) & UIDHASH_MASK)
++#define uidhashentry(ns, xid, uid) ((ns)->uidhash_table + __uidhashfn(xid, uid))
++
++static struct kmem_cache *uid_cachep;
++static struct list_head uidhash_table[UIDHASH_SZ];
++
++/*
++ * The uidhash_lock is mostly taken from process context, but it is
++ * occasionally also taken from softirq/tasklet context, when
++ * task-structs get RCU-freed. Hence all locking must be softirq-safe.
++ * But free_uid() is also called with local interrupts disabled, and running
++ * local_bh_enable() with local interrupts disabled is an error - we'll run
++ * softirq callbacks, and they can unconditionally enable interrupts, and
++ * the caller of free_uid() didn't expect that..
++ */
++static DEFINE_SPINLOCK(uidhash_lock);
++
++struct user_struct root_user = {
++ .__count = ATOMIC_INIT(1),
++ .processes = ATOMIC_INIT(1),
++ .files = ATOMIC_INIT(0),
++ .sigpending = ATOMIC_INIT(0),
++ .mq_bytes = 0,
++ .locked_shm = 0,
++#ifdef CONFIG_KEYS
++ .uid_keyring = &root_user_keyring,
++ .session_keyring = &root_session_keyring,
++#endif
++};
++
++/*
++ * These routines must be called with the uidhash spinlock held!
++ */
++static inline void uid_hash_insert(struct user_struct *up, struct list_head *hashent)
++{
++ list_add(&up->uidhash_list, hashent);
++}
++
++static inline void uid_hash_remove(struct user_struct *up)
++{
++ list_del(&up->uidhash_list);
++}
++
++static inline struct user_struct *uid_hash_find(xid_t xid, uid_t uid, struct list_head *hashent)
++{
++ struct list_head *up;
++
++ list_for_each(up, hashent) {
++ struct user_struct *user;
++
++ user = list_entry(up, struct user_struct, uidhash_list);
++
++ if(user->uid == uid && user->xid == xid) {
++ atomic_inc(&user->__count);
++ return user;
++ }
++ }
++
++ return NULL;
++}
++
++/*
++ * Locate the user_struct for the passed UID. If found, take a ref on it. The
++ * caller must undo that ref with free_uid().
++ *
++ * If the user_struct could not be found, return NULL.
++ */
++struct user_struct *find_user(xid_t xid, uid_t uid)
++{
++ struct user_struct *ret;
++ unsigned long flags;
++ struct user_namespace *ns = current->nsproxy->user_ns;
++
++ spin_lock_irqsave(&uidhash_lock, flags);
++ ret = uid_hash_find(xid, uid, uidhashentry(ns, xid, uid));
++ spin_unlock_irqrestore(&uidhash_lock, flags);
++ return ret;
++}
++
++void free_uid(struct user_struct *up)
++{
++ unsigned long flags;
++
++ if (!up)
++ return;
++
++ local_irq_save(flags);
++ if (atomic_dec_and_lock(&up->__count, &uidhash_lock)) {
++ uid_hash_remove(up);
++ spin_unlock_irqrestore(&uidhash_lock, flags);
++ key_put(up->uid_keyring);
++ key_put(up->session_keyring);
++ kmem_cache_free(uid_cachep, up);
++ } else {
++ local_irq_restore(flags);
++ }
++}
++
++struct user_struct * alloc_uid(xid_t xid, uid_t uid)
++{
++ struct user_namespace *ns = current->nsproxy->user_ns;
++ struct list_head *hashent = uidhashentry(ns,xid, uid);
++ struct user_struct *up;
++
++ spin_lock_irq(&uidhash_lock);
++ up = uid_hash_find(xid, uid, hashent);
++ spin_unlock_irq(&uidhash_lock);
++
++ if (!up) {
++ struct user_struct *new;
++
++ new = kmem_cache_alloc(uid_cachep, GFP_KERNEL);
++ if (!new)
++ return NULL;
++ new->uid = uid;
++ new->xid = xid;
++ atomic_set(&new->__count, 1);
++ atomic_set(&new->processes, 0);
++ atomic_set(&new->files, 0);
++ atomic_set(&new->sigpending, 0);
++#ifdef CONFIG_INOTIFY_USER
++ atomic_set(&new->inotify_watches, 0);
++ atomic_set(&new->inotify_devs, 0);
++#endif
++
++ new->mq_bytes = 0;
++ new->locked_shm = 0;
++
++ if (alloc_uid_keyring(new, current) < 0) {
++ kmem_cache_free(uid_cachep, new);
++ return NULL;
++ }
++
++ /*
++ * Before adding this, check whether we raced
++ * on adding the same user already..
++ */
++ spin_lock_irq(&uidhash_lock);
++ up = uid_hash_find(xid, uid, hashent);
++ if (up) {
++ key_put(new->uid_keyring);
++ key_put(new->session_keyring);
++ kmem_cache_free(uid_cachep, new);
++ } else {
++ uid_hash_insert(new, hashent);
++ up = new;
++ }
++ spin_unlock_irq(&uidhash_lock);
++
++ }
++ return up;
++}
++
++void switch_uid(struct user_struct *new_user)
++{
++ struct user_struct *old_user;
++
++ /* What if a process setreuid()'s and this brings the
++ * new uid over his NPROC rlimit? We can check this now
++ * cheaply with the new uid cache, so if it matters
++ * we should be checking for it. -DaveM
++ */
++ old_user = current->user;
++ atomic_inc(&new_user->processes);
++ atomic_dec(&old_user->processes);
++ switch_uid_keyring(new_user);
++ current->user = new_user;
++
++ /*
++ * We need to synchronize with __sigqueue_alloc()
++ * doing a get_uid(p->user).. If that saw the old
++ * user value, we need to wait until it has exited
++ * its critical region before we can free the old
++ * structure.
++ */
++ smp_mb();
++ spin_unlock_wait(¤t->sighand->siglock);
++
++ free_uid(old_user);
++ suid_keys(current);
++}
++
++
++static int __init uid_cache_init(void)
++{
++ int n;
++
++ uid_cachep = kmem_cache_create("uid_cache", sizeof(struct user_struct),
++ 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
++
++ for(n = 0; n < UIDHASH_SZ; ++n)
++ INIT_LIST_HEAD(init_user_ns.uidhash_table + n);
++
++ /* Insert the root user immediately (init already runs as root) */
++ spin_lock_irq(&uidhash_lock);
++ uid_hash_insert(&root_user, uidhashentry(&init_user_ns, 0, 0));
++ spin_unlock_irq(&uidhash_lock);
++
++ return 0;
++}
++
++module_init(uid_cache_init);
diff -Nurb linux-2.6.22-570/kernel/user_namespace.c linux-2.6.22-590/kernel/user_namespace.c
--- linux-2.6.22-570/kernel/user_namespace.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/kernel/user_namespace.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/kernel/user_namespace.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,87 @@
+/*
+ * This program is free software; you can redistribute it and/or
+
+#endif /* CONFIG_USER_NS */
diff -Nurb linux-2.6.22-570/kernel/utsname.c linux-2.6.22-590/kernel/utsname.c
---- linux-2.6.22-570/kernel/utsname.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/kernel/utsname.c 2008-03-15 10:35:47.000000000 -0400
-@@ -25,11 +25,12 @@
+--- linux-2.6.22-570/kernel/utsname.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/kernel/utsname.c 2008-01-29 22:12:32.000000000 -0500
+@@ -14,6 +14,7 @@
+ #include <linux/utsname.h>
+ #include <linux/version.h>
+ #include <linux/vserver/global.h>
++#include <linux/err.h>
+
+ /*
+ * Clone a new ns copying an original utsname, setting refcount to 1
+@@ -25,11 +26,12 @@
struct uts_namespace *ns;
ns = kmalloc(sizeof(struct uts_namespace), GFP_KERNEL);
return ns;
}
-@@ -39,7 +40,7 @@
+@@ -39,7 +41,7 @@
* utsname of this process won't be seen by parent, and vice
* versa.
*/
diff -Nurb linux-2.6.22-570/kernel/utsname_sysctl.c linux-2.6.22-590/kernel/utsname_sysctl.c
--- linux-2.6.22-570/kernel/utsname_sysctl.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/kernel/utsname_sysctl.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/kernel/utsname_sysctl.c 2008-01-29 22:12:32.000000000 -0500
@@ -18,10 +18,7 @@
static void *get_uts(ctl_table *table, int write)
{
down_read(&uts_sem);
else
diff -Nurb linux-2.6.22-570/kernel/workqueue.c linux-2.6.22-590/kernel/workqueue.c
---- linux-2.6.22-570/kernel/workqueue.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/kernel/workqueue.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/kernel/workqueue.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/kernel/workqueue.c 2008-01-29 22:12:32.000000000 -0500
@@ -282,8 +282,8 @@
struct cpu_workqueue_struct *cwq = __cwq;
DEFINE_WAIT(wait);
diff -Nurb linux-2.6.22-570/lib/Kconfig.debug linux-2.6.22-590/lib/Kconfig.debug
--- linux-2.6.22-570/lib/Kconfig.debug 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/lib/Kconfig.debug 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/lib/Kconfig.debug 2008-01-29 22:12:32.000000000 -0500
@@ -364,6 +364,24 @@
some architectures or if you use external debuggers.
If you don't debug the kernel, you can say N.
+source "lib/Kconfig.kgdb"
diff -Nurb linux-2.6.22-570/lib/Kconfig.kgdb linux-2.6.22-590/lib/Kconfig.kgdb
--- linux-2.6.22-570/lib/Kconfig.kgdb 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/lib/Kconfig.kgdb 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/lib/Kconfig.kgdb 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,255 @@
+
+config WANT_EXTRA_DEBUG_INFORMATION
+ io,2f8,115200,3
diff -Nurb linux-2.6.22-570/lib/Makefile linux-2.6.22-590/lib/Makefile
--- linux-2.6.22-570/lib/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/lib/Makefile 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/lib/Makefile 2008-01-29 22:12:32.000000000 -0500
@@ -5,9 +5,10 @@
lib-y := ctype.o string.o vsprintf.o cmdline.o \
rbtree.o radix-tree.o dump_stack.o \
lib-y += kobject.o kref.o kobject_uevent.o klist.o
diff -Nurb linux-2.6.22-570/lib/argv_split.c linux-2.6.22-590/lib/argv_split.c
--- linux-2.6.22-570/lib/argv_split.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/lib/argv_split.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/lib/argv_split.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,159 @@
+/*
+ * Helper function for splitting a string into an argv-like array.
+#endif
diff -Nurb linux-2.6.22-570/lib/check_signature.c linux-2.6.22-590/lib/check_signature.c
--- linux-2.6.22-570/lib/check_signature.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/lib/check_signature.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/lib/check_signature.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,26 @@
+#include <linux/io.h>
+#include <linux/module.h>
+ return 1;
+}
+EXPORT_SYMBOL(check_signature);
+diff -Nurb linux-2.6.22-570/lib/idr.c linux-2.6.22-590/lib/idr.c
+--- linux-2.6.22-570/lib/idr.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/lib/idr.c 2008-01-29 22:12:32.000000000 -0500
+@@ -70,6 +70,26 @@
+ spin_unlock_irqrestore(&idp->lock, flags);
+ }
+
++static void idr_mark_full(struct idr_layer **pa, int id)
++{
++ struct idr_layer *p = pa[0];
++ int l = 0;
++
++ __set_bit(id & IDR_MASK, &p->bitmap);
++ /*
++ * If this layer is full mark the bit in the layer above to
++ * show that this part of the radix tree is full. This may
++ * complete the layer above and require walking up the radix
++ * tree.
++ */
++ while (p->bitmap == IDR_FULL) {
++ if (!(p = pa[++l]))
++ break;
++ id = id >> IDR_BITS;
++ __set_bit((id & IDR_MASK), &p->bitmap);
++ }
++}
++
+ /**
+ * idr_pre_get - reserver resources for idr allocation
+ * @idp: idr handle
+@@ -95,11 +115,10 @@
+ }
+ EXPORT_SYMBOL(idr_pre_get);
+
+-static int sub_alloc(struct idr *idp, void *ptr, int *starting_id)
++static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa)
+ {
+ int n, m, sh;
+ struct idr_layer *p, *new;
+- struct idr_layer *pa[MAX_LEVEL];
+ int l, id;
+ long bm;
+
+@@ -144,30 +163,13 @@
+ pa[l--] = p;
+ p = p->ary[m];
+ }
+- /*
+- * We have reached the leaf node, plant the
+- * users pointer and return the raw id.
+- */
+- p->ary[m] = (struct idr_layer *)ptr;
+- __set_bit(m, &p->bitmap);
+- p->count++;
+- /*
+- * If this layer is full mark the bit in the layer above
+- * to show that this part of the radix tree is full.
+- * This may complete the layer above and require walking
+- * up the radix tree.
+- */
+- n = id;
+- while (p->bitmap == IDR_FULL) {
+- if (!(p = pa[++l]))
+- break;
+- n = n >> IDR_BITS;
+- __set_bit((n & IDR_MASK), &p->bitmap);
+- }
+- return(id);
++
++ pa[l] = p;
++ return id;
+ }
+
+-static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
++static int idr_get_empty_slot(struct idr *idp, int starting_id,
++ struct idr_layer **pa)
+ {
+ struct idr_layer *p, *new;
+ int layers, v, id;
+@@ -213,12 +215,31 @@
+ }
+ idp->top = p;
+ idp->layers = layers;
+- v = sub_alloc(idp, ptr, &id);
++ v = sub_alloc(idp, &id, pa);
+ if (v == -2)
+ goto build_up;
+ return(v);
+ }
+
++static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
++{
++ struct idr_layer *pa[MAX_LEVEL];
++ int id;
++
++ id = idr_get_empty_slot(idp, starting_id, pa);
++ if (id >= 0) {
++ /*
++ * Successfully found an empty slot. Install the user
++ * pointer and mark the slot full.
++ */
++ pa[0]->ary[id & IDR_MASK] = (struct idr_layer *)ptr;
++ pa[0]->count++;
++ idr_mark_full(pa, id);
++ }
++
++ return id;
++}
++
+ /**
+ * idr_get_new_above - allocate new idr entry above or equal to a start id
+ * @idp: idr handle
+@@ -473,3 +494,248 @@
+ spin_lock_init(&idp->lock);
+ }
+ EXPORT_SYMBOL(idr_init);
++
++
++/*
++ * IDA - IDR based ID allocator
++ *
++ * this is id allocator without id -> pointer translation. Memory
++ * usage is much lower than full blown idr because each id only
++ * occupies a bit. ida uses a custom leaf node which contains
++ * IDA_BITMAP_BITS slots.
++ *
++ * 2007-04-25 written by Tejun Heo <htejun@gmail.com>
++ */
++
++static void free_bitmap(struct ida *ida, struct ida_bitmap *bitmap)
++{
++ unsigned long flags;
++
++ if (!ida->free_bitmap) {
++ spin_lock_irqsave(&ida->idr.lock, flags);
++ if (!ida->free_bitmap) {
++ ida->free_bitmap = bitmap;
++ bitmap = NULL;
++ }
++ spin_unlock_irqrestore(&ida->idr.lock, flags);
++ }
++
++ kfree(bitmap);
++}
++
++/**
++ * ida_pre_get - reserve resources for ida allocation
++ * @ida: ida handle
++ * @gfp_mask: memory allocation flag
++ *
++ * This function should be called prior to locking and calling the
++ * following function. It preallocates enough memory to satisfy the
++ * worst possible allocation.
++ *
++ * If the system is REALLY out of memory this function returns 0,
++ * otherwise 1.
++ */
++int ida_pre_get(struct ida *ida, gfp_t gfp_mask)
++{
++ /* allocate idr_layers */
++ if (!idr_pre_get(&ida->idr, gfp_mask))
++ return 0;
++
++ /* allocate free_bitmap */
++ if (!ida->free_bitmap) {
++ struct ida_bitmap *bitmap;
++
++ bitmap = kmalloc(sizeof(struct ida_bitmap), gfp_mask);
++ if (!bitmap)
++ return 0;
++
++ free_bitmap(ida, bitmap);
++ }
++
++ return 1;
++}
++EXPORT_SYMBOL(ida_pre_get);
++
++/**
++ * ida_get_new_above - allocate new ID above or equal to a start id
++ * @ida: ida handle
++ * @staring_id: id to start search at
++ * @p_id: pointer to the allocated handle
++ *
++ * Allocate new ID above or equal to @ida. It should be called with
++ * any required locks.
++ *
++ * If memory is required, it will return -EAGAIN, you should unlock
++ * and go back to the ida_pre_get() call. If the ida is full, it will
++ * return -ENOSPC.
++ *
++ * @p_id returns a value in the range 0 ... 0x7fffffff.
++ */
++int ida_get_new_above(struct ida *ida, int starting_id, int *p_id)
++{
++ struct idr_layer *pa[MAX_LEVEL];
++ struct ida_bitmap *bitmap;
++ unsigned long flags;
++ int idr_id = starting_id / IDA_BITMAP_BITS;
++ int offset = starting_id % IDA_BITMAP_BITS;
++ int t, id;
++
++ restart:
++ /* get vacant slot */
++ t = idr_get_empty_slot(&ida->idr, idr_id, pa);
++ if (t < 0) {
++ if (t == -1)
++ return -EAGAIN;
++ else /* will be -3 */
++ return -ENOSPC;
++ }
++
++ if (t * IDA_BITMAP_BITS >= MAX_ID_BIT)
++ return -ENOSPC;
++
++ if (t != idr_id)
++ offset = 0;
++ idr_id = t;
++
++ /* if bitmap isn't there, create a new one */
++ bitmap = (void *)pa[0]->ary[idr_id & IDR_MASK];
++ if (!bitmap) {
++ spin_lock_irqsave(&ida->idr.lock, flags);
++ bitmap = ida->free_bitmap;
++ ida->free_bitmap = NULL;
++ spin_unlock_irqrestore(&ida->idr.lock, flags);
++
++ if (!bitmap)
++ return -EAGAIN;
++
++ memset(bitmap, 0, sizeof(struct ida_bitmap));
++ pa[0]->ary[idr_id & IDR_MASK] = (void *)bitmap;
++ pa[0]->count++;
++ }
++
++ /* lookup for empty slot */
++ t = find_next_zero_bit(bitmap->bitmap, IDA_BITMAP_BITS, offset);
++ if (t == IDA_BITMAP_BITS) {
++ /* no empty slot after offset, continue to the next chunk */
++ idr_id++;
++ offset = 0;
++ goto restart;
++ }
++
++ id = idr_id * IDA_BITMAP_BITS + t;
++ if (id >= MAX_ID_BIT)
++ return -ENOSPC;
++
++ __set_bit(t, bitmap->bitmap);
++ if (++bitmap->nr_busy == IDA_BITMAP_BITS)
++ idr_mark_full(pa, idr_id);
++
++ *p_id = id;
++
++ /* Each leaf node can handle nearly a thousand slots and the
++ * whole idea of ida is to have small memory foot print.
++ * Throw away extra resources one by one after each successful
++ * allocation.
++ */
++ if (ida->idr.id_free_cnt || ida->free_bitmap) {
++ struct idr_layer *p = alloc_layer(&ida->idr);
++ if (p)
++ kmem_cache_free(idr_layer_cache, p);
++ }
++
++ return 0;
++}
++EXPORT_SYMBOL(ida_get_new_above);
++
++/**
++ * ida_get_new - allocate new ID
++ * @ida: idr handle
++ * @p_id: pointer to the allocated handle
++ *
++ * Allocate new ID. It should be called with any required locks.
++ *
++ * If memory is required, it will return -EAGAIN, you should unlock
++ * and go back to the idr_pre_get() call. If the idr is full, it will
++ * return -ENOSPC.
++ *
++ * @id returns a value in the range 0 ... 0x7fffffff.
++ */
++int ida_get_new(struct ida *ida, int *p_id)
++{
++ return ida_get_new_above(ida, 0, p_id);
++}
++EXPORT_SYMBOL(ida_get_new);
++
++/**
++ * ida_remove - remove the given ID
++ * @ida: ida handle
++ * @id: ID to free
++ */
++void ida_remove(struct ida *ida, int id)
++{
++ struct idr_layer *p = ida->idr.top;
++ int shift = (ida->idr.layers - 1) * IDR_BITS;
++ int idr_id = id / IDA_BITMAP_BITS;
++ int offset = id % IDA_BITMAP_BITS;
++ int n;
++ struct ida_bitmap *bitmap;
++
++ /* clear full bits while looking up the leaf idr_layer */
++ while ((shift > 0) && p) {
++ n = (idr_id >> shift) & IDR_MASK;
++ __clear_bit(n, &p->bitmap);
++ p = p->ary[n];
++ shift -= IDR_BITS;
++ }
++
++ if (p == NULL)
++ goto err;
++
++ n = idr_id & IDR_MASK;
++ __clear_bit(n, &p->bitmap);
++
++ bitmap = (void *)p->ary[n];
++ if (!test_bit(offset, bitmap->bitmap))
++ goto err;
++
++ /* update bitmap and remove it if empty */
++ __clear_bit(offset, bitmap->bitmap);
++ if (--bitmap->nr_busy == 0) {
++ __set_bit(n, &p->bitmap); /* to please idr_remove() */
++ idr_remove(&ida->idr, idr_id);
++ free_bitmap(ida, bitmap);
++ }
++
++ return;
++
++ err:
++ printk(KERN_WARNING
++ "ida_remove called for id=%d which is not allocated.\n", id);
++}
++EXPORT_SYMBOL(ida_remove);
++
++/**
++ * ida_destroy - release all cached layers within an ida tree
++ * ida: ida handle
++ */
++void ida_destroy(struct ida *ida)
++{
++ idr_destroy(&ida->idr);
++ kfree(ida->free_bitmap);
++}
++EXPORT_SYMBOL(ida_destroy);
++
++/**
++ * ida_init - initialize ida handle
++ * @ida: ida handle
++ *
++ * This function is use to set up the handle (@ida) that you will pass
++ * to the rest of the functions.
++ */
++void ida_init(struct ida *ida)
++{
++ memset(ida, 0, sizeof(struct ida));
++ idr_init(&ida->idr);
++
++}
++EXPORT_SYMBOL(ida_init);
diff -Nurb linux-2.6.22-570/lib/kobject.c linux-2.6.22-590/lib/kobject.c
--- linux-2.6.22-570/lib/kobject.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/lib/kobject.c 2008-03-15 10:35:47.000000000 -0400
-@@ -44,7 +44,7 @@
++++ linux-2.6.22-590/lib/kobject.c 2008-01-29 22:12:32.000000000 -0500
+@@ -44,11 +44,11 @@
return error;
}
-static int create_dir(struct kobject * kobj, struct dentry *shadow_parent)
-+static int create_dir(struct kobject *kobj, struct sysfs_dirent *shadow_parent)
++static int create_dir(struct kobject * kobj)
{
int error = 0;
if (kobject_name(kobj)) {
-@@ -162,7 +162,7 @@
- * @shadow_parent: sysfs directory to add to.
+- error = sysfs_create_dir(kobj, shadow_parent);
++ error = sysfs_create_dir(kobj);
+ if (!error) {
+ if ((error = populate_dir(kobj)))
+ sysfs_remove_dir(kobj);
+@@ -157,12 +157,11 @@
+ }
+
+ /**
+- * kobject_shadow_add - add an object to the hierarchy.
++ * kobject_add - add an object to the hierarchy.
+ * @kobj: object.
+- * @shadow_parent: sysfs directory to add to.
*/
-int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent)
-+int kobject_shadow_add(struct kobject *kobj, struct sysfs_dirent *shadow_parent)
++int kobject_add(struct kobject * kobj)
{
int error = 0;
struct kobject * parent;
-@@ -338,7 +338,7 @@
+@@ -194,7 +193,7 @@
+ kobj->parent = parent;
+ }
+
+- error = create_dir(kobj, shadow_parent);
++ error = create_dir(kobj);
+ if (error) {
+ /* unlink does the kobject_put() for us */
+ unlink(kobj);
+@@ -216,16 +215,6 @@
+ }
+
+ /**
+- * kobject_add - add an object to the hierarchy.
+- * @kobj: object.
+- */
+-int kobject_add(struct kobject * kobj)
+-{
+- return kobject_shadow_add(kobj, NULL);
+-}
+-
+-
+-/**
+ * kobject_register - initialize and add an object.
+ * @kobj: object in question.
+ */
+@@ -338,7 +327,7 @@
/* Note : if we want to send the new name alone, not the full path,
* we could probably use kobject_name(kobj); */
- error = sysfs_rename_dir(kobj, kobj->parent->dentry, new_name);
-+ error = sysfs_rename_dir(kobj, kobj->parent->sd, new_name);
++ error = sysfs_rename_dir(kobj, new_name);
/* This function is mostly/only used for network interface.
* Some hotplug package track interfaces by their name and
-@@ -361,8 +361,8 @@
- * @new_name: object's new name
- */
+@@ -355,27 +344,6 @@
+ }
+ /**
+- * kobject_rename - change the name of an object
+- * @kobj: object in question.
+- * @new_parent: object's new parent
+- * @new_name: object's new name
+- */
+-
-int kobject_shadow_rename(struct kobject * kobj, struct dentry *new_parent,
- const char *new_name)
-+int kobject_shadow_rename(struct kobject *kobj,
-+ struct sysfs_dirent *new_parent, const char *new_name)
- {
- int error = 0;
-
+-{
+- int error = 0;
+-
+- kobj = kobject_get(kobj);
+- if (!kobj)
+- return -EINVAL;
+- error = sysfs_rename_dir(kobj, new_parent, new_name);
+- kobject_put(kobj);
+-
+- return error;
+-}
+-
+-/**
+ * kobject_move - move object to another parent
+ * @kobj: object in question.
+ * @new_parent: object's new parent (can be NULL)
diff -Nurb linux-2.6.22-570/lib/kobject_uevent.c linux-2.6.22-590/lib/kobject_uevent.c
--- linux-2.6.22-570/lib/kobject_uevent.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/lib/kobject_uevent.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/lib/kobject_uevent.c 2008-01-29 22:12:32.000000000 -0500
@@ -208,7 +208,7 @@
argv [0] = uevent_helper;
argv [1] = (char *)subsystem;
}
exit:
+@@ -290,9 +290,8 @@
+ #if defined(CONFIG_NET)
+ static int __init kobject_uevent_init(void)
+ {
+- uevent_sock = netlink_kernel_create(NETLINK_KOBJECT_UEVENT, 1, NULL,
+- NULL, THIS_MODULE);
+-
++ uevent_sock = netlink_kernel_create(&init_net, NETLINK_KOBJECT_UEVENT,
++ 1, NULL, NULL, THIS_MODULE);
+ if (!uevent_sock) {
+ printk(KERN_ERR
+ "kobject_uevent: unable to create netlink socket!\n");
diff -Nurb linux-2.6.22-570/lib/pagewalk.c linux-2.6.22-590/lib/pagewalk.c
--- linux-2.6.22-570/lib/pagewalk.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/lib/pagewalk.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/lib/pagewalk.c 2008-01-29 22:12:32.000000000 -0500
@@ -0,0 +1,112 @@
+#include <linux/mm.h>
+#include <linux/highmem.h>
+}
diff -Nurb linux-2.6.22-570/lib/radix-tree.c linux-2.6.22-590/lib/radix-tree.c
--- linux-2.6.22-570/lib/radix-tree.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/lib/radix-tree.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/lib/radix-tree.c 2008-01-29 22:12:32.000000000 -0500
@@ -93,7 +93,8 @@
struct radix_tree_node *ret;
gfp_t gfp_mask = root_gfp_mask(root);
preempt_disable();
diff -Nurb linux-2.6.22-570/mm/filemap.c linux-2.6.22-590/mm/filemap.c
--- linux-2.6.22-570/mm/filemap.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/mm/filemap.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/mm/filemap.c 2008-01-29 22:12:32.000000000 -0500
@@ -1334,39 +1334,38 @@
#define MMAP_LOTSAMISS (100)
}
diff -Nurb linux-2.6.22-570/mm/filemap_xip.c linux-2.6.22-590/mm/filemap_xip.c
---- linux-2.6.22-570/mm/filemap_xip.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/mm/filemap_xip.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/mm/filemap_xip.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/mm/filemap_xip.c 2008-01-29 22:12:32.000000000 -0500
@@ -228,62 +228,67 @@
}
}
EXPORT_SYMBOL_GPL(xip_file_mmap);
diff -Nurb linux-2.6.22-570/mm/fremap.c linux-2.6.22-590/mm/fremap.c
---- linux-2.6.22-570/mm/fremap.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/mm/fremap.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/mm/fremap.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/mm/fremap.c 2008-01-29 22:12:32.000000000 -0500
@@ -129,6 +129,25 @@
return err;
}
up_read(&mm->mmap_sem);
else
diff -Nurb linux-2.6.22-570/mm/hugetlb.c linux-2.6.22-590/mm/hugetlb.c
---- linux-2.6.22-570/mm/hugetlb.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/mm/hugetlb.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/mm/hugetlb.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/mm/hugetlb.c 2008-01-29 22:12:32.000000000 -0500
@@ -28,6 +28,9 @@
static struct list_head hugepage_freelists[MAX_NUMNODES];
static unsigned int nr_huge_pages_node[MAX_NUMNODES];
int hugetlb_report_meminfo(char *buf)
diff -Nurb linux-2.6.22-570/mm/memory.c linux-2.6.22-590/mm/memory.c
---- linux-2.6.22-570/mm/memory.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/mm/memory.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/mm/memory.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/mm/memory.c 2008-01-29 22:12:32.000000000 -0500
@@ -1052,7 +1052,8 @@
if (pages)
foll_flags |= FOLL_GET;
pmd, write_access);
diff -Nurb linux-2.6.22-570/mm/mempolicy.c linux-2.6.22-590/mm/mempolicy.c
--- linux-2.6.22-570/mm/mempolicy.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/mm/mempolicy.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/mm/mempolicy.c 2008-01-29 22:12:32.000000000 -0500
@@ -594,7 +594,7 @@
static struct page *new_node_page(struct page *page, unsigned long node, int **x)
-
diff -Nurb linux-2.6.22-570/mm/migrate.c linux-2.6.22-590/mm/migrate.c
--- linux-2.6.22-570/mm/migrate.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/mm/migrate.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/mm/migrate.c 2008-01-29 22:12:32.000000000 -0500
@@ -761,7 +761,8 @@
*result = &pm->status;
/*
diff -Nurb linux-2.6.22-570/mm/mmap.c linux-2.6.22-590/mm/mmap.c
---- linux-2.6.22-570/mm/mmap.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/mm/mmap.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/mm/mmap.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/mm/mmap.c 2008-01-29 22:12:32.000000000 -0500
@@ -202,6 +202,17 @@
}
unmap_and_free_vma:
diff -Nurb linux-2.6.22-570/mm/mremap.c linux-2.6.22-590/mm/mremap.c
---- linux-2.6.22-570/mm/mremap.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/mm/mremap.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/mm/mremap.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/mm/mremap.c 2008-01-29 22:12:32.000000000 -0500
@@ -292,6 +292,10 @@
if ((addr <= new_addr) && (addr+old_len) > new_addr)
goto out;
}
ret = move_vma(vma, addr, old_len, new_len, new_addr);
diff -Nurb linux-2.6.22-570/mm/nommu.c linux-2.6.22-590/mm/nommu.c
---- linux-2.6.22-570/mm/nommu.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/mm/nommu.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/mm/nommu.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/mm/nommu.c 2008-01-29 22:12:32.000000000 -0500
@@ -639,7 +639,7 @@
}
BUG();
return NULL;
diff -Nurb linux-2.6.22-570/mm/page_alloc.c linux-2.6.22-590/mm/page_alloc.c
---- linux-2.6.22-570/mm/page_alloc.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/mm/page_alloc.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/mm/page_alloc.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/mm/page_alloc.c 2008-01-29 22:12:32.000000000 -0500
@@ -143,6 +143,42 @@
EXPORT_SYMBOL(nr_node_ids);
#endif
+}
diff -Nurb linux-2.6.22-570/mm/pdflush.c linux-2.6.22-590/mm/pdflush.c
--- linux-2.6.22-570/mm/pdflush.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/mm/pdflush.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/mm/pdflush.c 2008-01-29 22:12:32.000000000 -0500
@@ -92,6 +92,7 @@
static int __pdflush(struct pdflush_work *my_work)
{
my_work->who = current;
INIT_LIST_HEAD(&my_work->list);
diff -Nurb linux-2.6.22-570/mm/rmap.c linux-2.6.22-590/mm/rmap.c
---- linux-2.6.22-570/mm/rmap.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/mm/rmap.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/mm/rmap.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/mm/rmap.c 2008-01-29 22:12:32.000000000 -0500
@@ -622,8 +622,10 @@
printk (KERN_EMERG " page->count = %x\n", page_count(page));
printk (KERN_EMERG " page->mapping = %p\n", page->mapping);
print_symbol (KERN_EMERG " vma->vm_file->f_op->mmap = %s\n", (unsigned long)vma->vm_file->f_op->mmap);
BUG();
diff -Nurb linux-2.6.22-570/mm/shmem.c linux-2.6.22-590/mm/shmem.c
---- linux-2.6.22-570/mm/shmem.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/mm/shmem.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/mm/shmem.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/mm/shmem.c 2008-01-29 22:12:32.000000000 -0500
@@ -81,6 +81,7 @@
SGP_READ, /* don't exceed i_size, don't allocate page */
SGP_CACHE, /* don't exceed i_size, may allocate page */
+ vma->vm_flags |= VM_CAN_INVALIDATE;
return 0;
}
+diff -Nurb linux-2.6.22-570/mm/shmem.c.orig linux-2.6.22-590/mm/shmem.c.orig
+--- linux-2.6.22-570/mm/shmem.c.orig 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/mm/shmem.c.orig 1969-12-31 19:00:00.000000000 -0500
+@@ -1,2619 +0,0 @@
+-/*
+- * Resizable virtual memory filesystem for Linux.
+- *
+- * Copyright (C) 2000 Linus Torvalds.
+- * 2000 Transmeta Corp.
+- * 2000-2001 Christoph Rohland
+- * 2000-2001 SAP AG
+- * 2002 Red Hat Inc.
+- * Copyright (C) 2002-2005 Hugh Dickins.
+- * Copyright (C) 2002-2005 VERITAS Software Corporation.
+- * Copyright (C) 2004 Andi Kleen, SuSE Labs
+- *
+- * Extended attribute support for tmpfs:
+- * Copyright (c) 2004, Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+- * Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
+- *
+- * This file is released under the GPL.
+- */
+-
+-/*
+- * This virtual memory filesystem is heavily based on the ramfs. It
+- * extends ramfs by the ability to use swap and honor resource limits
+- * which makes it a completely usable filesystem.
+- */
+-
+-#include <linux/module.h>
+-#include <linux/init.h>
+-#include <linux/fs.h>
+-#include <linux/xattr.h>
+-#include <linux/generic_acl.h>
+-#include <linux/mm.h>
+-#include <linux/mman.h>
+-#include <linux/file.h>
+-#include <linux/swap.h>
+-#include <linux/pagemap.h>
+-#include <linux/string.h>
+-#include <linux/slab.h>
+-#include <linux/backing-dev.h>
+-#include <linux/shmem_fs.h>
+-#include <linux/mount.h>
+-#include <linux/writeback.h>
+-#include <linux/vfs.h>
+-#include <linux/blkdev.h>
+-#include <linux/security.h>
+-#include <linux/swapops.h>
+-#include <linux/mempolicy.h>
+-#include <linux/namei.h>
+-#include <linux/ctype.h>
+-#include <linux/migrate.h>
+-#include <linux/highmem.h>
+-#include <linux/backing-dev.h>
+-
+-#include <asm/uaccess.h>
+-#include <asm/div64.h>
+-#include <asm/pgtable.h>
+-
+-/* This magic number is used in glibc for posix shared memory */
+-#define TMPFS_MAGIC 0x01021994
+-
+-#define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long))
+-#define ENTRIES_PER_PAGEPAGE (ENTRIES_PER_PAGE*ENTRIES_PER_PAGE)
+-#define BLOCKS_PER_PAGE (PAGE_CACHE_SIZE/512)
+-
+-#define SHMEM_MAX_INDEX (SHMEM_NR_DIRECT + (ENTRIES_PER_PAGEPAGE/2) * (ENTRIES_PER_PAGE+1))
+-#define SHMEM_MAX_BYTES ((unsigned long long)SHMEM_MAX_INDEX << PAGE_CACHE_SHIFT)
+-
+-#define VM_ACCT(size) (PAGE_CACHE_ALIGN(size) >> PAGE_SHIFT)
+-
+-/* info->flags needs VM_flags to handle pagein/truncate races efficiently */
+-#define SHMEM_PAGEIN VM_READ
+-#define SHMEM_TRUNCATE VM_WRITE
+-
+-/* Definition to limit shmem_truncate's steps between cond_rescheds */
+-#define LATENCY_LIMIT 64
+-
+-/* Pretend that each entry is of this size in directory's i_size */
+-#define BOGO_DIRENT_SIZE 20
+-
+-/* Flag allocation requirements to shmem_getpage and shmem_swp_alloc */
+-enum sgp_type {
+- SGP_QUICK, /* don't try more than file page cache lookup */
+- SGP_READ, /* don't exceed i_size, don't allocate page */
+- SGP_CACHE, /* don't exceed i_size, may allocate page */
+- SGP_WRITE, /* may exceed i_size, may allocate page */
+-};
+-
+-static int shmem_getpage(struct inode *inode, unsigned long idx,
+- struct page **pagep, enum sgp_type sgp, int *type);
+-
+-static inline struct page *shmem_dir_alloc(gfp_t gfp_mask)
+-{
+- /*
+- * The above definition of ENTRIES_PER_PAGE, and the use of
+- * BLOCKS_PER_PAGE on indirect pages, assume PAGE_CACHE_SIZE:
+- * might be reconsidered if it ever diverges from PAGE_SIZE.
+- */
+- return alloc_pages(gfp_mask, PAGE_CACHE_SHIFT-PAGE_SHIFT);
+-}
+-
+-static inline void shmem_dir_free(struct page *page)
+-{
+- __free_pages(page, PAGE_CACHE_SHIFT-PAGE_SHIFT);
+-}
+-
+-static struct page **shmem_dir_map(struct page *page)
+-{
+- return (struct page **)kmap_atomic(page, KM_USER0);
+-}
+-
+-static inline void shmem_dir_unmap(struct page **dir)
+-{
+- kunmap_atomic(dir, KM_USER0);
+-}
+-
+-static swp_entry_t *shmem_swp_map(struct page *page)
+-{
+- return (swp_entry_t *)kmap_atomic(page, KM_USER1);
+-}
+-
+-static inline void shmem_swp_balance_unmap(void)
+-{
+- /*
+- * When passing a pointer to an i_direct entry, to code which
+- * also handles indirect entries and so will shmem_swp_unmap,
+- * we must arrange for the preempt count to remain in balance.
+- * What kmap_atomic of a lowmem page does depends on config
+- * and architecture, so pretend to kmap_atomic some lowmem page.
+- */
+- (void) kmap_atomic(ZERO_PAGE(0), KM_USER1);
+-}
+-
+-static inline void shmem_swp_unmap(swp_entry_t *entry)
+-{
+- kunmap_atomic(entry, KM_USER1);
+-}
+-
+-static inline struct shmem_sb_info *SHMEM_SB(struct super_block *sb)
+-{
+- return sb->s_fs_info;
+-}
+-
+-/*
+- * shmem_file_setup pre-accounts the whole fixed size of a VM object,
+- * for shared memory and for shared anonymous (/dev/zero) mappings
+- * (unless MAP_NORESERVE and sysctl_overcommit_memory <= 1),
+- * consistent with the pre-accounting of private mappings ...
+- */
+-static inline int shmem_acct_size(unsigned long flags, loff_t size)
+-{
+- return (flags & VM_ACCOUNT)?
+- security_vm_enough_memory(VM_ACCT(size)): 0;
+-}
+-
+-static inline void shmem_unacct_size(unsigned long flags, loff_t size)
+-{
+- if (flags & VM_ACCOUNT)
+- vm_unacct_memory(VM_ACCT(size));
+-}
+-
+-/*
+- * ... whereas tmpfs objects are accounted incrementally as
+- * pages are allocated, in order to allow huge sparse files.
+- * shmem_getpage reports shmem_acct_block failure as -ENOSPC not -ENOMEM,
+- * so that a failure on a sparse tmpfs mapping will give SIGBUS not OOM.
+- */
+-static inline int shmem_acct_block(unsigned long flags)
+-{
+- return (flags & VM_ACCOUNT)?
+- 0: security_vm_enough_memory(VM_ACCT(PAGE_CACHE_SIZE));
+-}
+-
+-static inline void shmem_unacct_blocks(unsigned long flags, long pages)
+-{
+- if (!(flags & VM_ACCOUNT))
+- vm_unacct_memory(pages * VM_ACCT(PAGE_CACHE_SIZE));
+-}
+-
+-static const struct super_operations shmem_ops;
+-static const struct address_space_operations shmem_aops;
+-static const struct file_operations shmem_file_operations;
+-static const struct inode_operations shmem_inode_operations;
+-static const struct inode_operations shmem_dir_inode_operations;
+-static const struct inode_operations shmem_special_inode_operations;
+-static struct vm_operations_struct shmem_vm_ops;
+-
+-static struct backing_dev_info shmem_backing_dev_info __read_mostly = {
+- .ra_pages = 0, /* No readahead */
+- .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
+- .unplug_io_fn = default_unplug_io_fn,
+-};
+-
+-static LIST_HEAD(shmem_swaplist);
+-static DEFINE_SPINLOCK(shmem_swaplist_lock);
+-
+-static void shmem_free_blocks(struct inode *inode, long pages)
+-{
+- struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
+- if (sbinfo->max_blocks) {
+- spin_lock(&sbinfo->stat_lock);
+- sbinfo->free_blocks += pages;
+- inode->i_blocks -= pages*BLOCKS_PER_PAGE;
+- spin_unlock(&sbinfo->stat_lock);
+- }
+-}
+-
+-/*
+- * shmem_recalc_inode - recalculate the size of an inode
+- *
+- * @inode: inode to recalc
+- *
+- * We have to calculate the free blocks since the mm can drop
+- * undirtied hole pages behind our back.
+- *
+- * But normally info->alloced == inode->i_mapping->nrpages + info->swapped
+- * So mm freed is info->alloced - (inode->i_mapping->nrpages + info->swapped)
+- *
+- * It has to be called with the spinlock held.
+- */
+-static void shmem_recalc_inode(struct inode *inode)
+-{
+- struct shmem_inode_info *info = SHMEM_I(inode);
+- long freed;
+-
+- freed = info->alloced - info->swapped - inode->i_mapping->nrpages;
+- if (freed > 0) {
+- info->alloced -= freed;
+- shmem_unacct_blocks(info->flags, freed);
+- shmem_free_blocks(inode, freed);
+- }
+-}
+-
+-/*
+- * shmem_swp_entry - find the swap vector position in the info structure
+- *
+- * @info: info structure for the inode
+- * @index: index of the page to find
+- * @page: optional page to add to the structure. Has to be preset to
+- * all zeros
+- *
+- * If there is no space allocated yet it will return NULL when
+- * page is NULL, else it will use the page for the needed block,
+- * setting it to NULL on return to indicate that it has been used.
+- *
+- * The swap vector is organized the following way:
+- *
+- * There are SHMEM_NR_DIRECT entries directly stored in the
+- * shmem_inode_info structure. So small files do not need an addional
+- * allocation.
+- *
+- * For pages with index > SHMEM_NR_DIRECT there is the pointer
+- * i_indirect which points to a page which holds in the first half
+- * doubly indirect blocks, in the second half triple indirect blocks:
+- *
+- * For an artificial ENTRIES_PER_PAGE = 4 this would lead to the
+- * following layout (for SHMEM_NR_DIRECT == 16):
+- *
+- * i_indirect -> dir --> 16-19
+- * | +-> 20-23
+- * |
+- * +-->dir2 --> 24-27
+- * | +-> 28-31
+- * | +-> 32-35
+- * | +-> 36-39
+- * |
+- * +-->dir3 --> 40-43
+- * +-> 44-47
+- * +-> 48-51
+- * +-> 52-55
+- */
+-static swp_entry_t *shmem_swp_entry(struct shmem_inode_info *info, unsigned long index, struct page **page)
+-{
+- unsigned long offset;
+- struct page **dir;
+- struct page *subdir;
+-
+- if (index < SHMEM_NR_DIRECT) {
+- shmem_swp_balance_unmap();
+- return info->i_direct+index;
+- }
+- if (!info->i_indirect) {
+- if (page) {
+- info->i_indirect = *page;
+- *page = NULL;
+- }
+- return NULL; /* need another page */
+- }
+-
+- index -= SHMEM_NR_DIRECT;
+- offset = index % ENTRIES_PER_PAGE;
+- index /= ENTRIES_PER_PAGE;
+- dir = shmem_dir_map(info->i_indirect);
+-
+- if (index >= ENTRIES_PER_PAGE/2) {
+- index -= ENTRIES_PER_PAGE/2;
+- dir += ENTRIES_PER_PAGE/2 + index/ENTRIES_PER_PAGE;
+- index %= ENTRIES_PER_PAGE;
+- subdir = *dir;
+- if (!subdir) {
+- if (page) {
+- *dir = *page;
+- *page = NULL;
+- }
+- shmem_dir_unmap(dir);
+- return NULL; /* need another page */
+- }
+- shmem_dir_unmap(dir);
+- dir = shmem_dir_map(subdir);
+- }
+-
+- dir += index;
+- subdir = *dir;
+- if (!subdir) {
+- if (!page || !(subdir = *page)) {
+- shmem_dir_unmap(dir);
+- return NULL; /* need a page */
+- }
+- *dir = subdir;
+- *page = NULL;
+- }
+- shmem_dir_unmap(dir);
+- return shmem_swp_map(subdir) + offset;
+-}
+-
+-static void shmem_swp_set(struct shmem_inode_info *info, swp_entry_t *entry, unsigned long value)
+-{
+- long incdec = value? 1: -1;
+-
+- entry->val = value;
+- info->swapped += incdec;
+- if ((unsigned long)(entry - info->i_direct) >= SHMEM_NR_DIRECT) {
+- struct page *page = kmap_atomic_to_page(entry);
+- set_page_private(page, page_private(page) + incdec);
+- }
+-}
+-
+-/*
+- * shmem_swp_alloc - get the position of the swap entry for the page.
+- * If it does not exist allocate the entry.
+- *
+- * @info: info structure for the inode
+- * @index: index of the page to find
+- * @sgp: check and recheck i_size? skip allocation?
+- */
+-static swp_entry_t *shmem_swp_alloc(struct shmem_inode_info *info, unsigned long index, enum sgp_type sgp)
+-{
+- struct inode *inode = &info->vfs_inode;
+- struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
+- struct page *page = NULL;
+- swp_entry_t *entry;
+-
+- if (sgp != SGP_WRITE &&
+- ((loff_t) index << PAGE_CACHE_SHIFT) >= i_size_read(inode))
+- return ERR_PTR(-EINVAL);
+-
+- while (!(entry = shmem_swp_entry(info, index, &page))) {
+- if (sgp == SGP_READ)
+- return shmem_swp_map(ZERO_PAGE(0));
+- /*
+- * Test free_blocks against 1 not 0, since we have 1 data
+- * page (and perhaps indirect index pages) yet to allocate:
+- * a waste to allocate index if we cannot allocate data.
+- */
+- if (sbinfo->max_blocks) {
+- spin_lock(&sbinfo->stat_lock);
+- if (sbinfo->free_blocks <= 1) {
+- spin_unlock(&sbinfo->stat_lock);
+- return ERR_PTR(-ENOSPC);
+- }
+- sbinfo->free_blocks--;
+- inode->i_blocks += BLOCKS_PER_PAGE;
+- spin_unlock(&sbinfo->stat_lock);
+- }
+-
+- spin_unlock(&info->lock);
+- page = shmem_dir_alloc(mapping_gfp_mask(inode->i_mapping) | __GFP_ZERO);
+- if (page)
+- set_page_private(page, 0);
+- spin_lock(&info->lock);
+-
+- if (!page) {
+- shmem_free_blocks(inode, 1);
+- return ERR_PTR(-ENOMEM);
+- }
+- if (sgp != SGP_WRITE &&
+- ((loff_t) index << PAGE_CACHE_SHIFT) >= i_size_read(inode)) {
+- entry = ERR_PTR(-EINVAL);
+- break;
+- }
+- if (info->next_index <= index)
+- info->next_index = index + 1;
+- }
+- if (page) {
+- /* another task gave its page, or truncated the file */
+- shmem_free_blocks(inode, 1);
+- shmem_dir_free(page);
+- }
+- if (info->next_index <= index && !IS_ERR(entry))
+- info->next_index = index + 1;
+- return entry;
+-}
+-
+-/*
+- * shmem_free_swp - free some swap entries in a directory
+- *
+- * @dir: pointer to the directory
+- * @edir: pointer after last entry of the directory
+- * @punch_lock: pointer to spinlock when needed for the holepunch case
+- */
+-static int shmem_free_swp(swp_entry_t *dir, swp_entry_t *edir,
+- spinlock_t *punch_lock)
+-{
+- spinlock_t *punch_unlock = NULL;
+- swp_entry_t *ptr;
+- int freed = 0;
+-
+- for (ptr = dir; ptr < edir; ptr++) {
+- if (ptr->val) {
+- if (unlikely(punch_lock)) {
+- punch_unlock = punch_lock;
+- punch_lock = NULL;
+- spin_lock(punch_unlock);
+- if (!ptr->val)
+- continue;
+- }
+- free_swap_and_cache(*ptr);
+- *ptr = (swp_entry_t){0};
+- freed++;
+- }
+- }
+- if (punch_unlock)
+- spin_unlock(punch_unlock);
+- return freed;
+-}
+-
+-static int shmem_map_and_free_swp(struct page *subdir, int offset,
+- int limit, struct page ***dir, spinlock_t *punch_lock)
+-{
+- swp_entry_t *ptr;
+- int freed = 0;
+-
+- ptr = shmem_swp_map(subdir);
+- for (; offset < limit; offset += LATENCY_LIMIT) {
+- int size = limit - offset;
+- if (size > LATENCY_LIMIT)
+- size = LATENCY_LIMIT;
+- freed += shmem_free_swp(ptr+offset, ptr+offset+size,
+- punch_lock);
+- if (need_resched()) {
+- shmem_swp_unmap(ptr);
+- if (*dir) {
+- shmem_dir_unmap(*dir);
+- *dir = NULL;
+- }
+- cond_resched();
+- ptr = shmem_swp_map(subdir);
+- }
+- }
+- shmem_swp_unmap(ptr);
+- return freed;
+-}
+-
+-static void shmem_free_pages(struct list_head *next)
+-{
+- struct page *page;
+- int freed = 0;
+-
+- do {
+- page = container_of(next, struct page, lru);
+- next = next->next;
+- shmem_dir_free(page);
+- freed++;
+- if (freed >= LATENCY_LIMIT) {
+- cond_resched();
+- freed = 0;
+- }
+- } while (next);
+-}
+-
+-static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end)
+-{
+- struct shmem_inode_info *info = SHMEM_I(inode);
+- unsigned long idx;
+- unsigned long size;
+- unsigned long limit;
+- unsigned long stage;
+- unsigned long diroff;
+- struct page **dir;
+- struct page *topdir;
+- struct page *middir;
+- struct page *subdir;
+- swp_entry_t *ptr;
+- LIST_HEAD(pages_to_free);
+- long nr_pages_to_free = 0;
+- long nr_swaps_freed = 0;
+- int offset;
+- int freed;
+- int punch_hole;
+- spinlock_t *needs_lock;
+- spinlock_t *punch_lock;
+- unsigned long upper_limit;
+-
+- inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+- idx = (start + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+- if (idx >= info->next_index)
+- return;
+-
+- spin_lock(&info->lock);
+- info->flags |= SHMEM_TRUNCATE;
+- if (likely(end == (loff_t) -1)) {
+- limit = info->next_index;
+- upper_limit = SHMEM_MAX_INDEX;
+- info->next_index = idx;
+- needs_lock = NULL;
+- punch_hole = 0;
+- } else {
+- if (end + 1 >= inode->i_size) { /* we may free a little more */
+- limit = (inode->i_size + PAGE_CACHE_SIZE - 1) >>
+- PAGE_CACHE_SHIFT;
+- upper_limit = SHMEM_MAX_INDEX;
+- } else {
+- limit = (end + 1) >> PAGE_CACHE_SHIFT;
+- upper_limit = limit;
+- }
+- needs_lock = &info->lock;
+- punch_hole = 1;
+- }
+-
+- topdir = info->i_indirect;
+- if (topdir && idx <= SHMEM_NR_DIRECT && !punch_hole) {
+- info->i_indirect = NULL;
+- nr_pages_to_free++;
+- list_add(&topdir->lru, &pages_to_free);
+- }
+- spin_unlock(&info->lock);
+-
+- if (info->swapped && idx < SHMEM_NR_DIRECT) {
+- ptr = info->i_direct;
+- size = limit;
+- if (size > SHMEM_NR_DIRECT)
+- size = SHMEM_NR_DIRECT;
+- nr_swaps_freed = shmem_free_swp(ptr+idx, ptr+size, needs_lock);
+- }
+-
+- /*
+- * If there are no indirect blocks or we are punching a hole
+- * below indirect blocks, nothing to be done.
+- */
+- if (!topdir || limit <= SHMEM_NR_DIRECT)
+- goto done2;
+-
+- /*
+- * The truncation case has already dropped info->lock, and we're safe
+- * because i_size and next_index have already been lowered, preventing
+- * access beyond. But in the punch_hole case, we still need to take
+- * the lock when updating the swap directory, because there might be
+- * racing accesses by shmem_getpage(SGP_CACHE), shmem_unuse_inode or
+- * shmem_writepage. However, whenever we find we can remove a whole
+- * directory page (not at the misaligned start or end of the range),
+- * we first NULLify its pointer in the level above, and then have no
+- * need to take the lock when updating its contents: needs_lock and
+- * punch_lock (either pointing to info->lock or NULL) manage this.
+- */
+-
+- upper_limit -= SHMEM_NR_DIRECT;
+- limit -= SHMEM_NR_DIRECT;
+- idx = (idx > SHMEM_NR_DIRECT)? (idx - SHMEM_NR_DIRECT): 0;
+- offset = idx % ENTRIES_PER_PAGE;
+- idx -= offset;
+-
+- dir = shmem_dir_map(topdir);
+- stage = ENTRIES_PER_PAGEPAGE/2;
+- if (idx < ENTRIES_PER_PAGEPAGE/2) {
+- middir = topdir;
+- diroff = idx/ENTRIES_PER_PAGE;
+- } else {
+- dir += ENTRIES_PER_PAGE/2;
+- dir += (idx - ENTRIES_PER_PAGEPAGE/2)/ENTRIES_PER_PAGEPAGE;
+- while (stage <= idx)
+- stage += ENTRIES_PER_PAGEPAGE;
+- middir = *dir;
+- if (*dir) {
+- diroff = ((idx - ENTRIES_PER_PAGEPAGE/2) %
+- ENTRIES_PER_PAGEPAGE) / ENTRIES_PER_PAGE;
+- if (!diroff && !offset && upper_limit >= stage) {
+- if (needs_lock) {
+- spin_lock(needs_lock);
+- *dir = NULL;
+- spin_unlock(needs_lock);
+- needs_lock = NULL;
+- } else
+- *dir = NULL;
+- nr_pages_to_free++;
+- list_add(&middir->lru, &pages_to_free);
+- }
+- shmem_dir_unmap(dir);
+- dir = shmem_dir_map(middir);
+- } else {
+- diroff = 0;
+- offset = 0;
+- idx = stage;
+- }
+- }
+-
+- for (; idx < limit; idx += ENTRIES_PER_PAGE, diroff++) {
+- if (unlikely(idx == stage)) {
+- shmem_dir_unmap(dir);
+- dir = shmem_dir_map(topdir) +
+- ENTRIES_PER_PAGE/2 + idx/ENTRIES_PER_PAGEPAGE;
+- while (!*dir) {
+- dir++;
+- idx += ENTRIES_PER_PAGEPAGE;
+- if (idx >= limit)
+- goto done1;
+- }
+- stage = idx + ENTRIES_PER_PAGEPAGE;
+- middir = *dir;
+- if (punch_hole)
+- needs_lock = &info->lock;
+- if (upper_limit >= stage) {
+- if (needs_lock) {
+- spin_lock(needs_lock);
+- *dir = NULL;
+- spin_unlock(needs_lock);
+- needs_lock = NULL;
+- } else
+- *dir = NULL;
+- nr_pages_to_free++;
+- list_add(&middir->lru, &pages_to_free);
+- }
+- shmem_dir_unmap(dir);
+- cond_resched();
+- dir = shmem_dir_map(middir);
+- diroff = 0;
+- }
+- punch_lock = needs_lock;
+- subdir = dir[diroff];
+- if (subdir && !offset && upper_limit-idx >= ENTRIES_PER_PAGE) {
+- if (needs_lock) {
+- spin_lock(needs_lock);
+- dir[diroff] = NULL;
+- spin_unlock(needs_lock);
+- punch_lock = NULL;
+- } else
+- dir[diroff] = NULL;
+- nr_pages_to_free++;
+- list_add(&subdir->lru, &pages_to_free);
+- }
+- if (subdir && page_private(subdir) /* has swap entries */) {
+- size = limit - idx;
+- if (size > ENTRIES_PER_PAGE)
+- size = ENTRIES_PER_PAGE;
+- freed = shmem_map_and_free_swp(subdir,
+- offset, size, &dir, punch_lock);
+- if (!dir)
+- dir = shmem_dir_map(middir);
+- nr_swaps_freed += freed;
+- if (offset || punch_lock) {
+- spin_lock(&info->lock);
+- set_page_private(subdir,
+- page_private(subdir) - freed);
+- spin_unlock(&info->lock);
+- } else
+- BUG_ON(page_private(subdir) != freed);
+- }
+- offset = 0;
+- }
+-done1:
+- shmem_dir_unmap(dir);
+-done2:
+- if (inode->i_mapping->nrpages && (info->flags & SHMEM_PAGEIN)) {
+- /*
+- * Call truncate_inode_pages again: racing shmem_unuse_inode
+- * may have swizzled a page in from swap since vmtruncate or
+- * generic_delete_inode did it, before we lowered next_index.
+- * Also, though shmem_getpage checks i_size before adding to
+- * cache, no recheck after: so fix the narrow window there too.
+- *
+- * Recalling truncate_inode_pages_range and unmap_mapping_range
+- * every time for punch_hole (which never got a chance to clear
+- * SHMEM_PAGEIN at the start of vmtruncate_range) is expensive,
+- * yet hardly ever necessary: try to optimize them out later.
+- */
+- truncate_inode_pages_range(inode->i_mapping, start, end);
+- if (punch_hole)
+- unmap_mapping_range(inode->i_mapping, start,
+- end - start, 1);
+- }
+-
+- spin_lock(&info->lock);
+- info->flags &= ~SHMEM_TRUNCATE;
+- info->swapped -= nr_swaps_freed;
+- if (nr_pages_to_free)
+- shmem_free_blocks(inode, nr_pages_to_free);
+- shmem_recalc_inode(inode);
+- spin_unlock(&info->lock);
+-
+- /*
+- * Empty swap vector directory pages to be freed?
+- */
+- if (!list_empty(&pages_to_free)) {
+- pages_to_free.prev->next = NULL;
+- shmem_free_pages(pages_to_free.next);
+- }
+-}
+-
+-static void shmem_truncate(struct inode *inode)
+-{
+- shmem_truncate_range(inode, inode->i_size, (loff_t)-1);
+-}
+-
+-static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
+-{
+- struct inode *inode = dentry->d_inode;
+- struct page *page = NULL;
+- int error;
+-
+- if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) {
+- if (attr->ia_size < inode->i_size) {
+- /*
+- * If truncating down to a partial page, then
+- * if that page is already allocated, hold it
+- * in memory until the truncation is over, so
+- * truncate_partial_page cannnot miss it were
+- * it assigned to swap.
+- */
+- if (attr->ia_size & (PAGE_CACHE_SIZE-1)) {
+- (void) shmem_getpage(inode,
+- attr->ia_size>>PAGE_CACHE_SHIFT,
+- &page, SGP_READ, NULL);
+- }
+- /*
+- * Reset SHMEM_PAGEIN flag so that shmem_truncate can
+- * detect if any pages might have been added to cache
+- * after truncate_inode_pages. But we needn't bother
+- * if it's being fully truncated to zero-length: the
+- * nrpages check is efficient enough in that case.
+- */
+- if (attr->ia_size) {
+- struct shmem_inode_info *info = SHMEM_I(inode);
+- spin_lock(&info->lock);
+- info->flags &= ~SHMEM_PAGEIN;
+- spin_unlock(&info->lock);
+- }
+- }
+- }
+-
+- error = inode_change_ok(inode, attr);
+- if (!error)
+- error = inode_setattr(inode, attr);
+-#ifdef CONFIG_TMPFS_POSIX_ACL
+- if (!error && (attr->ia_valid & ATTR_MODE))
+- error = generic_acl_chmod(inode, &shmem_acl_ops);
+-#endif
+- if (page)
+- page_cache_release(page);
+- return error;
+-}
+-
+-static void shmem_delete_inode(struct inode *inode)
+-{
+- struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
+- struct shmem_inode_info *info = SHMEM_I(inode);
+-
+- if (inode->i_op->truncate == shmem_truncate) {
+- truncate_inode_pages(inode->i_mapping, 0);
+- shmem_unacct_size(info->flags, inode->i_size);
+- inode->i_size = 0;
+- shmem_truncate(inode);
+- if (!list_empty(&info->swaplist)) {
+- spin_lock(&shmem_swaplist_lock);
+- list_del_init(&info->swaplist);
+- spin_unlock(&shmem_swaplist_lock);
+- }
+- }
+- BUG_ON(inode->i_blocks);
+- if (sbinfo->max_inodes) {
+- spin_lock(&sbinfo->stat_lock);
+- sbinfo->free_inodes++;
+- spin_unlock(&sbinfo->stat_lock);
+- }
+- clear_inode(inode);
+-}
+-
+-static inline int shmem_find_swp(swp_entry_t entry, swp_entry_t *dir, swp_entry_t *edir)
+-{
+- swp_entry_t *ptr;
+-
+- for (ptr = dir; ptr < edir; ptr++) {
+- if (ptr->val == entry.val)
+- return ptr - dir;
+- }
+- return -1;
+-}
+-
+-static int shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry, struct page *page)
+-{
+- struct inode *inode;
+- unsigned long idx;
+- unsigned long size;
+- unsigned long limit;
+- unsigned long stage;
+- struct page **dir;
+- struct page *subdir;
+- swp_entry_t *ptr;
+- int offset;
+-
+- idx = 0;
+- ptr = info->i_direct;
+- spin_lock(&info->lock);
+- limit = info->next_index;
+- size = limit;
+- if (size > SHMEM_NR_DIRECT)
+- size = SHMEM_NR_DIRECT;
+- offset = shmem_find_swp(entry, ptr, ptr+size);
+- if (offset >= 0) {
+- shmem_swp_balance_unmap();
+- goto found;
+- }
+- if (!info->i_indirect)
+- goto lost2;
+-
+- dir = shmem_dir_map(info->i_indirect);
+- stage = SHMEM_NR_DIRECT + ENTRIES_PER_PAGEPAGE/2;
+-
+- for (idx = SHMEM_NR_DIRECT; idx < limit; idx += ENTRIES_PER_PAGE, dir++) {
+- if (unlikely(idx == stage)) {
+- shmem_dir_unmap(dir-1);
+- dir = shmem_dir_map(info->i_indirect) +
+- ENTRIES_PER_PAGE/2 + idx/ENTRIES_PER_PAGEPAGE;
+- while (!*dir) {
+- dir++;
+- idx += ENTRIES_PER_PAGEPAGE;
+- if (idx >= limit)
+- goto lost1;
+- }
+- stage = idx + ENTRIES_PER_PAGEPAGE;
+- subdir = *dir;
+- shmem_dir_unmap(dir);
+- dir = shmem_dir_map(subdir);
+- }
+- subdir = *dir;
+- if (subdir && page_private(subdir)) {
+- ptr = shmem_swp_map(subdir);
+- size = limit - idx;
+- if (size > ENTRIES_PER_PAGE)
+- size = ENTRIES_PER_PAGE;
+- offset = shmem_find_swp(entry, ptr, ptr+size);
+- if (offset >= 0) {
+- shmem_dir_unmap(dir);
+- goto found;
+- }
+- shmem_swp_unmap(ptr);
+- }
+- }
+-lost1:
+- shmem_dir_unmap(dir-1);
+-lost2:
+- spin_unlock(&info->lock);
+- return 0;
+-found:
+- idx += offset;
+- inode = &info->vfs_inode;
+- if (move_from_swap_cache(page, idx, inode->i_mapping) == 0) {
+- info->flags |= SHMEM_PAGEIN;
+- shmem_swp_set(info, ptr + offset, 0);
+- }
+- shmem_swp_unmap(ptr);
+- spin_unlock(&info->lock);
+- /*
+- * Decrement swap count even when the entry is left behind:
+- * try_to_unuse will skip over mms, then reincrement count.
+- */
+- swap_free(entry);
+- return 1;
+-}
+-
+-/*
+- * shmem_unuse() search for an eventually swapped out shmem page.
+- */
+-int shmem_unuse(swp_entry_t entry, struct page *page)
+-{
+- struct list_head *p, *next;
+- struct shmem_inode_info *info;
+- int found = 0;
+-
+- spin_lock(&shmem_swaplist_lock);
+- list_for_each_safe(p, next, &shmem_swaplist) {
+- info = list_entry(p, struct shmem_inode_info, swaplist);
+- if (!info->swapped)
+- list_del_init(&info->swaplist);
+- else if (shmem_unuse_inode(info, entry, page)) {
+- /* move head to start search for next from here */
+- list_move_tail(&shmem_swaplist, &info->swaplist);
+- found = 1;
+- break;
+- }
+- }
+- spin_unlock(&shmem_swaplist_lock);
+- return found;
+-}
+-
+-/*
+- * Move the page from the page cache to the swap cache.
+- */
+-static int shmem_writepage(struct page *page, struct writeback_control *wbc)
+-{
+- struct shmem_inode_info *info;
+- swp_entry_t *entry, swap;
+- struct address_space *mapping;
+- unsigned long index;
+- struct inode *inode;
+-
+- BUG_ON(!PageLocked(page));
+- /*
+- * shmem_backing_dev_info's capabilities prevent regular writeback or
+- * sync from ever calling shmem_writepage; but a stacking filesystem
+- * may use the ->writepage of its underlying filesystem, in which case
+- * we want to do nothing when that underlying filesystem is tmpfs
+- * (writing out to swap is useful as a response to memory pressure, but
+- * of no use to stabilize the data) - just redirty the page, unlock it
+- * and claim success in this case. AOP_WRITEPAGE_ACTIVATE, and the
+- * page_mapped check below, must be avoided unless we're in reclaim.
+- */
+- if (!wbc->for_reclaim) {
+- set_page_dirty(page);
+- unlock_page(page);
+- return 0;
+- }
+- BUG_ON(page_mapped(page));
+-
+- mapping = page->mapping;
+- index = page->index;
+- inode = mapping->host;
+- info = SHMEM_I(inode);
+- if (info->flags & VM_LOCKED)
+- goto redirty;
+- swap = get_swap_page();
+- if (!swap.val)
+- goto redirty;
+-
+- spin_lock(&info->lock);
+- shmem_recalc_inode(inode);
+- if (index >= info->next_index) {
+- BUG_ON(!(info->flags & SHMEM_TRUNCATE));
+- goto unlock;
+- }
+- entry = shmem_swp_entry(info, index, NULL);
+- BUG_ON(!entry);
+- BUG_ON(entry->val);
+-
+- if (move_to_swap_cache(page, swap) == 0) {
+- shmem_swp_set(info, entry, swap.val);
+- shmem_swp_unmap(entry);
+- spin_unlock(&info->lock);
+- if (list_empty(&info->swaplist)) {
+- spin_lock(&shmem_swaplist_lock);
+- /* move instead of add in case we're racing */
+- list_move_tail(&info->swaplist, &shmem_swaplist);
+- spin_unlock(&shmem_swaplist_lock);
+- }
+- unlock_page(page);
+- return 0;
+- }
+-
+- shmem_swp_unmap(entry);
+-unlock:
+- spin_unlock(&info->lock);
+- swap_free(swap);
+-redirty:
+- set_page_dirty(page);
+- return AOP_WRITEPAGE_ACTIVATE; /* Return with the page locked */
+-}
+-
+-#ifdef CONFIG_NUMA
+-static inline int shmem_parse_mpol(char *value, int *policy, nodemask_t *policy_nodes)
+-{
+- char *nodelist = strchr(value, ':');
+- int err = 1;
+-
+- if (nodelist) {
+- /* NUL-terminate policy string */
+- *nodelist++ = '\0';
+- if (nodelist_parse(nodelist, *policy_nodes))
+- goto out;
+- if (!nodes_subset(*policy_nodes, node_online_map))
+- goto out;
+- }
+- if (!strcmp(value, "default")) {
+- *policy = MPOL_DEFAULT;
+- /* Don't allow a nodelist */
+- if (!nodelist)
+- err = 0;
+- } else if (!strcmp(value, "prefer")) {
+- *policy = MPOL_PREFERRED;
+- /* Insist on a nodelist of one node only */
+- if (nodelist) {
+- char *rest = nodelist;
+- while (isdigit(*rest))
+- rest++;
+- if (!*rest)
+- err = 0;
+- }
+- } else if (!strcmp(value, "bind")) {
+- *policy = MPOL_BIND;
+- /* Insist on a nodelist */
+- if (nodelist)
+- err = 0;
+- } else if (!strcmp(value, "interleave")) {
+- *policy = MPOL_INTERLEAVE;
+- /* Default to nodes online if no nodelist */
+- if (!nodelist)
+- *policy_nodes = node_online_map;
+- err = 0;
+- }
+-out:
+- /* Restore string for error message */
+- if (nodelist)
+- *--nodelist = ':';
+- return err;
+-}
+-
+-static struct page *shmem_swapin_async(struct shared_policy *p,
+- swp_entry_t entry, unsigned long idx)
+-{
+- struct page *page;
+- struct vm_area_struct pvma;
+-
+- /* Create a pseudo vma that just contains the policy */
+- memset(&pvma, 0, sizeof(struct vm_area_struct));
+- pvma.vm_end = PAGE_SIZE;
+- pvma.vm_pgoff = idx;
+- pvma.vm_policy = mpol_shared_policy_lookup(p, idx);
+- page = read_swap_cache_async(entry, &pvma, 0);
+- mpol_free(pvma.vm_policy);
+- return page;
+-}
+-
+-struct page *shmem_swapin(struct shmem_inode_info *info, swp_entry_t entry,
+- unsigned long idx)
+-{
+- struct shared_policy *p = &info->policy;
+- int i, num;
+- struct page *page;
+- unsigned long offset;
+-
+- num = valid_swaphandles(entry, &offset);
+- for (i = 0; i < num; offset++, i++) {
+- page = shmem_swapin_async(p,
+- swp_entry(swp_type(entry), offset), idx);
+- if (!page)
+- break;
+- page_cache_release(page);
+- }
+- lru_add_drain(); /* Push any new pages onto the LRU now */
+- return shmem_swapin_async(p, entry, idx);
+-}
+-
+-static struct page *
+-shmem_alloc_page(gfp_t gfp, struct shmem_inode_info *info,
+- unsigned long idx)
+-{
+- struct vm_area_struct pvma;
+- struct page *page;
+-
+- memset(&pvma, 0, sizeof(struct vm_area_struct));
+- pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, idx);
+- pvma.vm_pgoff = idx;
+- pvma.vm_end = PAGE_SIZE;
+- page = alloc_page_vma(gfp | __GFP_ZERO, &pvma, 0);
+- mpol_free(pvma.vm_policy);
+- return page;
+-}
+-#else
+-static inline int shmem_parse_mpol(char *value, int *policy, nodemask_t *policy_nodes)
+-{
+- return 1;
+-}
+-
+-static inline struct page *
+-shmem_swapin(struct shmem_inode_info *info,swp_entry_t entry,unsigned long idx)
+-{
+- swapin_readahead(entry, 0, NULL);
+- return read_swap_cache_async(entry, NULL, 0);
+-}
+-
+-static inline struct page *
+-shmem_alloc_page(gfp_t gfp,struct shmem_inode_info *info, unsigned long idx)
+-{
+- return alloc_page(gfp | __GFP_ZERO);
+-}
+-#endif
+-
+-/*
+- * shmem_getpage - either get the page from swap or allocate a new one
+- *
+- * If we allocate a new one we do not mark it dirty. That's up to the
+- * vm. If we swap it in we mark it dirty since we also free the swap
+- * entry since a page cannot live in both the swap and page cache
+- */
+-static int shmem_getpage(struct inode *inode, unsigned long idx,
+- struct page **pagep, enum sgp_type sgp, int *type)
+-{
+- struct address_space *mapping = inode->i_mapping;
+- struct shmem_inode_info *info = SHMEM_I(inode);
+- struct shmem_sb_info *sbinfo;
+- struct page *filepage = *pagep;
+- struct page *swappage;
+- swp_entry_t *entry;
+- swp_entry_t swap;
+- int error;
+-
+- if (idx >= SHMEM_MAX_INDEX)
+- return -EFBIG;
+- /*
+- * Normally, filepage is NULL on entry, and either found
+- * uptodate immediately, or allocated and zeroed, or read
+- * in under swappage, which is then assigned to filepage.
+- * But shmem_prepare_write passes in a locked filepage,
+- * which may be found not uptodate by other callers too,
+- * and may need to be copied from the swappage read in.
+- */
+-repeat:
+- if (!filepage)
+- filepage = find_lock_page(mapping, idx);
+- if (filepage && PageUptodate(filepage))
+- goto done;
+- error = 0;
+- if (sgp == SGP_QUICK)
+- goto failed;
+-
+- spin_lock(&info->lock);
+- shmem_recalc_inode(inode);
+- entry = shmem_swp_alloc(info, idx, sgp);
+- if (IS_ERR(entry)) {
+- spin_unlock(&info->lock);
+- error = PTR_ERR(entry);
+- goto failed;
+- }
+- swap = *entry;
+-
+- if (swap.val) {
+- /* Look it up and read it in.. */
+- swappage = lookup_swap_cache(swap);
+- if (!swappage) {
+- shmem_swp_unmap(entry);
+- /* here we actually do the io */
+- if (type && *type == VM_FAULT_MINOR) {
+- __count_vm_event(PGMAJFAULT);
+- *type = VM_FAULT_MAJOR;
+- }
+- spin_unlock(&info->lock);
+- swappage = shmem_swapin(info, swap, idx);
+- if (!swappage) {
+- spin_lock(&info->lock);
+- entry = shmem_swp_alloc(info, idx, sgp);
+- if (IS_ERR(entry))
+- error = PTR_ERR(entry);
+- else {
+- if (entry->val == swap.val)
+- error = -ENOMEM;
+- shmem_swp_unmap(entry);
+- }
+- spin_unlock(&info->lock);
+- if (error)
+- goto failed;
+- goto repeat;
+- }
+- wait_on_page_locked(swappage);
+- page_cache_release(swappage);
+- goto repeat;
+- }
+-
+- /* We have to do this with page locked to prevent races */
+- if (TestSetPageLocked(swappage)) {
+- shmem_swp_unmap(entry);
+- spin_unlock(&info->lock);
+- wait_on_page_locked(swappage);
+- page_cache_release(swappage);
+- goto repeat;
+- }
+- if (PageWriteback(swappage)) {
+- shmem_swp_unmap(entry);
+- spin_unlock(&info->lock);
+- wait_on_page_writeback(swappage);
+- unlock_page(swappage);
+- page_cache_release(swappage);
+- goto repeat;
+- }
+- if (!PageUptodate(swappage)) {
+- shmem_swp_unmap(entry);
+- spin_unlock(&info->lock);
+- unlock_page(swappage);
+- page_cache_release(swappage);
+- error = -EIO;
+- goto failed;
+- }
+-
+- if (filepage) {
+- shmem_swp_set(info, entry, 0);
+- shmem_swp_unmap(entry);
+- delete_from_swap_cache(swappage);
+- spin_unlock(&info->lock);
+- copy_highpage(filepage, swappage);
+- unlock_page(swappage);
+- page_cache_release(swappage);
+- flush_dcache_page(filepage);
+- SetPageUptodate(filepage);
+- set_page_dirty(filepage);
+- swap_free(swap);
+- } else if (!(error = move_from_swap_cache(
+- swappage, idx, mapping))) {
+- info->flags |= SHMEM_PAGEIN;
+- shmem_swp_set(info, entry, 0);
+- shmem_swp_unmap(entry);
+- spin_unlock(&info->lock);
+- filepage = swappage;
+- swap_free(swap);
+- } else {
+- shmem_swp_unmap(entry);
+- spin_unlock(&info->lock);
+- unlock_page(swappage);
+- page_cache_release(swappage);
+- if (error == -ENOMEM) {
+- /* let kswapd refresh zone for GFP_ATOMICs */
+- congestion_wait(WRITE, HZ/50);
+- }
+- goto repeat;
+- }
+- } else if (sgp == SGP_READ && !filepage) {
+- shmem_swp_unmap(entry);
+- filepage = find_get_page(mapping, idx);
+- if (filepage &&
+- (!PageUptodate(filepage) || TestSetPageLocked(filepage))) {
+- spin_unlock(&info->lock);
+- wait_on_page_locked(filepage);
+- page_cache_release(filepage);
+- filepage = NULL;
+- goto repeat;
+- }
+- spin_unlock(&info->lock);
+- } else {
+- shmem_swp_unmap(entry);
+- sbinfo = SHMEM_SB(inode->i_sb);
+- if (sbinfo->max_blocks) {
+- spin_lock(&sbinfo->stat_lock);
+- if (sbinfo->free_blocks == 0 ||
+- shmem_acct_block(info->flags)) {
+- spin_unlock(&sbinfo->stat_lock);
+- spin_unlock(&info->lock);
+- error = -ENOSPC;
+- goto failed;
+- }
+- sbinfo->free_blocks--;
+- inode->i_blocks += BLOCKS_PER_PAGE;
+- spin_unlock(&sbinfo->stat_lock);
+- } else if (shmem_acct_block(info->flags)) {
+- spin_unlock(&info->lock);
+- error = -ENOSPC;
+- goto failed;
+- }
+-
+- if (!filepage) {
+- spin_unlock(&info->lock);
+- filepage = shmem_alloc_page(mapping_gfp_mask(mapping),
+- info,
+- idx);
+- if (!filepage) {
+- shmem_unacct_blocks(info->flags, 1);
+- shmem_free_blocks(inode, 1);
+- error = -ENOMEM;
+- goto failed;
+- }
+-
+- spin_lock(&info->lock);
+- entry = shmem_swp_alloc(info, idx, sgp);
+- if (IS_ERR(entry))
+- error = PTR_ERR(entry);
+- else {
+- swap = *entry;
+- shmem_swp_unmap(entry);
+- }
+- if (error || swap.val || 0 != add_to_page_cache_lru(
+- filepage, mapping, idx, GFP_ATOMIC)) {
+- spin_unlock(&info->lock);
+- page_cache_release(filepage);
+- shmem_unacct_blocks(info->flags, 1);
+- shmem_free_blocks(inode, 1);
+- filepage = NULL;
+- if (error)
+- goto failed;
+- goto repeat;
+- }
+- info->flags |= SHMEM_PAGEIN;
+- }
+-
+- info->alloced++;
+- spin_unlock(&info->lock);
+- flush_dcache_page(filepage);
+- SetPageUptodate(filepage);
+- }
+-done:
+- if (*pagep != filepage) {
+- unlock_page(filepage);
+- *pagep = filepage;
+- }
+- return 0;
+-
+-failed:
+- if (*pagep != filepage) {
+- unlock_page(filepage);
+- page_cache_release(filepage);
+- }
+- return error;
+-}
+-
+-static struct page *shmem_nopage(struct vm_area_struct *vma,
+- unsigned long address, int *type)
+-{
+- struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
+- struct page *page = NULL;
+- unsigned long idx;
+- int error;
+-
+- idx = (address - vma->vm_start) >> PAGE_SHIFT;
+- idx += vma->vm_pgoff;
+- idx >>= PAGE_CACHE_SHIFT - PAGE_SHIFT;
+- if (((loff_t) idx << PAGE_CACHE_SHIFT) >= i_size_read(inode))
+- return NOPAGE_SIGBUS;
+-
+- error = shmem_getpage(inode, idx, &page, SGP_CACHE, type);
+- if (error)
+- return (error == -ENOMEM)? NOPAGE_OOM: NOPAGE_SIGBUS;
+-
+- mark_page_accessed(page);
+- return page;
+-}
+-
+-static int shmem_populate(struct vm_area_struct *vma,
+- unsigned long addr, unsigned long len,
+- pgprot_t prot, unsigned long pgoff, int nonblock)
+-{
+- struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
+- struct mm_struct *mm = vma->vm_mm;
+- enum sgp_type sgp = nonblock? SGP_QUICK: SGP_CACHE;
+- unsigned long size;
+-
+- size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT;
+- if (pgoff >= size || pgoff + (len >> PAGE_SHIFT) > size)
+- return -EINVAL;
+-
+- while ((long) len > 0) {
+- struct page *page = NULL;
+- int err;
+- /*
+- * Will need changing if PAGE_CACHE_SIZE != PAGE_SIZE
+- */
+- err = shmem_getpage(inode, pgoff, &page, sgp, NULL);
+- if (err)
+- return err;
+- /* Page may still be null, but only if nonblock was set. */
+- if (page) {
+- mark_page_accessed(page);
+- err = install_page(mm, vma, addr, page, prot);
+- if (err) {
+- page_cache_release(page);
+- return err;
+- }
+- } else if (vma->vm_flags & VM_NONLINEAR) {
+- /* No page was found just because we can't read it in
+- * now (being here implies nonblock != 0), but the page
+- * may exist, so set the PTE to fault it in later. */
+- err = install_file_pte(mm, vma, addr, pgoff, prot);
+- if (err)
+- return err;
+- }
+-
+- len -= PAGE_SIZE;
+- addr += PAGE_SIZE;
+- pgoff++;
+- }
+- return 0;
+-}
+-
+-#ifdef CONFIG_NUMA
+-int shmem_set_policy(struct vm_area_struct *vma, struct mempolicy *new)
+-{
+- struct inode *i = vma->vm_file->f_path.dentry->d_inode;
+- return mpol_set_shared_policy(&SHMEM_I(i)->policy, vma, new);
+-}
+-
+-struct mempolicy *
+-shmem_get_policy(struct vm_area_struct *vma, unsigned long addr)
+-{
+- struct inode *i = vma->vm_file->f_path.dentry->d_inode;
+- unsigned long idx;
+-
+- idx = ((addr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
+- return mpol_shared_policy_lookup(&SHMEM_I(i)->policy, idx);
+-}
+-#endif
+-
+-int shmem_lock(struct file *file, int lock, struct user_struct *user)
+-{
+- struct inode *inode = file->f_path.dentry->d_inode;
+- struct shmem_inode_info *info = SHMEM_I(inode);
+- int retval = -ENOMEM;
+-
+- spin_lock(&info->lock);
+- if (lock && !(info->flags & VM_LOCKED)) {
+- if (!user_shm_lock(inode->i_size, user))
+- goto out_nomem;
+- info->flags |= VM_LOCKED;
+- }
+- if (!lock && (info->flags & VM_LOCKED) && user) {
+- user_shm_unlock(inode->i_size, user);
+- info->flags &= ~VM_LOCKED;
+- }
+- retval = 0;
+-out_nomem:
+- spin_unlock(&info->lock);
+- return retval;
+-}
+-
+-static int shmem_mmap(struct file *file, struct vm_area_struct *vma)
+-{
+- file_accessed(file);
+- vma->vm_ops = &shmem_vm_ops;
+- return 0;
+-}
+-
+-static struct inode *
+-shmem_get_inode(struct super_block *sb, int mode, dev_t dev)
+-{
+- struct inode *inode;
+- struct shmem_inode_info *info;
+- struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
+-
+- if (sbinfo->max_inodes) {
+- spin_lock(&sbinfo->stat_lock);
+- if (!sbinfo->free_inodes) {
+- spin_unlock(&sbinfo->stat_lock);
+- return NULL;
+- }
+- sbinfo->free_inodes--;
+- spin_unlock(&sbinfo->stat_lock);
+- }
+-
+- inode = new_inode(sb);
+- if (inode) {
+- inode->i_mode = mode;
+- inode->i_uid = current->fsuid;
+- inode->i_gid = current->fsgid;
+- inode->i_blocks = 0;
+- inode->i_mapping->a_ops = &shmem_aops;
+- inode->i_mapping->backing_dev_info = &shmem_backing_dev_info;
+- inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+- inode->i_generation = get_seconds();
+- info = SHMEM_I(inode);
+- memset(info, 0, (char *)inode - (char *)info);
+- spin_lock_init(&info->lock);
+- INIT_LIST_HEAD(&info->swaplist);
+-
+- switch (mode & S_IFMT) {
+- default:
+- inode->i_op = &shmem_special_inode_operations;
+- init_special_inode(inode, mode, dev);
+- break;
+- case S_IFREG:
+- inode->i_op = &shmem_inode_operations;
+- inode->i_fop = &shmem_file_operations;
+- mpol_shared_policy_init(&info->policy, sbinfo->policy,
+- &sbinfo->policy_nodes);
+- break;
+- case S_IFDIR:
+- inc_nlink(inode);
+- /* Some things misbehave if size == 0 on a directory */
+- inode->i_size = 2 * BOGO_DIRENT_SIZE;
+- inode->i_op = &shmem_dir_inode_operations;
+- inode->i_fop = &simple_dir_operations;
+- break;
+- case S_IFLNK:
+- /*
+- * Must not load anything in the rbtree,
+- * mpol_free_shared_policy will not be called.
+- */
+- mpol_shared_policy_init(&info->policy, MPOL_DEFAULT,
+- NULL);
+- break;
+- }
+- } else if (sbinfo->max_inodes) {
+- spin_lock(&sbinfo->stat_lock);
+- sbinfo->free_inodes++;
+- spin_unlock(&sbinfo->stat_lock);
+- }
+- return inode;
+-}
+-
+-#ifdef CONFIG_TMPFS
+-static const struct inode_operations shmem_symlink_inode_operations;
+-static const struct inode_operations shmem_symlink_inline_operations;
+-
+-/*
+- * Normally tmpfs makes no use of shmem_prepare_write, but it
+- * lets a tmpfs file be used read-write below the loop driver.
+- */
+-static int
+-shmem_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+-{
+- struct inode *inode = page->mapping->host;
+- return shmem_getpage(inode, page->index, &page, SGP_WRITE, NULL);
+-}
+-
+-static ssize_t
+-shmem_file_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+-{
+- struct inode *inode = file->f_path.dentry->d_inode;
+- loff_t pos;
+- unsigned long written;
+- ssize_t err;
+-
+- if ((ssize_t) count < 0)
+- return -EINVAL;
+-
+- if (!access_ok(VERIFY_READ, buf, count))
+- return -EFAULT;
+-
+- mutex_lock(&inode->i_mutex);
+-
+- pos = *ppos;
+- written = 0;
+-
+- err = generic_write_checks(file, &pos, &count, 0);
+- if (err || !count)
+- goto out;
+-
+- err = remove_suid(file->f_path.dentry);
+- if (err)
+- goto out;
+-
+- inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+-
+- do {
+- struct page *page = NULL;
+- unsigned long bytes, index, offset;
+- char *kaddr;
+- int left;
+-
+- offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
+- index = pos >> PAGE_CACHE_SHIFT;
+- bytes = PAGE_CACHE_SIZE - offset;
+- if (bytes > count)
+- bytes = count;
+-
+- /*
+- * We don't hold page lock across copy from user -
+- * what would it guard against? - so no deadlock here.
+- * But it still may be a good idea to prefault below.
+- */
+-
+- err = shmem_getpage(inode, index, &page, SGP_WRITE, NULL);
+- if (err)
+- break;
+-
+- left = bytes;
+- if (PageHighMem(page)) {
+- volatile unsigned char dummy;
+- __get_user(dummy, buf);
+- __get_user(dummy, buf + bytes - 1);
+-
+- kaddr = kmap_atomic(page, KM_USER0);
+- left = __copy_from_user_inatomic(kaddr + offset,
+- buf, bytes);
+- kunmap_atomic(kaddr, KM_USER0);
+- }
+- if (left) {
+- kaddr = kmap(page);
+- left = __copy_from_user(kaddr + offset, buf, bytes);
+- kunmap(page);
+- }
+-
+- written += bytes;
+- count -= bytes;
+- pos += bytes;
+- buf += bytes;
+- if (pos > inode->i_size)
+- i_size_write(inode, pos);
+-
+- flush_dcache_page(page);
+- set_page_dirty(page);
+- mark_page_accessed(page);
+- page_cache_release(page);
+-
+- if (left) {
+- pos -= left;
+- written -= left;
+- err = -EFAULT;
+- break;
+- }
+-
+- /*
+- * Our dirty pages are not counted in nr_dirty,
+- * and we do not attempt to balance dirty pages.
+- */
+-
+- cond_resched();
+- } while (count);
+-
+- *ppos = pos;
+- if (written)
+- err = written;
+-out:
+- mutex_unlock(&inode->i_mutex);
+- return err;
+-}
+-
+-static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_t *desc, read_actor_t actor)
+-{
+- struct inode *inode = filp->f_path.dentry->d_inode;
+- struct address_space *mapping = inode->i_mapping;
+- unsigned long index, offset;
+-
+- index = *ppos >> PAGE_CACHE_SHIFT;
+- offset = *ppos & ~PAGE_CACHE_MASK;
+-
+- for (;;) {
+- struct page *page = NULL;
+- unsigned long end_index, nr, ret;
+- loff_t i_size = i_size_read(inode);
+-
+- end_index = i_size >> PAGE_CACHE_SHIFT;
+- if (index > end_index)
+- break;
+- if (index == end_index) {
+- nr = i_size & ~PAGE_CACHE_MASK;
+- if (nr <= offset)
+- break;
+- }
+-
+- desc->error = shmem_getpage(inode, index, &page, SGP_READ, NULL);
+- if (desc->error) {
+- if (desc->error == -EINVAL)
+- desc->error = 0;
+- break;
+- }
+-
+- /*
+- * We must evaluate after, since reads (unlike writes)
+- * are called without i_mutex protection against truncate
+- */
+- nr = PAGE_CACHE_SIZE;
+- i_size = i_size_read(inode);
+- end_index = i_size >> PAGE_CACHE_SHIFT;
+- if (index == end_index) {
+- nr = i_size & ~PAGE_CACHE_MASK;
+- if (nr <= offset) {
+- if (page)
+- page_cache_release(page);
+- break;
+- }
+- }
+- nr -= offset;
+-
+- if (page) {
+- /*
+- * If users can be writing to this page using arbitrary
+- * virtual addresses, take care about potential aliasing
+- * before reading the page on the kernel side.
+- */
+- if (mapping_writably_mapped(mapping))
+- flush_dcache_page(page);
+- /*
+- * Mark the page accessed if we read the beginning.
+- */
+- if (!offset)
+- mark_page_accessed(page);
+- } else {
+- page = ZERO_PAGE(0);
+- page_cache_get(page);
+- }
+-
+- /*
+- * Ok, we have the page, and it's up-to-date, so
+- * now we can copy it to user space...
+- *
+- * The actor routine returns how many bytes were actually used..
+- * NOTE! This may not be the same as how much of a user buffer
+- * we filled up (we may be padding etc), so we can only update
+- * "pos" here (the actor routine has to update the user buffer
+- * pointers and the remaining count).
+- */
+- ret = actor(desc, page, offset, nr);
+- offset += ret;
+- index += offset >> PAGE_CACHE_SHIFT;
+- offset &= ~PAGE_CACHE_MASK;
+-
+- page_cache_release(page);
+- if (ret != nr || !desc->count)
+- break;
+-
+- cond_resched();
+- }
+-
+- *ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
+- file_accessed(filp);
+-}
+-
+-static ssize_t shmem_file_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
+-{
+- read_descriptor_t desc;
+-
+- if ((ssize_t) count < 0)
+- return -EINVAL;
+- if (!access_ok(VERIFY_WRITE, buf, count))
+- return -EFAULT;
+- if (!count)
+- return 0;
+-
+- desc.written = 0;
+- desc.count = count;
+- desc.arg.buf = buf;
+- desc.error = 0;
+-
+- do_shmem_file_read(filp, ppos, &desc, file_read_actor);
+- if (desc.written)
+- return desc.written;
+- return desc.error;
+-}
+-
+-static ssize_t shmem_file_sendfile(struct file *in_file, loff_t *ppos,
+- size_t count, read_actor_t actor, void *target)
+-{
+- read_descriptor_t desc;
+-
+- if (!count)
+- return 0;
+-
+- desc.written = 0;
+- desc.count = count;
+- desc.arg.data = target;
+- desc.error = 0;
+-
+- do_shmem_file_read(in_file, ppos, &desc, actor);
+- if (desc.written)
+- return desc.written;
+- return desc.error;
+-}
+-
+-static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf)
+-{
+- struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb);
+-
+- buf->f_type = TMPFS_MAGIC;
+- buf->f_bsize = PAGE_CACHE_SIZE;
+- buf->f_namelen = NAME_MAX;
+- spin_lock(&sbinfo->stat_lock);
+- if (sbinfo->max_blocks) {
+- buf->f_blocks = sbinfo->max_blocks;
+- buf->f_bavail = buf->f_bfree = sbinfo->free_blocks;
+- }
+- if (sbinfo->max_inodes) {
+- buf->f_files = sbinfo->max_inodes;
+- buf->f_ffree = sbinfo->free_inodes;
+- }
+- /* else leave those fields 0 like simple_statfs */
+- spin_unlock(&sbinfo->stat_lock);
+- return 0;
+-}
+-
+-/*
+- * File creation. Allocate an inode, and we're done..
+- */
+-static int
+-shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
+-{
+- struct inode *inode = shmem_get_inode(dir->i_sb, mode, dev);
+- int error = -ENOSPC;
+-
+- if (inode) {
+- error = security_inode_init_security(inode, dir, NULL, NULL,
+- NULL);
+- if (error) {
+- if (error != -EOPNOTSUPP) {
+- iput(inode);
+- return error;
+- }
+- }
+- error = shmem_acl_init(inode, dir);
+- if (error) {
+- iput(inode);
+- return error;
+- }
+- if (dir->i_mode & S_ISGID) {
+- inode->i_gid = dir->i_gid;
+- if (S_ISDIR(mode))
+- inode->i_mode |= S_ISGID;
+- }
+- dir->i_size += BOGO_DIRENT_SIZE;
+- dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+- d_instantiate(dentry, inode);
+- dget(dentry); /* Extra count - pin the dentry in core */
+- }
+- return error;
+-}
+-
+-static int shmem_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+-{
+- int error;
+-
+- if ((error = shmem_mknod(dir, dentry, mode | S_IFDIR, 0)))
+- return error;
+- inc_nlink(dir);
+- return 0;
+-}
+-
+-static int shmem_create(struct inode *dir, struct dentry *dentry, int mode,
+- struct nameidata *nd)
+-{
+- return shmem_mknod(dir, dentry, mode | S_IFREG, 0);
+-}
+-
+-/*
+- * Link a file..
+- */
+-static int shmem_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
+-{
+- struct inode *inode = old_dentry->d_inode;
+- struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
+-
+- /*
+- * No ordinary (disk based) filesystem counts links as inodes;
+- * but each new link needs a new dentry, pinning lowmem, and
+- * tmpfs dentries cannot be pruned until they are unlinked.
+- */
+- if (sbinfo->max_inodes) {
+- spin_lock(&sbinfo->stat_lock);
+- if (!sbinfo->free_inodes) {
+- spin_unlock(&sbinfo->stat_lock);
+- return -ENOSPC;
+- }
+- sbinfo->free_inodes--;
+- spin_unlock(&sbinfo->stat_lock);
+- }
+-
+- dir->i_size += BOGO_DIRENT_SIZE;
+- inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+- inc_nlink(inode);
+- atomic_inc(&inode->i_count); /* New dentry reference */
+- dget(dentry); /* Extra pinning count for the created dentry */
+- d_instantiate(dentry, inode);
+- return 0;
+-}
+-
+-static int shmem_unlink(struct inode *dir, struct dentry *dentry)
+-{
+- struct inode *inode = dentry->d_inode;
+-
+- if (inode->i_nlink > 1 && !S_ISDIR(inode->i_mode)) {
+- struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
+- if (sbinfo->max_inodes) {
+- spin_lock(&sbinfo->stat_lock);
+- sbinfo->free_inodes++;
+- spin_unlock(&sbinfo->stat_lock);
+- }
+- }
+-
+- dir->i_size -= BOGO_DIRENT_SIZE;
+- inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+- drop_nlink(inode);
+- dput(dentry); /* Undo the count from "create" - this does all the work */
+- return 0;
+-}
+-
+-static int shmem_rmdir(struct inode *dir, struct dentry *dentry)
+-{
+- if (!simple_empty(dentry))
+- return -ENOTEMPTY;
+-
+- drop_nlink(dentry->d_inode);
+- drop_nlink(dir);
+- return shmem_unlink(dir, dentry);
+-}
+-
+-/*
+- * The VFS layer already does all the dentry stuff for rename,
+- * we just have to decrement the usage count for the target if
+- * it exists so that the VFS layer correctly free's it when it
+- * gets overwritten.
+- */
+-static int shmem_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry)
+-{
+- struct inode *inode = old_dentry->d_inode;
+- int they_are_dirs = S_ISDIR(inode->i_mode);
+-
+- if (!simple_empty(new_dentry))
+- return -ENOTEMPTY;
+-
+- if (new_dentry->d_inode) {
+- (void) shmem_unlink(new_dir, new_dentry);
+- if (they_are_dirs)
+- drop_nlink(old_dir);
+- } else if (they_are_dirs) {
+- drop_nlink(old_dir);
+- inc_nlink(new_dir);
+- }
+-
+- old_dir->i_size -= BOGO_DIRENT_SIZE;
+- new_dir->i_size += BOGO_DIRENT_SIZE;
+- old_dir->i_ctime = old_dir->i_mtime =
+- new_dir->i_ctime = new_dir->i_mtime =
+- inode->i_ctime = CURRENT_TIME;
+- return 0;
+-}
+-
+-static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
+-{
+- int error;
+- int len;
+- struct inode *inode;
+- struct page *page = NULL;
+- char *kaddr;
+- struct shmem_inode_info *info;
+-
+- len = strlen(symname) + 1;
+- if (len > PAGE_CACHE_SIZE)
+- return -ENAMETOOLONG;
+-
+- inode = shmem_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0);
+- if (!inode)
+- return -ENOSPC;
+-
+- error = security_inode_init_security(inode, dir, NULL, NULL,
+- NULL);
+- if (error) {
+- if (error != -EOPNOTSUPP) {
+- iput(inode);
+- return error;
+- }
+- error = 0;
+- }
+-
+- info = SHMEM_I(inode);
+- inode->i_size = len-1;
+- if (len <= (char *)inode - (char *)info) {
+- /* do it inline */
+- memcpy(info, symname, len);
+- inode->i_op = &shmem_symlink_inline_operations;
+- } else {
+- error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL);
+- if (error) {
+- iput(inode);
+- return error;
+- }
+- inode->i_op = &shmem_symlink_inode_operations;
+- kaddr = kmap_atomic(page, KM_USER0);
+- memcpy(kaddr, symname, len);
+- kunmap_atomic(kaddr, KM_USER0);
+- set_page_dirty(page);
+- page_cache_release(page);
+- }
+- if (dir->i_mode & S_ISGID)
+- inode->i_gid = dir->i_gid;
+- dir->i_size += BOGO_DIRENT_SIZE;
+- dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+- d_instantiate(dentry, inode);
+- dget(dentry);
+- return 0;
+-}
+-
+-static void *shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd)
+-{
+- nd_set_link(nd, (char *)SHMEM_I(dentry->d_inode));
+- return NULL;
+-}
+-
+-static void *shmem_follow_link(struct dentry *dentry, struct nameidata *nd)
+-{
+- struct page *page = NULL;
+- int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ, NULL);
+- nd_set_link(nd, res ? ERR_PTR(res) : kmap(page));
+- return page;
+-}
+-
+-static void shmem_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
+-{
+- if (!IS_ERR(nd_get_link(nd))) {
+- struct page *page = cookie;
+- kunmap(page);
+- mark_page_accessed(page);
+- page_cache_release(page);
+- }
+-}
+-
+-static const struct inode_operations shmem_symlink_inline_operations = {
+- .readlink = generic_readlink,
+- .follow_link = shmem_follow_link_inline,
+-};
+-
+-static const struct inode_operations shmem_symlink_inode_operations = {
+- .truncate = shmem_truncate,
+- .readlink = generic_readlink,
+- .follow_link = shmem_follow_link,
+- .put_link = shmem_put_link,
+-};
+-
+-#ifdef CONFIG_TMPFS_POSIX_ACL
+-/**
+- * Superblocks without xattr inode operations will get security.* xattr
+- * support from the VFS "for free". As soon as we have any other xattrs
+- * like ACLs, we also need to implement the security.* handlers at
+- * filesystem level, though.
+- */
+-
+-static size_t shmem_xattr_security_list(struct inode *inode, char *list,
+- size_t list_len, const char *name,
+- size_t name_len)
+-{
+- return security_inode_listsecurity(inode, list, list_len);
+-}
+-
+-static int shmem_xattr_security_get(struct inode *inode, const char *name,
+- void *buffer, size_t size)
+-{
+- if (strcmp(name, "") == 0)
+- return -EINVAL;
+- return security_inode_getsecurity(inode, name, buffer, size,
+- -EOPNOTSUPP);
+-}
+-
+-static int shmem_xattr_security_set(struct inode *inode, const char *name,
+- const void *value, size_t size, int flags)
+-{
+- if (strcmp(name, "") == 0)
+- return -EINVAL;
+- return security_inode_setsecurity(inode, name, value, size, flags);
+-}
+-
+-static struct xattr_handler shmem_xattr_security_handler = {
+- .prefix = XATTR_SECURITY_PREFIX,
+- .list = shmem_xattr_security_list,
+- .get = shmem_xattr_security_get,
+- .set = shmem_xattr_security_set,
+-};
+-
+-static struct xattr_handler *shmem_xattr_handlers[] = {
+- &shmem_xattr_acl_access_handler,
+- &shmem_xattr_acl_default_handler,
+- &shmem_xattr_security_handler,
+- NULL
+-};
+-#endif
+-
+-static struct dentry *shmem_get_parent(struct dentry *child)
+-{
+- return ERR_PTR(-ESTALE);
+-}
+-
+-static int shmem_match(struct inode *ino, void *vfh)
+-{
+- __u32 *fh = vfh;
+- __u64 inum = fh[2];
+- inum = (inum << 32) | fh[1];
+- return ino->i_ino == inum && fh[0] == ino->i_generation;
+-}
+-
+-static struct dentry *shmem_get_dentry(struct super_block *sb, void *vfh)
+-{
+- struct dentry *de = NULL;
+- struct inode *inode;
+- __u32 *fh = vfh;
+- __u64 inum = fh[2];
+- inum = (inum << 32) | fh[1];
+-
+- inode = ilookup5(sb, (unsigned long)(inum+fh[0]), shmem_match, vfh);
+- if (inode) {
+- de = d_find_alias(inode);
+- iput(inode);
+- }
+-
+- return de? de: ERR_PTR(-ESTALE);
+-}
+-
+-static struct dentry *shmem_decode_fh(struct super_block *sb, __u32 *fh,
+- int len, int type,
+- int (*acceptable)(void *context, struct dentry *de),
+- void *context)
+-{
+- if (len < 3)
+- return ERR_PTR(-ESTALE);
+-
+- return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable,
+- context);
+-}
+-
+-static int shmem_encode_fh(struct dentry *dentry, __u32 *fh, int *len,
+- int connectable)
+-{
+- struct inode *inode = dentry->d_inode;
+-
+- if (*len < 3)
+- return 255;
+-
+- if (hlist_unhashed(&inode->i_hash)) {
+- /* Unfortunately insert_inode_hash is not idempotent,
+- * so as we hash inodes here rather than at creation
+- * time, we need a lock to ensure we only try
+- * to do it once
+- */
+- static DEFINE_SPINLOCK(lock);
+- spin_lock(&lock);
+- if (hlist_unhashed(&inode->i_hash))
+- __insert_inode_hash(inode,
+- inode->i_ino + inode->i_generation);
+- spin_unlock(&lock);
+- }
+-
+- fh[0] = inode->i_generation;
+- fh[1] = inode->i_ino;
+- fh[2] = ((__u64)inode->i_ino) >> 32;
+-
+- *len = 3;
+- return 1;
+-}
+-
+-static struct export_operations shmem_export_ops = {
+- .get_parent = shmem_get_parent,
+- .get_dentry = shmem_get_dentry,
+- .encode_fh = shmem_encode_fh,
+- .decode_fh = shmem_decode_fh,
+-};
+-
+-static int shmem_parse_options(char *options, int *mode, uid_t *uid,
+- gid_t *gid, unsigned long *blocks, unsigned long *inodes,
+- int *policy, nodemask_t *policy_nodes)
+-{
+- char *this_char, *value, *rest;
+-
+- while (options != NULL) {
+- this_char = options;
+- for (;;) {
+- /*
+- * NUL-terminate this option: unfortunately,
+- * mount options form a comma-separated list,
+- * but mpol's nodelist may also contain commas.
+- */
+- options = strchr(options, ',');
+- if (options == NULL)
+- break;
+- options++;
+- if (!isdigit(*options)) {
+- options[-1] = '\0';
+- break;
+- }
+- }
+- if (!*this_char)
+- continue;
+- if ((value = strchr(this_char,'=')) != NULL) {
+- *value++ = 0;
+- } else {
+- printk(KERN_ERR
+- "tmpfs: No value for mount option '%s'\n",
+- this_char);
+- return 1;
+- }
+-
+- if (!strcmp(this_char,"size")) {
+- unsigned long long size;
+- size = memparse(value,&rest);
+- if (*rest == '%') {
+- size <<= PAGE_SHIFT;
+- size *= totalram_pages;
+- do_div(size, 100);
+- rest++;
+- }
+- if (*rest)
+- goto bad_val;
+- *blocks = size >> PAGE_CACHE_SHIFT;
+- } else if (!strcmp(this_char,"nr_blocks")) {
+- *blocks = memparse(value,&rest);
+- if (*rest)
+- goto bad_val;
+- } else if (!strcmp(this_char,"nr_inodes")) {
+- *inodes = memparse(value,&rest);
+- if (*rest)
+- goto bad_val;
+- } else if (!strcmp(this_char,"mode")) {
+- if (!mode)
+- continue;
+- *mode = simple_strtoul(value,&rest,8);
+- if (*rest)
+- goto bad_val;
+- } else if (!strcmp(this_char,"uid")) {
+- if (!uid)
+- continue;
+- *uid = simple_strtoul(value,&rest,0);
+- if (*rest)
+- goto bad_val;
+- } else if (!strcmp(this_char,"gid")) {
+- if (!gid)
+- continue;
+- *gid = simple_strtoul(value,&rest,0);
+- if (*rest)
+- goto bad_val;
+- } else if (!strcmp(this_char,"mpol")) {
+- if (shmem_parse_mpol(value,policy,policy_nodes))
+- goto bad_val;
+- } else {
+- printk(KERN_ERR "tmpfs: Bad mount option %s\n",
+- this_char);
+- return 1;
+- }
+- }
+- return 0;
+-
+-bad_val:
+- printk(KERN_ERR "tmpfs: Bad value '%s' for mount option '%s'\n",
+- value, this_char);
+- return 1;
+-
+-}
+-
+-static int shmem_remount_fs(struct super_block *sb, int *flags, char *data)
+-{
+- struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
+- unsigned long max_blocks = sbinfo->max_blocks;
+- unsigned long max_inodes = sbinfo->max_inodes;
+- int policy = sbinfo->policy;
+- nodemask_t policy_nodes = sbinfo->policy_nodes;
+- unsigned long blocks;
+- unsigned long inodes;
+- int error = -EINVAL;
+-
+- if (shmem_parse_options(data, NULL, NULL, NULL, &max_blocks,
+- &max_inodes, &policy, &policy_nodes))
+- return error;
+-
+- spin_lock(&sbinfo->stat_lock);
+- blocks = sbinfo->max_blocks - sbinfo->free_blocks;
+- inodes = sbinfo->max_inodes - sbinfo->free_inodes;
+- if (max_blocks < blocks)
+- goto out;
+- if (max_inodes < inodes)
+- goto out;
+- /*
+- * Those tests also disallow limited->unlimited while any are in
+- * use, so i_blocks will always be zero when max_blocks is zero;
+- * but we must separately disallow unlimited->limited, because
+- * in that case we have no record of how much is already in use.
+- */
+- if (max_blocks && !sbinfo->max_blocks)
+- goto out;
+- if (max_inodes && !sbinfo->max_inodes)
+- goto out;
+-
+- error = 0;
+- sbinfo->max_blocks = max_blocks;
+- sbinfo->free_blocks = max_blocks - blocks;
+- sbinfo->max_inodes = max_inodes;
+- sbinfo->free_inodes = max_inodes - inodes;
+- sbinfo->policy = policy;
+- sbinfo->policy_nodes = policy_nodes;
+-out:
+- spin_unlock(&sbinfo->stat_lock);
+- return error;
+-}
+-#endif
+-
+-static void shmem_put_super(struct super_block *sb)
+-{
+- kfree(sb->s_fs_info);
+- sb->s_fs_info = NULL;
+-}
+-
+-static int shmem_fill_super(struct super_block *sb,
+- void *data, int silent)
+-{
+- struct inode *inode;
+- struct dentry *root;
+- int mode = S_IRWXUGO | S_ISVTX;
+- uid_t uid = current->fsuid;
+- gid_t gid = current->fsgid;
+- int err = -ENOMEM;
+- struct shmem_sb_info *sbinfo;
+- unsigned long blocks = 0;
+- unsigned long inodes = 0;
+- int policy = MPOL_DEFAULT;
+- nodemask_t policy_nodes = node_online_map;
+-
+-#ifdef CONFIG_TMPFS
+- /*
+- * Per default we only allow half of the physical ram per
+- * tmpfs instance, limiting inodes to one per page of lowmem;
+- * but the internal instance is left unlimited.
+- */
+- if (!(sb->s_flags & MS_NOUSER)) {
+- blocks = totalram_pages / 2;
+- inodes = totalram_pages - totalhigh_pages;
+- if (inodes > blocks)
+- inodes = blocks;
+- if (shmem_parse_options(data, &mode, &uid, &gid, &blocks,
+- &inodes, &policy, &policy_nodes))
+- return -EINVAL;
+- }
+- sb->s_export_op = &shmem_export_ops;
+-#else
+- sb->s_flags |= MS_NOUSER;
+-#endif
+-
+- /* Round up to L1_CACHE_BYTES to resist false sharing */
+- sbinfo = kmalloc(max((int)sizeof(struct shmem_sb_info),
+- L1_CACHE_BYTES), GFP_KERNEL);
+- if (!sbinfo)
+- return -ENOMEM;
+-
+- spin_lock_init(&sbinfo->stat_lock);
+- sbinfo->max_blocks = blocks;
+- sbinfo->free_blocks = blocks;
+- sbinfo->max_inodes = inodes;
+- sbinfo->free_inodes = inodes;
+- sbinfo->policy = policy;
+- sbinfo->policy_nodes = policy_nodes;
+-
+- sb->s_fs_info = sbinfo;
+- sb->s_maxbytes = SHMEM_MAX_BYTES;
+- sb->s_blocksize = PAGE_CACHE_SIZE;
+- sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+- sb->s_magic = TMPFS_MAGIC;
+- sb->s_op = &shmem_ops;
+- sb->s_time_gran = 1;
+-#ifdef CONFIG_TMPFS_POSIX_ACL
+- sb->s_xattr = shmem_xattr_handlers;
+- sb->s_flags |= MS_POSIXACL;
+-#endif
+-
+- inode = shmem_get_inode(sb, S_IFDIR | mode, 0);
+- if (!inode)
+- goto failed;
+- inode->i_uid = uid;
+- inode->i_gid = gid;
+- root = d_alloc_root(inode);
+- if (!root)
+- goto failed_iput;
+- sb->s_root = root;
+- return 0;
+-
+-failed_iput:
+- iput(inode);
+-failed:
+- shmem_put_super(sb);
+- return err;
+-}
+-
+-static struct kmem_cache *shmem_inode_cachep;
+-
+-static struct inode *shmem_alloc_inode(struct super_block *sb)
+-{
+- struct shmem_inode_info *p;
+- p = (struct shmem_inode_info *)kmem_cache_alloc(shmem_inode_cachep, GFP_KERNEL);
+- if (!p)
+- return NULL;
+- return &p->vfs_inode;
+-}
+-
+-static void shmem_destroy_inode(struct inode *inode)
+-{
+- if ((inode->i_mode & S_IFMT) == S_IFREG) {
+- /* only struct inode is valid if it's an inline symlink */
+- mpol_free_shared_policy(&SHMEM_I(inode)->policy);
+- }
+- shmem_acl_destroy_inode(inode);
+- kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode));
+-}
+-
+-static void init_once(void *foo, struct kmem_cache *cachep,
+- unsigned long flags)
+-{
+- struct shmem_inode_info *p = (struct shmem_inode_info *) foo;
+-
+- inode_init_once(&p->vfs_inode);
+-#ifdef CONFIG_TMPFS_POSIX_ACL
+- p->i_acl = NULL;
+- p->i_default_acl = NULL;
+-#endif
+-}
+-
+-static int init_inodecache(void)
+-{
+- shmem_inode_cachep = kmem_cache_create("shmem_inode_cache",
+- sizeof(struct shmem_inode_info),
+- 0, 0, init_once, NULL);
+- if (shmem_inode_cachep == NULL)
+- return -ENOMEM;
+- return 0;
+-}
+-
+-static void destroy_inodecache(void)
+-{
+- kmem_cache_destroy(shmem_inode_cachep);
+-}
+-
+-static const struct address_space_operations shmem_aops = {
+- .writepage = shmem_writepage,
+- .set_page_dirty = __set_page_dirty_no_writeback,
+-#ifdef CONFIG_TMPFS
+- .prepare_write = shmem_prepare_write,
+- .commit_write = simple_commit_write,
+-#endif
+- .migratepage = migrate_page,
+-};
+-
+-static const struct file_operations shmem_file_operations = {
+- .mmap = shmem_mmap,
+-#ifdef CONFIG_TMPFS
+- .llseek = generic_file_llseek,
+- .read = shmem_file_read,
+- .write = shmem_file_write,
+- .fsync = simple_sync_file,
+- .sendfile = shmem_file_sendfile,
+-#endif
+-};
+-
+-static const struct inode_operations shmem_inode_operations = {
+- .truncate = shmem_truncate,
+- .setattr = shmem_notify_change,
+- .truncate_range = shmem_truncate_range,
+-#ifdef CONFIG_TMPFS_POSIX_ACL
+- .setxattr = generic_setxattr,
+- .getxattr = generic_getxattr,
+- .listxattr = generic_listxattr,
+- .removexattr = generic_removexattr,
+- .permission = shmem_permission,
+-#endif
+-
+-};
+-
+-static const struct inode_operations shmem_dir_inode_operations = {
+-#ifdef CONFIG_TMPFS
+- .create = shmem_create,
+- .lookup = simple_lookup,
+- .link = shmem_link,
+- .unlink = shmem_unlink,
+- .symlink = shmem_symlink,
+- .mkdir = shmem_mkdir,
+- .rmdir = shmem_rmdir,
+- .mknod = shmem_mknod,
+- .rename = shmem_rename,
+-#endif
+-#ifdef CONFIG_TMPFS_POSIX_ACL
+- .setattr = shmem_notify_change,
+- .setxattr = generic_setxattr,
+- .getxattr = generic_getxattr,
+- .listxattr = generic_listxattr,
+- .removexattr = generic_removexattr,
+- .permission = shmem_permission,
+-#endif
+-};
+-
+-static const struct inode_operations shmem_special_inode_operations = {
+-#ifdef CONFIG_TMPFS_POSIX_ACL
+- .setattr = shmem_notify_change,
+- .setxattr = generic_setxattr,
+- .getxattr = generic_getxattr,
+- .listxattr = generic_listxattr,
+- .removexattr = generic_removexattr,
+- .permission = shmem_permission,
+-#endif
+-};
+-
+-static const struct super_operations shmem_ops = {
+- .alloc_inode = shmem_alloc_inode,
+- .destroy_inode = shmem_destroy_inode,
+-#ifdef CONFIG_TMPFS
+- .statfs = shmem_statfs,
+- .remount_fs = shmem_remount_fs,
+-#endif
+- .delete_inode = shmem_delete_inode,
+- .drop_inode = generic_delete_inode,
+- .put_super = shmem_put_super,
+-};
+-
+-static struct vm_operations_struct shmem_vm_ops = {
+- .nopage = shmem_nopage,
+- .populate = shmem_populate,
+-#ifdef CONFIG_NUMA
+- .set_policy = shmem_set_policy,
+- .get_policy = shmem_get_policy,
+-#endif
+-};
+-
+-
+-static int shmem_get_sb(struct file_system_type *fs_type,
+- int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+-{
+- return get_sb_nodev(fs_type, flags, data, shmem_fill_super, mnt);
+-}
+-
+-static struct file_system_type tmpfs_fs_type = {
+- .owner = THIS_MODULE,
+- .name = "tmpfs",
+- .get_sb = shmem_get_sb,
+- .kill_sb = kill_litter_super,
+-};
+-static struct vfsmount *shm_mnt;
+-
+-static int __init init_tmpfs(void)
+-{
+- int error;
+-
+- error = init_inodecache();
+- if (error)
+- goto out3;
+-
+- error = register_filesystem(&tmpfs_fs_type);
+- if (error) {
+- printk(KERN_ERR "Could not register tmpfs\n");
+- goto out2;
+- }
+-
+- shm_mnt = vfs_kern_mount(&tmpfs_fs_type, MS_NOUSER,
+- tmpfs_fs_type.name, NULL);
+- if (IS_ERR(shm_mnt)) {
+- error = PTR_ERR(shm_mnt);
+- printk(KERN_ERR "Could not kern_mount tmpfs\n");
+- goto out1;
+- }
+- return 0;
+-
+-out1:
+- unregister_filesystem(&tmpfs_fs_type);
+-out2:
+- destroy_inodecache();
+-out3:
+- shm_mnt = ERR_PTR(error);
+- return error;
+-}
+-module_init(init_tmpfs)
+-
+-/*
+- * shmem_file_setup - get an unlinked file living in tmpfs
+- *
+- * @name: name for dentry (to be seen in /proc/<pid>/maps
+- * @size: size to be set for the file
+- *
+- */
+-struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags)
+-{
+- int error;
+- struct file *file;
+- struct inode *inode;
+- struct dentry *dentry, *root;
+- struct qstr this;
+-
+- if (IS_ERR(shm_mnt))
+- return (void *)shm_mnt;
+-
+- if (size < 0 || size > SHMEM_MAX_BYTES)
+- return ERR_PTR(-EINVAL);
+-
+- if (shmem_acct_size(flags, size))
+- return ERR_PTR(-ENOMEM);
+-
+- error = -ENOMEM;
+- this.name = name;
+- this.len = strlen(name);
+- this.hash = 0; /* will go */
+- root = shm_mnt->mnt_root;
+- dentry = d_alloc(root, &this);
+- if (!dentry)
+- goto put_memory;
+-
+- error = -ENFILE;
+- file = get_empty_filp();
+- if (!file)
+- goto put_dentry;
+-
+- error = -ENOSPC;
+- inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0);
+- if (!inode)
+- goto close_file;
+-
+- SHMEM_I(inode)->flags = flags & VM_ACCOUNT;
+- d_instantiate(dentry, inode);
+- inode->i_size = size;
+- inode->i_nlink = 0; /* It is unlinked */
+- file->f_path.mnt = mntget(shm_mnt);
+- file->f_path.dentry = dentry;
+- file->f_mapping = inode->i_mapping;
+- file->f_op = &shmem_file_operations;
+- file->f_mode = FMODE_WRITE | FMODE_READ;
+- return file;
+-
+-close_file:
+- put_filp(file);
+-put_dentry:
+- dput(dentry);
+-put_memory:
+- shmem_unacct_size(flags, size);
+- return ERR_PTR(error);
+-}
+-
+-/*
+- * shmem_zero_setup - setup a shared anonymous mapping
+- *
+- * @vma: the vma to be mmapped is prepared by do_mmap_pgoff
+- */
+-int shmem_zero_setup(struct vm_area_struct *vma)
+-{
+- struct file *file;
+- loff_t size = vma->vm_end - vma->vm_start;
+-
+- file = shmem_file_setup("dev/zero", size, vma->vm_flags);
+- if (IS_ERR(file))
+- return PTR_ERR(file);
+-
+- if (vma->vm_file)
+- fput(vma->vm_file);
+- vma->vm_file = file;
+- vma->vm_ops = &shmem_vm_ops;
+- return 0;
+-}
diff -Nurb linux-2.6.22-570/mm/slab.c linux-2.6.22-590/mm/slab.c
---- linux-2.6.22-570/mm/slab.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/mm/slab.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/mm/slab.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/mm/slab.c 2008-01-29 22:12:32.000000000 -0500
@@ -1639,6 +1639,8 @@
#endif
page = alloc_pages_node(nodeid, flags, cachep->gfporder);
if (!page)
diff -Nurb linux-2.6.22-570/mm/slub.c linux-2.6.22-590/mm/slub.c
---- linux-2.6.22-570/mm/slub.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/mm/slub.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/mm/slub.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/mm/slub.c 2008-01-29 22:12:32.000000000 -0500
@@ -985,6 +985,9 @@
if (s->flags & SLAB_CACHE_DMA)
flags |= SLUB_DMA;
return 1;
diff -Nurb linux-2.6.22-570/mm/swap_state.c linux-2.6.22-590/mm/swap_state.c
--- linux-2.6.22-570/mm/swap_state.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/mm/swap_state.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/mm/swap_state.c 2008-01-29 22:12:32.000000000 -0500
@@ -334,7 +334,8 @@
* Get a new page to read into from swap.
*/
}
diff -Nurb linux-2.6.22-570/mm/truncate.c linux-2.6.22-590/mm/truncate.c
--- linux-2.6.22-570/mm/truncate.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/mm/truncate.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/mm/truncate.c 2008-01-29 22:12:32.000000000 -0500
@@ -82,7 +82,7 @@
/*
* If truncate cannot remove the fs-private metadata from the page, the page
ret = -EIO;
diff -Nurb linux-2.6.22-570/mm/util.c linux-2.6.22-590/mm/util.c
--- linux-2.6.22-570/mm/util.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/mm/util.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/mm/util.c 2008-01-29 22:12:32.000000000 -0500
@@ -18,9 +18,8 @@
}
EXPORT_SYMBOL(__kzalloc);
*/
diff -Nurb linux-2.6.22-570/mm/vmalloc.c linux-2.6.22-590/mm/vmalloc.c
--- linux-2.6.22-570/mm/vmalloc.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/mm/vmalloc.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/mm/vmalloc.c 2008-01-29 22:12:32.000000000 -0500
@@ -68,12 +68,12 @@
} while (pud++, addr = next, addr != end);
}
static int vmap_pte_range(pmd_t *pmd, unsigned long addr,
diff -Nurb linux-2.6.22-570/mm/vmscan.c linux-2.6.22-590/mm/vmscan.c
--- linux-2.6.22-570/mm/vmscan.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/mm/vmscan.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/mm/vmscan.c 2008-01-29 22:12:32.000000000 -0500
@@ -1272,6 +1272,34 @@
return nr_reclaimed;
}
}
finish_wait(&pgdat->kswapd_wait, &wait);
+diff -Nurb linux-2.6.22-570/net/802/tr.c linux-2.6.22-590/net/802/tr.c
+--- linux-2.6.22-570/net/802/tr.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/802/tr.c 2008-01-29 22:12:32.000000000 -0500
+@@ -36,6 +36,7 @@
+ #include <linux/seq_file.h>
+ #include <linux/init.h>
+ #include <net/arp.h>
++#include <net/net_namespace.h>
+
+ static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev);
+ static void rif_check_expire(unsigned long dummy);
+@@ -532,7 +533,7 @@
+ seq_puts(seq,
+ "if TR address TTL rcf routing segments\n");
+ else {
+- struct net_device *dev = dev_get_by_index(entry->iface);
++ struct net_device *dev = dev_get_by_index(&init_net, entry->iface);
+ long ttl = (long) (entry->last_used + sysctl_tr_rif_timeout)
+ - (long) jiffies;
+
+@@ -639,7 +640,7 @@
+ rif_timer.function = rif_check_expire;
+ add_timer(&rif_timer);
+
+- proc_net_fops_create("tr_rif", S_IRUGO, &rif_seq_fops);
++ proc_net_fops_create(&init_net, "tr_rif", S_IRUGO, &rif_seq_fops);
+ return 0;
+ }
+
diff -Nurb linux-2.6.22-570/net/8021q/Makefile linux-2.6.22-590/net/8021q/Makefile
--- linux-2.6.22-570/net/8021q/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/8021q/Makefile 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/8021q/Makefile 2008-01-29 22:12:32.000000000 -0500
@@ -4,7 +4,7 @@
obj-$(CONFIG_VLAN_8021Q) += 8021q.o
8021q-objs += vlanproc.o
diff -Nurb linux-2.6.22-570/net/8021q/vlan.c linux-2.6.22-590/net/8021q/vlan.c
--- linux-2.6.22-570/net/8021q/vlan.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/8021q/vlan.c 2008-03-15 10:35:47.000000000 -0400
-@@ -97,15 +97,22 @@
++++ linux-2.6.22-590/net/8021q/vlan.c 2008-01-29 22:12:32.000000000 -0500
+@@ -31,6 +31,7 @@
+ #include <net/arp.h>
+ #include <linux/rtnetlink.h>
+ #include <linux/notifier.h>
++#include <net/net_namespace.h>
+
+ #include <linux/if_vlan.h>
+ #include "vlan.h"
+@@ -50,7 +51,7 @@
+ static char vlan_buggyright[] = "David S. Miller <davem@redhat.com>";
+
+ static int vlan_device_event(struct notifier_block *, unsigned long, void *);
+-static int vlan_ioctl_handler(void __user *);
++static int vlan_ioctl_handler(struct net *net, void __user *);
+ static int unregister_vlan_dev(struct net_device *, unsigned short );
+
+ static struct notifier_block vlan_notifier_block = {
+@@ -97,15 +98,22 @@
/* Register us to receive netdevice events */
err = register_netdevice_notifier(&vlan_notifier_block);
}
/* Cleanup all vlan devices
-@@ -136,6 +143,7 @@
+@@ -117,7 +125,7 @@
+ struct net_device *dev, *nxt;
+
+ rtnl_lock();
+- for_each_netdev_safe(dev, nxt) {
++ for_each_netdev_safe(&init_net, dev, nxt) {
+ if (dev->priv_flags & IFF_802_1Q_VLAN) {
+ unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
+ VLAN_DEV_INFO(dev)->vlan_id);
+@@ -136,6 +144,7 @@
{
int i;
vlan_ioctl_set(NULL);
/* Un-register us from receiving netdevice events */
-@@ -197,6 +205,34 @@
+@@ -197,6 +206,34 @@
kfree(grp);
}
static void vlan_rcu_free(struct rcu_head *rcu)
{
vlan_group_free(container_of(rcu, struct vlan_group, rcu));
-@@ -278,47 +314,62 @@
+@@ -278,47 +315,62 @@
return ret;
}
{
SET_MODULE_OWNER(new_dev);
-@@ -338,6 +389,7 @@
+@@ -338,6 +390,7 @@
/* set up method calls */
new_dev->change_mtu = vlan_dev_change_mtu;
new_dev->open = vlan_dev_open;
new_dev->stop = vlan_dev_stop;
new_dev->set_mac_address = vlan_dev_set_mac_address;
-@@ -366,77 +418,110 @@
+@@ -366,77 +419,110 @@
}
}
/* Gotta set up the fields for the device. */
#ifdef VLAN_DEBUG
printk(VLAN_DBG "About to allocate name, vlan_name_type: %i\n",
-@@ -471,138 +556,40 @@
+@@ -471,138 +557,40 @@
vlan_setup);
if (new_dev == NULL)
VLAN_DEV_INFO(new_dev)->real_dev = real_dev;
VLAN_DEV_INFO(new_dev)->dent = NULL;
- VLAN_DEV_INFO(new_dev)->flags = 1;
--
++ VLAN_DEV_INFO(new_dev)->flags = VLAN_FLAG_REORDER_HDR;
+
-#ifdef VLAN_DEBUG
- printk(VLAN_DBG "About to go find the group for idx: %i\n",
- real_dev->ifindex);
-#endif
-+ VLAN_DEV_INFO(new_dev)->flags = VLAN_FLAG_REORDER_HDR;
-
+-
- if (register_netdevice(new_dev))
+ new_dev->rtnl_link_ops = &vlan_link_ops;
+ err = register_vlan_dev(new_dev);
}
static int vlan_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
-@@ -693,9 +680,10 @@
+@@ -612,6 +600,9 @@
+ int i, flgs;
+ struct net_device *vlandev;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ if (!grp)
+ goto out;
+
+@@ -691,11 +682,12 @@
+ * o execute requested action or pass command to the device driver
+ * arg is really a struct vlan_ioctl_args __user *.
*/
- static int vlan_ioctl_handler(void __user *arg)
+-static int vlan_ioctl_handler(void __user *arg)
++static int vlan_ioctl_handler(struct net *net, void __user *arg)
{
- int err = 0;
+ int err;
if (copy_from_user(&args, arg, sizeof(struct vlan_ioctl_args)))
return -EFAULT;
-@@ -708,35 +696,61 @@
+@@ -708,35 +700,61 @@
printk(VLAN_DBG "%s: args.cmd: %x\n", __FUNCTION__, args.cmd);
#endif
+ rtnl_lock();
+
-+ switch (args.cmd) {
-+ case SET_VLAN_INGRESS_PRIORITY_CMD:
+ switch (args.cmd) {
+ case SET_VLAN_INGRESS_PRIORITY_CMD:
+ case SET_VLAN_EGRESS_PRIORITY_CMD:
+ case SET_VLAN_FLAG_CMD:
+ case ADD_VLAN_CMD:
+ case GET_VLAN_REALDEV_NAME_CMD:
+ case GET_VLAN_VID_CMD:
+ err = -ENODEV;
-+ dev = __dev_get_by_name(args.device1);
++ dev = __dev_get_by_name(&init_net, args.device1);
+ if (!dev)
+ goto out;
+
+ goto out;
+ }
+
- switch (args.cmd) {
- case SET_VLAN_INGRESS_PRIORITY_CMD:
++ switch (args.cmd) {
++ case SET_VLAN_INGRESS_PRIORITY_CMD:
+ err = -EPERM;
if (!capable(CAP_NET_ADMIN))
- return -EPERM;
vlan_name_type = args.u.name_type;
err = 0;
} else {
-@@ -745,26 +759,17 @@
+@@ -745,26 +763,17 @@
break;
case ADD_VLAN_CMD:
break;
case GET_VLAN_INGRESS_PRIORITY_CMD:
-@@ -788,9 +793,7 @@
+@@ -788,9 +797,7 @@
err = -EINVAL;
break;
case GET_VLAN_REALDEV_NAME_CMD:
if (copy_to_user(arg, &args,
sizeof(struct vlan_ioctl_args))) {
err = -EFAULT;
-@@ -798,9 +801,7 @@
+@@ -798,9 +805,7 @@
break;
case GET_VLAN_VID_CMD:
args.u.VID = vid;
if (copy_to_user(arg, &args,
sizeof(struct vlan_ioctl_args))) {
-@@ -812,9 +813,11 @@
+@@ -812,9 +817,11 @@
/* pass on to underlying device instead?? */
printk(VLAN_DBG "%s: Unknown VLAN CMD: %x \n",
__FUNCTION__, args.cmd);
diff -Nurb linux-2.6.22-570/net/8021q/vlan.h linux-2.6.22-590/net/8021q/vlan.h
--- linux-2.6.22-570/net/8021q/vlan.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/8021q/vlan.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/8021q/vlan.h 2008-01-29 22:12:32.000000000 -0500
@@ -62,11 +62,24 @@
int vlan_dev_open(struct net_device* dev);
int vlan_dev_stop(struct net_device* dev);
+
#endif /* !(__BEN_VLAN_802_1Q_INC__) */
diff -Nurb linux-2.6.22-570/net/8021q/vlan_dev.c linux-2.6.22-590/net/8021q/vlan_dev.c
---- linux-2.6.22-570/net/8021q/vlan_dev.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/net/8021q/vlan_dev.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/net/8021q/vlan_dev.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/8021q/vlan_dev.c 2008-01-29 22:12:32.000000000 -0500
@@ -73,7 +73,7 @@
static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
if (skb_shared(skb) || skb_cloned(skb)) {
struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
kfree_skb(skb);
-@@ -360,7 +360,8 @@
+@@ -132,6 +132,11 @@
+
+ vhdr = (struct vlan_hdr *)(skb->data);
+
++ if (dev->nd_net != &init_net) {
++ kfree_skb(skb);
++ return 0;
++ }
++
+ /* vlan_TCI = ntohs(get_unaligned(&vhdr->h_vlan_TCI)); */
+ vlan_TCI = ntohs(vhdr->h_vlan_TCI);
+
+@@ -360,7 +365,8 @@
* header shuffling in the hard_start_xmit. Users can turn off this
* REORDER behaviour with the vconfig tool.
*/
if (build_vlan_header) {
vhdr = (struct vlan_hdr *) skb_push(skb, VLAN_HLEN);
-@@ -544,136 +545,83 @@
+@@ -544,136 +550,83 @@
return 0;
}
int vlan_dev_set_mac_address(struct net_device *dev, void *addr_struct_p)
{
struct sockaddr *addr = (struct sockaddr *)(addr_struct_p);
+@@ -828,7 +781,7 @@
+ break;
+
+ case SIOCETHTOOL:
+- err = dev_ethtool(&ifrr);
++ err = dev_ethtool(real_dev->nd_net, &ifrr);
+ }
+
+ if (!err)
diff -Nurb linux-2.6.22-570/net/8021q/vlan_netlink.c linux-2.6.22-590/net/8021q/vlan_netlink.c
--- linux-2.6.22-570/net/8021q/vlan_netlink.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/net/8021q/vlan_netlink.c 2008-03-15 10:35:47.000000000 -0400
-@@ -0,0 +1,236 @@
++++ linux-2.6.22-590/net/8021q/vlan_netlink.c 2008-01-29 22:12:32.000000000 -0500
+@@ -0,0 +1,237 @@
+/*
+ * VLAN netlink control interface
+ *
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/if_vlan.h>
++#include <net/net_namespace.h>
+#include <net/netlink.h>
+#include <net/rtnetlink.h>
+#include "vlan.h"
+
+ if (!tb[IFLA_LINK])
+ return -EINVAL;
-+ real_dev = __dev_get_by_index(nla_get_u32(tb[IFLA_LINK]));
++ real_dev = __dev_get_by_index(&init_net, nla_get_u32(tb[IFLA_LINK]));
+ if (!real_dev)
+ return -ENODEV;
+
+MODULE_ALIAS_RTNL_LINK("vlan");
diff -Nurb linux-2.6.22-570/net/8021q/vlanproc.c linux-2.6.22-590/net/8021q/vlanproc.c
--- linux-2.6.22-570/net/8021q/vlanproc.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/8021q/vlanproc.c 2008-03-15 10:35:47.000000000 -0400
-@@ -342,7 +342,7 @@
++++ linux-2.6.22-590/net/8021q/vlanproc.c 2008-01-29 22:12:32.000000000 -0500
+@@ -33,6 +33,7 @@
+ #include <linux/fs.h>
+ #include <linux/netdevice.h>
+ #include <linux/if_vlan.h>
++#include <net/net_namespace.h>
+ #include "vlanproc.h"
+ #include "vlan.h"
+
+@@ -143,7 +144,7 @@
+ remove_proc_entry(name_conf, proc_vlan_dir);
+
+ if (proc_vlan_dir)
+- proc_net_remove(name_root);
++ proc_net_remove(&init_net, name_root);
+
+ /* Dynamically added entries should be cleaned up as their vlan_device
+ * is removed, so we should not have to take care of it here...
+@@ -156,7 +157,7 @@
+
+ int __init vlan_proc_init(void)
+ {
+- proc_vlan_dir = proc_mkdir(name_root, proc_net);
++ proc_vlan_dir = proc_mkdir(name_root, init_net.proc_net);
+ if (proc_vlan_dir) {
+ proc_vlan_conf = create_proc_entry(name_conf,
+ S_IFREG|S_IRUSR|S_IWUSR,
+@@ -253,7 +254,7 @@
+ if (*pos == 0)
+ return SEQ_START_TOKEN;
+
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ if (!is_vlan_dev(dev))
+ continue;
+
+@@ -272,9 +273,9 @@
+
+ dev = (struct net_device *)v;
+ if (v == SEQ_START_TOKEN)
+- dev = net_device_entry(&dev_base_head);
++ dev = net_device_entry(&init_net.dev_base_head);
+
+- for_each_netdev_continue(dev) {
++ for_each_netdev_continue(&init_net, dev) {
+ if (!is_vlan_dev(dev))
+ continue;
+
+@@ -342,7 +343,7 @@
seq_printf(seq, "Device: %s", dev_info->real_dev->name);
/* now show all PRIORITY mappings relating to this VLAN */
seq_printf(seq,
dev_info->ingress_priority_map[0],
dev_info->ingress_priority_map[1],
dev_info->ingress_priority_map[2],
-@@ -357,7 +357,7 @@
+@@ -357,7 +358,7 @@
const struct vlan_priority_tci_mapping *mp
= dev_info->egress_priority_map[i];
while (mp) {
mp->priority, ((mp->vlan_qos >> 13) & 0x7));
mp = mp->next;
}
-diff -Nurb linux-2.6.22-570/net/bluetooth/bnep/core.c linux-2.6.22-590/net/bluetooth/bnep/core.c
---- linux-2.6.22-570/net/bluetooth/bnep/core.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/bluetooth/bnep/core.c 2008-03-15 10:35:47.000000000 -0400
-@@ -36,6 +36,7 @@
- #include <linux/signal.h>
- #include <linux/init.h>
- #include <linux/wait.h>
-+#include <linux/freezer.h>
- #include <linux/errno.h>
- #include <linux/net.h>
- #include <net/sock.h>
-@@ -474,7 +475,6 @@
+diff -Nurb linux-2.6.22-570/net/Kconfig linux-2.6.22-590/net/Kconfig
+--- linux-2.6.22-570/net/Kconfig 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/Kconfig 2008-01-29 22:12:32.000000000 -0500
+@@ -27,6 +27,13 @@
- daemonize("kbnepd %s", dev->name);
- set_user_nice(current, -15);
-- current->flags |= PF_NOFREEZE;
+ menu "Networking options"
- init_waitqueue_entry(&wait, current);
- add_wait_queue(sk->sk_sleep, &wait);
-diff -Nurb linux-2.6.22-570/net/bluetooth/cmtp/core.c linux-2.6.22-590/net/bluetooth/cmtp/core.c
---- linux-2.6.22-570/net/bluetooth/cmtp/core.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/bluetooth/cmtp/core.c 2008-03-15 10:35:47.000000000 -0400
-@@ -29,6 +29,7 @@
- #include <linux/slab.h>
- #include <linux/poll.h>
- #include <linux/fcntl.h>
-+#include <linux/freezer.h>
- #include <linux/skbuff.h>
- #include <linux/socket.h>
- #include <linux/ioctl.h>
-@@ -287,7 +288,6 @@
++config NET_NS
++ bool "Network namespace support"
++ depends on EXPERIMENTAL
++ help
++ Support what appear to user space as multiple instances of the
++ network stack.
++
+ source "net/packet/Kconfig"
+ source "net/unix/Kconfig"
+ source "net/xfrm/Kconfig"
+diff -Nurb linux-2.6.22-570/net/Makefile linux-2.6.22-590/net/Makefile
+--- linux-2.6.22-570/net/Makefile 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/Makefile 2008-01-29 22:12:32.000000000 -0500
+@@ -14,7 +14,7 @@
- daemonize("kcmtpd_ctr_%d", session->num);
- set_user_nice(current, -15);
+ # LLC has to be linked before the files in net/802/
+ obj-$(CONFIG_LLC) += llc/
+-obj-$(CONFIG_NET) += ethernet/ 802/ sched/ netlink/
++obj-$(CONFIG_NET) += ethernet/ sched/ netlink/ 802/
+ obj-$(CONFIG_NETFILTER) += netfilter/
+ obj-$(CONFIG_INET) += ipv4/
+ obj-$(CONFIG_XFRM) += xfrm/
+diff -Nurb linux-2.6.22-570/net/appletalk/aarp.c linux-2.6.22-590/net/appletalk/aarp.c
+--- linux-2.6.22-570/net/appletalk/aarp.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/appletalk/aarp.c 2008-01-29 22:12:32.000000000 -0500
+@@ -330,15 +330,19 @@
+ static int aarp_device_event(struct notifier_block *this, unsigned long event,
+ void *ptr)
+ {
++ struct net_device *dev = ptr;
+ int ct;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ if (event == NETDEV_DOWN) {
+ write_lock_bh(&aarp_lock);
+
+ for (ct = 0; ct < AARP_HASH_SIZE; ct++) {
+- __aarp_expire_device(&resolved[ct], ptr);
+- __aarp_expire_device(&unresolved[ct], ptr);
+- __aarp_expire_device(&proxies[ct], ptr);
++ __aarp_expire_device(&resolved[ct], dev);
++ __aarp_expire_device(&unresolved[ct], dev);
++ __aarp_expire_device(&proxies[ct], dev);
+ }
+
+ write_unlock_bh(&aarp_lock);
+@@ -712,6 +716,9 @@
+ struct atalk_addr sa, *ma, da;
+ struct atalk_iface *ifa;
+
++ if (dev->nd_net != &init_net)
++ goto out0;
++
+ /* We only do Ethernet SNAP AARP. */
+ if (dev->type != ARPHRD_ETHER)
+ goto out0;
+diff -Nurb linux-2.6.22-570/net/appletalk/atalk_proc.c linux-2.6.22-590/net/appletalk/atalk_proc.c
+--- linux-2.6.22-570/net/appletalk/atalk_proc.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/appletalk/atalk_proc.c 2008-01-29 22:12:32.000000000 -0500
+@@ -13,6 +13,7 @@
+ #include <linux/seq_file.h>
+ #include <net/sock.h>
+ #include <linux/atalk.h>
++#include <net/net_namespace.h>
+
+
+ static __inline__ struct atalk_iface *atalk_get_interface_idx(loff_t pos)
+@@ -271,7 +272,7 @@
+ struct proc_dir_entry *p;
+ int rc = -ENOMEM;
+
+- atalk_proc_dir = proc_mkdir("atalk", proc_net);
++ atalk_proc_dir = proc_mkdir("atalk", init_net.proc_net);
+ if (!atalk_proc_dir)
+ goto out;
+ atalk_proc_dir->owner = THIS_MODULE;
+@@ -306,7 +307,7 @@
+ out_route:
+ remove_proc_entry("interface", atalk_proc_dir);
+ out_interface:
+- remove_proc_entry("atalk", proc_net);
++ remove_proc_entry("atalk", init_net.proc_net);
+ goto out;
+ }
+
+@@ -316,5 +317,5 @@
+ remove_proc_entry("route", atalk_proc_dir);
+ remove_proc_entry("socket", atalk_proc_dir);
+ remove_proc_entry("arp", atalk_proc_dir);
+- remove_proc_entry("atalk", proc_net);
++ remove_proc_entry("atalk", init_net.proc_net);
+ }
+diff -Nurb linux-2.6.22-570/net/appletalk/ddp.c linux-2.6.22-590/net/appletalk/ddp.c
+--- linux-2.6.22-570/net/appletalk/ddp.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/appletalk/ddp.c 2008-01-29 22:12:32.000000000 -0500
+@@ -647,9 +647,14 @@
+ static int ddp_device_event(struct notifier_block *this, unsigned long event,
+ void *ptr)
+ {
++ struct net_device *dev = ptr;
++
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ if (event == NETDEV_DOWN)
+ /* Discard any use of this */
+- atalk_dev_down(ptr);
++ atalk_dev_down(dev);
+
+ return NOTIFY_DONE;
+ }
+@@ -672,7 +677,7 @@
+ if (copy_from_user(&atreq, arg, sizeof(atreq)))
+ return -EFAULT;
+
+- dev = __dev_get_by_name(atreq.ifr_name);
++ dev = __dev_get_by_name(&init_net, atreq.ifr_name);
+ if (!dev)
+ return -ENODEV;
+
+@@ -896,7 +901,7 @@
+ if (copy_from_user(name, rt.rt_dev, IFNAMSIZ-1))
+ return -EFAULT;
+ name[IFNAMSIZ-1] = '\0';
+- dev = __dev_get_by_name(name);
++ dev = __dev_get_by_name(&init_net, name);
+ if (!dev)
+ return -ENODEV;
+ }
+@@ -1024,11 +1029,14 @@
+ * Create a socket. Initialise the socket, blank the addresses
+ * set the state.
+ */
+-static int atalk_create(struct socket *sock, int protocol)
++static int atalk_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct sock *sk;
+ int rc = -ESOCKTNOSUPPORT;
+
++ if (net != &init_net)
++ return -EAFNOSUPPORT;
++
+ /*
+ * We permit SOCK_DGRAM and RAW is an extension. It is trivial to do
+ * and gives you the full ELAP frame. Should be handy for CAP 8)
+@@ -1036,7 +1044,7 @@
+ if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
+ goto out;
+ rc = -ENOMEM;
+- sk = sk_alloc(PF_APPLETALK, GFP_KERNEL, &ddp_proto, 1);
++ sk = sk_alloc(net, PF_APPLETALK, GFP_KERNEL, &ddp_proto, 1);
+ if (!sk)
+ goto out;
+ rc = 0;
+@@ -1265,7 +1273,7 @@
+
+ static int handle_ip_over_ddp(struct sk_buff *skb)
+ {
+- struct net_device *dev = __dev_get_by_name("ipddp0");
++ struct net_device *dev = __dev_get_by_name(&init_net, "ipddp0");
+ struct net_device_stats *stats;
+
+ /* This needs to be able to handle ipddp"N" devices */
+@@ -1398,6 +1406,9 @@
+ int origlen;
+ __u16 len_hops;
+
++ if (dev->nd_net != &init_net)
++ goto freeit;
++
+ /* Don't mangle buffer if shared */
+ if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
+ goto out;
+@@ -1483,6 +1494,9 @@
+ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev,
+ struct packet_type *pt, struct net_device *orig_dev)
+ {
++ if (dev->nd_net != &init_net)
++ goto freeit;
++
+ /* Expand any short form frames */
+ if (skb_mac_header(skb)[2] == 1) {
+ struct ddpehdr *ddp;
+diff -Nurb linux-2.6.22-570/net/atm/clip.c linux-2.6.22-590/net/atm/clip.c
+--- linux-2.6.22-570/net/atm/clip.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/atm/clip.c 2008-01-29 22:12:32.000000000 -0500
+@@ -293,7 +293,7 @@
+ struct neigh_parms *parms;
+
+ DPRINTK("clip_constructor (neigh %p, entry %p)\n", neigh, entry);
+- neigh->type = inet_addr_type(entry->ip);
++ neigh->type = inet_addr_type(&init_net, entry->ip);
+ if (neigh->type != RTN_UNICAST)
+ return -EINVAL;
+
+@@ -525,7 +525,10 @@
+ struct atmarp_entry *entry;
+ int error;
+ struct clip_vcc *clip_vcc;
+- struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip, .tos = 1}} };
++ struct flowi fl = {
++ .fl_net = &init_net,
++ .nl_u = { .ip4_u = { .daddr = ip, .tos = 1}}
++ };
+ struct rtable *rt;
+
+ if (vcc->push != clip_push) {
+@@ -620,6 +623,9 @@
+ {
+ struct net_device *dev = arg;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ if (event == NETDEV_UNREGISTER) {
+ neigh_ifdown(&clip_tbl, dev);
+ return NOTIFY_DONE;
+@@ -954,6 +960,7 @@
+
+ seq = file->private_data;
+ seq->private = state;
++ state->ns.net = get_net(PROC_NET(inode));
+ out:
+ return rc;
+
+@@ -962,11 +969,19 @@
+ goto out;
+ }
+
++static int arp_seq_release(struct inode *inode, struct file *file)
++{
++ struct seq_file *seq = file->private_data;
++ struct clip_seq_state *state = seq->private;
++ put_net(state->ns.net);
++ return seq_release_private(inode, file);
++}
++
+ static const struct file_operations arp_seq_fops = {
+ .open = arp_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+- .release = seq_release_private,
++ .release = arp_seq_release,
+ .owner = THIS_MODULE
+ };
+ #endif
+diff -Nurb linux-2.6.22-570/net/atm/common.c linux-2.6.22-590/net/atm/common.c
+--- linux-2.6.22-570/net/atm/common.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/atm/common.c 2008-01-29 22:12:32.000000000 -0500
+@@ -132,7 +132,7 @@
+ .obj_size = sizeof(struct atm_vcc),
+ };
+
+-int vcc_create(struct socket *sock, int protocol, int family)
++int vcc_create(struct net *net, struct socket *sock, int protocol, int family)
+ {
+ struct sock *sk;
+ struct atm_vcc *vcc;
+@@ -140,7 +140,7 @@
+ sock->sk = NULL;
+ if (sock->type == SOCK_STREAM)
+ return -EINVAL;
+- sk = sk_alloc(family, GFP_KERNEL, &vcc_proto, 1);
++ sk = sk_alloc(net, family, GFP_KERNEL, &vcc_proto, 1);
+ if (!sk)
+ return -ENOMEM;
+ sock_init_data(sock, sk);
+diff -Nurb linux-2.6.22-570/net/atm/common.h linux-2.6.22-590/net/atm/common.h
+--- linux-2.6.22-570/net/atm/common.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/atm/common.h 2008-01-29 22:12:32.000000000 -0500
+@@ -10,7 +10,7 @@
+ #include <linux/poll.h> /* for poll_table */
+
+
+-int vcc_create(struct socket *sock, int protocol, int family);
++int vcc_create(struct net *net, struct socket *sock, int protocol, int family);
+ int vcc_release(struct socket *sock);
+ int vcc_connect(struct socket *sock, int itf, short vpi, int vci);
+ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
+diff -Nurb linux-2.6.22-570/net/atm/mpc.c linux-2.6.22-590/net/atm/mpc.c
+--- linux-2.6.22-570/net/atm/mpc.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/atm/mpc.c 2008-01-29 22:12:32.000000000 -0500
+@@ -244,7 +244,7 @@
+ char name[IFNAMSIZ];
+
+ sprintf(name, "lec%d", itf);
+- dev = dev_get_by_name(name);
++ dev = dev_get_by_name(&init_net, name);
+
+ return dev;
+ }
+@@ -956,6 +956,10 @@
+ struct lec_priv *priv;
+
+ dev = (struct net_device *)dev_ptr;
++
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ if (dev->name == NULL || strncmp(dev->name, "lec", 3))
+ return NOTIFY_DONE; /* we are only interested in lec:s */
+
+diff -Nurb linux-2.6.22-570/net/atm/proc.c linux-2.6.22-590/net/atm/proc.c
+--- linux-2.6.22-570/net/atm/proc.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/atm/proc.c 2008-01-29 22:12:32.000000000 -0500
+@@ -22,6 +22,7 @@
+ #include <linux/netdevice.h>
+ #include <linux/atmclip.h>
+ #include <linux/init.h> /* for __init */
++#include <net/net_namespace.h>
+ #include <net/atmclip.h>
+ #include <asm/uaccess.h>
+ #include <asm/atomic.h>
+@@ -475,7 +476,7 @@
+ if (e->dirent)
+ remove_proc_entry(e->name, atm_proc_root);
+ }
+- remove_proc_entry("net/atm", NULL);
++ remove_proc_entry("atm", init_net.proc_net);
+ }
+
+ int __init atm_proc_init(void)
+@@ -483,7 +484,7 @@
+ static struct atm_proc_entry *e;
+ int ret;
+
+- atm_proc_root = proc_mkdir("net/atm",NULL);
++ atm_proc_root = proc_mkdir("atm", init_net.proc_net);
+ if (!atm_proc_root)
+ goto err_out;
+ for (e = atm_proc_ents; e->name; e++) {
+diff -Nurb linux-2.6.22-570/net/atm/pvc.c linux-2.6.22-590/net/atm/pvc.c
+--- linux-2.6.22-570/net/atm/pvc.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/atm/pvc.c 2008-01-29 22:12:32.000000000 -0500
+@@ -124,10 +124,13 @@
+ };
+
+
+-static int pvc_create(struct socket *sock,int protocol)
++static int pvc_create(struct net *net, struct socket *sock,int protocol)
+ {
++ if (net != &init_net)
++ return -EAFNOSUPPORT;
++
+ sock->ops = &pvc_proto_ops;
+- return vcc_create(sock, protocol, PF_ATMPVC);
++ return vcc_create(net, sock, protocol, PF_ATMPVC);
+ }
+
+
+diff -Nurb linux-2.6.22-570/net/atm/svc.c linux-2.6.22-590/net/atm/svc.c
+--- linux-2.6.22-570/net/atm/svc.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/atm/svc.c 2008-01-29 22:12:32.000000000 -0500
+@@ -33,7 +33,7 @@
+ #endif
+
+
+-static int svc_create(struct socket *sock,int protocol);
++static int svc_create(struct net *net, struct socket *sock,int protocol);
+
+
+ /*
+@@ -335,7 +335,7 @@
+
+ lock_sock(sk);
+
+- error = svc_create(newsock,0);
++ error = svc_create(sk->sk_net, newsock,0);
+ if (error)
+ goto out;
+
+@@ -636,12 +636,15 @@
+ };
+
+
+-static int svc_create(struct socket *sock,int protocol)
++static int svc_create(struct net *net, struct socket *sock,int protocol)
+ {
+ int error;
+
++ if (net != &init_net)
++ return -EAFNOSUPPORT;
++
+ sock->ops = &svc_proto_ops;
+- error = vcc_create(sock, protocol, AF_ATMSVC);
++ error = vcc_create(net, sock, protocol, AF_ATMSVC);
+ if (error) return error;
+ ATM_SD(sock)->local.sas_family = AF_ATMSVC;
+ ATM_SD(sock)->remote.sas_family = AF_ATMSVC;
+diff -Nurb linux-2.6.22-570/net/ax25/af_ax25.c linux-2.6.22-590/net/ax25/af_ax25.c
+--- linux-2.6.22-570/net/ax25/af_ax25.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ax25/af_ax25.c 2008-01-29 22:12:32.000000000 -0500
+@@ -47,6 +47,7 @@
+ #include <net/tcp_states.h>
+ #include <net/ip.h>
+ #include <net/arp.h>
++#include <net/net_namespace.h>
+
+
+
+@@ -103,6 +104,9 @@
+ {
+ struct net_device *dev = (struct net_device *)ptr;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ /* Reject non AX.25 devices */
+ if (dev->type != ARPHRD_AX25)
+ return NOTIFY_DONE;
+@@ -627,7 +631,7 @@
+ break;
+ }
+
+- dev = dev_get_by_name(devname);
++ dev = dev_get_by_name(&init_net, devname);
+ if (dev == NULL) {
+ res = -ENODEV;
+ break;
+@@ -779,11 +783,14 @@
+ .obj_size = sizeof(struct sock),
+ };
+
+-static int ax25_create(struct socket *sock, int protocol)
++static int ax25_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct sock *sk;
+ ax25_cb *ax25;
+
++ if (net != &init_net)
++ return -EAFNOSUPPORT;
++
+ switch (sock->type) {
+ case SOCK_DGRAM:
+ if (protocol == 0 || protocol == PF_AX25)
+@@ -829,7 +836,7 @@
+ return -ESOCKTNOSUPPORT;
+ }
+
+- if ((sk = sk_alloc(PF_AX25, GFP_ATOMIC, &ax25_proto, 1)) == NULL)
++ if ((sk = sk_alloc(net, PF_AX25, GFP_ATOMIC, &ax25_proto, 1)) == NULL)
+ return -ENOMEM;
+
+ ax25 = sk->sk_protinfo = ax25_create_cb();
+@@ -854,7 +861,7 @@
+ struct sock *sk;
+ ax25_cb *ax25, *oax25;
+
+- if ((sk = sk_alloc(PF_AX25, GFP_ATOMIC, osk->sk_prot, 1)) == NULL)
++ if ((sk = sk_alloc(osk->sk_net, PF_AX25, GFP_ATOMIC, osk->sk_prot, 1)) == NULL)
+ return NULL;
+
+ if ((ax25 = ax25_create_cb()) == NULL) {
+@@ -1998,9 +2005,9 @@
+ register_netdevice_notifier(&ax25_dev_notifier);
+ ax25_register_sysctl();
+
+- proc_net_fops_create("ax25_route", S_IRUGO, &ax25_route_fops);
+- proc_net_fops_create("ax25", S_IRUGO, &ax25_info_fops);
+- proc_net_fops_create("ax25_calls", S_IRUGO, &ax25_uid_fops);
++ proc_net_fops_create(&init_net, "ax25_route", S_IRUGO, &ax25_route_fops);
++ proc_net_fops_create(&init_net, "ax25", S_IRUGO, &ax25_info_fops);
++ proc_net_fops_create(&init_net, "ax25_calls", S_IRUGO, &ax25_uid_fops);
+ out:
+ return rc;
+ }
+@@ -2014,9 +2021,9 @@
+
+ static void __exit ax25_exit(void)
+ {
+- proc_net_remove("ax25_route");
+- proc_net_remove("ax25");
+- proc_net_remove("ax25_calls");
++ proc_net_remove(&init_net, "ax25_route");
++ proc_net_remove(&init_net, "ax25");
++ proc_net_remove(&init_net, "ax25_calls");
+ ax25_rt_free();
+ ax25_uid_free();
+ ax25_dev_free();
+diff -Nurb linux-2.6.22-570/net/ax25/ax25_in.c linux-2.6.22-590/net/ax25/ax25_in.c
+--- linux-2.6.22-570/net/ax25/ax25_in.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ax25/ax25_in.c 2008-01-29 22:12:32.000000000 -0500
+@@ -451,6 +451,11 @@
+ skb->sk = NULL; /* Initially we don't know who it's for */
+ skb->destructor = NULL; /* Who initializes this, dammit?! */
+
++ if (dev->nd_net != &init_net) {
++ kfree_skb(skb);
++ return 0;
++ }
++
+ if ((*skb->data & 0x0F) != 0) {
+ kfree_skb(skb); /* Not a KISS data frame */
+ return 0;
+diff -Nurb linux-2.6.22-570/net/bluetooth/af_bluetooth.c linux-2.6.22-590/net/bluetooth/af_bluetooth.c
+--- linux-2.6.22-570/net/bluetooth/af_bluetooth.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/bluetooth/af_bluetooth.c 2008-01-29 22:12:32.000000000 -0500
+@@ -95,10 +95,13 @@
+ }
+ EXPORT_SYMBOL(bt_sock_unregister);
+
+-static int bt_sock_create(struct socket *sock, int proto)
++static int bt_sock_create(struct net *net, struct socket *sock, int proto)
+ {
+ int err;
+
++ if (net != &init_net)
++ return -EAFNOSUPPORT;
++
+ if (proto < 0 || proto >= BT_MAX_PROTO)
+ return -EINVAL;
+
+@@ -113,7 +116,7 @@
+ read_lock(&bt_proto_lock);
+
+ if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
+- err = bt_proto[proto]->create(sock, proto);
++ err = bt_proto[proto]->create(net, sock, proto);
+ module_put(bt_proto[proto]->owner);
+ }
+
+diff -Nurb linux-2.6.22-570/net/bluetooth/bnep/core.c linux-2.6.22-590/net/bluetooth/bnep/core.c
+--- linux-2.6.22-570/net/bluetooth/bnep/core.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/bluetooth/bnep/core.c 2008-01-29 22:12:32.000000000 -0500
+@@ -36,6 +36,7 @@
+ #include <linux/signal.h>
+ #include <linux/init.h>
+ #include <linux/wait.h>
++#include <linux/freezer.h>
+ #include <linux/errno.h>
+ #include <linux/net.h>
+ #include <net/sock.h>
+@@ -474,7 +475,6 @@
+
+ daemonize("kbnepd %s", dev->name);
+ set_user_nice(current, -15);
+- current->flags |= PF_NOFREEZE;
+
+ init_waitqueue_entry(&wait, current);
+ add_wait_queue(sk->sk_sleep, &wait);
+diff -Nurb linux-2.6.22-570/net/bluetooth/bnep/sock.c linux-2.6.22-590/net/bluetooth/bnep/sock.c
+--- linux-2.6.22-570/net/bluetooth/bnep/sock.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/bluetooth/bnep/sock.c 2008-01-29 22:12:32.000000000 -0500
+@@ -204,7 +204,7 @@
+ .obj_size = sizeof(struct bt_sock)
+ };
+
+-static int bnep_sock_create(struct socket *sock, int protocol)
++static int bnep_sock_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct sock *sk;
+
+@@ -213,7 +213,7 @@
+ if (sock->type != SOCK_RAW)
+ return -ESOCKTNOSUPPORT;
+
+- sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, 1);
++ sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, 1);
+ if (!sk)
+ return -ENOMEM;
+
+diff -Nurb linux-2.6.22-570/net/bluetooth/cmtp/core.c linux-2.6.22-590/net/bluetooth/cmtp/core.c
+--- linux-2.6.22-570/net/bluetooth/cmtp/core.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/bluetooth/cmtp/core.c 2008-01-29 22:12:32.000000000 -0500
+@@ -29,6 +29,7 @@
+ #include <linux/slab.h>
+ #include <linux/poll.h>
+ #include <linux/fcntl.h>
++#include <linux/freezer.h>
+ #include <linux/skbuff.h>
+ #include <linux/socket.h>
+ #include <linux/ioctl.h>
+@@ -287,7 +288,6 @@
+
+ daemonize("kcmtpd_ctr_%d", session->num);
+ set_user_nice(current, -15);
- current->flags |= PF_NOFREEZE;
init_waitqueue_entry(&wait, current);
add_wait_queue(sk->sk_sleep, &wait);
+diff -Nurb linux-2.6.22-570/net/bluetooth/cmtp/sock.c linux-2.6.22-590/net/bluetooth/cmtp/sock.c
+--- linux-2.6.22-570/net/bluetooth/cmtp/sock.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/bluetooth/cmtp/sock.c 2008-01-29 22:12:32.000000000 -0500
+@@ -195,7 +195,7 @@
+ .obj_size = sizeof(struct bt_sock)
+ };
+
+-static int cmtp_sock_create(struct socket *sock, int protocol)
++static int cmtp_sock_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct sock *sk;
+
+@@ -204,7 +204,7 @@
+ if (sock->type != SOCK_RAW)
+ return -ESOCKTNOSUPPORT;
+
+- sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, 1);
++ sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, 1);
+ if (!sk)
+ return -ENOMEM;
+
+diff -Nurb linux-2.6.22-570/net/bluetooth/hci_sock.c linux-2.6.22-590/net/bluetooth/hci_sock.c
+--- linux-2.6.22-570/net/bluetooth/hci_sock.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/bluetooth/hci_sock.c 2008-01-29 22:12:32.000000000 -0500
+@@ -618,7 +618,7 @@
+ .obj_size = sizeof(struct hci_pinfo)
+ };
+
+-static int hci_sock_create(struct socket *sock, int protocol)
++static int hci_sock_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct sock *sk;
+
+@@ -629,7 +629,7 @@
+
+ sock->ops = &hci_sock_ops;
+
+- sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, 1);
++ sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, 1);
+ if (!sk)
+ return -ENOMEM;
+
diff -Nurb linux-2.6.22-570/net/bluetooth/hidp/core.c linux-2.6.22-590/net/bluetooth/hidp/core.c
--- linux-2.6.22-570/net/bluetooth/hidp/core.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/bluetooth/hidp/core.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/bluetooth/hidp/core.c 2008-01-29 22:12:32.000000000 -0500
@@ -28,6 +28,7 @@
#include <linux/sched.h>
#include <linux/slab.h>
init_waitqueue_entry(&ctrl_wait, current);
init_waitqueue_entry(&intr_wait, current);
+diff -Nurb linux-2.6.22-570/net/bluetooth/hidp/sock.c linux-2.6.22-590/net/bluetooth/hidp/sock.c
+--- linux-2.6.22-570/net/bluetooth/hidp/sock.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/bluetooth/hidp/sock.c 2008-01-29 22:12:32.000000000 -0500
+@@ -246,7 +246,7 @@
+ .obj_size = sizeof(struct bt_sock)
+ };
+
+-static int hidp_sock_create(struct socket *sock, int protocol)
++static int hidp_sock_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct sock *sk;
+
+@@ -255,7 +255,7 @@
+ if (sock->type != SOCK_RAW)
+ return -ESOCKTNOSUPPORT;
+
+- sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, 1);
++ sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, 1);
+ if (!sk)
+ return -ENOMEM;
+
+diff -Nurb linux-2.6.22-570/net/bluetooth/l2cap.c linux-2.6.22-590/net/bluetooth/l2cap.c
+--- linux-2.6.22-570/net/bluetooth/l2cap.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/bluetooth/l2cap.c 2008-01-29 22:12:32.000000000 -0500
+@@ -518,11 +518,11 @@
+ .obj_size = sizeof(struct l2cap_pinfo)
+ };
+
+-static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, gfp_t prio)
++static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
+ {
+ struct sock *sk;
+
+- sk = sk_alloc(PF_BLUETOOTH, prio, &l2cap_proto, 1);
++ sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto, 1);
+ if (!sk)
+ return NULL;
+
+@@ -543,7 +543,7 @@
+ return sk;
+ }
+
+-static int l2cap_sock_create(struct socket *sock, int protocol)
++static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct sock *sk;
+
+@@ -560,7 +560,7 @@
+
+ sock->ops = &l2cap_sock_ops;
+
+- sk = l2cap_sock_alloc(sock, protocol, GFP_ATOMIC);
++ sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
+ if (!sk)
+ return -ENOMEM;
+
+@@ -1425,7 +1425,7 @@
+ goto response;
+ }
+
+- sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC);
++ sk = l2cap_sock_alloc(parent->sk_net, NULL, BTPROTO_L2CAP, GFP_ATOMIC);
+ if (!sk)
+ goto response;
+
diff -Nurb linux-2.6.22-570/net/bluetooth/rfcomm/core.c linux-2.6.22-590/net/bluetooth/rfcomm/core.c
--- linux-2.6.22-570/net/bluetooth/rfcomm/core.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/bluetooth/rfcomm/core.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/bluetooth/rfcomm/core.c 2008-01-29 22:12:32.000000000 -0500
@@ -33,6 +33,7 @@
#include <linux/sched.h>
#include <linux/signal.h>
BT_DBG("");
+diff -Nurb linux-2.6.22-570/net/bluetooth/rfcomm/sock.c linux-2.6.22-590/net/bluetooth/rfcomm/sock.c
+--- linux-2.6.22-570/net/bluetooth/rfcomm/sock.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/bluetooth/rfcomm/sock.c 2008-01-29 22:12:32.000000000 -0500
+@@ -282,12 +282,12 @@
+ .obj_size = sizeof(struct rfcomm_pinfo)
+ };
+
+-static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, gfp_t prio)
++static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
+ {
+ struct rfcomm_dlc *d;
+ struct sock *sk;
+
+- sk = sk_alloc(PF_BLUETOOTH, prio, &rfcomm_proto, 1);
++ sk = sk_alloc(net, PF_BLUETOOTH, prio, &rfcomm_proto, 1);
+ if (!sk)
+ return NULL;
+
+@@ -323,7 +323,7 @@
+ return sk;
+ }
+
+-static int rfcomm_sock_create(struct socket *sock, int protocol)
++static int rfcomm_sock_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct sock *sk;
+
+@@ -336,7 +336,7 @@
+
+ sock->ops = &rfcomm_sock_ops;
+
+- sk = rfcomm_sock_alloc(sock, protocol, GFP_ATOMIC);
++ sk = rfcomm_sock_alloc(net, sock, protocol, GFP_ATOMIC);
+ if (!sk)
+ return -ENOMEM;
+
+@@ -868,7 +868,7 @@
+ goto done;
+ }
+
+- sk = rfcomm_sock_alloc(NULL, BTPROTO_RFCOMM, GFP_ATOMIC);
++ sk = rfcomm_sock_alloc(parent->sk_net, NULL, BTPROTO_RFCOMM, GFP_ATOMIC);
+ if (!sk)
+ goto done;
+
+diff -Nurb linux-2.6.22-570/net/bluetooth/sco.c linux-2.6.22-590/net/bluetooth/sco.c
+--- linux-2.6.22-570/net/bluetooth/sco.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/bluetooth/sco.c 2008-01-29 22:12:32.000000000 -0500
+@@ -414,11 +414,11 @@
+ .obj_size = sizeof(struct sco_pinfo)
+ };
+
+-static struct sock *sco_sock_alloc(struct socket *sock, int proto, gfp_t prio)
++static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
+ {
+ struct sock *sk;
+
+- sk = sk_alloc(PF_BLUETOOTH, prio, &sco_proto, 1);
++ sk = sk_alloc(net, PF_BLUETOOTH, prio, &sco_proto, 1);
+ if (!sk)
+ return NULL;
+
+@@ -439,7 +439,7 @@
+ return sk;
+ }
+
+-static int sco_sock_create(struct socket *sock, int protocol)
++static int sco_sock_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct sock *sk;
+
+@@ -452,7 +452,7 @@
+
+ sock->ops = &sco_sock_ops;
+
+- sk = sco_sock_alloc(sock, protocol, GFP_ATOMIC);
++ sk = sco_sock_alloc(net, sock, protocol, GFP_ATOMIC);
+ if (!sk)
+ return -ENOMEM;
+
+@@ -807,7 +807,7 @@
+
+ bh_lock_sock(parent);
+
+- sk = sco_sock_alloc(NULL, BTPROTO_SCO, GFP_ATOMIC);
++ sk = sco_sock_alloc(parent->sk_net, NULL, BTPROTO_SCO, GFP_ATOMIC);
+ if (!sk) {
+ bh_unlock_sock(parent);
+ goto done;
+diff -Nurb linux-2.6.22-570/net/bridge/br_if.c linux-2.6.22-590/net/bridge/br_if.c
+--- linux-2.6.22-570/net/bridge/br_if.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/bridge/br_if.c 2008-01-29 22:12:32.000000000 -0500
+@@ -45,7 +45,7 @@
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+- err = dev_ethtool(&ifr);
++ err = dev_ethtool(dev->nd_net, &ifr);
+ set_fs(old_fs);
+
+ if (!err) {
+@@ -314,7 +314,7 @@
+ int ret = 0;
+
+ rtnl_lock();
+- dev = __dev_get_by_name(name);
++ dev = __dev_get_by_name(&init_net, name);
+ if (dev == NULL)
+ ret = -ENXIO; /* Could not find device */
+
+@@ -455,7 +455,7 @@
+ struct net_device *dev, *nxt;
+
+ rtnl_lock();
+- for_each_netdev_safe(dev, nxt)
++ for_each_netdev_safe(&init_net, dev, nxt)
+ if (dev->priv_flags & IFF_EBRIDGE)
+ del_br(dev->priv);
+ rtnl_unlock();
+diff -Nurb linux-2.6.22-570/net/bridge/br_ioctl.c linux-2.6.22-590/net/bridge/br_ioctl.c
+--- linux-2.6.22-570/net/bridge/br_ioctl.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/bridge/br_ioctl.c 2008-01-29 22:12:32.000000000 -0500
+@@ -18,6 +18,7 @@
+ #include <linux/if_bridge.h>
+ #include <linux/netdevice.h>
+ #include <linux/times.h>
++#include <net/net_namespace.h>
+ #include <asm/uaccess.h>
+ #include "br_private.h"
+
+@@ -27,7 +28,7 @@
+ struct net_device *dev;
+ int i = 0;
+
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ if (i >= num)
+ break;
+ if (dev->priv_flags & IFF_EBRIDGE)
+@@ -90,7 +91,7 @@
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+- dev = dev_get_by_index(ifindex);
++ dev = dev_get_by_index(&init_net, ifindex);
+ if (dev == NULL)
+ return -EINVAL;
+
+@@ -364,7 +365,7 @@
+ return -EOPNOTSUPP;
+ }
+
+-int br_ioctl_deviceless_stub(unsigned int cmd, void __user *uarg)
++int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *uarg)
+ {
+ switch (cmd) {
+ case SIOCGIFBR:
+diff -Nurb linux-2.6.22-570/net/bridge/br_netfilter.c linux-2.6.22-590/net/bridge/br_netfilter.c
+--- linux-2.6.22-570/net/bridge/br_netfilter.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/bridge/br_netfilter.c 2008-01-29 22:12:32.000000000 -0500
+@@ -310,6 +310,7 @@
+ if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) {
+ struct rtable *rt;
+ struct flowi fl = {
++ .fl_net = &init_net,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = iph->daddr,
+@@ -518,6 +519,10 @@
+ if (unlikely(!pskb_may_pull(skb, len)))
+ goto out;
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb) ||
+ IS_PPPOE_IPV6(skb)) {
+ #ifdef CONFIG_SYSCTL
+@@ -591,6 +596,10 @@
+ {
+ struct sk_buff *skb = *pskb;
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ if (skb->dst == (struct dst_entry *)&__fake_rtable) {
+ dst_release(skb->dst);
+ skb->dst = NULL;
+@@ -635,6 +644,10 @@
+ struct net_device *parent;
+ int pf;
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ if (!skb->nf_bridge)
+ return NF_ACCEPT;
+
+@@ -674,6 +687,10 @@
+ struct sk_buff *skb = *pskb;
+ struct net_device **d = (struct net_device **)(skb->cb);
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ #ifdef CONFIG_SYSCTL
+ if (!brnf_call_arptables)
+ return NF_ACCEPT;
+@@ -718,6 +735,10 @@
+ struct sk_buff *skb = *pskb;
+ struct nf_bridge_info *nf_bridge;
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ if (!skb->nf_bridge)
+ return NF_ACCEPT;
+
+@@ -762,6 +783,10 @@
+ struct net_device *realoutdev = bridge_parent(skb->dev);
+ int pf;
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ #ifdef CONFIG_NETFILTER_DEBUG
+ /* Be very paranoid. This probably won't happen anymore, but let's
+ * keep the check just to be sure... */
+@@ -833,6 +858,10 @@
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ if ((*pskb)->nf_bridge &&
+ !((*pskb)->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)) {
+ return NF_STOP;
+diff -Nurb linux-2.6.22-570/net/bridge/br_netlink.c linux-2.6.22-590/net/bridge/br_netlink.c
+--- linux-2.6.22-570/net/bridge/br_netlink.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/bridge/br_netlink.c 2008-01-29 22:12:32.000000000 -0500
+@@ -12,6 +12,8 @@
+
+ #include <linux/kernel.h>
+ #include <net/rtnetlink.h>
++#include <net/net_namespace.h>
++#include <net/sock.h>
+ #include "br_private.h"
+
+ static inline size_t br_nlmsg_size(void)
+@@ -95,10 +97,10 @@
+ kfree_skb(skb);
+ goto errout;
+ }
+- err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
++ err = rtnl_notify(skb, &init_net,0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
+ errout:
+ if (err < 0)
+- rtnl_set_sk_err(RTNLGRP_LINK, err);
++ rtnl_set_sk_err(&init_net, RTNLGRP_LINK, err);
+ }
+
+ /*
+@@ -106,11 +108,15 @@
+ */
+ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct net_device *dev;
+ int idx;
+
++ if (net != &init_net)
++ return 0;
++
+ idx = 0;
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ /* not a bridge port */
+ if (dev->br_port == NULL || idx < cb->args[0])
+ goto skip;
+@@ -134,12 +140,16 @@
+ */
+ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct ifinfomsg *ifm;
+ struct nlattr *protinfo;
+ struct net_device *dev;
+ struct net_bridge_port *p;
+ u8 new_state;
+
++ if (net != &init_net)
++ return -EINVAL;
++
+ if (nlmsg_len(nlh) < sizeof(*ifm))
+ return -EINVAL;
+
+@@ -155,7 +165,7 @@
+ if (new_state > BR_STATE_BLOCKING)
+ return -EINVAL;
+
+- dev = __dev_get_by_index(ifm->ifi_index);
++ dev = __dev_get_by_index(&init_net, ifm->ifi_index);
+ if (!dev)
+ return -ENODEV;
+
+diff -Nurb linux-2.6.22-570/net/bridge/br_notify.c linux-2.6.22-590/net/bridge/br_notify.c
+--- linux-2.6.22-570/net/bridge/br_notify.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/bridge/br_notify.c 2008-01-29 22:12:32.000000000 -0500
+@@ -15,6 +15,7 @@
+
+ #include <linux/kernel.h>
+ #include <linux/rtnetlink.h>
++#include <net/net_namespace.h>
+
+ #include "br_private.h"
+
+@@ -36,6 +37,9 @@
+ struct net_bridge_port *p = dev->br_port;
+ struct net_bridge *br;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ /* not a port of a bridge */
+ if (p == NULL)
+ return NOTIFY_DONE;
+diff -Nurb linux-2.6.22-570/net/bridge/br_private.h linux-2.6.22-590/net/bridge/br_private.h
+--- linux-2.6.22-570/net/bridge/br_private.h 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/bridge/br_private.h 2008-01-29 22:12:32.000000000 -0500
+@@ -196,7 +196,7 @@
+
+ /* br_ioctl.c */
+ extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+-extern int br_ioctl_deviceless_stub(unsigned int cmd, void __user *arg);
++extern int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *arg);
+
+ /* br_netfilter.c */
+ #ifdef CONFIG_BRIDGE_NETFILTER
+diff -Nurb linux-2.6.22-570/net/bridge/br_stp_bpdu.c linux-2.6.22-590/net/bridge/br_stp_bpdu.c
+--- linux-2.6.22-570/net/bridge/br_stp_bpdu.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/bridge/br_stp_bpdu.c 2008-01-29 22:12:32.000000000 -0500
+@@ -17,6 +17,7 @@
+ #include <linux/netfilter_bridge.h>
+ #include <linux/etherdevice.h>
+ #include <linux/llc.h>
++#include <net/net_namespace.h>
+ #include <net/llc.h>
+ #include <net/llc_pdu.h>
+ #include <asm/unaligned.h>
+@@ -141,6 +142,9 @@
+ struct net_bridge *br;
+ const unsigned char *buf;
+
++ if (dev->nd_net != &init_net)
++ goto err;
++
+ if (!p)
+ goto err;
+
diff -Nurb linux-2.6.22-570/net/bridge/br_stp_if.c linux-2.6.22-590/net/bridge/br_stp_if.c
--- linux-2.6.22-570/net/bridge/br_stp_if.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/bridge/br_stp_if.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/bridge/br_stp_if.c 2008-01-29 22:12:32.000000000 -0500
@@ -125,7 +125,7 @@
char *argv[] = { BR_STP_PROG, br->dev->name, "start", NULL };
char *envp[] = { NULL };
printk(KERN_INFO "%s: userspace STP started\n", br->dev->name);
diff -Nurb linux-2.6.22-570/net/bridge/br_sysfs_br.c linux-2.6.22-590/net/bridge/br_sysfs_br.c
--- linux-2.6.22-570/net/bridge/br_sysfs_br.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/bridge/br_sysfs_br.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/bridge/br_sysfs_br.c 2008-01-29 22:12:32.000000000 -0500
@@ -360,8 +360,9 @@
*
* Returns the number of bytes read.
diff -Nurb linux-2.6.22-570/net/bridge/br_sysfs_if.c linux-2.6.22-590/net/bridge/br_sysfs_if.c
--- linux-2.6.22-570/net/bridge/br_sysfs_if.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/bridge/br_sysfs_if.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/bridge/br_sysfs_if.c 2008-01-29 22:12:32.000000000 -0500
@@ -29,8 +29,7 @@
#define BRPORT_ATTR(_name,_mode,_show,_store) \
struct brport_attribute brport_attr_##_name = { \
.show = _show, \
.store = _store, \
};
+diff -Nurb linux-2.6.22-570/net/bridge/netfilter/ebt_ulog.c linux-2.6.22-590/net/bridge/netfilter/ebt_ulog.c
+--- linux-2.6.22-570/net/bridge/netfilter/ebt_ulog.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/bridge/netfilter/ebt_ulog.c 2008-01-29 22:12:32.000000000 -0500
+@@ -301,8 +301,9 @@
+ spin_lock_init(&ulog_buffers[i].lock);
+ }
+
+- ebtulognl = netlink_kernel_create(NETLINK_NFLOG, EBT_ULOG_MAXNLGROUPS,
+- NULL, NULL, THIS_MODULE);
++ ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG,
++ EBT_ULOG_MAXNLGROUPS, NULL, NULL,
++ THIS_MODULE);
+ if (!ebtulognl)
+ ret = -ENOMEM;
+ else if ((ret = ebt_register_watcher(&ulog)))
+diff -Nurb linux-2.6.22-570/net/bridge/netfilter/ebtable_filter.c linux-2.6.22-590/net/bridge/netfilter/ebtable_filter.c
+--- linux-2.6.22-570/net/bridge/netfilter/ebtable_filter.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/bridge/netfilter/ebtable_filter.c 2008-01-29 22:12:32.000000000 -0500
+@@ -64,6 +64,10 @@
+ ebt_hook (unsigned int hook, struct sk_buff **pskb, const struct net_device *in,
+ const struct net_device *out, int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ return ebt_do_table(hook, pskb, in, out, &frame_filter);
+ }
+
+diff -Nurb linux-2.6.22-570/net/bridge/netfilter/ebtable_nat.c linux-2.6.22-590/net/bridge/netfilter/ebtable_nat.c
+--- linux-2.6.22-570/net/bridge/netfilter/ebtable_nat.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/bridge/netfilter/ebtable_nat.c 2008-01-29 22:12:32.000000000 -0500
+@@ -64,6 +64,10 @@
+ ebt_nat_dst(unsigned int hook, struct sk_buff **pskb, const struct net_device *in
+ , const struct net_device *out, int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ return ebt_do_table(hook, pskb, in, out, &frame_nat);
+ }
+
+@@ -71,6 +75,10 @@
+ ebt_nat_src(unsigned int hook, struct sk_buff **pskb, const struct net_device *in
+ , const struct net_device *out, int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ return ebt_do_table(hook, pskb, in, out, &frame_nat);
+ }
+
+diff -Nurb linux-2.6.22-570/net/bridge/netfilter/ebtables.c linux-2.6.22-590/net/bridge/netfilter/ebtables.c
+--- linux-2.6.22-570/net/bridge/netfilter/ebtables.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/bridge/netfilter/ebtables.c 2008-01-29 22:12:32.000000000 -0500
+@@ -28,6 +28,7 @@
+ #include <linux/smp.h>
+ #include <linux/cpumask.h>
+ #include <net/sock.h>
++#include <net/net_namespace.h>
+ /* needed for logical [in,out]-dev filtering */
+ #include "../br_private.h"
+
+@@ -1438,6 +1439,9 @@
+ {
+ int ret;
+
++ if (sk->sk_net != &init_net)
++ return -ENOPROTOOPT;
++
+ switch(cmd) {
+ case EBT_SO_SET_ENTRIES:
+ ret = do_replace(user, len);
+@@ -1457,6 +1461,9 @@
+ struct ebt_replace tmp;
+ struct ebt_table *t;
+
++ if (sk->sk_net != &init_net)
++ return -ENOPROTOOPT;
++
+ if (copy_from_user(&tmp, user, sizeof(tmp)))
+ return -EFAULT;
+
+diff -Nurb linux-2.6.22-570/net/core/Makefile linux-2.6.22-590/net/core/Makefile
+--- linux-2.6.22-570/net/core/Makefile 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/core/Makefile 2008-01-29 22:12:32.000000000 -0500
+@@ -3,7 +3,7 @@
+ #
+
+ obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \
+- gen_stats.o gen_estimator.o
++ gen_stats.o gen_estimator.o net_namespace.o
+
+ obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
+
diff -Nurb linux-2.6.22-570/net/core/dev.c linux-2.6.22-590/net/core/dev.c
---- linux-2.6.22-570/net/core/dev.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/net/core/dev.c 2008-03-15 10:35:47.000000000 -0400
-@@ -152,9 +152,22 @@
+--- linux-2.6.22-570/net/core/dev.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/core/dev.c 2008-01-29 22:12:32.000000000 -0500
+@@ -116,6 +116,7 @@
+ #include <linux/dmaengine.h>
+ #include <linux/err.h>
+ #include <linux/ctype.h>
++#include <net/net_namespace.h>
+ #include <linux/if_arp.h>
+ #include <linux/vs_inet.h>
+
+@@ -152,9 +153,22 @@
static struct list_head ptype_all __read_mostly; /* Taps */
#ifdef CONFIG_NET_DMA
#endif
/*
-@@ -822,8 +835,12 @@
+@@ -176,25 +190,50 @@
+ * unregister_netdevice(), which must be called with the rtnl
+ * semaphore held.
+ */
+-LIST_HEAD(dev_base_head);
+ DEFINE_RWLOCK(dev_base_lock);
+
+-EXPORT_SYMBOL(dev_base_head);
+ EXPORT_SYMBOL(dev_base_lock);
+
+ #define NETDEV_HASHBITS 8
+-static struct hlist_head dev_name_head[1<<NETDEV_HASHBITS];
+-static struct hlist_head dev_index_head[1<<NETDEV_HASHBITS];
++#define NETDEV_HASHENTRIES (1 << NETDEV_HASHBITS)
+
+-static inline struct hlist_head *dev_name_hash(const char *name)
++static inline struct hlist_head *dev_name_hash(struct net *net, const char *name)
+ {
+ unsigned hash = full_name_hash(name, strnlen(name, IFNAMSIZ));
+- return &dev_name_head[hash & ((1<<NETDEV_HASHBITS)-1)];
++ return &net->dev_name_head[hash & ((1 << NETDEV_HASHBITS) - 1)];
++}
++
++static inline struct hlist_head *dev_index_hash(struct net *net, int ifindex)
++{
++ return &net->dev_index_head[ifindex & ((1 << NETDEV_HASHBITS) - 1)];
++}
++
++/* Device list insertion */
++static int list_netdevice(struct net_device *dev)
++{
++ struct net *net = dev->nd_net;
++
++ ASSERT_RTNL();
++
++ write_lock_bh(&dev_base_lock);
++ list_add_tail(&dev->dev_list, &net->dev_base_head);
++ hlist_add_head(&dev->name_hlist, dev_name_hash(net, dev->name));
++ hlist_add_head(&dev->index_hlist, dev_index_hash(net, dev->ifindex));
++ write_unlock_bh(&dev_base_lock);
++ return 0;
+ }
+
+-static inline struct hlist_head *dev_index_hash(int ifindex)
++/* Device list removal */
++static void unlist_netdevice(struct net_device *dev)
+ {
+- return &dev_index_head[ifindex & ((1<<NETDEV_HASHBITS)-1)];
++ ASSERT_RTNL();
++
++ /* Unlink dev from the device chain */
++ write_lock_bh(&dev_base_lock);
++ list_del(&dev->dev_list);
++ hlist_del(&dev->name_hlist);
++ hlist_del(&dev->index_hlist);
++ write_unlock_bh(&dev_base_lock);
+ }
+
+ /*
+@@ -477,7 +516,7 @@
+ * If device already registered then return base of 1
+ * to indicate not to probe for this interface
+ */
+- if (__dev_get_by_name(name))
++ if (__dev_get_by_name(&init_net, name))
+ return 1;
+
+ for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++)
+@@ -532,11 +571,11 @@
+ * careful with locks.
+ */
+
+-struct net_device *__dev_get_by_name(const char *name)
++struct net_device *__dev_get_by_name(struct net *net, const char *name)
+ {
+ struct hlist_node *p;
+
+- hlist_for_each(p, dev_name_hash(name)) {
++ hlist_for_each(p, dev_name_hash(net, name)) {
+ struct net_device *dev
+ = hlist_entry(p, struct net_device, name_hlist);
+ if (!strncmp(dev->name, name, IFNAMSIZ))
+@@ -556,12 +595,12 @@
+ * matching device is found.
+ */
+
+-struct net_device *dev_get_by_name(const char *name)
++struct net_device *dev_get_by_name(struct net *net, const char *name)
+ {
+ struct net_device *dev;
+
+ read_lock(&dev_base_lock);
+- dev = __dev_get_by_name(name);
++ dev = __dev_get_by_name(net, name);
+ if (dev)
+ dev_hold(dev);
+ read_unlock(&dev_base_lock);
+@@ -579,11 +618,11 @@
+ * or @dev_base_lock.
+ */
+
+-struct net_device *__dev_get_by_index(int ifindex)
++struct net_device *__dev_get_by_index(struct net *net, int ifindex)
+ {
+ struct hlist_node *p;
+
+- hlist_for_each(p, dev_index_hash(ifindex)) {
++ hlist_for_each(p, dev_index_hash(net, ifindex)) {
+ struct net_device *dev
+ = hlist_entry(p, struct net_device, index_hlist);
+ if (dev->ifindex == ifindex)
+@@ -603,12 +642,12 @@
+ * dev_put to indicate they have finished with it.
+ */
+
+-struct net_device *dev_get_by_index(int ifindex)
++struct net_device *dev_get_by_index(struct net *net, int ifindex)
+ {
+ struct net_device *dev;
+
+ read_lock(&dev_base_lock);
+- dev = __dev_get_by_index(ifindex);
++ dev = __dev_get_by_index(net, ifindex);
+ if (dev)
+ dev_hold(dev);
+ read_unlock(&dev_base_lock);
+@@ -629,13 +668,13 @@
+ * If the API was consistent this would be __dev_get_by_hwaddr
+ */
+
+-struct net_device *dev_getbyhwaddr(unsigned short type, char *ha)
++struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, char *ha)
+ {
+ struct net_device *dev;
+
+ ASSERT_RTNL();
+
+- for_each_netdev(dev)
++ for_each_netdev(&init_net, dev)
+ if (dev->type == type &&
+ !memcmp(dev->dev_addr, ha, dev->addr_len))
+ return dev;
+@@ -645,12 +684,12 @@
+
+ EXPORT_SYMBOL(dev_getbyhwaddr);
+
+-struct net_device *__dev_getfirstbyhwtype(unsigned short type)
++struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type)
+ {
+ struct net_device *dev;
+
+ ASSERT_RTNL();
+- for_each_netdev(dev)
++ for_each_netdev(net, dev)
+ if (dev->type == type)
+ return dev;
+
+@@ -659,12 +698,12 @@
+
+ EXPORT_SYMBOL(__dev_getfirstbyhwtype);
+
+-struct net_device *dev_getfirstbyhwtype(unsigned short type)
++struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type)
+ {
+ struct net_device *dev;
+
+ rtnl_lock();
+- dev = __dev_getfirstbyhwtype(type);
++ dev = __dev_getfirstbyhwtype(net, type);
+ if (dev)
+ dev_hold(dev);
+ rtnl_unlock();
+@@ -684,13 +723,13 @@
+ * dev_put to indicate they have finished with it.
+ */
+
+-struct net_device * dev_get_by_flags(unsigned short if_flags, unsigned short mask)
++struct net_device * dev_get_by_flags(struct net *net, unsigned short if_flags, unsigned short mask)
+ {
+ struct net_device *dev, *ret;
+
+ ret = NULL;
+ read_lock(&dev_base_lock);
+- for_each_netdev(dev) {
++ for_each_netdev(net, dev) {
+ if (((dev->flags ^ if_flags) & mask) == 0) {
+ dev_hold(dev);
+ ret = dev;
+@@ -727,9 +766,10 @@
+ }
+
+ /**
+- * dev_alloc_name - allocate a name for a device
+- * @dev: device
++ * __dev_alloc_name - allocate a name for a device
++ * @net: network namespace to allocate the device name in
+ * @name: name format string
++ * @buf: scratch buffer and result name string
+ *
+ * Passed a format string - eg "lt%d" it will try and find a suitable
+ * id. It scans list of devices to build up a free map, then chooses
+@@ -740,10 +780,9 @@
+ * Returns the number of the unit assigned or a negative errno code.
+ */
+
+-int dev_alloc_name(struct net_device *dev, const char *name)
++static int __dev_alloc_name(struct net *net, const char *name, char *buf)
+ {
+ int i = 0;
+- char buf[IFNAMSIZ];
+ const char *p;
+ const int max_netdevices = 8*PAGE_SIZE;
+ long *inuse;
+@@ -764,14 +803,14 @@
+ if (!inuse)
+ return -ENOMEM;
+
+- for_each_netdev(d) {
++ for_each_netdev(net, d) {
+ if (!sscanf(d->name, name, &i))
+ continue;
+ if (i < 0 || i >= max_netdevices)
+ continue;
+
+ /* avoid cases where sscanf is not exact inverse of printf */
+- snprintf(buf, sizeof(buf), name, i);
++ snprintf(buf, IFNAMSIZ, name, i);
+ if (!strncmp(buf, d->name, IFNAMSIZ))
+ set_bit(i, inuse);
+ }
+@@ -780,11 +819,9 @@
+ free_page((unsigned long) inuse);
+ }
+
+- snprintf(buf, sizeof(buf), name, i);
+- if (!__dev_get_by_name(buf)) {
+- strlcpy(dev->name, buf, IFNAMSIZ);
++ snprintf(buf, IFNAMSIZ, name, i);
++ if (!__dev_get_by_name(net, buf))
+ return i;
+- }
+
+ /* It is possible to run out of possible slots
+ * when the name is long and there isn't enough space left
+@@ -793,6 +830,34 @@
+ return -ENFILE;
+ }
+
++/**
++ * dev_alloc_name - allocate a name for a device
++ * @dev: device
++ * @name: name format string
++ *
++ * Passed a format string - eg "lt%d" it will try and find a suitable
++ * id. It scans list of devices to build up a free map, then chooses
++ * the first empty slot. The caller must hold the dev_base or rtnl lock
++ * while allocating the name and adding the device in order to avoid
++ * duplicates.
++ * Limited to bits_per_byte * page size devices (ie 32K on most platforms).
++ * Returns the number of the unit assigned or a negative errno code.
++ */
++
++int dev_alloc_name(struct net_device *dev, const char *name)
++{
++ char buf[IFNAMSIZ];
++ struct net *net;
++ int ret;
++
++ BUG_ON(!dev->nd_net);
++ net = dev->nd_net;
++ ret = __dev_alloc_name(net, name, buf);
++ if (ret >= 0)
++ strlcpy(dev->name, buf, IFNAMSIZ);
++ return ret;
++}
++
+
+ /**
+ * dev_change_name - change name of a device
+@@ -805,9 +870,12 @@
+ int dev_change_name(struct net_device *dev, char *newname)
+ {
+ int err = 0;
++ struct net *net;
+
+ ASSERT_RTNL();
++ BUG_ON(!dev->nd_net);
+
++ net = dev->nd_net;
+ if (dev->flags & IFF_UP)
+ return -EBUSY;
+
+@@ -820,14 +888,18 @@
+ return err;
+ strcpy(newname, dev->name);
}
- else if (__dev_get_by_name(newname))
+- else if (__dev_get_by_name(newname))
++ else if (__dev_get_by_name(net, newname))
return -EEXIST;
- else
+ else {
device_rename(&dev->dev, dev->name);
hlist_del(&dev->name_hlist);
-@@ -1510,9 +1527,11 @@
+- hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name));
++ hlist_add_head(&dev->name_hlist, dev_name_hash(net, dev->name));
+ raw_notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev);
+
+ return err;
+@@ -871,12 +943,12 @@
+ * available in this kernel then it becomes a nop.
+ */
+
+-void dev_load(const char *name)
++void dev_load(struct net *net, const char *name)
+ {
+ struct net_device *dev;
+
+ read_lock(&dev_base_lock);
+- dev = __dev_get_by_name(name);
++ dev = __dev_get_by_name(net, name);
+ read_unlock(&dev_base_lock);
+
+ if (!dev && capable(CAP_SYS_MODULE))
+@@ -1019,6 +1091,8 @@
+ }
+
+
++static int dev_boot_phase = 1;
++
+ /*
+ * Device change register/unregister. These are not inline or static
+ * as we export them to the world.
+@@ -1045,14 +1119,17 @@
+
+ rtnl_lock();
+ err = raw_notifier_chain_register(&netdev_chain, nb);
+- if (!err) {
+- for_each_netdev(dev) {
++ if (!err && !dev_boot_phase) {
++ struct net *net;
++ for_each_net(net) {
++ for_each_netdev(net, dev) {
+ nb->notifier_call(nb, NETDEV_REGISTER, dev);
+
+ if (dev->flags & IFF_UP)
+ nb->notifier_call(nb, NETDEV_UP, dev);
+ }
+ }
++ }
+ rtnl_unlock();
+ return err;
+ }
+@@ -1086,9 +1163,9 @@
+ * are as for raw_notifier_call_chain().
+ */
+
+-int call_netdevice_notifiers(unsigned long val, void *v)
++int call_netdevice_notifiers(unsigned long val, struct net_device *dev)
+ {
+- return raw_notifier_call_chain(&netdev_chain, val, v);
++ return raw_notifier_call_chain(&netdev_chain, val, dev);
+ }
+
+ /* When > 0 there are consumers of rx skb time stamps */
+@@ -1510,9 +1587,11 @@
skb_set_transport_header(skb, skb->csum_start -
skb_headroom(skb));
if (skb_checksum_help(skb))
goto out_kfree_skb;
}
-@@ -2016,12 +2035,13 @@
+@@ -2016,12 +2095,13 @@
* There may not be any more sk_buffs coming right now, so push
* any pending DMA copies to hardware
*/
}
#endif
return;
-@@ -3113,6 +3133,22 @@
+@@ -2063,7 +2143,7 @@
+ * match. --pb
+ */
+
+-static int dev_ifname(struct ifreq __user *arg)
++static int dev_ifname(struct net *net, struct ifreq __user *arg)
+ {
+ struct net_device *dev;
+ struct ifreq ifr;
+@@ -2076,7 +2156,7 @@
+ return -EFAULT;
+
+ read_lock(&dev_base_lock);
+- dev = __dev_get_by_index(ifr.ifr_ifindex);
++ dev = __dev_get_by_index(net, ifr.ifr_ifindex);
+ if (!dev) {
+ read_unlock(&dev_base_lock);
+ return -ENODEV;
+@@ -2096,7 +2176,7 @@
+ * Thus we will need a 'compatibility mode'.
+ */
+
+-static int dev_ifconf(char __user *arg)
++static int dev_ifconf(struct net *net, char __user *arg)
+ {
+ struct ifconf ifc;
+ struct net_device *dev;
+@@ -2120,7 +2200,7 @@
+ */
+
+ total = 0;
+- for_each_netdev(dev) {
++ for_each_netdev(net, dev) {
+ if (!nx_dev_visible(current->nx_info, dev))
+ continue;
+ for (i = 0; i < NPROTO; i++) {
+@@ -2156,6 +2236,7 @@
+ */
+ void *dev_seq_start(struct seq_file *seq, loff_t *pos)
+ {
++ struct net *net = seq->private;
+ loff_t off;
+ struct net_device *dev;
+
+@@ -2164,7 +2245,7 @@
+ return SEQ_START_TOKEN;
+
+ off = 1;
+- for_each_netdev(dev)
++ for_each_netdev(net, dev)
+ if (off++ == *pos)
+ return dev;
+
+@@ -2173,9 +2254,10 @@
+
+ void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
++ struct net *net = seq->private;
+ ++*pos;
+ return v == SEQ_START_TOKEN ?
+- first_net_device() : next_net_device((struct net_device *)v);
++ first_net_device(net) : next_net_device((struct net_device *)v);
+ }
+
+ void dev_seq_stop(struct seq_file *seq, void *v)
+@@ -2274,7 +2356,22 @@
+
+ static int dev_seq_open(struct inode *inode, struct file *file)
+ {
+- return seq_open(file, &dev_seq_ops);
++ struct seq_file *seq;
++ int res;
++ res = seq_open(file, &dev_seq_ops);
++ if (!res) {
++ seq = file->private_data;
++ seq->private = get_net(PROC_NET(inode));
++ }
++ return res;
++}
++
++static int dev_seq_release(struct inode *inode, struct file *file)
++{
++ struct seq_file *seq = file->private_data;
++ struct net *net = seq->private;
++ put_net(net);
++ return seq_release(inode, file);
+ }
+
+ static const struct file_operations dev_seq_fops = {
+@@ -2282,7 +2379,7 @@
+ .open = dev_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+- .release = seq_release,
++ .release = dev_seq_release,
+ };
+
+ static const struct seq_operations softnet_seq_ops = {
+@@ -2434,30 +2531,49 @@
+ };
+
+
+-static int __init dev_proc_init(void)
++static int dev_proc_net_init(struct net *net)
+ {
+ int rc = -ENOMEM;
+
+- if (!proc_net_fops_create("dev", S_IRUGO, &dev_seq_fops))
++ if (!proc_net_fops_create(net, "dev", S_IRUGO, &dev_seq_fops))
+ goto out;
+- if (!proc_net_fops_create("softnet_stat", S_IRUGO, &softnet_seq_fops))
++ if (!proc_net_fops_create(net, "softnet_stat", S_IRUGO, &softnet_seq_fops))
+ goto out_dev;
+- if (!proc_net_fops_create("ptype", S_IRUGO, &ptype_seq_fops))
+- goto out_dev2;
+-
+- if (wext_proc_init())
++ if (!proc_net_fops_create(net, "ptype", S_IRUGO, &ptype_seq_fops))
+ goto out_softnet;
++
++ if (wext_proc_init(net))
++ goto out_ptype;
+ rc = 0;
+ out:
+ return rc;
++out_ptype:
++ proc_net_remove(net, "ptype");
+ out_softnet:
+- proc_net_remove("ptype");
+-out_dev2:
+- proc_net_remove("softnet_stat");
++ proc_net_remove(net, "softnet_stat");
+ out_dev:
+- proc_net_remove("dev");
++ proc_net_remove(net, "dev");
+ goto out;
+ }
++
++static void dev_proc_net_exit(struct net *net)
++{
++ wext_proc_exit(net);
++
++ proc_net_remove(net, "ptype");
++ proc_net_remove(net, "softnet_stat");
++ proc_net_remove(net, "dev");
++}
++
++static struct pernet_operations dev_proc_ops = {
++ .init = dev_proc_net_init,
++ .exit = dev_proc_net_exit,
++};
++
++static int __init dev_proc_init(void)
++{
++ return register_pernet_subsys(&dev_proc_ops);
++}
+ #else
+ #define dev_proc_init() 0
+ #endif /* CONFIG_PROC_FS */
+@@ -2691,10 +2807,10 @@
+ /*
+ * Perform the SIOCxIFxxx calls.
+ */
+-static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd)
++static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
+ {
+ int err;
+- struct net_device *dev = __dev_get_by_name(ifr->ifr_name);
++ struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name);
+
+ if (!dev)
+ return -ENODEV;
+@@ -2847,7 +2963,7 @@
+ * positive or a negative errno code on error.
+ */
+
+-int dev_ioctl(unsigned int cmd, void __user *arg)
++int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
+ {
+ struct ifreq ifr;
+ int ret;
+@@ -2860,12 +2976,12 @@
+
+ if (cmd == SIOCGIFCONF) {
+ rtnl_lock();
+- ret = dev_ifconf((char __user *) arg);
++ ret = dev_ifconf(net, (char __user *) arg);
+ rtnl_unlock();
+ return ret;
+ }
+ if (cmd == SIOCGIFNAME)
+- return dev_ifname((struct ifreq __user *)arg);
++ return dev_ifname(net, (struct ifreq __user *)arg);
+
+ if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
+ return -EFAULT;
+@@ -2895,9 +3011,9 @@
+ case SIOCGIFMAP:
+ case SIOCGIFINDEX:
+ case SIOCGIFTXQLEN:
+- dev_load(ifr.ifr_name);
++ dev_load(net, ifr.ifr_name);
+ read_lock(&dev_base_lock);
+- ret = dev_ifsioc(&ifr, cmd);
++ ret = dev_ifsioc(net, &ifr, cmd);
+ read_unlock(&dev_base_lock);
+ if (!ret) {
+ if (colon)
+@@ -2909,9 +3025,9 @@
+ return ret;
+
+ case SIOCETHTOOL:
+- dev_load(ifr.ifr_name);
++ dev_load(net, ifr.ifr_name);
+ rtnl_lock();
+- ret = dev_ethtool(&ifr);
++ ret = dev_ethtool(net, &ifr);
+ rtnl_unlock();
+ if (!ret) {
+ if (colon)
+@@ -2933,9 +3049,9 @@
+ case SIOCSIFNAME:
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+- dev_load(ifr.ifr_name);
++ dev_load(net, ifr.ifr_name);
+ rtnl_lock();
+- ret = dev_ifsioc(&ifr, cmd);
++ ret = dev_ifsioc(net, &ifr, cmd);
+ rtnl_unlock();
+ if (!ret) {
+ if (colon)
+@@ -2974,9 +3090,9 @@
+ /* fall through */
+ case SIOCBONDSLAVEINFOQUERY:
+ case SIOCBONDINFOQUERY:
+- dev_load(ifr.ifr_name);
++ dev_load(net, ifr.ifr_name);
+ rtnl_lock();
+- ret = dev_ifsioc(&ifr, cmd);
++ ret = dev_ifsioc(net, &ifr, cmd);
+ rtnl_unlock();
+ return ret;
+
+@@ -2996,9 +3112,9 @@
+ if (cmd == SIOCWANDEV ||
+ (cmd >= SIOCDEVPRIVATE &&
+ cmd <= SIOCDEVPRIVATE + 15)) {
+- dev_load(ifr.ifr_name);
++ dev_load(net, ifr.ifr_name);
+ rtnl_lock();
+- ret = dev_ifsioc(&ifr, cmd);
++ ret = dev_ifsioc(net, &ifr, cmd);
+ rtnl_unlock();
+ if (!ret && copy_to_user(arg, &ifr,
+ sizeof(struct ifreq)))
+@@ -3007,7 +3123,7 @@
+ }
+ /* Take care of Wireless Extensions */
+ if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)
+- return wext_handle_ioctl(&ifr, cmd, arg);
++ return wext_handle_ioctl(net, &ifr, cmd, arg);
+ return -EINVAL;
+ }
+ }
+@@ -3020,19 +3136,17 @@
+ * number. The caller must hold the rtnl semaphore or the
+ * dev_base_lock to be sure it remains unique.
+ */
+-static int dev_new_index(void)
++static int dev_new_index(struct net *net)
+ {
+ static int ifindex;
+ for (;;) {
+ if (++ifindex <= 0)
+ ifindex = 1;
+- if (!__dev_get_by_index(ifindex))
++ if (!__dev_get_by_index(net, ifindex))
+ return ifindex;
+ }
+ }
+
+-static int dev_boot_phase = 1;
+-
+ /* Delayed registration/unregisteration */
+ static DEFINE_SPINLOCK(net_todo_list_lock);
+ static struct list_head net_todo_list = LIST_HEAD_INIT(net_todo_list);
+@@ -3066,6 +3180,7 @@
+ struct hlist_head *head;
+ struct hlist_node *p;
+ int ret;
++ struct net *net;
+
+ BUG_ON(dev_boot_phase);
+ ASSERT_RTNL();
+@@ -3074,6 +3189,8 @@
+
+ /* When net_device's are persistent, this will be fatal. */
+ BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
++ BUG_ON(!dev->nd_net);
++ net = dev->nd_net;
+
+ spin_lock_init(&dev->queue_lock);
+ spin_lock_init(&dev->_xmit_lock);
+@@ -3098,12 +3215,12 @@
+ goto out;
+ }
+
+- dev->ifindex = dev_new_index();
++ dev->ifindex = dev_new_index(net);
+ if (dev->iflink == -1)
+ dev->iflink = dev->ifindex;
+
+ /* Check for existence of name */
+- head = dev_name_hash(dev->name);
++ head = dev_name_hash(net, dev->name);
+ hlist_for_each(p, head) {
+ struct net_device *d
+ = hlist_entry(p, struct net_device, name_hlist);
+@@ -3113,6 +3230,22 @@
}
}
/* Fix illegal SG+CSUM combinations. */
if ((dev->features & NETIF_F_SG) &&
!(dev->features & NETIF_F_ALL_CSUM)) {
-@@ -3569,12 +3605,13 @@
+@@ -3164,12 +3297,8 @@
+ set_bit(__LINK_STATE_PRESENT, &dev->state);
+
+ dev_init_scheduler(dev);
+- write_lock_bh(&dev_base_lock);
+- list_add_tail(&dev->dev_list, &dev_base_head);
+- hlist_add_head(&dev->name_hlist, head);
+- hlist_add_head(&dev->index_hlist, dev_index_hash(dev->ifindex));
+ dev_hold(dev);
+- write_unlock_bh(&dev_base_lock);
++ list_netdevice(dev);
+
+ /* Notify protocols, that a new device appeared. */
+ raw_notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev);
+@@ -3379,6 +3508,7 @@
+ dev = (struct net_device *)
+ (((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
+ dev->padded = (char *)dev - (char *)p;
++ dev->nd_net = &init_net;
+
+ if (sizeof_priv)
+ dev->priv = netdev_priv(dev);
+@@ -3457,11 +3587,7 @@
+ dev_close(dev);
+
+ /* And unlink it from device chain. */
+- write_lock_bh(&dev_base_lock);
+- list_del(&dev->dev_list);
+- hlist_del(&dev->name_hlist);
+- hlist_del(&dev->index_hlist);
+- write_unlock_bh(&dev_base_lock);
++ unlist_netdevice(dev);
+
+ dev->reg_state = NETREG_UNREGISTERING;
+
+@@ -3519,6 +3645,122 @@
+
+ EXPORT_SYMBOL(unregister_netdev);
+
++/**
++ * dev_change_net_namespace - move device to different nethost namespace
++ * @dev: device
++ * @net: network namespace
++ * @pat: If not NULL name pattern to try if the current device name
++ * is already taken in the destination network namespace.
++ *
++ * This function shuts down a device interface and moves it
++ * to a new network namespace. On success 0 is returned, on
++ * a failure a netagive errno code is returned.
++ *
++ * Callers must hold the rtnl semaphore.
++ */
++
++int dev_change_net_namespace(struct net_device *dev, struct net *net, const char *pat)
++{
++ char buf[IFNAMSIZ];
++ const char *destname;
++ int err;
++
++ ASSERT_RTNL();
++
++ /* Don't allow namespace local devices to be moved. */
++ err = -EINVAL;
++ if (dev->features & NETIF_F_NETNS_LOCAL)
++ goto out;
++
++ /* Ensure the device has been registrered */
++ err = -EINVAL;
++ if (dev->reg_state != NETREG_REGISTERED)
++ goto out;
++
++ /* Get out if there is nothing todo */
++ err = 0;
++ if (dev->nd_net == net)
++ goto out;
++
++ /* Pick the destination device name, and ensure
++ * we can use it in the destination network namespace.
++ */
++ err = -EEXIST;
++ destname = dev->name;
++ if (__dev_get_by_name(net, destname)) {
++ /* We get here if we can't use the current device name */
++ if (!pat)
++ goto out;
++ if (!dev_valid_name(pat))
++ goto out;
++ if (strchr(pat, '%')) {
++ if (__dev_alloc_name(net, pat, buf) < 0)
++ goto out;
++ destname = buf;
++ } else
++ destname = pat;
++ if (__dev_get_by_name(net, destname))
++ goto out;
++ }
++
++ /*
++ * And now a mini version of register_netdevice unregister_netdevice.
++ */
++
++ /* If device is running close it first. */
++ if (dev->flags & IFF_UP)
++ dev_close(dev);
++
++ /* And unlink it from device chain */
++ err = -ENODEV;
++ unlist_netdevice(dev);
++
++ synchronize_net();
++
++ /* Shutdown queueing discipline. */
++ dev_shutdown(dev);
++
++ /* Notify protocols, that we are about to destroy
++ this device. They should clean all the things.
++ */
++ call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
++
++ /*
++ * Flush the multicast chain
++ */
++ dev_mc_discard(dev);
++
++ /* Actually switch the network namespace */
++ dev->nd_net = net;
++
++ /* Assign the new device name */
++ if (destname != dev->name)
++ strcpy(dev->name, destname);
++
++ /* If there is an ifindex conflict assign a new one */
++ if (__dev_get_by_index(net, dev->ifindex)) {
++ int iflink = (dev->iflink == dev->ifindex);
++ dev->ifindex = dev_new_index(net);
++ if (iflink)
++ dev->iflink = dev->ifindex;
++ }
++
++ /* Fixup sysfs */
++ err = device_rename(&dev->dev, dev->name);
++ BUG_ON(err);
++
++ /* Add the device back in the hashes */
++ list_netdevice(dev);
++
++ /* Notify protocols, that a new device appeared. */
++ call_netdevice_notifiers(NETDEV_REGISTER, dev);
++
++ synchronize_net();
++ err = 0;
++out:
++ return err;
++}
++
+ static int dev_cpu_callback(struct notifier_block *nfb,
+ unsigned long action,
+ void *ocpu)
+@@ -3569,12 +3811,13 @@
* This is called when the number of channels allocated to the net_dma_client
* changes. The net_dma_client tries to have one DMA channel per CPU.
*/
for_each_online_cpu(cpu)
rcu_assign_pointer(per_cpu(softnet_data, cpu).net_dma, NULL);
return;
-@@ -3583,10 +3620,12 @@
+@@ -3583,10 +3826,12 @@
i = 0;
cpu = first_cpu(cpu_online_map);
while(n) {
per_cpu(softnet_data, cpu).net_dma = chan;
-@@ -3595,7 +3634,6 @@
+@@ -3595,7 +3840,6 @@
}
i++;
}
}
/**
-@@ -3604,23 +3642,53 @@
+@@ -3604,23 +3848,53 @@
* @chan: DMA channel for the event
* @event: event type
*/
}
/**
-@@ -3628,12 +3696,10 @@
+@@ -3628,12 +3902,10 @@
*/
static int __init netdev_dma_register(void)
{
return 0;
}
-diff -Nurb linux-2.6.22-570/net/core/netpoll.c linux-2.6.22-590/net/core/netpoll.c
---- linux-2.6.22-570/net/core/netpoll.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/net/core/netpoll.c 2008-03-15 10:35:47.000000000 -0400
-@@ -503,7 +503,8 @@
-
- np->rx_hook(np, ntohs(uh->source),
- (char *)(uh+1),
-- ulen - sizeof(struct udphdr));
-+ ulen - sizeof(struct udphdr),
-+ skb);
-
- kfree_skb(skb);
- return 1;
-diff -Nurb linux-2.6.22-570/net/core/pktgen.c linux-2.6.22-590/net/core/pktgen.c
---- linux-2.6.22-570/net/core/pktgen.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/net/core/pktgen.c 2008-03-15 10:35:47.000000000 -0400
-@@ -3284,6 +3284,8 @@
-
- set_current_state(TASK_INTERRUPTIBLE);
-
-+ set_freezable();
-+
- while (!kthread_should_stop()) {
- pkt_dev = next_to_run(t);
-
-diff -Nurb linux-2.6.22-570/net/core/rtnetlink.c linux-2.6.22-590/net/core/rtnetlink.c
---- linux-2.6.22-570/net/core/rtnetlink.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/net/core/rtnetlink.c 2008-03-15 10:35:47.000000000 -0400
-@@ -97,6 +97,19 @@
- return 0;
+@@ -3679,6 +3951,75 @@
}
+ EXPORT_SYMBOL(netdev_compute_features);
-+int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
-+ struct rtattr *rta, int len)
++/* Initialize per network namespace state */
++static int netdev_init(struct net *net)
+{
-+ if (RTA_PAYLOAD(rta) < len)
-+ return -1;
-+ if (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) {
-+ rta = RTA_DATA(rta) + RTA_ALIGN(len);
-+ return rtattr_parse_nested(tb, maxattr, rta);
++ int i;
++ INIT_LIST_HEAD(&net->dev_base_head);
++ rwlock_init(&dev_base_lock);
++
++ net->dev_name_head = kmalloc(
++ sizeof(*net->dev_name_head)*NETDEV_HASHENTRIES, GFP_KERNEL);
++ if (!net->dev_name_head)
++ return -ENOMEM;
++
++ net->dev_index_head = kmalloc(
++ sizeof(*net->dev_index_head)*NETDEV_HASHENTRIES, GFP_KERNEL);
++ if (!net->dev_index_head) {
++ kfree(net->dev_name_head);
++ return -ENOMEM;
+ }
-+ memset(tb, 0, sizeof(struct rtattr *) * maxattr);
-+ return 0;
-+}
+
- static struct rtnl_link *rtnl_msg_handlers[NPROTO];
-
- static inline int rtm_msgindex(int msgtype)
-@@ -243,6 +256,143 @@
-
- EXPORT_SYMBOL_GPL(rtnl_unregister_all);
-
-+static LIST_HEAD(link_ops);
++ for (i = 0; i < NETDEV_HASHENTRIES; i++)
++ INIT_HLIST_HEAD(&net->dev_name_head[i]);
++
++ for (i = 0; i < NETDEV_HASHENTRIES; i++)
++ INIT_HLIST_HEAD(&net->dev_index_head[i]);
+
-+/**
-+ * __rtnl_link_register - Register rtnl_link_ops with rtnetlink.
-+ * @ops: struct rtnl_link_ops * to register
-+ *
-+ * The caller must hold the rtnl_mutex. This function should be used
-+ * by drivers that create devices during module initialization. It
-+ * must be called before registering the devices.
-+ *
-+ * Returns 0 on success or a negative error code.
-+ */
-+int __rtnl_link_register(struct rtnl_link_ops *ops)
-+{
-+ list_add_tail(&ops->list, &link_ops);
+ return 0;
+}
+
-+EXPORT_SYMBOL_GPL(__rtnl_link_register);
-+
-+/**
-+ * rtnl_link_register - Register rtnl_link_ops with rtnetlink.
-+ * @ops: struct rtnl_link_ops * to register
-+ *
-+ * Returns 0 on success or a negative error code.
-+ */
-+int rtnl_link_register(struct rtnl_link_ops *ops)
++static void netdev_exit(struct net *net)
+{
-+ int err;
-+
-+ rtnl_lock();
-+ err = __rtnl_link_register(ops);
-+ rtnl_unlock();
-+ return err;
++ kfree(net->dev_name_head);
++ kfree(net->dev_index_head);
+}
+
-+EXPORT_SYMBOL_GPL(rtnl_link_register);
++static struct pernet_operations netdev_net_ops = {
++ .init = netdev_init,
++ .exit = netdev_exit,
++};
+
-+/**
-+ * __rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink.
-+ * @ops: struct rtnl_link_ops * to unregister
-+ *
-+ * The caller must hold the rtnl_mutex. This function should be used
-+ * by drivers that unregister devices during module unloading. It must
-+ * be called after unregistering the devices.
-+ */
-+void __rtnl_link_unregister(struct rtnl_link_ops *ops)
++static void default_device_exit(struct net *net)
+{
-+ list_del(&ops->list);
-+}
++ struct net_device *dev, *next;
++ /*
++ * Push all migratable of the network devices back to the
++ * initial network namespace
++ */
++ rtnl_lock();
++ for_each_netdev_safe(net, dev, next) {
++ int err;
+
-+EXPORT_SYMBOL_GPL(__rtnl_link_unregister);
++ /* Ignore unmoveable devices (i.e. loopback) */
++ if (dev->features & NETIF_F_NETNS_LOCAL)
++ continue;
+
-+/**
-+ * rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink.
-+ * @ops: struct rtnl_link_ops * to unregister
-+ */
-+void rtnl_link_unregister(struct rtnl_link_ops *ops)
-+{
-+ rtnl_lock();
-+ __rtnl_link_unregister(ops);
++ /* Push remaing network devices to init_net */
++ err = dev_change_net_namespace(dev, &init_net, "dev%d");
++ if (err) {
++ printk(KERN_WARNING "%s: failed to move %s to init_net: %d\n",
++ __func__, dev->name, err);
++ unregister_netdevice(dev);
++ }
++ }
+ rtnl_unlock();
+}
+
-+EXPORT_SYMBOL_GPL(rtnl_link_unregister);
-+
-+static const struct rtnl_link_ops *rtnl_link_ops_get(const char *kind)
-+{
-+ const struct rtnl_link_ops *ops;
++static struct pernet_operations default_device_ops = {
++ .exit = default_device_exit,
++};
+
-+ list_for_each_entry(ops, &link_ops, list) {
-+ if (!strcmp(ops->kind, kind))
-+ return ops;
+ /*
+ * Initialize the DEV module. At boot time this walks the device list and
+ * unhooks any devices that fail to initialise (normally hardware not
+@@ -3706,11 +4047,11 @@
+ for (i = 0; i < 16; i++)
+ INIT_LIST_HEAD(&ptype_base[i]);
+
+- for (i = 0; i < ARRAY_SIZE(dev_name_head); i++)
+- INIT_HLIST_HEAD(&dev_name_head[i]);
++ if (register_pernet_subsys(&netdev_net_ops))
++ goto out;
+
+- for (i = 0; i < ARRAY_SIZE(dev_index_head); i++)
+- INIT_HLIST_HEAD(&dev_index_head[i]);
++ if (register_pernet_device(&default_device_ops))
++ goto out;
+
+ /*
+ * Initialise the packet receive queues.
+diff -Nurb linux-2.6.22-570/net/core/dev_mcast.c linux-2.6.22-590/net/core/dev_mcast.c
+--- linux-2.6.22-570/net/core/dev_mcast.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/core/dev_mcast.c 2008-01-29 22:12:32.000000000 -0500
+@@ -46,6 +46,7 @@
+ #include <linux/skbuff.h>
+ #include <net/sock.h>
+ #include <net/arp.h>
++#include <net/net_namespace.h>
+
+
+ /*
+@@ -219,11 +220,12 @@
+ #ifdef CONFIG_PROC_FS
+ static void *dev_mc_seq_start(struct seq_file *seq, loff_t *pos)
+ {
++ struct net *net = seq->private;
+ struct net_device *dev;
+ loff_t off = 0;
+
+ read_lock(&dev_base_lock);
+- for_each_netdev(dev) {
++ for_each_netdev(net, dev) {
+ if (off++ == *pos)
+ return dev;
+ }
+@@ -272,7 +274,22 @@
+
+ static int dev_mc_seq_open(struct inode *inode, struct file *file)
+ {
+- return seq_open(file, &dev_mc_seq_ops);
++ struct seq_file *seq;
++ int res;
++ res = seq_open(file, &dev_mc_seq_ops);
++ if (!res) {
++ seq = file->private_data;
++ seq->private = get_net(PROC_NET(inode));
+ }
-+ return NULL;
++ return res;
+}
+
-+static size_t rtnl_link_get_size(const struct net_device *dev)
++static int dev_mc_seq_release(struct inode *inode, struct file *file)
+{
-+ const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
-+ size_t size;
-+
-+ if (!ops)
-+ return 0;
-+
-+ size = nlmsg_total_size(sizeof(struct nlattr)) + /* IFLA_LINKINFO */
-+ nlmsg_total_size(strlen(ops->kind) + 1); /* IFLA_INFO_KIND */
-+
-+ if (ops->get_size)
-+ /* IFLA_INFO_DATA + nested data */
-+ size += nlmsg_total_size(sizeof(struct nlattr)) +
-+ ops->get_size(dev);
-+
-+ if (ops->get_xstats_size)
-+ size += ops->get_xstats_size(dev); /* IFLA_INFO_XSTATS */
-+
-+ return size;
-+}
-+
-+static int rtnl_link_fill(struct sk_buff *skb, const struct net_device *dev)
++ struct seq_file *seq = file->private_data;
++ struct net *net = seq->private;
++ put_net(net);
++ return seq_release(inode, file);
+ }
+
+ static const struct file_operations dev_mc_seq_fops = {
+@@ -280,14 +297,31 @@
+ .open = dev_mc_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+- .release = seq_release,
++ .release = dev_mc_seq_release,
+ };
+
+ #endif
+
++static int dev_mc_net_init(struct net *net)
+{
-+ const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
-+ struct nlattr *linkinfo, *data;
-+ int err = -EMSGSIZE;
-+
-+ linkinfo = nla_nest_start(skb, IFLA_LINKINFO);
-+ if (linkinfo == NULL)
-+ goto out;
-+
-+ if (nla_put_string(skb, IFLA_INFO_KIND, ops->kind) < 0)
-+ goto err_cancel_link;
-+ if (ops->fill_xstats) {
-+ err = ops->fill_xstats(skb, dev);
-+ if (err < 0)
-+ goto err_cancel_link;
-+ }
-+ if (ops->fill_info) {
-+ data = nla_nest_start(skb, IFLA_INFO_DATA);
-+ if (data == NULL)
-+ goto err_cancel_link;
-+ err = ops->fill_info(skb, dev);
-+ if (err < 0)
-+ goto err_cancel_data;
-+ nla_nest_end(skb, data);
-+ }
-+
-+ nla_nest_end(skb, linkinfo);
++ if (!proc_net_fops_create(net, "dev_mcast", 0, &dev_mc_seq_fops))
++ return -ENOMEM;
+ return 0;
++}
+
-+err_cancel_data:
-+ nla_nest_cancel(skb, data);
-+err_cancel_link:
-+ nla_nest_cancel(skb, linkinfo);
-+out:
-+ return err;
++static void dev_mc_net_exit(struct net *net)
++{
++ proc_net_remove(net, "dev_mcast");
+}
+
- static const int rtm_min[RTM_NR_FAMILIES] =
- {
- [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
-@@ -437,7 +587,7 @@
- a->tx_compressed = b->tx_compressed;
- };
-
--static inline size_t if_nlmsg_size(void)
-+static inline size_t if_nlmsg_size(const struct net_device *dev)
++static struct pernet_operations dev_mc_net_ops = {
++ .init = dev_mc_net_init,
++ .exit = dev_mc_net_exit,
++};
++
+ void __init dev_mcast_init(void)
{
- return NLMSG_ALIGN(sizeof(struct ifinfomsg))
- + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
-@@ -452,7 +602,8 @@
- + nla_total_size(4) /* IFLA_LINK */
- + nla_total_size(4) /* IFLA_MASTER */
- + nla_total_size(1) /* IFLA_OPERSTATE */
-- + nla_total_size(1); /* IFLA_LINKMODE */
-+ + nla_total_size(1) /* IFLA_LINKMODE */
-+ + rtnl_link_get_size(dev); /* IFLA_LINKINFO */
+- proc_net_fops_create("dev_mcast", 0, &dev_mc_seq_fops);
++ register_pernet_subsys(&dev_mc_net_ops);
}
- static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
-@@ -522,6 +673,11 @@
+ EXPORT_SYMBOL(dev_mc_add);
+diff -Nurb linux-2.6.22-570/net/core/dst.c linux-2.6.22-590/net/core/dst.c
+--- linux-2.6.22-570/net/core/dst.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/core/dst.c 2008-01-29 22:12:32.000000000 -0500
+@@ -15,7 +15,9 @@
+ #include <linux/skbuff.h>
+ #include <linux/string.h>
+ #include <linux/types.h>
++#include <net/net_namespace.h>
+
++#include <net/net_namespace.h>
+ #include <net/dst.h>
+
+ /* Locking strategy:
+@@ -236,13 +238,14 @@
+ if (!unregister) {
+ dst->input = dst->output = dst_discard;
+ } else {
+- dst->dev = &loopback_dev;
+- dev_hold(&loopback_dev);
++ struct net *net = dev->nd_net;
++ dst->dev = &net->loopback_dev;
++ dev_hold(dst->dev);
+ dev_put(dev);
+ if (dst->neighbour && dst->neighbour->dev == dev) {
+- dst->neighbour->dev = &loopback_dev;
++ dst->neighbour->dev = &net->loopback_dev;
+ dev_put(dev);
+- dev_hold(&loopback_dev);
++ dev_hold(dst->neighbour->dev);
}
}
+ }
+@@ -252,6 +255,9 @@
+ struct net_device *dev = ptr;
+ struct dst_entry *dst;
-+ if (dev->rtnl_link_ops) {
-+ if (rtnl_link_fill(skb, dev) < 0)
-+ goto nla_put_failure;
-+ }
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
+
- return nlmsg_end(skb, nlh);
+ switch (event) {
+ case NETDEV_UNREGISTER:
+ case NETDEV_DOWN:
+diff -Nurb linux-2.6.22-570/net/core/ethtool.c linux-2.6.22-590/net/core/ethtool.c
+--- linux-2.6.22-570/net/core/ethtool.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/core/ethtool.c 2008-01-29 22:12:32.000000000 -0500
+@@ -798,9 +798,9 @@
- nla_put_failure:
-@@ -555,6 +711,8 @@
+ /* The main entry point in this file. Called from net/core/dev.c */
- static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
- [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 },
-+ [IFLA_ADDRESS] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
-+ [IFLA_BROADCAST] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
- [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) },
- [IFLA_MTU] = { .type = NLA_U32 },
- [IFLA_TXQLEN] = { .type = NLA_U32 },
-@@ -563,44 +721,16 @@
- [IFLA_LINKMODE] = { .type = NLA_U8 },
- };
+-int dev_ethtool(struct ifreq *ifr)
++int dev_ethtool(struct net *net, struct ifreq *ifr)
+ {
+- struct net_device *dev = __dev_get_by_name(ifr->ifr_name);
++ struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name);
+ void __user *useraddr = ifr->ifr_data;
+ u32 ethcmd;
+ int rc;
+diff -Nurb linux-2.6.22-570/net/core/fib_rules.c linux-2.6.22-590/net/core/fib_rules.c
+--- linux-2.6.22-570/net/core/fib_rules.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/core/fib_rules.c 2008-01-29 22:12:32.000000000 -0500
+@@ -11,21 +11,20 @@
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/list.h>
++#include <net/net_namespace.h>
++#include <net/sock.h>
+ #include <net/fib_rules.h>
--static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
--{
-- struct ifinfomsg *ifm;
-- struct net_device *dev;
-- int err, send_addr_notify = 0, modified = 0;
-- struct nlattr *tb[IFLA_MAX+1];
-- char ifname[IFNAMSIZ];
--
-- err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
-- if (err < 0)
-- goto errout;
--
-- if (tb[IFLA_IFNAME])
-- nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
-- else
-- ifname[0] = '\0';
--
-- err = -EINVAL;
-- ifm = nlmsg_data(nlh);
-- if (ifm->ifi_index > 0)
-- dev = dev_get_by_index(ifm->ifi_index);
-- else if (tb[IFLA_IFNAME])
-- dev = dev_get_by_name(ifname);
-- else
-- goto errout;
+-static LIST_HEAD(rules_ops);
+-static DEFINE_SPINLOCK(rules_mod_lock);
-
-- if (dev == NULL) {
-- err = -ENODEV;
-- goto errout;
-- }
--
-- if (tb[IFLA_ADDRESS] &&
-- nla_len(tb[IFLA_ADDRESS]) < dev->addr_len)
-- goto errout_dev;
-+static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
-+ [IFLA_INFO_KIND] = { .type = NLA_STRING },
-+ [IFLA_INFO_DATA] = { .type = NLA_NESTED },
-+};
+-static void notify_rule_change(int event, struct fib_rule *rule,
++static void notify_rule_change(struct net *net, int event, struct fib_rule *rule,
+ struct fib_rules_ops *ops, struct nlmsghdr *nlh,
+ u32 pid);
-- if (tb[IFLA_BROADCAST] &&
-- nla_len(tb[IFLA_BROADCAST]) < dev->addr_len)
-- goto errout_dev;
-+static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
-+ struct nlattr **tb, char *ifname, int modified)
-+{
-+ int send_addr_notify = 0;
-+ int err;
+-static struct fib_rules_ops *lookup_rules_ops(int family)
++static struct fib_rules_ops *lookup_rules_ops(struct net *net, int family)
+ {
+ struct fib_rules_ops *ops;
- if (tb[IFLA_MAP]) {
- struct rtnl_link_ifmap *u_map;
-@@ -608,12 +738,12 @@
+ rcu_read_lock();
+- list_for_each_entry_rcu(ops, &rules_ops, list) {
++ list_for_each_entry_rcu(ops, &net->rules_ops, list) {
+ if (ops->family == family) {
+ if (!try_module_get(ops->owner))
+ ops = NULL;
+@@ -47,10 +46,10 @@
+ static void flush_route_cache(struct fib_rules_ops *ops)
+ {
+ if (ops->flush_cache)
+- ops->flush_cache();
++ ops->flush_cache(ops);
+ }
+
+-int fib_rules_register(struct fib_rules_ops *ops)
++int fib_rules_register(struct net *net, struct fib_rules_ops *ops)
+ {
+ int err = -EEXIST;
+ struct fib_rules_ops *o;
+@@ -63,15 +62,16 @@
+ ops->action == NULL)
+ return -EINVAL;
- if (!dev->set_config) {
- err = -EOPNOTSUPP;
-- goto errout_dev;
-+ goto errout;
- }
+- spin_lock(&rules_mod_lock);
+- list_for_each_entry(o, &rules_ops, list)
++ spin_lock(&net->rules_mod_lock);
++ list_for_each_entry(o, &net->rules_ops, list)
+ if (ops->family == o->family)
+ goto errout;
- if (!netif_device_present(dev)) {
- err = -ENODEV;
-- goto errout_dev;
-+ goto errout;
- }
+- list_add_tail_rcu(&ops->list, &rules_ops);
++ hold_net(net);
++ list_add_tail_rcu(&ops->list, &net->rules_ops);
+ err = 0;
+ errout:
+- spin_unlock(&rules_mod_lock);
++ spin_unlock(&net->rules_mod_lock);
- u_map = nla_data(tb[IFLA_MAP]);
-@@ -626,7 +756,7 @@
+ return err;
+ }
+@@ -88,13 +88,13 @@
+ }
+ }
- err = dev->set_config(dev, &k_map);
- if (err < 0)
-- goto errout_dev;
-+ goto errout;
+-int fib_rules_unregister(struct fib_rules_ops *ops)
++int fib_rules_unregister(struct net *net, struct fib_rules_ops *ops)
+ {
+ int err = 0;
+ struct fib_rules_ops *o;
+
+- spin_lock(&rules_mod_lock);
+- list_for_each_entry(o, &rules_ops, list) {
++ spin_lock(&net->rules_mod_lock);
++ list_for_each_entry(o, &net->rules_ops, list) {
+ if (o == ops) {
+ list_del_rcu(&o->list);
+ cleanup_ops(ops);
+@@ -104,9 +104,11 @@
+
+ err = -ENOENT;
+ out:
+- spin_unlock(&rules_mod_lock);
++ spin_unlock(&net->rules_mod_lock);
- modified = 1;
+ synchronize_rcu();
++ if (!err)
++ release_net(net);
+
+ return err;
+ }
+@@ -197,6 +199,7 @@
+
+ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct fib_rule_hdr *frh = nlmsg_data(nlh);
+ struct fib_rules_ops *ops = NULL;
+ struct fib_rule *rule, *r, *last = NULL;
+@@ -206,7 +209,7 @@
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh)))
+ goto errout;
+
+- ops = lookup_rules_ops(frh->family);
++ ops = lookup_rules_ops(net, frh->family);
+ if (ops == NULL) {
+ err = EAFNOSUPPORT;
+ goto errout;
+@@ -234,7 +237,7 @@
+
+ rule->ifindex = -1;
+ nla_strlcpy(rule->ifname, tb[FRA_IFNAME], IFNAMSIZ);
+- dev = __dev_get_by_name(rule->ifname);
++ dev = __dev_get_by_name(net, rule->ifname);
+ if (dev)
+ rule->ifindex = dev->ifindex;
}
-@@ -637,19 +767,19 @@
+@@ -256,7 +259,7 @@
+ rule->table = frh_get_table(frh, tb);
- if (!dev->set_mac_address) {
- err = -EOPNOTSUPP;
-- goto errout_dev;
-+ goto errout;
- }
+ if (!rule->pref && ops->default_pref)
+- rule->pref = ops->default_pref();
++ rule->pref = ops->default_pref(ops);
- if (!netif_device_present(dev)) {
- err = -ENODEV;
-- goto errout_dev;
-+ goto errout;
- }
+ err = -EINVAL;
+ if (tb[FRA_GOTO]) {
+@@ -319,7 +322,7 @@
+ else
+ list_add_rcu(&rule->list, ops->rules_list);
- len = sizeof(sa_family_t) + dev->addr_len;
- sa = kmalloc(len, GFP_KERNEL);
- if (!sa) {
- err = -ENOMEM;
-- goto errout_dev;
-+ goto errout;
+- notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).pid);
++ notify_rule_change(net, RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).pid);
+ flush_route_cache(ops);
+ rules_ops_put(ops);
+ return 0;
+@@ -333,6 +336,7 @@
+
+ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct fib_rule_hdr *frh = nlmsg_data(nlh);
+ struct fib_rules_ops *ops = NULL;
+ struct fib_rule *rule, *tmp;
+@@ -342,7 +346,7 @@
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh)))
+ goto errout;
+
+- ops = lookup_rules_ops(frh->family);
++ ops = lookup_rules_ops(net, frh->family);
+ if (ops == NULL) {
+ err = EAFNOSUPPORT;
+ goto errout;
+@@ -408,7 +412,7 @@
}
- sa->sa_family = dev->type;
- memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]),
-@@ -657,7 +787,7 @@
- err = dev->set_mac_address(dev, sa);
- kfree(sa);
+
+ synchronize_rcu();
+- notify_rule_change(RTM_DELRULE, rule, ops, nlh,
++ notify_rule_change(net, RTM_DELRULE, rule, ops, nlh,
+ NETLINK_CB(skb).pid);
+ fib_rule_put(rule);
+ flush_route_cache(ops);
+@@ -514,13 +518,17 @@
+
+ static int fib_nl_dumprule(struct sk_buff *skb, struct netlink_callback *cb)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct fib_rules_ops *ops;
+ int idx = 0, family;
+
++ if (net != &init_net)
++ return -EINVAL;
++
+ family = rtnl_msg_family(cb->nlh);
+ if (family != AF_UNSPEC) {
+ /* Protocol specific dump request */
+- ops = lookup_rules_ops(family);
++ ops = lookup_rules_ops(net, family);
+ if (ops == NULL)
+ return -EAFNOSUPPORT;
+
+@@ -528,7 +536,7 @@
+ }
+
+ rcu_read_lock();
+- list_for_each_entry_rcu(ops, &rules_ops, list) {
++ list_for_each_entry_rcu(ops, &net->rules_ops, list) {
+ if (idx < cb->args[0] || !try_module_get(ops->owner))
+ goto skip;
+
+@@ -545,7 +553,7 @@
+ return skb->len;
+ }
+
+-static void notify_rule_change(int event, struct fib_rule *rule,
++static void notify_rule_change(struct net *net, int event, struct fib_rule *rule,
+ struct fib_rules_ops *ops, struct nlmsghdr *nlh,
+ u32 pid)
+ {
+@@ -563,10 +571,10 @@
+ kfree_skb(skb);
+ goto errout;
+ }
+- err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL);
++ err = rtnl_notify(skb, net, pid, ops->nlgroup, nlh, GFP_KERNEL);
+ errout:
+ if (err < 0)
+- rtnl_set_sk_err(ops->nlgroup, err);
++ rtnl_set_sk_err(net, ops->nlgroup, err);
+ }
+
+ static void attach_rules(struct list_head *rules, struct net_device *dev)
+@@ -594,19 +602,23 @@
+ void *ptr)
+ {
+ struct net_device *dev = ptr;
++ struct net *net = dev->nd_net;
+ struct fib_rules_ops *ops;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ ASSERT_RTNL();
+ rcu_read_lock();
+
+ switch (event) {
+ case NETDEV_REGISTER:
+- list_for_each_entry(ops, &rules_ops, list)
++ list_for_each_entry(ops, &net->rules_ops, list)
+ attach_rules(ops->rules_list, dev);
+ break;
+
+ case NETDEV_UNREGISTER:
+- list_for_each_entry(ops, &rules_ops, list)
++ list_for_each_entry(ops, &net->rules_ops, list)
+ detach_rules(ops->rules_list, dev);
+ break;
+ }
+@@ -620,13 +632,28 @@
+ .notifier_call = fib_rules_event,
+ };
+
++static int fib_rules_net_init(struct net *net)
++{
++ INIT_LIST_HEAD(&net->rules_ops);
++ spin_lock_init(&net->rules_mod_lock);
++ return 0;
++}
++
++static struct pernet_operations fib_rules_net_ops = {
++ .init = fib_rules_net_init,
++};
++
+ static int __init fib_rules_init(void)
+ {
++ int ret;
+ rtnl_register(PF_UNSPEC, RTM_NEWRULE, fib_nl_newrule, NULL);
+ rtnl_register(PF_UNSPEC, RTM_DELRULE, fib_nl_delrule, NULL);
+ rtnl_register(PF_UNSPEC, RTM_GETRULE, NULL, fib_nl_dumprule);
+
+- return register_netdevice_notifier(&fib_rules_notifier);
++ ret = register_pernet_subsys(&fib_rules_net_ops);
++ if (!ret)
++ ret = register_netdevice_notifier(&fib_rules_notifier);
++ return ret;
+ }
+
+ subsys_initcall(fib_rules_init);
+diff -Nurb linux-2.6.22-570/net/core/neighbour.c linux-2.6.22-590/net/core/neighbour.c
+--- linux-2.6.22-570/net/core/neighbour.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/core/neighbour.c 2008-01-29 22:12:32.000000000 -0500
+@@ -33,6 +33,7 @@
+ #include <linux/rtnetlink.h>
+ #include <linux/random.h>
+ #include <linux/string.h>
++#include <net/net_namespace.h>
+
+ #define NEIGH_DEBUG 1
+
+@@ -361,7 +362,7 @@
+ return n;
+ }
+
+-struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, const void *pkey)
++struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net * net, const void *pkey)
+ {
+ struct neighbour *n;
+ int key_len = tbl->key_len;
+@@ -371,7 +372,8 @@
+
+ read_lock_bh(&tbl->lock);
+ for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) {
+- if (!memcmp(n->primary_key, pkey, key_len)) {
++ if (!memcmp(n->primary_key, pkey, key_len) &&
++ (net == n->dev->nd_net)) {
+ neigh_hold(n);
+ NEIGH_CACHE_STAT_INC(tbl, hits);
+ break;
+@@ -449,7 +451,8 @@
+ goto out;
+ }
+
+-struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, const void *pkey,
++struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl,
++ struct net * net, const void *pkey,
+ struct net_device *dev, int creat)
+ {
+ struct pneigh_entry *n;
+@@ -465,6 +468,7 @@
+
+ for (n = tbl->phash_buckets[hash_val]; n; n = n->next) {
+ if (!memcmp(n->key, pkey, key_len) &&
++ (n->net == net) &&
+ (n->dev == dev || !n->dev)) {
+ read_unlock_bh(&tbl->lock);
+ goto out;
+@@ -479,6 +483,7 @@
+ if (!n)
+ goto out;
+
++ n->net = hold_net(net);
+ memcpy(n->key, pkey, key_len);
+ n->dev = dev;
+ if (dev)
+@@ -501,7 +506,7 @@
+ }
+
+
+-int pneigh_delete(struct neigh_table *tbl, const void *pkey,
++int pneigh_delete(struct neigh_table *tbl, struct net * net, const void *pkey,
+ struct net_device *dev)
+ {
+ struct pneigh_entry *n, **np;
+@@ -516,13 +521,15 @@
+ write_lock_bh(&tbl->lock);
+ for (np = &tbl->phash_buckets[hash_val]; (n = *np) != NULL;
+ np = &n->next) {
+- if (!memcmp(n->key, pkey, key_len) && n->dev == dev) {
++ if (!memcmp(n->key, pkey, key_len) && n->dev == dev &&
++ (n->net == net)) {
+ *np = n->next;
+ write_unlock_bh(&tbl->lock);
+ if (tbl->pdestructor)
+ tbl->pdestructor(n);
+ if (n->dev)
+ dev_put(n->dev);
++ release_net(n->net);
+ kfree(n);
+ return 0;
+ }
+@@ -545,6 +552,7 @@
+ tbl->pdestructor(n);
+ if (n->dev)
+ dev_put(n->dev);
++ release_net(n->net);
+ kfree(n);
+ continue;
+ }
+@@ -1266,12 +1274,37 @@
+ spin_unlock(&tbl->proxy_queue.lock);
+ }
+
++static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
++ struct net * net, int ifindex)
++{
++ struct neigh_parms *p;
++
++ for (p = &tbl->parms; p; p = p->next) {
++ if (p->net != net)
++ continue;
++ if ((p->dev && p->dev->ifindex == ifindex) ||
++ (!p->dev && !ifindex))
++ return p;
++ }
++
++ return NULL;
++}
+
+ struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
+ struct neigh_table *tbl)
+ {
+- struct neigh_parms *p = kmemdup(&tbl->parms, sizeof(*p), GFP_KERNEL);
++ struct neigh_parms *p, *ref;
++ struct net * net;
++
++ net = &init_net;
++ if (dev)
++ net = dev->nd_net;
++
++ ref = lookup_neigh_params(tbl, net, 0);
++ if (!ref)
++ return NULL;
+
++ p = kmemdup(ref, sizeof(*p), GFP_KERNEL);
+ if (p) {
+ p->tbl = tbl;
+ atomic_set(&p->refcnt, 1);
+@@ -1287,6 +1320,7 @@
+ dev_hold(dev);
+ p->dev = dev;
+ }
++ p->net = hold_net(net);
+ p->sysctl_table = NULL;
+ write_lock_bh(&tbl->lock);
+ p->next = tbl->parms.next;
+@@ -1296,6 +1330,20 @@
+ return p;
+ }
+
++struct neigh_parms *neigh_parms_alloc_default(struct neigh_table *tbl,
++ struct net *net)
++{
++ struct neigh_parms *parms;
++ if (net != &init_net) {
++ parms = neigh_parms_alloc(NULL, tbl);
++ release_net(parms->net);
++ parms->net = hold_net(net);
++ }
++ else
++ parms = neigh_parms_clone(&tbl->parms);
++ return parms;
++}
++
+ static void neigh_rcu_free_parms(struct rcu_head *head)
+ {
+ struct neigh_parms *parms =
+@@ -1328,6 +1376,7 @@
+
+ void neigh_parms_destroy(struct neigh_parms *parms)
+ {
++ release_net(parms->net);
+ kfree(parms);
+ }
+
+@@ -1338,6 +1387,7 @@
+ unsigned long now = jiffies;
+ unsigned long phsize;
+
++ tbl->parms.net = &init_net;
+ atomic_set(&tbl->parms.refcnt, 1);
+ INIT_RCU_HEAD(&tbl->parms.rcu_head);
+ tbl->parms.reachable_time =
+@@ -1353,7 +1403,7 @@
+ panic("cannot create neighbour cache statistics");
+
+ #ifdef CONFIG_PROC_FS
+- tbl->pde = create_proc_entry(tbl->id, 0, proc_net_stat);
++ tbl->pde = create_proc_entry(tbl->id, 0, init_net.proc_net_stat);
+ if (!tbl->pde)
+ panic("cannot create neighbour proc dir entry");
+ tbl->pde->proc_fops = &neigh_stat_seq_fops;
+@@ -1443,6 +1493,7 @@
+
+ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct ndmsg *ndm;
+ struct nlattr *dst_attr;
+ struct neigh_table *tbl;
+@@ -1458,7 +1509,7 @@
+
+ ndm = nlmsg_data(nlh);
+ if (ndm->ndm_ifindex) {
+- dev = dev_get_by_index(ndm->ndm_ifindex);
++ dev = dev_get_by_index(net, ndm->ndm_ifindex);
+ if (dev == NULL) {
+ err = -ENODEV;
+ goto out;
+@@ -1477,7 +1528,7 @@
+ goto out_dev_put;
+
+ if (ndm->ndm_flags & NTF_PROXY) {
+- err = pneigh_delete(tbl, nla_data(dst_attr), dev);
++ err = pneigh_delete(tbl, net, nla_data(dst_attr), dev);
+ goto out_dev_put;
+ }
+
+@@ -1508,6 +1559,7 @@
+
+ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct ndmsg *ndm;
+ struct nlattr *tb[NDA_MAX+1];
+ struct neigh_table *tbl;
+@@ -1524,7 +1576,7 @@
+
+ ndm = nlmsg_data(nlh);
+ if (ndm->ndm_ifindex) {
+- dev = dev_get_by_index(ndm->ndm_ifindex);
++ dev = dev_get_by_index(net, ndm->ndm_ifindex);
+ if (dev == NULL) {
+ err = -ENODEV;
+ goto out;
+@@ -1553,7 +1605,7 @@
+ struct pneigh_entry *pn;
+
+ err = -ENOBUFS;
+- pn = pneigh_lookup(tbl, dst, dev, 1);
++ pn = pneigh_lookup(tbl, net, dst, dev, 1);
+ if (pn) {
+ pn->flags = ndm->ndm_flags;
+ err = 0;
+@@ -1748,19 +1800,6 @@
+ return -EMSGSIZE;
+ }
+
+-static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
+- int ifindex)
+-{
+- struct neigh_parms *p;
+-
+- for (p = &tbl->parms; p; p = p->next)
+- if ((p->dev && p->dev->ifindex == ifindex) ||
+- (!p->dev && !ifindex))
+- return p;
+-
+- return NULL;
+-}
+-
+ static const struct nla_policy nl_neightbl_policy[NDTA_MAX+1] = {
+ [NDTA_NAME] = { .type = NLA_STRING },
+ [NDTA_THRESH1] = { .type = NLA_U32 },
+@@ -1788,6 +1827,7 @@
+
+ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct neigh_table *tbl;
+ struct ndtmsg *ndtmsg;
+ struct nlattr *tb[NDTA_MAX+1];
+@@ -1837,7 +1877,7 @@
+ if (tbp[NDTPA_IFINDEX])
+ ifindex = nla_get_u32(tbp[NDTPA_IFINDEX]);
+
+- p = lookup_neigh_params(tbl, ifindex);
++ p = lookup_neigh_params(tbl, net, ifindex);
+ if (p == NULL) {
+ err = -ENOENT;
+ goto errout_tbl_lock;
+@@ -1912,6 +1952,7 @@
+
+ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
+ {
++ struct net *net = skb->sk->sk_net;
+ int family, tidx, nidx = 0;
+ int tbl_skip = cb->args[0];
+ int neigh_skip = cb->args[1];
+@@ -1931,8 +1972,11 @@
+ NLM_F_MULTI) <= 0)
+ break;
+
+- for (nidx = 0, p = tbl->parms.next; p; p = p->next, nidx++) {
+- if (nidx < neigh_skip)
++ for (nidx = 0, p = tbl->parms.next; p; p = p->next) {
++ if (net != p->net)
++ continue;
++
++ if (nidx++ < neigh_skip)
+ continue;
+
+ if (neightbl_fill_param_info(skb, tbl, p,
+@@ -2003,6 +2047,7 @@
+ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
+ struct netlink_callback *cb)
+ {
++ struct net * net = skb->sk->sk_net;
+ struct neighbour *n;
+ int rc, h, s_h = cb->args[1];
+ int idx, s_idx = idx = cb->args[2];
+@@ -2013,8 +2058,12 @@
+ continue;
+ if (h > s_h)
+ s_idx = 0;
+- for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next, idx++) {
+- if (idx < s_idx)
++ for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next) {
++ int lidx;
++ if (n->dev->nd_net != net)
++ continue;
++ lidx = idx++;
++ if (lidx < s_idx)
+ continue;
+ if (neigh_fill_info(skb, n, NETLINK_CB(cb->skb).pid,
+ cb->nlh->nlmsg_seq,
+@@ -2109,6 +2158,7 @@
+ static struct neighbour *neigh_get_first(struct seq_file *seq)
+ {
+ struct neigh_seq_state *state = seq->private;
++ struct net * net = state->net;
+ struct neigh_table *tbl = state->tbl;
+ struct neighbour *n = NULL;
+ int bucket = state->bucket;
+@@ -2118,6 +2168,8 @@
+ n = tbl->hash_buckets[bucket];
+
+ while (n) {
++ if (n->dev->nd_net != net)
++ goto next;
+ if (state->neigh_sub_iter) {
+ loff_t fakep = 0;
+ void *v;
+@@ -2147,6 +2199,7 @@
+ loff_t *pos)
+ {
+ struct neigh_seq_state *state = seq->private;
++ struct net * net = state->net;
+ struct neigh_table *tbl = state->tbl;
+
+ if (state->neigh_sub_iter) {
+@@ -2158,6 +2211,8 @@
+
+ while (1) {
+ while (n) {
++ if (n->dev->nd_net != net)
++ goto next;
+ if (state->neigh_sub_iter) {
+ void *v = state->neigh_sub_iter(state, n, pos);
+ if (v)
+@@ -2204,6 +2259,7 @@
+ static struct pneigh_entry *pneigh_get_first(struct seq_file *seq)
+ {
+ struct neigh_seq_state *state = seq->private;
++ struct net * net = state->net;
+ struct neigh_table *tbl = state->tbl;
+ struct pneigh_entry *pn = NULL;
+ int bucket = state->bucket;
+@@ -2211,6 +2267,8 @@
+ state->flags |= NEIGH_SEQ_IS_PNEIGH;
+ for (bucket = 0; bucket <= PNEIGH_HASHMASK; bucket++) {
+ pn = tbl->phash_buckets[bucket];
++ while (pn && (pn->net != net))
++ pn = pn->next;
+ if (pn)
+ break;
+ }
+@@ -2224,6 +2282,7 @@
+ loff_t *pos)
+ {
+ struct neigh_seq_state *state = seq->private;
++ struct net * net = state->net;
+ struct neigh_table *tbl = state->tbl;
+
+ pn = pn->next;
+@@ -2231,6 +2290,8 @@
+ if (++state->bucket > PNEIGH_HASHMASK)
+ break;
+ pn = tbl->phash_buckets[state->bucket];
++ while (pn && (pn->net != net))
++ pn = pn->next;
+ if (pn)
+ break;
+ }
+@@ -2433,6 +2494,7 @@
+
+ static void __neigh_notify(struct neighbour *n, int type, int flags)
+ {
++ struct net * net = n->dev->nd_net;
+ struct sk_buff *skb;
+ int err = -ENOBUFS;
+
+@@ -2447,10 +2509,10 @@
+ kfree_skb(skb);
+ goto errout;
+ }
+- err = rtnl_notify(skb, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
++ err = rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
+ errout:
+ if (err < 0)
+- rtnl_set_sk_err(RTNLGRP_NEIGH, err);
++ rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
+ }
+
+ void neigh_app_ns(struct neighbour *n)
+@@ -2648,6 +2710,7 @@
+
+ if (!t)
+ return -ENOBUFS;
++
+ t->neigh_vars[0].data = &p->mcast_probes;
+ t->neigh_vars[1].data = &p->ucast_probes;
+ t->neigh_vars[2].data = &p->app_probes;
+@@ -2716,7 +2779,7 @@
+ t->neigh_proto_dir[0].child = t->neigh_neigh_dir;
+ t->neigh_root_dir[0].child = t->neigh_proto_dir;
+
+- t->sysctl_header = register_sysctl_table(t->neigh_root_dir);
++ t->sysctl_header = register_net_sysctl_table(p->net, t->neigh_root_dir);
+ if (!t->sysctl_header) {
+ err = -ENOBUFS;
+ goto free_procname;
+@@ -2738,7 +2801,7 @@
+ if (p->sysctl_table) {
+ struct neigh_sysctl_table *t = p->sysctl_table;
+ p->sysctl_table = NULL;
+- unregister_sysctl_table(t->sysctl_header);
++ unregister_net_sysctl_table(t->sysctl_header);
+ kfree(t->neigh_dev[0].procname);
+ kfree(t);
+ }
+@@ -2771,6 +2834,7 @@
+ EXPORT_SYMBOL(neigh_lookup);
+ EXPORT_SYMBOL(neigh_lookup_nodev);
+ EXPORT_SYMBOL(neigh_parms_alloc);
++EXPORT_SYMBOL(neigh_parms_alloc_default);
+ EXPORT_SYMBOL(neigh_parms_release);
+ EXPORT_SYMBOL(neigh_rand_reach_time);
+ EXPORT_SYMBOL(neigh_resolve_output);
+diff -Nurb linux-2.6.22-570/net/core/net-sysfs.c linux-2.6.22-590/net/core/net-sysfs.c
+--- linux-2.6.22-570/net/core/net-sysfs.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/core/net-sysfs.c 2008-01-29 22:12:32.000000000 -0500
+@@ -13,7 +13,9 @@
+ #include <linux/kernel.h>
+ #include <linux/netdevice.h>
+ #include <linux/if_arp.h>
++#include <linux/nsproxy.h>
+ #include <net/sock.h>
++#include <net/net_namespace.h>
+ #include <linux/rtnetlink.h>
+ #include <linux/wireless.h>
+ #include <net/iw_handler.h>
+@@ -29,16 +31,16 @@
+ }
+
+ /* use same locking rules as GIF* ioctl's */
+-static ssize_t netdev_show(const struct device *dev,
++static ssize_t netdev_show(const struct device *device,
+ struct device_attribute *attr, char *buf,
+ ssize_t (*format)(const struct net_device *, char *))
+ {
+- struct net_device *net = to_net_dev(dev);
++ struct net_device *dev = to_net_dev(device);
+ ssize_t ret = -EINVAL;
+
+ read_lock(&dev_base_lock);
+- if (dev_isalive(net))
+- ret = (*format)(net, buf);
++ if (dev_isalive(dev))
++ ret = (*format)(dev, buf);
+ read_unlock(&dev_base_lock);
+
+ return ret;
+@@ -46,9 +48,9 @@
+
+ /* generate a show function for simple field */
+ #define NETDEVICE_SHOW(field, format_string) \
+-static ssize_t format_##field(const struct net_device *net, char *buf) \
++static ssize_t format_##field(const struct net_device *dev, char *buf) \
+ { \
+- return sprintf(buf, format_string, net->field); \
++ return sprintf(buf, format_string, dev->field); \
+ } \
+ static ssize_t show_##field(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+@@ -58,11 +60,11 @@
+
+
+ /* use same locking and permission rules as SIF* ioctl's */
+-static ssize_t netdev_store(struct device *dev, struct device_attribute *attr,
++static ssize_t netdev_store(struct device *device, struct device_attribute *attr,
+ const char *buf, size_t len,
+ int (*set)(struct net_device *, unsigned long))
+ {
+- struct net_device *net = to_net_dev(dev);
++ struct net_device *dev = to_net_dev(device);
+ char *endp;
+ unsigned long new;
+ int ret = -EINVAL;
+@@ -75,8 +77,8 @@
+ goto err;
+
+ rtnl_lock();
+- if (dev_isalive(net)) {
+- if ((ret = (*set)(net, new)) == 0)
++ if (dev_isalive(dev)) {
++ if ((ret = (*set)(dev, new)) == 0)
+ ret = len;
+ }
+ rtnl_unlock();
+@@ -103,45 +105,45 @@
+ return cp - buf;
+ }
+
+-static ssize_t show_address(struct device *dev, struct device_attribute *attr,
++static ssize_t show_address(struct device *device, struct device_attribute *attr,
+ char *buf)
+ {
+- struct net_device *net = to_net_dev(dev);
++ struct net_device *dev = to_net_dev(device);
+ ssize_t ret = -EINVAL;
+
+ read_lock(&dev_base_lock);
+- if (dev_isalive(net))
+- ret = format_addr(buf, net->dev_addr, net->addr_len);
++ if (dev_isalive(dev))
++ ret = format_addr(buf, dev->dev_addr, dev->addr_len);
+ read_unlock(&dev_base_lock);
+ return ret;
+ }
+
+-static ssize_t show_broadcast(struct device *dev,
++static ssize_t show_broadcast(struct device *device,
+ struct device_attribute *attr, char *buf)
+ {
+- struct net_device *net = to_net_dev(dev);
+- if (dev_isalive(net))
+- return format_addr(buf, net->broadcast, net->addr_len);
++ struct net_device *dev = to_net_dev(device);
++ if (dev_isalive(dev))
++ return format_addr(buf, dev->broadcast, dev->addr_len);
+ return -EINVAL;
+ }
+
+-static ssize_t show_carrier(struct device *dev,
++static ssize_t show_carrier(struct device *device,
+ struct device_attribute *attr, char *buf)
+ {
+- struct net_device *netdev = to_net_dev(dev);
+- if (netif_running(netdev)) {
+- return sprintf(buf, fmt_dec, !!netif_carrier_ok(netdev));
++ struct net_device *dev = to_net_dev(device);
++ if (netif_running(dev)) {
++ return sprintf(buf, fmt_dec, !!netif_carrier_ok(dev));
+ }
+ return -EINVAL;
+ }
+
+-static ssize_t show_dormant(struct device *dev,
++static ssize_t show_dormant(struct device *device,
+ struct device_attribute *attr, char *buf)
+ {
+- struct net_device *netdev = to_net_dev(dev);
++ struct net_device *dev = to_net_dev(device);
+
+- if (netif_running(netdev))
+- return sprintf(buf, fmt_dec, !!netif_dormant(netdev));
++ if (netif_running(dev))
++ return sprintf(buf, fmt_dec, !!netif_dormant(dev));
+
+ return -EINVAL;
+ }
+@@ -156,15 +158,15 @@
+ "up"
+ };
+
+-static ssize_t show_operstate(struct device *dev,
++static ssize_t show_operstate(struct device *device,
+ struct device_attribute *attr, char *buf)
+ {
+- const struct net_device *netdev = to_net_dev(dev);
++ const struct net_device *dev = to_net_dev(device);
+ unsigned char operstate;
+
+ read_lock(&dev_base_lock);
+- operstate = netdev->operstate;
+- if (!netif_running(netdev))
++ operstate = dev->operstate;
++ if (!netif_running(dev))
+ operstate = IF_OPER_DOWN;
+ read_unlock(&dev_base_lock);
+
+@@ -177,57 +179,57 @@
+ /* read-write attributes */
+ NETDEVICE_SHOW(mtu, fmt_dec);
+
+-static int change_mtu(struct net_device *net, unsigned long new_mtu)
++static int change_mtu(struct net_device *dev, unsigned long new_mtu)
+ {
+- return dev_set_mtu(net, (int) new_mtu);
++ return dev_set_mtu(dev, (int) new_mtu);
+ }
+
+-static ssize_t store_mtu(struct device *dev, struct device_attribute *attr,
++static ssize_t store_mtu(struct device *device, struct device_attribute *attr,
+ const char *buf, size_t len)
+ {
+- return netdev_store(dev, attr, buf, len, change_mtu);
++ return netdev_store(device, attr, buf, len, change_mtu);
+ }
+
+ NETDEVICE_SHOW(flags, fmt_hex);
+
+-static int change_flags(struct net_device *net, unsigned long new_flags)
++static int change_flags(struct net_device *dev, unsigned long new_flags)
+ {
+- return dev_change_flags(net, (unsigned) new_flags);
++ return dev_change_flags(dev, (unsigned) new_flags);
+ }
+
+-static ssize_t store_flags(struct device *dev, struct device_attribute *attr,
++static ssize_t store_flags(struct device *device, struct device_attribute *attr,
+ const char *buf, size_t len)
+ {
+- return netdev_store(dev, attr, buf, len, change_flags);
++ return netdev_store(device, attr, buf, len, change_flags);
+ }
+
+ NETDEVICE_SHOW(tx_queue_len, fmt_ulong);
+
+-static int change_tx_queue_len(struct net_device *net, unsigned long new_len)
++static int change_tx_queue_len(struct net_device *dev, unsigned long new_len)
+ {
+- net->tx_queue_len = new_len;
++ dev->tx_queue_len = new_len;
+ return 0;
+ }
+
+-static ssize_t store_tx_queue_len(struct device *dev,
++static ssize_t store_tx_queue_len(struct device *device,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+ {
+- return netdev_store(dev, attr, buf, len, change_tx_queue_len);
++ return netdev_store(device, attr, buf, len, change_tx_queue_len);
+ }
+
+ NETDEVICE_SHOW(weight, fmt_dec);
+
+-static int change_weight(struct net_device *net, unsigned long new_weight)
++static int change_weight(struct net_device *dev, unsigned long new_weight)
+ {
+- net->weight = new_weight;
++ dev->weight = new_weight;
+ return 0;
+ }
+
+-static ssize_t store_weight(struct device *dev, struct device_attribute *attr,
++static ssize_t store_weight(struct device *device, struct device_attribute *attr,
+ const char *buf, size_t len)
+ {
+- return netdev_store(dev, attr, buf, len, change_weight);
++ return netdev_store(device, attr, buf, len, change_weight);
+ }
+
+ static struct device_attribute net_class_attributes[] = {
+@@ -447,6 +449,23 @@
+ kfree((char *)dev - dev->padded);
+ }
+
++static const void *net_current_tag(void)
++{
++ return current->nsproxy->net_ns;
++}
++
++static const void *net_kobject_tag(struct kobject *kobj)
++{
++ struct net_device *dev;
++ dev = container_of(kobj, struct net_device, dev.kobj);
++ return dev->nd_net;
++}
++
++static const struct shadow_dir_operations net_shadow_dir_operations = {
++ .current_tag = net_current_tag,
++ .kobject_tag = net_kobject_tag,
++};
++
+ static struct class net_class = {
+ .name = "net",
+ .dev_release = netdev_release,
+@@ -454,42 +473,43 @@
+ #ifdef CONFIG_HOTPLUG
+ .dev_uevent = netdev_uevent,
+ #endif
++ .shadow_ops = &net_shadow_dir_operations,
+ };
+
+ /* Delete sysfs entries but hold kobject reference until after all
+ * netdev references are gone.
+ */
+-void netdev_unregister_sysfs(struct net_device * net)
++void netdev_unregister_sysfs(struct net_device * dev)
+ {
+- struct device *dev = &(net->dev);
++ struct device *device = &(dev->dev);
+
+- kobject_get(&dev->kobj);
+- device_del(dev);
++ kobject_get(&device->kobj);
++ device_del(device);
+ }
+
+ /* Create sysfs entries for network device. */
+-int netdev_register_sysfs(struct net_device *net)
++int netdev_register_sysfs(struct net_device *dev)
+ {
+- struct device *dev = &(net->dev);
+- struct attribute_group **groups = net->sysfs_groups;
++ struct device *device = &(dev->dev);
++ struct attribute_group **groups = dev->sysfs_groups;
+
+- device_initialize(dev);
+- dev->class = &net_class;
+- dev->platform_data = net;
+- dev->groups = groups;
++ device_initialize(device);
++ device->class = &net_class;
++ device->platform_data = dev;
++ device->groups = groups;
+
+ BUILD_BUG_ON(BUS_ID_SIZE < IFNAMSIZ);
+- strlcpy(dev->bus_id, net->name, BUS_ID_SIZE);
++ strlcpy(device->bus_id, dev->name, BUS_ID_SIZE);
+
+- if (net->get_stats)
++ if (dev->get_stats)
+ *groups++ = &netstat_group;
+
+ #ifdef CONFIG_WIRELESS_EXT
+- if (net->wireless_handlers && net->wireless_handlers->get_wireless_stats)
++ if (dev->wireless_handlers && dev->wireless_handlers->get_wireless_stats)
+ *groups++ = &wireless_group;
+ #endif
+
+- return device_add(dev);
++ return device_add(device);
+ }
+
+ int netdev_sysfs_init(void)
+diff -Nurb linux-2.6.22-570/net/core/net_namespace.c linux-2.6.22-590/net/core/net_namespace.c
+--- linux-2.6.22-570/net/core/net_namespace.c 1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.22-590/net/core/net_namespace.c 2008-01-29 22:12:32.000000000 -0500
+@@ -0,0 +1,332 @@
++#include <linux/workqueue.h>
++#include <linux/rtnetlink.h>
++#include <linux/cache.h>
++#include <linux/slab.h>
++#include <linux/list.h>
++#include <linux/delay.h>
++#include <net/net_namespace.h>
++
++/*
++ * Our network namespace constructor/destructor lists
++ */
++
++static LIST_HEAD(pernet_list);
++static struct list_head *first_device = &pernet_list;
++static DEFINE_MUTEX(net_mutex);
++
++static DEFINE_MUTEX(net_list_mutex);
++LIST_HEAD(net_namespace_list);
++
++static struct kmem_cache *net_cachep;
++
++struct net init_net;
++EXPORT_SYMBOL_GPL(init_net);
++
++void net_lock(void)
++{
++ mutex_lock(&net_list_mutex);
++}
++
++void net_unlock(void)
++{
++ mutex_unlock(&net_list_mutex);
++}
++
++static struct net *net_alloc(void)
++{
++ return kmem_cache_alloc(net_cachep, GFP_KERNEL);
++}
++
++static void net_free(struct net *net)
++{
++ if (!net)
++ return;
++
++ if (unlikely(atomic_read(&net->use_count) != 0)) {
++ printk(KERN_EMERG "network namespace not free! Usage: %d\n",
++ atomic_read(&net->use_count));
++ return;
++ }
++
++ kmem_cache_free(net_cachep, net);
++}
++
++static void cleanup_net(struct work_struct *work)
++{
++ struct pernet_operations *ops;
++ struct list_head *ptr;
++ struct net *net;
++
++ net = container_of(work, struct net, work);
++
++ mutex_lock(&net_mutex);
++
++ /* Don't let anyone else find us. */
++ net_lock();
++ list_del(&net->list);
++ net_unlock();
++
++ /* Run all of the network namespace exit methods */
++ list_for_each_prev(ptr, &pernet_list) {
++ ops = list_entry(ptr, struct pernet_operations, list);
++ if (ops->exit)
++ ops->exit(net);
++ }
++
++ mutex_unlock(&net_mutex);
++
++ /* Ensure there are no outstanding rcu callbacks using this
++ * network namespace.
++ */
++ rcu_barrier();
++
++ /* Finally it is safe to free my network namespace structure */
++ net_free(net);
++}
++
++
++void __put_net(struct net *net)
++{
++ /* Cleanup the network namespace in process context */
++ INIT_WORK(&net->work, cleanup_net);
++ schedule_work(&net->work);
++}
++EXPORT_SYMBOL_GPL(__put_net);
++
++/*
++ * setup_net runs the initializers for the network namespace object.
++ */
++static int setup_net(struct net *net)
++{
++ /* Must be called with net_mutex held */
++ struct pernet_operations *ops;
++ struct list_head *ptr;
++ int error;
++
++ memset(net, 0, sizeof(struct net));
++ atomic_set(&net->count, 1);
++ atomic_set(&net->use_count, 0);
++
++ error = 0;
++ list_for_each(ptr, &pernet_list) {
++ ops = list_entry(ptr, struct pernet_operations, list);
++ if (ops->init) {
++ error = ops->init(net);
++ if (error < 0)
++ goto out_undo;
++ }
++ }
++out:
++ return error;
++out_undo:
++ /* Walk through the list backwards calling the exit functions
++ * for the pernet modules whose init functions did not fail.
++ */
++ for (ptr = ptr->prev; ptr != &pernet_list; ptr = ptr->prev) {
++ ops = list_entry(ptr, struct pernet_operations, list);
++ if (ops->exit)
++ ops->exit(net);
++ }
++ goto out;
++}
++
++struct net *copy_net_ns(unsigned long flags, struct net *old_net)
++{
++ struct net *new_net = NULL;
++ int err;
++
++ get_net(old_net);
++
++ if (!(flags & CLONE_NEWNET))
++ return old_net;
++
++ err = -EPERM;
++ if (!capable(CAP_SYS_ADMIN))
++ goto out;
++
++ err = -ENOMEM;
++ new_net = net_alloc();
++ if (!new_net)
++ goto out;
++
++ mutex_lock(&net_mutex);
++ err = setup_net(new_net);
++ if (err)
++ goto out_unlock;
++
++ net_lock();
++ list_add_tail(&new_net->list, &net_namespace_list);
++ net_unlock();
++
++
++out_unlock:
++ mutex_unlock(&net_mutex);
++out:
++ put_net(old_net);
++ if (err) {
++ net_free(new_net);
++ new_net = ERR_PTR(err);
++ }
++ return new_net;
++}
++
++static int __init net_ns_init(void)
++{
++ int err;
++
++ printk(KERN_INFO "net_namespace: %zd bytes\n", sizeof(struct net));
++ net_cachep = kmem_cache_create("net_namespace", sizeof(struct net),
++ SMP_CACHE_BYTES,
++ SLAB_PANIC, NULL, NULL);
++ mutex_lock(&net_mutex);
++ err = setup_net(&init_net);
++
++ net_lock();
++ list_add_tail(&init_net.list, &net_namespace_list);
++ net_unlock();
++
++ mutex_unlock(&net_mutex);
++ if (err)
++ panic("Could not setup the initial network namespace");
++
++ return 0;
++}
++
++pure_initcall(net_ns_init);
++
++static int register_pernet_operations(struct list_head *list,
++ struct pernet_operations *ops)
++{
++ struct net *net, *undo_net;
++ int error;
++
++ error = 0;
++ list_add_tail(&ops->list, list);
++ for_each_net(net) {
++ if (ops->init) {
++ error = ops->init(net);
++ if (error)
++ goto out_undo;
++ }
++ }
++out:
++ return error;
++
++out_undo:
++ /* If I have an error cleanup all namespaces I initialized */
++ list_del(&ops->list);
++ for_each_net(undo_net) {
++ if (undo_net == net)
++ goto undone;
++ if (ops->exit)
++ ops->exit(undo_net);
++ }
++undone:
++ goto out;
++}
++
++static void unregister_pernet_operations(struct pernet_operations *ops)
++{
++ struct net *net;
++
++ list_del(&ops->list);
++ for_each_net(net)
++ if (ops->exit)
++ ops->exit(net);
++}
++
++/**
++ * register_pernet_subsys - register a network namespace subsystem
++ * @ops: pernet operations structure for the subsystem
++ *
++ * Register a subsystem which has init and exit functions
++ * that are called when network namespaces are created and
++ * destroyed respectively.
++ *
++ * When registered all network namespace init functions are
++ * called for every existing network namespace. Allowing kernel
++ * modules to have a race free view of the set of network namespaces.
++ *
++ * When a new network namespace is created all of the init
++ * methods are called in the order in which they were registered.
++ *
++ * When a network namespace is destroyed all of the exit methods
++ * are called in the reverse of the order with which they were
++ * registered.
++ */
++int register_pernet_subsys(struct pernet_operations *ops)
++{
++ int error;
++ mutex_lock(&net_mutex);
++ error = register_pernet_operations(first_device, ops);
++ mutex_unlock(&net_mutex);
++ return error;
++}
++EXPORT_SYMBOL_GPL(register_pernet_subsys);
++
++/**
++ * unregister_pernet_subsys - unregister a network namespace subsystem
++ * @ops: pernet operations structure to manipulate
++ *
++ * Remove the pernet operations structure from the list to be
++ * used when network namespaces are created or destoryed. In
++ * addition run the exit method for all existing network
++ * namespaces.
++ */
++void unregister_pernet_subsys(struct pernet_operations *module)
++{
++ mutex_lock(&net_mutex);
++ unregister_pernet_operations(module);
++ mutex_unlock(&net_mutex);
++}
++EXPORT_SYMBOL_GPL(unregister_pernet_subsys);
++
++/**
++ * register_pernet_device - register a network namespace device
++ * @ops: pernet operations structure for the subsystem
++ *
++ * Register a device which has init and exit functions
++ * that are called when network namespaces are created and
++ * destroyed respectively.
++ *
++ * When registered all network namespace init functions are
++ * called for every existing network namespace. Allowing kernel
++ * modules to have a race free view of the set of network namespaces.
++ *
++ * When a new network namespace is created all of the init
++ * methods are called in the order in which they were registered.
++ *
++ * When a network namespace is destroyed all of the exit methods
++ * are called in the reverse of the order with which they were
++ * registered.
++ */
++int register_pernet_device(struct pernet_operations *ops)
++{
++ int error;
++ mutex_lock(&net_mutex);
++ error = register_pernet_operations(&pernet_list, ops);
++ if (!error && (first_device == &pernet_list))
++ first_device = &ops->list;
++ mutex_unlock(&net_mutex);
++ return error;
++}
++EXPORT_SYMBOL_GPL(register_pernet_device);
++
++/**
++ * unregister_pernet_device - unregister a network namespace netdevice
++ * @ops: pernet operations structure to manipulate
++ *
++ * Remove the pernet operations structure from the list to be
++ * used when network namespaces are created or destoryed. In
++ * addition run the exit method for all existing network
++ * namespaces.
++ */
++void unregister_pernet_device(struct pernet_operations *ops)
++{
++ mutex_lock(&net_mutex);
++ if (&ops->list == first_device)
++ first_device = first_device->next;
++ unregister_pernet_operations(ops);
++ mutex_unlock(&net_mutex);
++}
++EXPORT_SYMBOL_GPL(unregister_pernet_device);
+diff -Nurb linux-2.6.22-570/net/core/netpoll.c linux-2.6.22-590/net/core/netpoll.c
+--- linux-2.6.22-570/net/core/netpoll.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/core/netpoll.c 2008-01-29 22:12:32.000000000 -0500
+@@ -503,7 +503,8 @@
+
+ np->rx_hook(np, ntohs(uh->source),
+ (char *)(uh+1),
+- ulen - sizeof(struct udphdr));
++ ulen - sizeof(struct udphdr),
++ skb);
+
+ kfree_skb(skb);
+ return 1;
+@@ -633,7 +634,7 @@
+ int err;
+
+ if (np->dev_name)
+- ndev = dev_get_by_name(np->dev_name);
++ ndev = dev_get_by_name(&init_net, np->dev_name);
+ if (!ndev) {
+ printk(KERN_ERR "%s: %s doesn't exist, aborting.\n",
+ np->name, np->dev_name);
+diff -Nurb linux-2.6.22-570/net/core/pktgen.c linux-2.6.22-590/net/core/pktgen.c
+--- linux-2.6.22-570/net/core/pktgen.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/core/pktgen.c 2008-01-29 22:12:32.000000000 -0500
+@@ -155,6 +155,7 @@
+ #include <net/checksum.h>
+ #include <net/ipv6.h>
+ #include <net/addrconf.h>
++#include <net/net_namespace.h>
+ #include <asm/byteorder.h>
+ #include <linux/rcupdate.h>
+ #include <asm/bitops.h>
+@@ -1903,6 +1904,9 @@
+ {
+ struct net_device *dev = ptr;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ /* It is OK that we do not hold the group lock right now,
+ * as we run under the RTNL lock.
+ */
+@@ -1933,7 +1937,7 @@
+ pkt_dev->odev = NULL;
+ }
+
+- odev = dev_get_by_name(ifname);
++ odev = dev_get_by_name(&init_net, ifname);
+ if (!odev) {
+ printk("pktgen: no such netdevice: \"%s\"\n", ifname);
+ return -ENODEV;
+@@ -3284,6 +3288,8 @@
+
+ set_current_state(TASK_INTERRUPTIBLE);
+
++ set_freezable();
++
+ while (!kthread_should_stop()) {
+ pkt_dev = next_to_run(t);
+
+@@ -3568,7 +3574,7 @@
+
+ printk(version);
+
+- pg_proc_dir = proc_mkdir(PG_PROC_DIR, proc_net);
++ pg_proc_dir = proc_mkdir(PG_PROC_DIR, init_net.proc_net);
+ if (!pg_proc_dir)
+ return -ENODEV;
+ pg_proc_dir->owner = THIS_MODULE;
+@@ -3577,7 +3583,7 @@
+ if (pe == NULL) {
+ printk("pktgen: ERROR: cannot create %s procfs entry.\n",
+ PGCTRL);
+- proc_net_remove(PG_PROC_DIR);
++ proc_net_remove(&init_net, PG_PROC_DIR);
+ return -EINVAL;
+ }
+
+@@ -3600,7 +3606,7 @@
+ printk("pktgen: ERROR: Initialization failed for all threads\n");
+ unregister_netdevice_notifier(&pktgen_notifier_block);
+ remove_proc_entry(PGCTRL, pg_proc_dir);
+- proc_net_remove(PG_PROC_DIR);
++ proc_net_remove(&init_net, PG_PROC_DIR);
+ return -ENODEV;
+ }
+
+@@ -3627,7 +3633,7 @@
+
+ /* Clean up proc file system */
+ remove_proc_entry(PGCTRL, pg_proc_dir);
+- proc_net_remove(PG_PROC_DIR);
++ proc_net_remove(&init_net, PG_PROC_DIR);
+ }
+
+ module_init(pg_init);
+diff -Nurb linux-2.6.22-570/net/core/rtnetlink.c linux-2.6.22-590/net/core/rtnetlink.c
+--- linux-2.6.22-570/net/core/rtnetlink.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/core/rtnetlink.c 2008-01-29 22:12:32.000000000 -0500
+@@ -59,7 +59,6 @@
+ };
+
+ static DEFINE_MUTEX(rtnl_mutex);
+-static struct sock *rtnl;
+
+ void rtnl_lock(void)
+ {
+@@ -73,9 +72,17 @@
+
+ void rtnl_unlock(void)
+ {
++ struct net *net;
+ mutex_unlock(&rtnl_mutex);
++
++ net_lock();
++ for_each_net(net) {
++ struct sock *rtnl = net->rtnl;
+ if (rtnl && rtnl->sk_receive_queue.qlen)
+ rtnl->sk_data_ready(rtnl, 0);
++ }
++ net_unlock();
++
+ netdev_run_todo();
+ }
+
+@@ -97,6 +104,19 @@
+ return 0;
+ }
+
++int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
++ struct rtattr *rta, int len)
++{
++ if (RTA_PAYLOAD(rta) < len)
++ return -1;
++ if (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) {
++ rta = RTA_DATA(rta) + RTA_ALIGN(len);
++ return rtattr_parse_nested(tb, maxattr, rta);
++ }
++ memset(tb, 0, sizeof(struct rtattr *) * maxattr);
++ return 0;
++}
++
+ static struct rtnl_link *rtnl_msg_handlers[NPROTO];
+
+ static inline int rtm_msgindex(int msgtype)
+@@ -243,6 +263,143 @@
+
+ EXPORT_SYMBOL_GPL(rtnl_unregister_all);
+
++static LIST_HEAD(link_ops);
++
++/**
++ * __rtnl_link_register - Register rtnl_link_ops with rtnetlink.
++ * @ops: struct rtnl_link_ops * to register
++ *
++ * The caller must hold the rtnl_mutex. This function should be used
++ * by drivers that create devices during module initialization. It
++ * must be called before registering the devices.
++ *
++ * Returns 0 on success or a negative error code.
++ */
++int __rtnl_link_register(struct rtnl_link_ops *ops)
++{
++ list_add_tail(&ops->list, &link_ops);
++ return 0;
++}
++
++EXPORT_SYMBOL_GPL(__rtnl_link_register);
++
++/**
++ * rtnl_link_register - Register rtnl_link_ops with rtnetlink.
++ * @ops: struct rtnl_link_ops * to register
++ *
++ * Returns 0 on success or a negative error code.
++ */
++int rtnl_link_register(struct rtnl_link_ops *ops)
++{
++ int err;
++
++ rtnl_lock();
++ err = __rtnl_link_register(ops);
++ rtnl_unlock();
++ return err;
++}
++
++EXPORT_SYMBOL_GPL(rtnl_link_register);
++
++/**
++ * __rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink.
++ * @ops: struct rtnl_link_ops * to unregister
++ *
++ * The caller must hold the rtnl_mutex. This function should be used
++ * by drivers that unregister devices during module unloading. It must
++ * be called after unregistering the devices.
++ */
++void __rtnl_link_unregister(struct rtnl_link_ops *ops)
++{
++ list_del(&ops->list);
++}
++
++EXPORT_SYMBOL_GPL(__rtnl_link_unregister);
++
++/**
++ * rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink.
++ * @ops: struct rtnl_link_ops * to unregister
++ */
++void rtnl_link_unregister(struct rtnl_link_ops *ops)
++{
++ rtnl_lock();
++ __rtnl_link_unregister(ops);
++ rtnl_unlock();
++}
++
++EXPORT_SYMBOL_GPL(rtnl_link_unregister);
++
++static const struct rtnl_link_ops *rtnl_link_ops_get(const char *kind)
++{
++ const struct rtnl_link_ops *ops;
++
++ list_for_each_entry(ops, &link_ops, list) {
++ if (!strcmp(ops->kind, kind))
++ return ops;
++ }
++ return NULL;
++}
++
++static size_t rtnl_link_get_size(const struct net_device *dev)
++{
++ const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
++ size_t size;
++
++ if (!ops)
++ return 0;
++
++ size = nlmsg_total_size(sizeof(struct nlattr)) + /* IFLA_LINKINFO */
++ nlmsg_total_size(strlen(ops->kind) + 1); /* IFLA_INFO_KIND */
++
++ if (ops->get_size)
++ /* IFLA_INFO_DATA + nested data */
++ size += nlmsg_total_size(sizeof(struct nlattr)) +
++ ops->get_size(dev);
++
++ if (ops->get_xstats_size)
++ size += ops->get_xstats_size(dev); /* IFLA_INFO_XSTATS */
++
++ return size;
++}
++
++static int rtnl_link_fill(struct sk_buff *skb, const struct net_device *dev)
++{
++ const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
++ struct nlattr *linkinfo, *data;
++ int err = -EMSGSIZE;
++
++ linkinfo = nla_nest_start(skb, IFLA_LINKINFO);
++ if (linkinfo == NULL)
++ goto out;
++
++ if (nla_put_string(skb, IFLA_INFO_KIND, ops->kind) < 0)
++ goto err_cancel_link;
++ if (ops->fill_xstats) {
++ err = ops->fill_xstats(skb, dev);
++ if (err < 0)
++ goto err_cancel_link;
++ }
++ if (ops->fill_info) {
++ data = nla_nest_start(skb, IFLA_INFO_DATA);
++ if (data == NULL)
++ goto err_cancel_link;
++ err = ops->fill_info(skb, dev);
++ if (err < 0)
++ goto err_cancel_data;
++ nla_nest_end(skb, data);
++ }
++
++ nla_nest_end(skb, linkinfo);
++ return 0;
++
++err_cancel_data:
++ nla_nest_cancel(skb, data);
++err_cancel_link:
++ nla_nest_cancel(skb, linkinfo);
++out:
++ return err;
++}
++
+ static const int rtm_min[RTM_NR_FAMILIES] =
+ {
+ [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
+@@ -296,8 +453,9 @@
+ return ret;
+ }
+
+-int rtnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo)
++int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned group, int echo)
+ {
++ struct sock *rtnl = net->rtnl;
+ int err = 0;
+
+ NETLINK_CB(skb).dst_group = group;
+@@ -309,14 +467,17 @@
+ return err;
+ }
+
+-int rtnl_unicast(struct sk_buff *skb, u32 pid)
++int rtnl_unicast(struct sk_buff *skb, struct net *net, u32 pid)
+ {
++ struct sock *rtnl = net->rtnl;
++
+ return nlmsg_unicast(rtnl, skb, pid);
+ }
+
+-int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group,
++int rtnl_notify(struct sk_buff *skb, struct net *net, u32 pid, u32 group,
+ struct nlmsghdr *nlh, gfp_t flags)
+ {
++ struct sock *rtnl = net->rtnl;
+ int report = 0;
+
+ if (nlh)
+@@ -325,8 +486,10 @@
+ return nlmsg_notify(rtnl, skb, pid, group, report, flags);
+ }
+
+-void rtnl_set_sk_err(u32 group, int error)
++void rtnl_set_sk_err(struct net *net, u32 group, int error)
+ {
++ struct sock *rtnl = net->rtnl;
++
+ netlink_set_err(rtnl, 0, group, error);
+ }
+
+@@ -437,7 +600,7 @@
+ a->tx_compressed = b->tx_compressed;
+ };
+
+-static inline size_t if_nlmsg_size(void)
++static inline size_t if_nlmsg_size(const struct net_device *dev)
+ {
+ return NLMSG_ALIGN(sizeof(struct ifinfomsg))
+ + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
+@@ -452,7 +615,8 @@
+ + nla_total_size(4) /* IFLA_LINK */
+ + nla_total_size(4) /* IFLA_MASTER */
+ + nla_total_size(1) /* IFLA_OPERSTATE */
+- + nla_total_size(1); /* IFLA_LINKMODE */
++ + nla_total_size(1) /* IFLA_LINKMODE */
++ + rtnl_link_get_size(dev); /* IFLA_LINKINFO */
+ }
+
+ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
+@@ -522,6 +686,11 @@
+ }
+ }
+
++ if (dev->rtnl_link_ops) {
++ if (rtnl_link_fill(skb, dev) < 0)
++ goto nla_put_failure;
++ }
++
+ return nlmsg_end(skb, nlh);
+
+ nla_put_failure:
+@@ -531,12 +700,13 @@
+
+ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
+ {
++ struct net *net = skb->sk->sk_net;
+ int idx;
+ int s_idx = cb->args[0];
+ struct net_device *dev;
+
+ idx = 0;
+- for_each_netdev(dev) {
++ for_each_netdev(net, dev) {
+ if (!nx_dev_visible(skb->sk->sk_nx_info, dev))
+ continue;
+ if (idx < s_idx)
+@@ -555,6 +725,8 @@
+
+ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
+ [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 },
++ [IFLA_ADDRESS] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
++ [IFLA_BROADCAST] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
+ [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) },
+ [IFLA_MTU] = { .type = NLA_U32 },
+ [IFLA_TXQLEN] = { .type = NLA_U32 },
+@@ -563,44 +735,16 @@
+ [IFLA_LINKMODE] = { .type = NLA_U8 },
+ };
+
+-static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+-{
+- struct ifinfomsg *ifm;
+- struct net_device *dev;
+- int err, send_addr_notify = 0, modified = 0;
+- struct nlattr *tb[IFLA_MAX+1];
+- char ifname[IFNAMSIZ];
+-
+- err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
+- if (err < 0)
+- goto errout;
+-
+- if (tb[IFLA_IFNAME])
+- nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
+- else
+- ifname[0] = '\0';
+-
+- err = -EINVAL;
+- ifm = nlmsg_data(nlh);
+- if (ifm->ifi_index > 0)
+- dev = dev_get_by_index(ifm->ifi_index);
+- else if (tb[IFLA_IFNAME])
+- dev = dev_get_by_name(ifname);
+- else
+- goto errout;
+-
+- if (dev == NULL) {
+- err = -ENODEV;
+- goto errout;
+- }
+-
+- if (tb[IFLA_ADDRESS] &&
+- nla_len(tb[IFLA_ADDRESS]) < dev->addr_len)
+- goto errout_dev;
++static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
++ [IFLA_INFO_KIND] = { .type = NLA_STRING },
++ [IFLA_INFO_DATA] = { .type = NLA_NESTED },
++};
+
+- if (tb[IFLA_BROADCAST] &&
+- nla_len(tb[IFLA_BROADCAST]) < dev->addr_len)
+- goto errout_dev;
++static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
++ struct nlattr **tb, char *ifname, int modified)
++{
++ int send_addr_notify = 0;
++ int err;
+
+ if (tb[IFLA_MAP]) {
+ struct rtnl_link_ifmap *u_map;
+@@ -608,12 +752,12 @@
+
+ if (!dev->set_config) {
+ err = -EOPNOTSUPP;
+- goto errout_dev;
++ goto errout;
+ }
+
+ if (!netif_device_present(dev)) {
+ err = -ENODEV;
+- goto errout_dev;
++ goto errout;
+ }
+
+ u_map = nla_data(tb[IFLA_MAP]);
+@@ -626,7 +770,7 @@
+
+ err = dev->set_config(dev, &k_map);
+ if (err < 0)
+- goto errout_dev;
++ goto errout;
+
+ modified = 1;
+ }
+@@ -637,19 +781,19 @@
+
+ if (!dev->set_mac_address) {
+ err = -EOPNOTSUPP;
+- goto errout_dev;
++ goto errout;
+ }
+
+ if (!netif_device_present(dev)) {
+ err = -ENODEV;
+- goto errout_dev;
++ goto errout;
+ }
+
+ len = sizeof(sa_family_t) + dev->addr_len;
+ sa = kmalloc(len, GFP_KERNEL);
+ if (!sa) {
+ err = -ENOMEM;
+- goto errout_dev;
++ goto errout;
+ }
+ sa->sa_family = dev->type;
+ memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]),
+@@ -657,7 +801,7 @@
+ err = dev->set_mac_address(dev, sa);
+ kfree(sa);
if (err)
- goto errout_dev;
+ goto errout;
send_addr_notify = 1;
modified = 1;
}
-@@ -665,7 +795,7 @@
+@@ -665,7 +809,7 @@
if (tb[IFLA_MTU]) {
err = dev_set_mtu(dev, nla_get_u32(tb[IFLA_MTU]));
if (err < 0)
modified = 1;
}
-@@ -677,7 +807,7 @@
+@@ -677,7 +821,7 @@
if (ifm->ifi_index > 0 && ifname[0]) {
err = dev_change_name(dev, ifname);
if (err < 0)
modified = 1;
}
-@@ -686,7 +816,6 @@
+@@ -686,7 +830,6 @@
send_addr_notify = 1;
}
if (ifm->ifi_flags || ifm->ifi_change) {
unsigned int flags = ifm->ifi_flags;
-@@ -714,7 +843,7 @@
+@@ -714,7 +857,7 @@
err = 0;
if (err < 0 && modified && net_ratelimit())
printk(KERN_WARNING "A link change request failed with "
"some changes comitted already. Interface %s may "
-@@ -723,12 +852,231 @@
+@@ -723,14 +866,237 @@
if (send_addr_notify)
call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
+ return err;
+}
-
++
+static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+{
++ struct net *net = skb->sk->sk_net;
+ struct ifinfomsg *ifm;
+ struct net_device *dev;
+ int err;
+ struct nlattr *tb[IFLA_MAX+1];
+ char ifname[IFNAMSIZ];
-+
+
+ err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
+ if (err < 0)
+ goto errout;
+ err = -EINVAL;
+ ifm = nlmsg_data(nlh);
+ if (ifm->ifi_index > 0)
-+ dev = dev_get_by_index(ifm->ifi_index);
++ dev = dev_get_by_index(net, ifm->ifi_index);
+ else if (tb[IFLA_IFNAME])
-+ dev = dev_get_by_name(ifname);
++ dev = dev_get_by_name(net, ifname);
+ else
+ goto errout;
+
+static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+{
++ struct net *net = skb->sk->sk_net;
+ const struct rtnl_link_ops *ops;
+ struct net_device *dev;
+ struct ifinfomsg *ifm;
+
+ ifm = nlmsg_data(nlh);
+ if (ifm->ifi_index > 0)
-+ dev = __dev_get_by_index(ifm->ifi_index);
++ dev = __dev_get_by_index(net, ifm->ifi_index);
+ else if (tb[IFLA_IFNAME])
-+ dev = __dev_get_by_name(ifname);
++ dev = __dev_get_by_name(net, ifname);
+ else
+ return -EINVAL;
+
+
+static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+{
++ struct net *net = skb->sk->sk_net;
+ const struct rtnl_link_ops *ops;
+ struct net_device *dev;
+ struct ifinfomsg *ifm;
+
+ ifm = nlmsg_data(nlh);
+ if (ifm->ifi_index > 0)
-+ dev = __dev_get_by_index(ifm->ifi_index);
++ dev = __dev_get_by_index(net, ifm->ifi_index);
+ else if (ifname[0])
-+ dev = __dev_get_by_name(ifname);
++ dev = __dev_get_by_name(net, ifname);
+ else
+ dev = NULL;
+
+
static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
{
++ struct net *net = skb->sk->sk_net;
struct ifinfomsg *ifm;
-@@ -749,7 +1097,7 @@
+ struct nlattr *tb[IFLA_MAX+1];
+ struct net_device *dev = NULL;
+@@ -743,13 +1109,13 @@
+
+ ifm = nlmsg_data(nlh);
+ if (ifm->ifi_index > 0) {
+- dev = dev_get_by_index(ifm->ifi_index);
++ dev = dev_get_by_index(net, ifm->ifi_index);
+ if (dev == NULL)
+ return -ENODEV;
} else
return -EINVAL;
if (nskb == NULL) {
err = -ENOBUFS;
goto errout;
-@@ -802,7 +1150,7 @@
+@@ -763,7 +1129,7 @@
+ kfree_skb(nskb);
+ goto errout;
+ }
+- err = rtnl_unicast(nskb, NETLINK_CB(skb).pid);
++ err = rtnl_unicast(nskb, net, NETLINK_CB(skb).pid);
+ errout:
+ dev_put(dev);
+
+@@ -796,13 +1162,14 @@
+
+ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
+ {
++ struct net *net = dev->nd_net;
+ struct sk_buff *skb;
+ int err = -ENOBUFS;
+
if (!nx_dev_visible(current->nx_info, dev))
return;
if (skb == NULL)
goto errout;
-@@ -957,6 +1305,8 @@
+@@ -813,10 +1180,10 @@
+ kfree_skb(skb);
+ goto errout;
+ }
+- err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
++ err = rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
+ errout:
+ if (err < 0)
+- rtnl_set_sk_err(RTNLGRP_LINK, err);
++ rtnl_set_sk_err(net, RTNLGRP_LINK, err);
+ }
+
+ /* Protected by RTNL sempahore. */
+@@ -827,6 +1194,7 @@
+
+ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+ {
++ struct net *net = skb->sk->sk_net;
+ rtnl_doit_func doit;
+ int sz_idx, kind;
+ int min_len;
+@@ -855,6 +1223,7 @@
+ return -EPERM;
+
+ if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
++ struct sock *rtnl;
+ rtnl_dumpit_func dumpit;
+
+ dumpit = rtnl_get_dumpit(family, type);
+@@ -862,6 +1231,7 @@
+ return -EOPNOTSUPP;
+
+ __rtnl_unlock();
++ rtnl = net->rtnl;
+ err = netlink_dump_start(rtnl, skb, nlh, dumpit, NULL);
+ rtnl_lock();
+ return err;
+@@ -911,6 +1281,10 @@
+ static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr)
+ {
+ struct net_device *dev = ptr;
++
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ switch (event) {
+ case NETDEV_UNREGISTER:
+ rtmsg_ifinfo(RTM_DELLINK, dev, ~0U);
+@@ -936,6 +1310,36 @@
+ .notifier_call = rtnetlink_event,
+ };
+
++
++static int rtnetlink_net_init(struct net *net)
++{
++ struct sock *sk;
++ sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX,
++ rtnetlink_rcv, &rtnl_mutex, THIS_MODULE);
++ if (!sk)
++ return -ENOMEM;
++
++ /* Don't hold an extra reference on the namespace */
++ put_net(sk->sk_net);
++ net->rtnl = sk;
++ return 0;
++}
++
++static void rtnetlink_net_exit(struct net *net)
++{
++ /* At the last minute lie and say this is a socket for the
++ * initial network namespace. So the socket will be safe to
++ * free.
++ */
++ net->rtnl->sk_net = get_net(&init_net);
++ sock_put(net->rtnl);
++}
++
++static struct pernet_operations rtnetlink_net_ops = {
++ .init = rtnetlink_net_init,
++ .exit = rtnetlink_net_exit,
++};
++
+ void __init rtnetlink_init(void)
+ {
+ int i;
+@@ -948,15 +1352,16 @@
+ if (!rta_buf)
+ panic("rtnetlink_init: cannot allocate rta_buf\n");
+
+- rtnl = netlink_kernel_create(NETLINK_ROUTE, RTNLGRP_MAX, rtnetlink_rcv,
+- &rtnl_mutex, THIS_MODULE);
+- if (rtnl == NULL)
++ if (register_pernet_subsys(&rtnetlink_net_ops))
+ panic("rtnetlink_init: cannot initialize rtnetlink\n");
++
+ netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV);
+ register_netdevice_notifier(&rtnetlink_dev_notifier);
rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink, rtnl_dump_ifinfo);
rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL);
rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all);
rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all);
-@@ -965,6 +1315,7 @@
+@@ -965,6 +1370,7 @@
EXPORT_SYMBOL(__rta_fill);
EXPORT_SYMBOL(rtattr_strlcpy);
EXPORT_SYMBOL(rtattr_parse);
EXPORT_SYMBOL(rtnl_lock);
EXPORT_SYMBOL(rtnl_trylock);
diff -Nurb linux-2.6.22-570/net/core/skbuff.c linux-2.6.22-590/net/core/skbuff.c
---- linux-2.6.22-570/net/core/skbuff.c 2008-03-15 10:34:27.000000000 -0400
-+++ linux-2.6.22-590/net/core/skbuff.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/net/core/skbuff.c 2008-01-29 22:12:24.000000000 -0500
++++ linux-2.6.22-590/net/core/skbuff.c 2008-01-29 22:12:32.000000000 -0500
@@ -417,6 +417,7 @@
C(csum);
C(local_df);
NULL, NULL);
}
+diff -Nurb linux-2.6.22-570/net/core/sock.c linux-2.6.22-590/net/core/sock.c
+--- linux-2.6.22-570/net/core/sock.c 2008-01-29 22:12:24.000000000 -0500
++++ linux-2.6.22-590/net/core/sock.c 2008-01-29 22:12:32.000000000 -0500
+@@ -123,6 +123,7 @@
+ #include <net/sock.h>
+ #include <net/xfrm.h>
+ #include <linux/ipsec.h>
++#include <net/net_namespace.h>
+
+ #include <linux/filter.h>
+ #include <linux/vs_socket.h>
+@@ -360,6 +361,7 @@
+ char __user *optval, int optlen)
+ {
+ struct sock *sk=sock->sk;
++ struct net *net = sk->sk_net;
+ struct sk_filter *filter;
+ int val;
+ int valbool;
+@@ -614,7 +616,7 @@
+ if (devname[0] == '\0') {
+ sk->sk_bound_dev_if = 0;
+ } else {
+- struct net_device *dev = dev_get_by_name(devname);
++ struct net_device *dev = dev_get_by_name(net, devname);
+ if (!dev) {
+ ret = -ENODEV;
+ break;
+@@ -867,7 +869,7 @@
+ * @prot: struct proto associated with this new sock instance
+ * @zero_it: if we should zero the newly allocated sock
+ */
+-struct sock *sk_alloc(int family, gfp_t priority,
++struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
+ struct proto *prot, int zero_it)
+ {
+ struct sock *sk = NULL;
+@@ -888,6 +890,7 @@
+ */
+ sk->sk_prot = sk->sk_prot_creator = prot;
+ sock_lock_init(sk);
++ sk->sk_net = get_net(net);
+ }
+ sock_vx_init(sk);
+ sock_nx_init(sk);
+@@ -929,6 +932,7 @@
+ __FUNCTION__, atomic_read(&sk->sk_omem_alloc));
+
+ security_sk_free(sk);
++ put_net(sk->sk_net);
+ vx_sock_dec(sk);
+ clr_vx_info(&sk->sk_vx_info);
+ sk->sk_xid = -1;
+@@ -943,7 +947,7 @@
+
+ struct sock *sk_clone(const struct sock *sk, const gfp_t priority)
+ {
+- struct sock *newsk = sk_alloc(sk->sk_family, priority, sk->sk_prot, 0);
++ struct sock *newsk = sk_alloc(sk->sk_net, sk->sk_family, priority, sk->sk_prot, 0);
+
+ if (newsk != NULL) {
+ struct sk_filter *filter;
+@@ -2017,7 +2021,7 @@
+ static int __init proto_init(void)
+ {
+ /* register /proc/net/protocols */
+- return proc_net_fops_create("protocols", S_IRUGO, &proto_seq_fops) == NULL ? -ENOBUFS : 0;
++ return proc_net_fops_create(&init_net, "protocols", S_IRUGO, &proto_seq_fops) == NULL ? -ENOBUFS : 0;
+ }
+
+ subsys_initcall(proto_init);
+diff -Nurb linux-2.6.22-570/net/core/sysctl_net_core.c linux-2.6.22-590/net/core/sysctl_net_core.c
+--- linux-2.6.22-570/net/core/sysctl_net_core.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/core/sysctl_net_core.c 2008-01-29 22:12:32.000000000 -0500
+@@ -9,25 +9,10 @@
+ #include <linux/sysctl.h>
+ #include <linux/module.h>
+ #include <linux/socket.h>
++#include <linux/netdevice.h>
++#include <net/xfrm.h>
+ #include <net/sock.h>
+
+-#ifdef CONFIG_SYSCTL
+-
+-extern int netdev_max_backlog;
+-extern int weight_p;
+-
+-extern __u32 sysctl_wmem_max;
+-extern __u32 sysctl_rmem_max;
+-
+-extern int sysctl_core_destroy_delay;
+-
+-#ifdef CONFIG_XFRM
+-extern u32 sysctl_xfrm_aevent_etime;
+-extern u32 sysctl_xfrm_aevent_rseqth;
+-extern int sysctl_xfrm_larval_drop;
+-extern u32 sysctl_xfrm_acq_expires;
+-#endif
+-
+ ctl_table core_table[] = {
+ #ifdef CONFIG_NET
+ {
+@@ -103,11 +88,32 @@
+ .mode = 0644,
+ .proc_handler = &proc_dointvec
+ },
++#endif /* CONFIG_NET */
++ {
++ .ctl_name = NET_CORE_BUDGET,
++ .procname = "netdev_budget",
++ .data = &netdev_budget,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec
++ },
++ {
++ .ctl_name = NET_CORE_WARNINGS,
++ .procname = "warnings",
++ .data = &net_msg_warn,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec
++ },
++ { .ctl_name = 0 }
++};
++
++struct ctl_table multi_core_table[] = {
+ #ifdef CONFIG_XFRM
+ {
+ .ctl_name = NET_CORE_AEVENT_ETIME,
+ .procname = "xfrm_aevent_etime",
+- .data = &sysctl_xfrm_aevent_etime,
++ .data = &init_net.sysctl_xfrm_aevent_etime,
+ .maxlen = sizeof(u32),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec
+@@ -115,7 +121,7 @@
+ {
+ .ctl_name = NET_CORE_AEVENT_RSEQTH,
+ .procname = "xfrm_aevent_rseqth",
+- .data = &sysctl_xfrm_aevent_rseqth,
++ .data = &init_net.sysctl_xfrm_aevent_rseqth,
+ .maxlen = sizeof(u32),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec
+@@ -123,7 +129,7 @@
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "xfrm_larval_drop",
+- .data = &sysctl_xfrm_larval_drop,
++ .data = &init_net.sysctl_xfrm_larval_drop,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec
+@@ -131,38 +137,19 @@
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "xfrm_acq_expires",
+- .data = &sysctl_xfrm_acq_expires,
++ .data = &init_net.sysctl_xfrm_acq_expires,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec
+ },
+ #endif /* CONFIG_XFRM */
+-#endif /* CONFIG_NET */
+ {
+ .ctl_name = NET_CORE_SOMAXCONN,
+ .procname = "somaxconn",
+- .data = &sysctl_somaxconn,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec
+- },
+- {
+- .ctl_name = NET_CORE_BUDGET,
+- .procname = "netdev_budget",
+- .data = &netdev_budget,
++ .data = &init_net.sysctl_somaxconn,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec
+ },
+- {
+- .ctl_name = NET_CORE_WARNINGS,
+- .procname = "warnings",
+- .data = &net_msg_warn,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec
+- },
+- { .ctl_name = 0 }
++ {}
+ };
+-
+-#endif
diff -Nurb linux-2.6.22-570/net/dccp/ccids/ccid3.c linux-2.6.22-590/net/dccp/ccids/ccid3.c
--- linux-2.6.22-570/net/dccp/ccids/ccid3.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/dccp/ccids/ccid3.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/dccp/ccids/ccid3.c 2008-01-29 22:12:32.000000000 -0500
@@ -1,8 +1,8 @@
/*
* net/dccp/ccids/ccid3.c
diff -Nurb linux-2.6.22-570/net/dccp/ccids/ccid3.h linux-2.6.22-590/net/dccp/ccids/ccid3.h
--- linux-2.6.22-570/net/dccp/ccids/ccid3.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/dccp/ccids/ccid3.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/dccp/ccids/ccid3.h 2008-01-29 22:12:32.000000000 -0500
@@ -36,6 +36,7 @@
#ifndef _DCCP_CCID3_H_
#define _DCCP_CCID3_H_
struct ccid3_options_received ccid3hctx_options_received;
diff -Nurb linux-2.6.22-570/net/dccp/ccids/lib/loss_interval.c linux-2.6.22-590/net/dccp/ccids/lib/loss_interval.c
--- linux-2.6.22-570/net/dccp/ccids/lib/loss_interval.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/dccp/ccids/lib/loss_interval.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/dccp/ccids/lib/loss_interval.c 2008-01-29 22:12:32.000000000 -0500
@@ -1,8 +1,8 @@
/*
* net/dccp/ccids/lib/loss_interval.c
+module_exit(dccp_li_exit);
diff -Nurb linux-2.6.22-570/net/dccp/ccids/lib/loss_interval.h linux-2.6.22-590/net/dccp/ccids/lib/loss_interval.h
--- linux-2.6.22-570/net/dccp/ccids/lib/loss_interval.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/dccp/ccids/lib/loss_interval.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/dccp/ccids/lib/loss_interval.h 2008-01-29 22:12:32.000000000 -0500
@@ -3,8 +3,8 @@
/*
* net/dccp/ccids/lib/loss_interval.h
#endif /* _DCCP_LI_HIST_ */
diff -Nurb linux-2.6.22-570/net/dccp/dccp.h linux-2.6.22-590/net/dccp/dccp.h
--- linux-2.6.22-570/net/dccp/dccp.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/dccp/dccp.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/dccp/dccp.h 2008-01-29 22:12:32.000000000 -0500
@@ -184,7 +184,7 @@
/*
* Checksumming routines
if (cov >= skb->len)
dccp_hdr(skb)->dccph_cscov = 0;
-diff -Nurb linux-2.6.22-570/net/ipv4/Kconfig linux-2.6.22-590/net/ipv4/Kconfig
---- linux-2.6.22-570/net/ipv4/Kconfig 2008-03-15 10:34:26.000000000 -0400
-+++ linux-2.6.22-590/net/ipv4/Kconfig 2008-03-15 10:35:47.000000000 -0400
-@@ -116,48 +116,6 @@
- equal "cost" and chooses one of them in a non-deterministic fashion
- if a matching packet arrives.
-
--config IP_ROUTE_MULTIPATH_CACHED
-- bool "IP: equal cost multipath with caching support (EXPERIMENTAL)"
-- depends on IP_ROUTE_MULTIPATH
-- help
-- Normally, equal cost multipath routing is not supported by the
-- routing cache. If you say Y here, alternative routes are cached
-- and on cache lookup a route is chosen in a configurable fashion.
--
-- If unsure, say N.
--
--config IP_ROUTE_MULTIPATH_RR
-- tristate "MULTIPATH: round robin algorithm"
-- depends on IP_ROUTE_MULTIPATH_CACHED
-- help
-- Multipath routes are chosen according to Round Robin
--
--config IP_ROUTE_MULTIPATH_RANDOM
-- tristate "MULTIPATH: random algorithm"
-- depends on IP_ROUTE_MULTIPATH_CACHED
-- help
-- Multipath routes are chosen in a random fashion. Actually,
-- there is no weight for a route. The advantage of this policy
-- is that it is implemented stateless and therefore introduces only
-- a very small delay.
--
--config IP_ROUTE_MULTIPATH_WRANDOM
-- tristate "MULTIPATH: weighted random algorithm"
-- depends on IP_ROUTE_MULTIPATH_CACHED
-- help
-- Multipath routes are chosen in a weighted random fashion.
-- The per route weights are the weights visible via ip route 2. As the
-- corresponding state management introduces some overhead routing delay
-- is increased.
--
--config IP_ROUTE_MULTIPATH_DRR
-- tristate "MULTIPATH: interface round robin algorithm"
-- depends on IP_ROUTE_MULTIPATH_CACHED
-- help
-- Connections are distributed in a round robin fashion over the
-- available interfaces. This policy makes sense if the connections
-- should be primarily distributed on interfaces and not on routes.
--
- config IP_ROUTE_VERBOSE
- bool "IP: verbose route monitoring"
- depends on IP_ADVANCED_ROUTER
-diff -Nurb linux-2.6.22-570/net/ipv4/Makefile linux-2.6.22-590/net/ipv4/Makefile
---- linux-2.6.22-570/net/ipv4/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/ipv4/Makefile 2008-03-15 10:35:47.000000000 -0400
-@@ -29,14 +29,9 @@
- obj-$(CONFIG_INET_XFRM_MODE_TRANSPORT) += xfrm4_mode_transport.o
- obj-$(CONFIG_INET_XFRM_MODE_TUNNEL) += xfrm4_mode_tunnel.o
- obj-$(CONFIG_IP_PNP) += ipconfig.o
--obj-$(CONFIG_IP_ROUTE_MULTIPATH_RR) += multipath_rr.o
--obj-$(CONFIG_IP_ROUTE_MULTIPATH_RANDOM) += multipath_random.o
--obj-$(CONFIG_IP_ROUTE_MULTIPATH_WRANDOM) += multipath_wrandom.o
--obj-$(CONFIG_IP_ROUTE_MULTIPATH_DRR) += multipath_drr.o
- obj-$(CONFIG_NETFILTER) += netfilter.o netfilter/
- obj-$(CONFIG_IP_VS) += ipvs/
- obj-$(CONFIG_INET_DIAG) += inet_diag.o
--obj-$(CONFIG_IP_ROUTE_MULTIPATH_CACHED) += multipath.o
- obj-$(CONFIG_INET_TCP_DIAG) += tcp_diag.o
- obj-$(CONFIG_NET_TCPPROBE) += tcp_probe.o
- obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o
-diff -Nurb linux-2.6.22-570/net/ipv4/af_inet.c linux-2.6.22-590/net/ipv4/af_inet.c
---- linux-2.6.22-570/net/ipv4/af_inet.c 2008-03-15 10:34:27.000000000 -0400
-+++ linux-2.6.22-590/net/ipv4/af_inet.c 2008-03-15 10:35:47.000000000 -0400
-@@ -1186,6 +1186,9 @@
- int ihl;
- int id;
+diff -Nurb linux-2.6.22-570/net/dccp/ipv4.c linux-2.6.22-590/net/dccp/ipv4.c
+--- linux-2.6.22-570/net/dccp/ipv4.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/dccp/ipv4.c 2008-01-29 22:12:32.000000000 -0500
+@@ -202,6 +202,7 @@
+ */
+ static void dccp_v4_err(struct sk_buff *skb, u32 info)
+ {
++ struct net *net = skb->dev->nd_net;
+ const struct iphdr *iph = (struct iphdr *)skb->data;
+ const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data +
+ (iph->ihl << 2));
+@@ -213,13 +214,16 @@
+ __u64 seq;
+ int err;
-+ if (!(features & NETIF_F_V4_CSUM))
-+ features &= ~NETIF_F_SG;
-+
- if (unlikely(skb_shinfo(skb)->gso_type &
- ~(SKB_GSO_TCPV4 |
- SKB_GSO_UDP |
-diff -Nurb linux-2.6.22-570/net/ipv4/af_inet.c.orig linux-2.6.22-590/net/ipv4/af_inet.c.orig
---- linux-2.6.22-570/net/ipv4/af_inet.c.orig 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/net/ipv4/af_inet.c.orig 2008-03-15 10:34:27.000000000 -0400
-@@ -0,0 +1,1522 @@
-+/*
-+ * INET An implementation of the TCP/IP protocol suite for the LINUX
-+ * operating system. INET is implemented using the BSD Socket
-+ * interface as the means of communication with the user level.
-+ *
-+ * PF_INET protocol family socket handler.
-+ *
-+ * Version: $Id: af_inet.c,v 1.137 2002/02/01 22:01:03 davem Exp $
-+ *
-+ * Authors: Ross Biro
-+ * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
-+ * Florian La Roche, <flla@stud.uni-sb.de>
-+ * Alan Cox, <A.Cox@swansea.ac.uk>
-+ *
-+ * Changes (see also sock.c)
-+ *
-+ * piggy,
-+ * Karl Knutson : Socket protocol table
-+ * A.N.Kuznetsov : Socket death error in accept().
-+ * John Richardson : Fix non blocking error in connect()
-+ * so sockets that fail to connect
-+ * don't return -EINPROGRESS.
-+ * Alan Cox : Asynchronous I/O support
-+ * Alan Cox : Keep correct socket pointer on sock
-+ * structures
-+ * when accept() ed
-+ * Alan Cox : Semantics of SO_LINGER aren't state
-+ * moved to close when you look carefully.
-+ * With this fixed and the accept bug fixed
-+ * some RPC stuff seems happier.
-+ * Niibe Yutaka : 4.4BSD style write async I/O
-+ * Alan Cox,
-+ * Tony Gale : Fixed reuse semantics.
-+ * Alan Cox : bind() shouldn't abort existing but dead
-+ * sockets. Stops FTP netin:.. I hope.
-+ * Alan Cox : bind() works correctly for RAW sockets.
-+ * Note that FreeBSD at least was broken
-+ * in this respect so be careful with
-+ * compatibility tests...
-+ * Alan Cox : routing cache support
-+ * Alan Cox : memzero the socket structure for
-+ * compactness.
-+ * Matt Day : nonblock connect error handler
-+ * Alan Cox : Allow large numbers of pending sockets
-+ * (eg for big web sites), but only if
-+ * specifically application requested.
-+ * Alan Cox : New buffering throughout IP. Used
-+ * dumbly.
-+ * Alan Cox : New buffering now used smartly.
-+ * Alan Cox : BSD rather than common sense
-+ * interpretation of listen.
-+ * Germano Caronni : Assorted small races.
-+ * Alan Cox : sendmsg/recvmsg basic support.
-+ * Alan Cox : Only sendmsg/recvmsg now supported.
-+ * Alan Cox : Locked down bind (see security list).
-+ * Alan Cox : Loosened bind a little.
-+ * Mike McLagan : ADD/DEL DLCI Ioctls
-+ * Willy Konynenberg : Transparent proxying support.
-+ * David S. Miller : New socket lookup architecture.
-+ * Some other random speedups.
-+ * Cyrus Durgin : Cleaned up file for kmod hacks.
-+ * Andi Kleen : Fix inet_stream_connect TCP race.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/err.h>
-+#include <linux/errno.h>
-+#include <linux/types.h>
-+#include <linux/socket.h>
-+#include <linux/in.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/string.h>
-+#include <linux/sockios.h>
-+#include <linux/net.h>
-+#include <linux/capability.h>
-+#include <linux/fcntl.h>
-+#include <linux/mm.h>
-+#include <linux/interrupt.h>
-+#include <linux/stat.h>
-+#include <linux/init.h>
-+#include <linux/poll.h>
-+#include <linux/netfilter_ipv4.h>
-+#include <linux/random.h>
-+
-+#include <asm/uaccess.h>
-+#include <asm/system.h>
-+
-+#include <linux/inet.h>
-+#include <linux/igmp.h>
-+#include <linux/inetdevice.h>
-+#include <linux/netdevice.h>
-+#include <net/ip.h>
-+#include <net/protocol.h>
-+#include <net/arp.h>
-+#include <net/route.h>
-+#include <net/ip_fib.h>
-+#include <net/inet_connection_sock.h>
-+#include <net/tcp.h>
-+#include <net/udp.h>
-+#include <net/udplite.h>
-+#include <linux/skbuff.h>
-+#include <net/sock.h>
-+#include <net/raw.h>
-+#include <net/icmp.h>
-+#include <net/ipip.h>
-+#include <net/inet_common.h>
-+#include <net/xfrm.h>
-+#ifdef CONFIG_IP_MROUTE
-+#include <linux/mroute.h>
-+#endif
-+#include <linux/vs_limit.h>
-+
-+DEFINE_SNMP_STAT(struct linux_mib, net_statistics) __read_mostly;
-+
-+extern void ip_mc_drop_socket(struct sock *sk);
-+
-+/* The inetsw table contains everything that inet_create needs to
-+ * build a new socket.
-+ */
-+static struct list_head inetsw[SOCK_MAX];
-+static DEFINE_SPINLOCK(inetsw_lock);
-+
-+/* New destruction routine */
-+
-+void inet_sock_destruct(struct sock *sk)
-+{
-+ struct inet_sock *inet = inet_sk(sk);
-+
-+ __skb_queue_purge(&sk->sk_receive_queue);
-+ __skb_queue_purge(&sk->sk_error_queue);
-+
-+ if (sk->sk_type == SOCK_STREAM && sk->sk_state != TCP_CLOSE) {
-+ printk("Attempt to release TCP socket in state %d %p\n",
-+ sk->sk_state, sk);
++ if (skb->dev->nd_net != &init_net)
+ return;
-+ }
-+ if (!sock_flag(sk, SOCK_DEAD)) {
-+ printk("Attempt to release alive inet socket %p\n", sk);
-+ return;
-+ }
-+
-+ BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc));
-+ BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc));
-+ BUG_TRAP(!sk->sk_wmem_queued);
-+ BUG_TRAP(!sk->sk_forward_alloc);
-+
-+ kfree(inet->opt);
-+ dst_release(sk->sk_dst_cache);
-+ sk_refcnt_debug_dec(sk);
-+}
-+
-+/*
-+ * The routines beyond this point handle the behaviour of an AF_INET
-+ * socket object. Mostly it punts to the subprotocols of IP to do
-+ * the work.
-+ */
-+
-+/*
-+ * Automatically bind an unbound socket.
-+ */
+
-+static int inet_autobind(struct sock *sk)
-+{
-+ struct inet_sock *inet;
-+ /* We may need to bind the socket. */
-+ lock_sock(sk);
-+ inet = inet_sk(sk);
-+ if (!inet->num) {
-+ if (sk->sk_prot->get_port(sk, 0)) {
-+ release_sock(sk);
-+ return -EAGAIN;
-+ }
-+ inet->sport = htons(inet->num);
-+ sk->sk_xid = vx_current_xid();
-+ sk->sk_nid = nx_current_nid();
+ if (skb->len < (iph->ihl << 2) + 8) {
+ ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
+ return;
+ }
+
+ sk = inet_lookup(&dccp_hashinfo, iph->daddr, dh->dccph_dport,
+- iph->saddr, dh->dccph_sport, inet_iif(skb));
++ iph->saddr, dh->dccph_sport, inet_iif(skb), net);
+ if (sk == NULL) {
+ ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
+ return;
+@@ -441,7 +445,7 @@
+ nsk = inet_lookup_established(&dccp_hashinfo,
+ iph->saddr, dh->dccph_sport,
+ iph->daddr, dh->dccph_dport,
+- inet_iif(skb));
++ inet_iif(skb), sk->sk_net);
+ if (nsk != NULL) {
+ if (nsk->sk_state != DCCP_TIME_WAIT) {
+ bh_lock_sock(nsk);
+@@ -458,7 +462,8 @@
+ struct sk_buff *skb)
+ {
+ struct rtable *rt;
+- struct flowi fl = { .oif = ((struct rtable *)skb->dst)->rt_iif,
++ struct flowi fl = { .fl_net = &init_net,
++ .oif = ((struct rtable *)skb->dst)->rt_iif,
+ .nl_u = { .ip4_u =
+ { .daddr = ip_hdr(skb)->saddr,
+ .saddr = ip_hdr(skb)->daddr,
+@@ -809,11 +814,16 @@
+ /* this is called when real data arrives */
+ static int dccp_v4_rcv(struct sk_buff *skb)
+ {
++ struct net *net = skb->dev->nd_net;
+ const struct dccp_hdr *dh;
+ const struct iphdr *iph;
+ struct sock *sk;
+ int min_cov;
+
++ if (skb->dev->nd_net != &init_net) {
++ kfree_skb(skb);
++ return 0;
+ }
-+ release_sock(sk);
-+ return 0;
-+}
-+
-+/*
-+ * Move a socket into listening state.
-+ */
-+int inet_listen(struct socket *sock, int backlog)
-+{
-+ struct sock *sk = sock->sk;
-+ unsigned char old_state;
-+ int err;
-+
-+ lock_sock(sk);
-+
-+ err = -EINVAL;
-+ if (sock->state != SS_UNCONNECTED || sock->type != SOCK_STREAM)
-+ goto out;
+ /* Step 1: Check header basics */
+
+ if (dccp_invalid_packet(skb))
+@@ -852,7 +862,7 @@
+ * Look up flow ID in table and get corresponding socket */
+ sk = __inet_lookup(&dccp_hashinfo,
+ iph->saddr, dh->dccph_sport,
+- iph->daddr, dh->dccph_dport, inet_iif(skb));
++ iph->daddr, dh->dccph_dport, inet_iif(skb), net);
+ /*
+ * Step 2:
+ * If no socket ...
+diff -Nurb linux-2.6.22-570/net/dccp/ipv6.c linux-2.6.22-590/net/dccp/ipv6.c
+--- linux-2.6.22-570/net/dccp/ipv6.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/dccp/ipv6.c 2008-01-29 22:12:32.000000000 -0500
+@@ -94,6 +94,7 @@
+ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+ int type, int code, int offset, __be32 info)
+ {
++ struct net *net = skb->dev->nd_net;
+ struct ipv6hdr *hdr = (struct ipv6hdr *)skb->data;
+ const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset);
+ struct ipv6_pinfo *np;
+@@ -102,7 +103,7 @@
+ __u64 seq;
+
+ sk = inet6_lookup(&dccp_hashinfo, &hdr->daddr, dh->dccph_dport,
+- &hdr->saddr, dh->dccph_sport, inet6_iif(skb));
++ &hdr->saddr, dh->dccph_sport, inet6_iif(skb), net);
+
+ if (sk == NULL) {
+ ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
+@@ -142,6 +143,7 @@
+ for now.
+ */
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ fl.proto = IPPROTO_DCCP;
+ ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+ ipv6_addr_copy(&fl.fl6_src, &np->saddr);
+@@ -242,6 +244,7 @@
+ int err = -1;
+
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net,
+ fl.proto = IPPROTO_DCCP;
+ ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
+ ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr);
+@@ -358,6 +361,7 @@
+ &rxip6h->daddr);
+
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ ipv6_addr_copy(&fl.fl6_dst, &rxip6h->saddr);
+ ipv6_addr_copy(&fl.fl6_src, &rxip6h->daddr);
+
+@@ -407,7 +411,7 @@
+ nsk = __inet6_lookup_established(&dccp_hashinfo,
+ &iph->saddr, dh->dccph_sport,
+ &iph->daddr, ntohs(dh->dccph_dport),
+- inet6_iif(skb));
++ inet6_iif(skb), sk->sk_net);
+ if (nsk != NULL) {
+ if (nsk->sk_state != DCCP_TIME_WAIT) {
+ bh_lock_sock(nsk);
+@@ -584,6 +588,7 @@
+ struct flowi fl;
+
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ fl.proto = IPPROTO_DCCP;
+ ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
+ if (opt != NULL && opt->srcrt != NULL) {
+@@ -819,6 +824,7 @@
+ {
+ const struct dccp_hdr *dh;
+ struct sk_buff *skb = *pskb;
++ struct net *net = skb->dev->nd_net;
+ struct sock *sk;
+ int min_cov;
+
+@@ -849,7 +855,7 @@
+ sk = __inet6_lookup(&dccp_hashinfo, &ipv6_hdr(skb)->saddr,
+ dh->dccph_sport,
+ &ipv6_hdr(skb)->daddr, ntohs(dh->dccph_dport),
+- inet6_iif(skb));
++ inet6_iif(skb), net);
+ /*
+ * Step 2:
+ * If no socket ...
+@@ -937,6 +943,7 @@
+ return -EAFNOSUPPORT;
+
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+
+ if (np->sndflow) {
+ fl.fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
+diff -Nurb linux-2.6.22-570/net/dccp/probe.c linux-2.6.22-590/net/dccp/probe.c
+--- linux-2.6.22-570/net/dccp/probe.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/dccp/probe.c 2008-01-29 22:12:32.000000000 -0500
+@@ -30,6 +30,7 @@
+ #include <linux/module.h>
+ #include <linux/kfifo.h>
+ #include <linux/vmalloc.h>
++#include <net/net_namespace.h>
+
+ #include "dccp.h"
+ #include "ccid.h"
+@@ -168,7 +169,7 @@
+ if (IS_ERR(dccpw.fifo))
+ return PTR_ERR(dccpw.fifo);
+
+- if (!proc_net_fops_create(procname, S_IRUSR, &dccpprobe_fops))
++ if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &dccpprobe_fops))
+ goto err0;
+
+ ret = register_jprobe(&dccp_send_probe);
+@@ -178,7 +179,7 @@
+ pr_info("DCCP watch registered (port=%d)\n", port);
+ return 0;
+ err1:
+- proc_net_remove(procname);
++ proc_net_remove(&init_net, procname);
+ err0:
+ kfifo_free(dccpw.fifo);
+ return ret;
+@@ -188,7 +189,7 @@
+ static __exit void dccpprobe_exit(void)
+ {
+ kfifo_free(dccpw.fifo);
+- proc_net_remove(procname);
++ proc_net_remove(&init_net, procname);
+ unregister_jprobe(&dccp_send_probe);
+
+ }
+diff -Nurb linux-2.6.22-570/net/decnet/af_decnet.c linux-2.6.22-590/net/decnet/af_decnet.c
+--- linux-2.6.22-570/net/decnet/af_decnet.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/decnet/af_decnet.c 2008-01-29 22:12:32.000000000 -0500
+@@ -131,6 +131,7 @@
+ #include <net/neighbour.h>
+ #include <net/dst.h>
+ #include <net/fib_rules.h>
++#include <net/net_namespace.h>
+ #include <net/dn.h>
+ #include <net/dn_nsp.h>
+ #include <net/dn_dev.h>
+@@ -470,10 +471,10 @@
+ .obj_size = sizeof(struct dn_sock),
+ };
+
+-static struct sock *dn_alloc_sock(struct socket *sock, gfp_t gfp)
++static struct sock *dn_alloc_sock(struct net *net, struct socket *sock, gfp_t gfp)
+ {
+ struct dn_scp *scp;
+- struct sock *sk = sk_alloc(PF_DECnet, gfp, &dn_proto, 1);
++ struct sock *sk = sk_alloc(net, PF_DECnet, gfp, &dn_proto, 1);
+
+ if (!sk)
+ goto out;
+@@ -674,10 +675,13 @@
+
+
+
+-static int dn_create(struct socket *sock, int protocol)
++static int dn_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct sock *sk;
+
++ if (net != &init_net)
++ return -EAFNOSUPPORT;
+
-+ old_state = sk->sk_state;
-+ if (!((1 << old_state) & (TCPF_CLOSE | TCPF_LISTEN)))
-+ goto out;
+ switch(sock->type) {
+ case SOCK_SEQPACKET:
+ if (protocol != DNPROTO_NSP)
+@@ -690,7 +694,7 @@
+ }
+
+
+- if ((sk = dn_alloc_sock(sock, GFP_KERNEL)) == NULL)
++ if ((sk = dn_alloc_sock(net, sock, GFP_KERNEL)) == NULL)
+ return -ENOBUFS;
+
+ sk->sk_protocol = protocol;
+@@ -747,7 +751,7 @@
+ if (dn_ntohs(saddr->sdn_nodeaddrl)) {
+ read_lock(&dev_base_lock);
+ ldev = NULL;
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ if (!dev->dn_ptr)
+ continue;
+ if (dn_dev_islocal(dev, dn_saddr2dn(saddr))) {
+@@ -943,6 +947,7 @@
+
+ err = -EHOSTUNREACH;
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ fl.oif = sk->sk_bound_dev_if;
+ fl.fld_dst = dn_saddr2dn(&scp->peer);
+ fl.fld_src = dn_saddr2dn(&scp->addr);
+@@ -1090,7 +1095,7 @@
+
+ cb = DN_SKB_CB(skb);
+ sk->sk_ack_backlog--;
+- newsk = dn_alloc_sock(newsock, sk->sk_allocation);
++ newsk = dn_alloc_sock(sk->sk_net, newsock, sk->sk_allocation);
+ if (newsk == NULL) {
+ release_sock(sk);
+ kfree_skb(skb);
+@@ -2085,6 +2090,9 @@
+ {
+ struct net_device *dev = (struct net_device *)ptr;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
+
-+ /* Really, if the socket is already in listen state
-+ * we can only allow the backlog to be adjusted.
-+ */
-+ if (old_state != TCP_LISTEN) {
-+ err = inet_csk_listen_start(sk, backlog);
-+ if (err)
-+ goto out;
-+ }
-+ sk->sk_max_ack_backlog = backlog;
-+ err = 0;
+ switch(event) {
+ case NETDEV_UP:
+ dn_dev_up(dev);
+@@ -2399,7 +2407,7 @@
+ dev_add_pack(&dn_dix_packet_type);
+ register_netdevice_notifier(&dn_dev_notifier);
+
+- proc_net_fops_create("decnet", S_IRUGO, &dn_socket_seq_fops);
++ proc_net_fops_create(&init_net, "decnet", S_IRUGO, &dn_socket_seq_fops);
+ dn_register_sysctl();
+ out:
+ return rc;
+@@ -2428,7 +2436,7 @@
+ dn_neigh_cleanup();
+ dn_fib_cleanup();
+
+- proc_net_remove("decnet");
++ proc_net_remove(&init_net, "decnet");
+
+ proto_unregister(&dn_proto);
+ }
+diff -Nurb linux-2.6.22-570/net/decnet/dn_dev.c linux-2.6.22-590/net/decnet/dn_dev.c
+--- linux-2.6.22-570/net/decnet/dn_dev.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/decnet/dn_dev.c 2008-01-29 22:12:32.000000000 -0500
+@@ -47,6 +47,7 @@
+ #include <net/flow.h>
+ #include <net/fib_rules.h>
+ #include <net/netlink.h>
++#include <net/net_namespace.h>
+ #include <net/dn.h>
+ #include <net/dn_dev.h>
+ #include <net/dn_route.h>
+@@ -513,7 +514,7 @@
+ ifr->ifr_name[IFNAMSIZ-1] = 0;
+
+ #ifdef CONFIG_KMOD
+- dev_load(ifr->ifr_name);
++ dev_load(&init_net, ifr->ifr_name);
+ #endif
+
+ switch(cmd) {
+@@ -531,7 +532,7 @@
+
+ rtnl_lock();
+
+- if ((dev = __dev_get_by_name(ifr->ifr_name)) == NULL) {
++ if ((dev = __dev_get_by_name(&init_net, ifr->ifr_name)) == NULL) {
+ ret = -ENODEV;
+ goto done;
+ }
+@@ -629,7 +630,7 @@
+ {
+ struct net_device *dev;
+ struct dn_dev *dn_dev = NULL;
+- dev = dev_get_by_index(ifindex);
++ dev = dev_get_by_index(&init_net, ifindex);
+ if (dev) {
+ dn_dev = dev->dn_ptr;
+ dev_put(dev);
+@@ -647,12 +648,16 @@
+
+ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct nlattr *tb[IFA_MAX+1];
+ struct dn_dev *dn_db;
+ struct ifaddrmsg *ifm;
+ struct dn_ifaddr *ifa, **ifap;
+ int err = -EADDRNOTAVAIL;
+
++ if (net != &init_net)
++ goto errout;
+
-+out:
-+ release_sock(sk);
-+ return err;
-+}
+ err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy);
+ if (err < 0)
+ goto errout;
+@@ -679,6 +684,7 @@
+
+ static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct nlattr *tb[IFA_MAX+1];
+ struct net_device *dev;
+ struct dn_dev *dn_db;
+@@ -686,6 +692,9 @@
+ struct dn_ifaddr *ifa;
+ int err;
+
++ if (net != &init_net)
++ return -EINVAL;
+
-+u32 inet_ehash_secret __read_mostly;
-+EXPORT_SYMBOL(inet_ehash_secret);
+ err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy);
+ if (err < 0)
+ return err;
+@@ -694,7 +703,7 @@
+ return -EINVAL;
+
+ ifm = nlmsg_data(nlh);
+- if ((dev = __dev_get_by_index(ifm->ifa_index)) == NULL)
++ if ((dev = __dev_get_by_index(&init_net, ifm->ifa_index)) == NULL)
+ return -ENODEV;
+
+ if ((dn_db = dev->dn_ptr) == NULL) {
+@@ -783,24 +792,28 @@
+ kfree_skb(skb);
+ goto errout;
+ }
+- err = rtnl_notify(skb, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL);
++ err = rtnl_notify(skb, &init_net, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL);
+ errout:
+ if (err < 0)
+- rtnl_set_sk_err(RTNLGRP_DECnet_IFADDR, err);
++ rtnl_set_sk_err(&init_net, RTNLGRP_DECnet_IFADDR, err);
+ }
+
+ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
+ {
++ struct net *net = skb->sk->sk_net;
+ int idx, dn_idx = 0, skip_ndevs, skip_naddr;
+ struct net_device *dev;
+ struct dn_dev *dn_db;
+ struct dn_ifaddr *ifa;
+
++ if (net != &init_net)
++ return 0;
+
-+/*
-+ * inet_ehash_secret must be set exactly once
-+ * Instead of using a dedicated spinlock, we (ab)use inetsw_lock
-+ */
-+void build_ehash_secret(void)
-+{
-+ u32 rnd;
-+ do {
-+ get_random_bytes(&rnd, sizeof(rnd));
-+ } while (rnd == 0);
-+ spin_lock_bh(&inetsw_lock);
-+ if (!inet_ehash_secret)
-+ inet_ehash_secret = rnd;
-+ spin_unlock_bh(&inetsw_lock);
-+}
-+EXPORT_SYMBOL(build_ehash_secret);
+ skip_ndevs = cb->args[0];
+ skip_naddr = cb->args[1];
+
+ idx = 0;
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ if (idx < skip_ndevs)
+ goto cont;
+ else if (idx > skip_ndevs) {
+@@ -869,10 +882,10 @@
+ rv = dn_dev_get_first(dev, addr);
+ read_unlock(&dev_base_lock);
+ dev_put(dev);
+- if (rv == 0 || dev == &loopback_dev)
++ if (rv == 0 || dev == &init_net.loopback_dev)
+ return rv;
+ }
+- dev = &loopback_dev;
++ dev = &init_net.loopback_dev;
+ dev_hold(dev);
+ goto last_chance;
+ }
+@@ -1299,7 +1312,7 @@
+ struct net_device *dev;
+
+ rtnl_lock();
+- for_each_netdev(dev)
++ for_each_netdev(&init_net, dev)
+ dn_dev_down(dev);
+ rtnl_unlock();
+
+@@ -1310,7 +1323,7 @@
+ struct net_device *dev;
+
+ rtnl_lock();
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ if (dev->flags & IFF_UP)
+ dn_dev_up(dev);
+ }
+@@ -1344,7 +1357,7 @@
+ return SEQ_START_TOKEN;
+
+ i = 1;
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ if (!is_dn_dev(dev))
+ continue;
+
+@@ -1363,9 +1376,9 @@
+
+ dev = (struct net_device *)v;
+ if (v == SEQ_START_TOKEN)
+- dev = net_device_entry(&dev_base_head);
++ dev = net_device_entry(&init_net.dev_base_head);
+
+- for_each_netdev_continue(dev) {
++ for_each_netdev_continue(&init_net, dev) {
+ if (!is_dn_dev(dev))
+ continue;
+
+@@ -1465,7 +1478,7 @@
+ rtnl_register(PF_DECnet, RTM_DELADDR, dn_nl_deladdr, NULL);
+ rtnl_register(PF_DECnet, RTM_GETADDR, NULL, dn_nl_dump_ifaddr);
+
+- proc_net_fops_create("decnet_dev", S_IRUGO, &dn_dev_seq_fops);
++ proc_net_fops_create(&init_net, "decnet_dev", S_IRUGO, &dn_dev_seq_fops);
+
+ #ifdef CONFIG_SYSCTL
+ {
+@@ -1486,7 +1499,7 @@
+ }
+ #endif /* CONFIG_SYSCTL */
+
+- proc_net_remove("decnet_dev");
++ proc_net_remove(&init_net, "decnet_dev");
+
+ dn_dev_devices_off();
+ }
+diff -Nurb linux-2.6.22-570/net/decnet/dn_fib.c linux-2.6.22-590/net/decnet/dn_fib.c
+--- linux-2.6.22-570/net/decnet/dn_fib.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/decnet/dn_fib.c 2008-01-29 22:12:32.000000000 -0500
+@@ -203,8 +203,6 @@
+ struct flowi fl;
+ struct dn_fib_res res;
+
+- memset(&fl, 0, sizeof(fl));
+-
+ if (nh->nh_flags&RTNH_F_ONLINK) {
+ struct net_device *dev;
+
+@@ -212,7 +210,7 @@
+ return -EINVAL;
+ if (dnet_addr_type(nh->nh_gw) != RTN_UNICAST)
+ return -EINVAL;
+- if ((dev = __dev_get_by_index(nh->nh_oif)) == NULL)
++ if ((dev = __dev_get_by_index(&init_net, nh->nh_oif)) == NULL)
+ return -ENODEV;
+ if (!(dev->flags&IFF_UP))
+ return -ENETDOWN;
+@@ -223,6 +221,7 @@
+ }
+
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ fl.fld_dst = nh->nh_gw;
+ fl.oif = nh->nh_oif;
+ fl.fld_scope = r->rtm_scope + 1;
+@@ -255,7 +254,7 @@
+ if (nh->nh_flags&(RTNH_F_PERVASIVE|RTNH_F_ONLINK))
+ return -EINVAL;
+
+- dev = __dev_get_by_index(nh->nh_oif);
++ dev = __dev_get_by_index(&init_net, nh->nh_oif);
+ if (dev == NULL || dev->dn_ptr == NULL)
+ return -ENODEV;
+ if (!(dev->flags&IFF_UP))
+@@ -355,7 +354,7 @@
+ if (nhs != 1 || nh->nh_gw)
+ goto err_inval;
+ nh->nh_scope = RT_SCOPE_NOWHERE;
+- nh->nh_dev = dev_get_by_index(fi->fib_nh->nh_oif);
++ nh->nh_dev = dev_get_by_index(&init_net, fi->fib_nh->nh_oif);
+ err = -ENODEV;
+ if (nh->nh_dev == NULL)
+ goto failure;
+@@ -506,10 +505,14 @@
+
+ static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct dn_fib_table *tb;
+ struct rtattr **rta = arg;
+ struct rtmsg *r = NLMSG_DATA(nlh);
+
++ if (net != &init_net)
++ return -EINVAL;
+
-+/*
-+ * Create an inet socket.
-+ */
+ if (dn_fib_check_attr(r, rta))
+ return -EINVAL;
+
+@@ -522,10 +525,14 @@
+
+ static int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct dn_fib_table *tb;
+ struct rtattr **rta = arg;
+ struct rtmsg *r = NLMSG_DATA(nlh);
+
++ if (net != &init_net)
++ return -EINVAL;
+
-+static int inet_create(struct socket *sock, int protocol)
+ if (dn_fib_check_attr(r, rta))
+ return -EINVAL;
+
+@@ -602,7 +609,7 @@
+
+ /* Scan device list */
+ read_lock(&dev_base_lock);
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ dn_db = dev->dn_ptr;
+ if (dn_db == NULL)
+ continue;
+diff -Nurb linux-2.6.22-570/net/decnet/dn_neigh.c linux-2.6.22-590/net/decnet/dn_neigh.c
+--- linux-2.6.22-570/net/decnet/dn_neigh.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/decnet/dn_neigh.c 2008-01-29 22:12:32.000000000 -0500
+@@ -38,6 +38,7 @@
+ #include <linux/rcupdate.h>
+ #include <linux/jhash.h>
+ #include <asm/atomic.h>
++#include <net/net_namespace.h>
+ #include <net/neighbour.h>
+ #include <net/dst.h>
+ #include <net/flow.h>
+@@ -591,6 +592,7 @@
+
+ seq = file->private_data;
+ seq->private = s;
++ s->net = get_net(PROC_NET(inode));
+ out:
+ return rc;
+ out_kfree:
+@@ -598,12 +600,20 @@
+ goto out;
+ }
+
++static int dn_neigh_seq_release(struct inode *inode, struct file *file)
+{
-+ struct sock *sk;
-+ struct list_head *p;
-+ struct inet_protosw *answer;
-+ struct inet_sock *inet;
-+ struct proto *answer_prot;
-+ unsigned char answer_flags;
-+ char answer_no_check;
-+ int try_loading_module = 0;
-+ int err;
-+
-+ if (sock->type != SOCK_RAW &&
-+ sock->type != SOCK_DGRAM &&
-+ !inet_ehash_secret)
-+ build_ehash_secret();
-+
-+ sock->state = SS_UNCONNECTED;
-+
-+ /* Look for the requested type/protocol pair. */
-+ answer = NULL;
-+lookup_protocol:
-+ err = -ESOCKTNOSUPPORT;
-+ rcu_read_lock();
-+ list_for_each_rcu(p, &inetsw[sock->type]) {
-+ answer = list_entry(p, struct inet_protosw, list);
-+
-+ /* Check the non-wild match. */
-+ if (protocol == answer->protocol) {
-+ if (protocol != IPPROTO_IP)
-+ break;
-+ } else {
-+ /* Check for the two wild cases. */
-+ if (IPPROTO_IP == protocol) {
-+ protocol = answer->protocol;
-+ break;
-+ }
-+ if (IPPROTO_IP == answer->protocol)
-+ break;
-+ }
-+ err = -EPROTONOSUPPORT;
-+ answer = NULL;
-+ }
-+
-+ if (unlikely(answer == NULL)) {
-+ if (try_loading_module < 2) {
-+ rcu_read_unlock();
-+ /*
-+ * Be more specific, e.g. net-pf-2-proto-132-type-1
-+ * (net-pf-PF_INET-proto-IPPROTO_SCTP-type-SOCK_STREAM)
-+ */
-+ if (++try_loading_module == 1)
-+ request_module("net-pf-%d-proto-%d-type-%d",
-+ PF_INET, protocol, sock->type);
-+ /*
-+ * Fall back to generic, e.g. net-pf-2-proto-132
-+ * (net-pf-PF_INET-proto-IPPROTO_SCTP)
-+ */
-+ else
-+ request_module("net-pf-%d-proto-%d",
-+ PF_INET, protocol);
-+ goto lookup_protocol;
-+ } else
-+ goto out_rcu_unlock;
-+ }
-+
-+ err = -EPERM;
-+ if ((protocol == IPPROTO_ICMP) &&
-+ nx_capable(answer->capability, NXC_RAW_ICMP))
-+ goto override;
-+ if (sock->type == SOCK_RAW &&
-+ nx_capable(answer->capability, NXC_RAW_SOCKET))
-+ goto override;
-+ if (answer->capability > 0 && !capable(answer->capability))
-+ goto out_rcu_unlock;
-+override:
-+ sock->ops = answer->ops;
-+ answer_prot = answer->prot;
-+ answer_no_check = answer->no_check;
-+ answer_flags = answer->flags;
-+ rcu_read_unlock();
-+
-+ BUG_TRAP(answer_prot->slab != NULL);
-+
-+ err = -ENOBUFS;
-+ sk = sk_alloc(PF_INET, GFP_KERNEL, answer_prot, 1);
-+ if (sk == NULL)
-+ goto out;
-+
-+ err = 0;
-+ sk->sk_no_check = answer_no_check;
-+ if (INET_PROTOSW_REUSE & answer_flags)
-+ sk->sk_reuse = 1;
-+
-+ inet = inet_sk(sk);
-+ inet->is_icsk = (INET_PROTOSW_ICSK & answer_flags) != 0;
-+
-+ if (SOCK_RAW == sock->type) {
-+ inet->num = protocol;
-+ if (IPPROTO_RAW == protocol)
-+ inet->hdrincl = 1;
-+ }
++ struct seq_file *seq = file->private_data;
++ struct neigh_seq_state *state = seq->private;
++ put_net(state->net);
++ return seq_release_private(inode, file);
++}
+
-+ if (ipv4_config.no_pmtu_disc)
-+ inet->pmtudisc = IP_PMTUDISC_DONT;
-+ else
-+ inet->pmtudisc = IP_PMTUDISC_WANT;
+ static const struct file_operations dn_neigh_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = dn_neigh_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+- .release = seq_release_private,
++ .release = dn_neigh_seq_release,
+ };
+
+ #endif
+@@ -611,11 +621,11 @@
+ void __init dn_neigh_init(void)
+ {
+ neigh_table_init(&dn_neigh_table);
+- proc_net_fops_create("decnet_neigh", S_IRUGO, &dn_neigh_seq_fops);
++ proc_net_fops_create(&init_net, "decnet_neigh", S_IRUGO, &dn_neigh_seq_fops);
+ }
+
+ void __exit dn_neigh_cleanup(void)
+ {
+- proc_net_remove("decnet_neigh");
++ proc_net_remove(&init_net, "decnet_neigh");
+ neigh_table_clear(&dn_neigh_table);
+ }
+diff -Nurb linux-2.6.22-570/net/decnet/dn_nsp_out.c linux-2.6.22-590/net/decnet/dn_nsp_out.c
+--- linux-2.6.22-570/net/decnet/dn_nsp_out.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/decnet/dn_nsp_out.c 2008-01-29 22:12:32.000000000 -0500
+@@ -91,6 +91,7 @@
+ }
+
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ fl.oif = sk->sk_bound_dev_if;
+ fl.fld_src = dn_saddr2dn(&scp->addr);
+ fl.fld_dst = dn_saddr2dn(&scp->peer);
+diff -Nurb linux-2.6.22-570/net/decnet/dn_route.c linux-2.6.22-590/net/decnet/dn_route.c
+--- linux-2.6.22-570/net/decnet/dn_route.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/decnet/dn_route.c 2008-01-29 22:12:32.000000000 -0500
+@@ -82,6 +82,7 @@
+ #include <net/dst.h>
+ #include <net/flow.h>
+ #include <net/fib_rules.h>
++#include <net/net_namespace.h>
+ #include <net/dn.h>
+ #include <net/dn_dev.h>
+ #include <net/dn_nsp.h>
+@@ -583,6 +584,9 @@
+ struct dn_dev *dn = (struct dn_dev *)dev->dn_ptr;
+ unsigned char padlen = 0;
+
++ if (dev->nd_net != &init_net)
++ goto dump_it;
++
+ if (dn == NULL)
+ goto dump_it;
+
+@@ -877,13 +881,14 @@
+
+ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *oldflp, int try_hard)
+ {
+- struct flowi fl = { .nl_u = { .dn_u =
++ struct flowi fl = { .fl_net = &init_net,
++ .nl_u = { .dn_u =
+ { .daddr = oldflp->fld_dst,
+ .saddr = oldflp->fld_src,
+ .scope = RT_SCOPE_UNIVERSE,
+ } },
+ .mark = oldflp->mark,
+- .iif = loopback_dev.ifindex,
++ .iif = init_net.loopback_dev.ifindex,
+ .oif = oldflp->oif };
+ struct dn_route *rt = NULL;
+ struct net_device *dev_out = NULL, *dev;
+@@ -900,11 +905,11 @@
+ "dn_route_output_slow: dst=%04x src=%04x mark=%d"
+ " iif=%d oif=%d\n", dn_ntohs(oldflp->fld_dst),
+ dn_ntohs(oldflp->fld_src),
+- oldflp->mark, loopback_dev.ifindex, oldflp->oif);
++ oldflp->mark, init_net.loopback_dev.ifindex, oldflp->oif);
+
+ /* If we have an output interface, verify its a DECnet device */
+ if (oldflp->oif) {
+- dev_out = dev_get_by_index(oldflp->oif);
++ dev_out = dev_get_by_index(&init_net, oldflp->oif);
+ err = -ENODEV;
+ if (dev_out && dev_out->dn_ptr == NULL) {
+ dev_put(dev_out);
+@@ -925,7 +930,7 @@
+ goto out;
+ }
+ read_lock(&dev_base_lock);
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ if (!dev->dn_ptr)
+ continue;
+ if (!dn_dev_islocal(dev, oldflp->fld_src))
+@@ -953,7 +958,7 @@
+ err = -EADDRNOTAVAIL;
+ if (dev_out)
+ dev_put(dev_out);
+- dev_out = &loopback_dev;
++ dev_out = &init_net.loopback_dev;
+ dev_hold(dev_out);
+ if (!fl.fld_dst) {
+ fl.fld_dst =
+@@ -962,7 +967,7 @@
+ if (!fl.fld_dst)
+ goto out;
+ }
+- fl.oif = loopback_dev.ifindex;
++ fl.oif = init_net.loopback_dev.ifindex;
+ res.type = RTN_LOCAL;
+ goto make_route;
+ }
+@@ -995,7 +1000,7 @@
+ * here
+ */
+ if (!try_hard) {
+- neigh = neigh_lookup_nodev(&dn_neigh_table, &fl.fld_dst);
++ neigh = neigh_lookup_nodev(&dn_neigh_table, &init_net, &fl.fld_dst);
+ if (neigh) {
+ if ((oldflp->oif &&
+ (neigh->dev->ifindex != oldflp->oif)) ||
+@@ -1008,7 +1013,7 @@
+ if (dev_out)
+ dev_put(dev_out);
+ if (dn_dev_islocal(neigh->dev, fl.fld_dst)) {
+- dev_out = &loopback_dev;
++ dev_out = &init_net.loopback_dev;
+ res.type = RTN_LOCAL;
+ } else {
+ dev_out = neigh->dev;
+@@ -1029,7 +1034,7 @@
+ /* Possible improvement - check all devices for local addr */
+ if (dn_dev_islocal(dev_out, fl.fld_dst)) {
+ dev_put(dev_out);
+- dev_out = &loopback_dev;
++ dev_out = &init_net.loopback_dev;
+ dev_hold(dev_out);
+ res.type = RTN_LOCAL;
+ goto select_source;
+@@ -1065,7 +1070,7 @@
+ fl.fld_src = fl.fld_dst;
+ if (dev_out)
+ dev_put(dev_out);
+- dev_out = &loopback_dev;
++ dev_out = &init_net.loopback_dev;
+ dev_hold(dev_out);
+ fl.oif = dev_out->ifindex;
+ if (res.fi)
+@@ -1103,6 +1108,7 @@
+ atomic_set(&rt->u.dst.__refcnt, 1);
+ rt->u.dst.flags = DST_HOST;
+
++ rt->fl.fl_net = &init_net;
+ rt->fl.fld_src = oldflp->fld_src;
+ rt->fl.fld_dst = oldflp->fld_dst;
+ rt->fl.oif = oldflp->oif;
+@@ -1226,7 +1232,8 @@
+ int flags = 0;
+ __le16 gateway = 0;
+ __le16 local_src = 0;
+- struct flowi fl = { .nl_u = { .dn_u =
++ struct flowi fl = { .fl_net = &init_net,
++ .nl_u = { .dn_u =
+ { .daddr = cb->dst,
+ .saddr = cb->src,
+ .scope = RT_SCOPE_UNIVERSE,
+@@ -1374,6 +1381,7 @@
+ rt->rt_dst_map = fl.fld_dst;
+ rt->rt_src_map = fl.fld_src;
+
++ rt->fl.fl_net = &init_net;
+ rt->fl.fld_src = cb->src;
+ rt->fl.fld_dst = cb->dst;
+ rt->fl.oif = 0;
+@@ -1526,6 +1534,7 @@
+ */
+ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void *arg)
+ {
++ struct net *net = in_skb->sk->sk_net;
+ struct rtattr **rta = arg;
+ struct rtmsg *rtm = NLMSG_DATA(nlh);
+ struct dn_route *rt = NULL;
+@@ -1534,7 +1543,11 @@
+ struct sk_buff *skb;
+ struct flowi fl;
+
++ if (net != &init_net)
++ return -EINVAL;
+
-+ inet->id = 0;
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ fl.proto = DNPROTO_NSP;
+
+ skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
+@@ -1552,7 +1565,7 @@
+
+ if (fl.iif) {
+ struct net_device *dev;
+- if ((dev = dev_get_by_index(fl.iif)) == NULL) {
++ if ((dev = dev_get_by_index(&init_net, fl.iif)) == NULL) {
+ kfree_skb(skb);
+ return -ENODEV;
+ }
+@@ -1598,7 +1611,7 @@
+ goto out_free;
+ }
+
+- return rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
++ return rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
+
+ out_free:
+ kfree_skb(skb);
+@@ -1611,10 +1624,14 @@
+ */
+ int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct dn_route *rt;
+ int h, s_h;
+ int idx, s_idx;
+
++ if (net != &init_net)
++ return 0;
+
-+ sock_init_data(sock, sk);
+ if (NLMSG_PAYLOAD(cb->nlh, 0) < sizeof(struct rtmsg))
+ return -EINVAL;
+ if (!(((struct rtmsg *)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED))
+@@ -1814,7 +1831,7 @@
+
+ dn_dst_ops.gc_thresh = (dn_rt_hash_mask + 1);
+
+- proc_net_fops_create("decnet_cache", S_IRUGO, &dn_rt_cache_seq_fops);
++ proc_net_fops_create(&init_net, "decnet_cache", S_IRUGO, &dn_rt_cache_seq_fops);
+
+ #ifdef CONFIG_DECNET_ROUTER
+ rtnl_register(PF_DECnet, RTM_GETROUTE, dn_cache_getroute, dn_fib_dump);
+@@ -1829,6 +1846,6 @@
+ del_timer(&dn_route_timer);
+ dn_run_flush(0);
+
+- proc_net_remove("decnet_cache");
++ proc_net_remove(&init_net, "decnet_cache");
+ }
+
+diff -Nurb linux-2.6.22-570/net/decnet/dn_rules.c linux-2.6.22-590/net/decnet/dn_rules.c
+--- linux-2.6.22-570/net/decnet/dn_rules.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/decnet/dn_rules.c 2008-01-29 22:12:32.000000000 -0500
+@@ -186,7 +186,10 @@
+
+ unsigned dnet_addr_type(__le16 addr)
+ {
+- struct flowi fl = { .nl_u = { .dn_u = { .daddr = addr } } };
++ struct flowi fl = {
++ .fl_net = &init_net,
++ .nl_u = { .dn_u = { .daddr = addr } }
++ };
+ struct dn_fib_res res;
+ unsigned ret = RTN_UNICAST;
+ struct dn_fib_table *tb = dn_fib_get_table(RT_TABLE_LOCAL, 0);
+@@ -223,7 +226,7 @@
+ return -ENOBUFS;
+ }
+
+-static u32 dn_fib_rule_default_pref(void)
++static u32 dn_fib_rule_default_pref(struct fib_rules_ops *ops)
+ {
+ struct list_head *pos;
+ struct fib_rule *rule;
+@@ -240,7 +243,7 @@
+ return 0;
+ }
+
+-static void dn_fib_rule_flush_cache(void)
++static void dn_fib_rule_flush_cache(struct fib_rules_ops *ops)
+ {
+ dn_rt_cache_flush(-1);
+ }
+@@ -265,12 +268,12 @@
+ void __init dn_fib_rules_init(void)
+ {
+ list_add_tail(&default_rule.common.list, &dn_fib_rules);
+- fib_rules_register(&dn_fib_rules_ops);
++ fib_rules_register(&init_net, &dn_fib_rules_ops);
+ }
+
+ void __exit dn_fib_rules_cleanup(void)
+ {
+- fib_rules_unregister(&dn_fib_rules_ops);
++ fib_rules_unregister(&init_net, &dn_fib_rules_ops);
+ }
+
+
+diff -Nurb linux-2.6.22-570/net/decnet/dn_table.c linux-2.6.22-590/net/decnet/dn_table.c
+--- linux-2.6.22-570/net/decnet/dn_table.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/decnet/dn_table.c 2008-01-29 22:12:32.000000000 -0500
+@@ -375,10 +375,10 @@
+ kfree_skb(skb);
+ goto errout;
+ }
+- err = rtnl_notify(skb, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL);
++ err = rtnl_notify(skb, &init_net, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL);
+ errout:
+ if (err < 0)
+- rtnl_set_sk_err(RTNLGRP_DECnet_ROUTE, err);
++ rtnl_set_sk_err(&init_net, RTNLGRP_DECnet_ROUTE, err);
+ }
+
+ static __inline__ int dn_hash_dump_bucket(struct sk_buff *skb,
+@@ -463,12 +463,16 @@
+
+ int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb)
+ {
++ struct net *net = skb->sk->sk_net;
+ unsigned int h, s_h;
+ unsigned int e = 0, s_e;
+ struct dn_fib_table *tb;
+ struct hlist_node *node;
+ int dumped = 0;
+
++ if (net != &init_net)
++ return 0;
+
-+ sk->sk_destruct = inet_sock_destruct;
-+ sk->sk_family = PF_INET;
-+ sk->sk_protocol = protocol;
-+ sk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
+ if (NLMSG_PAYLOAD(cb->nlh, 0) >= sizeof(struct rtmsg) &&
+ ((struct rtmsg *)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED)
+ return dn_cache_dump(skb, cb);
+diff -Nurb linux-2.6.22-570/net/decnet/netfilter/dn_rtmsg.c linux-2.6.22-590/net/decnet/netfilter/dn_rtmsg.c
+--- linux-2.6.22-570/net/decnet/netfilter/dn_rtmsg.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/decnet/netfilter/dn_rtmsg.c 2008-01-29 22:12:32.000000000 -0500
+@@ -93,6 +93,10 @@
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ dnrmg_send_peer(*pskb);
+ return NF_ACCEPT;
+ }
+@@ -137,7 +141,8 @@
+ {
+ int rv = 0;
+
+- dnrmg = netlink_kernel_create(NETLINK_DNRTMSG, DNRNG_NLGRP_MAX,
++ dnrmg = netlink_kernel_create(&init_net,
++ NETLINK_DNRTMSG, DNRNG_NLGRP_MAX,
+ dnrmg_receive_user_sk, NULL, THIS_MODULE);
+ if (dnrmg == NULL) {
+ printk(KERN_ERR "dn_rtmsg: Cannot create netlink socket");
+diff -Nurb linux-2.6.22-570/net/decnet/sysctl_net_decnet.c linux-2.6.22-590/net/decnet/sysctl_net_decnet.c
+--- linux-2.6.22-570/net/decnet/sysctl_net_decnet.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/decnet/sysctl_net_decnet.c 2008-01-29 22:12:32.000000000 -0500
+@@ -259,7 +259,7 @@
+
+ devname[newlen] = 0;
+
+- dev = dev_get_by_name(devname);
++ dev = dev_get_by_name(&init_net, devname);
+ if (dev == NULL)
+ return -ENODEV;
+
+@@ -299,7 +299,7 @@
+ devname[*lenp] = 0;
+ strip_it(devname);
+
+- dev = dev_get_by_name(devname);
++ dev = dev_get_by_name(&init_net, devname);
+ if (dev == NULL)
+ return -ENODEV;
+
+diff -Nurb linux-2.6.22-570/net/econet/af_econet.c linux-2.6.22-590/net/econet/af_econet.c
+--- linux-2.6.22-570/net/econet/af_econet.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/econet/af_econet.c 2008-01-29 22:12:32.000000000 -0500
+@@ -608,12 +608,15 @@
+ * Create an Econet socket
+ */
+
+-static int econet_create(struct socket *sock, int protocol)
++static int econet_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct sock *sk;
+ struct econet_sock *eo;
+ int err;
+
++ if (net != &init_net)
++ return -EAFNOSUPPORT;
+
-+ inet->uc_ttl = -1;
-+ inet->mc_loop = 1;
-+ inet->mc_ttl = 1;
-+ inet->mc_index = 0;
-+ inet->mc_list = NULL;
+ /* Econet only provides datagram services. */
+ if (sock->type != SOCK_DGRAM)
+ return -ESOCKTNOSUPPORT;
+@@ -621,7 +624,7 @@
+ sock->state = SS_UNCONNECTED;
+
+ err = -ENOBUFS;
+- sk = sk_alloc(PF_ECONET, GFP_KERNEL, &econet_proto, 1);
++ sk = sk_alloc(net, PF_ECONET, GFP_KERNEL, &econet_proto, 1);
+ if (sk == NULL)
+ goto out;
+
+@@ -659,7 +662,7 @@
+ if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
+ return -EFAULT;
+
+- if ((dev = dev_get_by_name(ifr.ifr_name)) == NULL)
++ if ((dev = dev_get_by_name(&init_net, ifr.ifr_name)) == NULL)
+ return -ENODEV;
+
+ sec = (struct sockaddr_ec *)&ifr.ifr_addr;
+@@ -1062,6 +1065,9 @@
+ struct sock *sk;
+ struct ec_device *edev = dev->ec_ptr;
+
++ if (dev->nd_net != &init_net)
++ goto drop;
+
-+ sk_refcnt_debug_inc(sk);
+ if (skb->pkt_type == PACKET_OTHERHOST)
+ goto drop;
+
+@@ -1116,6 +1122,9 @@
+ struct net_device *dev = (struct net_device *)data;
+ struct ec_device *edev;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
+
-+ if (inet->num) {
-+ /* It assumes that any protocol which allows
-+ * the user to assign a number at socket
-+ * creation time automatically
-+ * shares.
-+ */
-+ inet->sport = htons(inet->num);
-+ /* Add to protocol hash chains. */
-+ sk->sk_prot->hash(sk);
-+ }
+ switch (msg) {
+ case NETDEV_UNREGISTER:
+ /* A device has gone down - kill any data we hold for it. */
+diff -Nurb linux-2.6.22-570/net/ieee80211/ieee80211_module.c linux-2.6.22-590/net/ieee80211/ieee80211_module.c
+--- linux-2.6.22-570/net/ieee80211/ieee80211_module.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ieee80211/ieee80211_module.c 2008-01-29 22:12:32.000000000 -0500
+@@ -264,7 +264,7 @@
+ struct proc_dir_entry *e;
+
+ ieee80211_debug_level = debug;
+- ieee80211_proc = proc_mkdir(DRV_NAME, proc_net);
++ ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net);
+ if (ieee80211_proc == NULL) {
+ IEEE80211_ERROR("Unable to create " DRV_NAME
+ " proc directory\n");
+@@ -273,7 +273,7 @@
+ e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
+ ieee80211_proc);
+ if (!e) {
+- remove_proc_entry(DRV_NAME, proc_net);
++ remove_proc_entry(DRV_NAME, init_net.proc_net);
+ ieee80211_proc = NULL;
+ return -EIO;
+ }
+@@ -293,7 +293,7 @@
+ #ifdef CONFIG_IEEE80211_DEBUG
+ if (ieee80211_proc) {
+ remove_proc_entry("debug_level", ieee80211_proc);
+- remove_proc_entry(DRV_NAME, proc_net);
++ remove_proc_entry(DRV_NAME, init_net.proc_net);
+ ieee80211_proc = NULL;
+ }
+ #endif /* CONFIG_IEEE80211_DEBUG */
+diff -Nurb linux-2.6.22-570/net/ipv4/Kconfig linux-2.6.22-590/net/ipv4/Kconfig
+--- linux-2.6.22-570/net/ipv4/Kconfig 2008-01-29 22:12:23.000000000 -0500
++++ linux-2.6.22-590/net/ipv4/Kconfig 2008-01-29 22:12:32.000000000 -0500
+@@ -116,48 +116,6 @@
+ equal "cost" and chooses one of them in a non-deterministic fashion
+ if a matching packet arrives.
+
+-config IP_ROUTE_MULTIPATH_CACHED
+- bool "IP: equal cost multipath with caching support (EXPERIMENTAL)"
+- depends on IP_ROUTE_MULTIPATH
+- help
+- Normally, equal cost multipath routing is not supported by the
+- routing cache. If you say Y here, alternative routes are cached
+- and on cache lookup a route is chosen in a configurable fashion.
+-
+- If unsure, say N.
+-
+-config IP_ROUTE_MULTIPATH_RR
+- tristate "MULTIPATH: round robin algorithm"
+- depends on IP_ROUTE_MULTIPATH_CACHED
+- help
+- Multipath routes are chosen according to Round Robin
+-
+-config IP_ROUTE_MULTIPATH_RANDOM
+- tristate "MULTIPATH: random algorithm"
+- depends on IP_ROUTE_MULTIPATH_CACHED
+- help
+- Multipath routes are chosen in a random fashion. Actually,
+- there is no weight for a route. The advantage of this policy
+- is that it is implemented stateless and therefore introduces only
+- a very small delay.
+-
+-config IP_ROUTE_MULTIPATH_WRANDOM
+- tristate "MULTIPATH: weighted random algorithm"
+- depends on IP_ROUTE_MULTIPATH_CACHED
+- help
+- Multipath routes are chosen in a weighted random fashion.
+- The per route weights are the weights visible via ip route 2. As the
+- corresponding state management introduces some overhead routing delay
+- is increased.
+-
+-config IP_ROUTE_MULTIPATH_DRR
+- tristate "MULTIPATH: interface round robin algorithm"
+- depends on IP_ROUTE_MULTIPATH_CACHED
+- help
+- Connections are distributed in a round robin fashion over the
+- available interfaces. This policy makes sense if the connections
+- should be primarily distributed on interfaces and not on routes.
+-
+ config IP_ROUTE_VERBOSE
+ bool "IP: verbose route monitoring"
+ depends on IP_ADVANCED_ROUTER
+diff -Nurb linux-2.6.22-570/net/ipv4/Makefile linux-2.6.22-590/net/ipv4/Makefile
+--- linux-2.6.22-570/net/ipv4/Makefile 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/Makefile 2008-01-29 22:12:32.000000000 -0500
+@@ -29,14 +29,9 @@
+ obj-$(CONFIG_INET_XFRM_MODE_TRANSPORT) += xfrm4_mode_transport.o
+ obj-$(CONFIG_INET_XFRM_MODE_TUNNEL) += xfrm4_mode_tunnel.o
+ obj-$(CONFIG_IP_PNP) += ipconfig.o
+-obj-$(CONFIG_IP_ROUTE_MULTIPATH_RR) += multipath_rr.o
+-obj-$(CONFIG_IP_ROUTE_MULTIPATH_RANDOM) += multipath_random.o
+-obj-$(CONFIG_IP_ROUTE_MULTIPATH_WRANDOM) += multipath_wrandom.o
+-obj-$(CONFIG_IP_ROUTE_MULTIPATH_DRR) += multipath_drr.o
+ obj-$(CONFIG_NETFILTER) += netfilter.o netfilter/
+ obj-$(CONFIG_IP_VS) += ipvs/
+ obj-$(CONFIG_INET_DIAG) += inet_diag.o
+-obj-$(CONFIG_IP_ROUTE_MULTIPATH_CACHED) += multipath.o
+ obj-$(CONFIG_INET_TCP_DIAG) += tcp_diag.o
+ obj-$(CONFIG_NET_TCPPROBE) += tcp_probe.o
+ obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o
+diff -Nurb linux-2.6.22-570/net/ipv4/af_inet.c linux-2.6.22-590/net/ipv4/af_inet.c
+--- linux-2.6.22-570/net/ipv4/af_inet.c 2008-01-29 22:12:24.000000000 -0500
++++ linux-2.6.22-590/net/ipv4/af_inet.c 2008-01-29 22:12:32.000000000 -0500
+@@ -244,7 +244,7 @@
+ * Create an inet socket.
+ */
+
+-static int inet_create(struct socket *sock, int protocol)
++static int inet_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct sock *sk;
+ struct list_head *p;
+@@ -310,6 +310,10 @@
+ goto out_rcu_unlock;
+ }
+
++ err = -EPROTONOSUPPORT;
++ if (!(answer->flags & INET_PROTOSW_NETNS) && (net != &init_net))
++ goto out_rcu_unlock;
+
-+ if (sk->sk_prot->init) {
-+ err = sk->sk_prot->init(sk);
-+ if (err)
-+ sk_common_release(sk);
-+ }
-+out:
-+ return err;
-+out_rcu_unlock:
-+ rcu_read_unlock();
-+ goto out;
-+}
+ err = -EPERM;
+ if ((protocol == IPPROTO_ICMP) &&
+ nx_capable(answer->capability, NXC_RAW_ICMP))
+@@ -326,7 +330,7 @@
+ BUG_TRAP(answer_prot->slab != NULL);
+
+ err = -ENOBUFS;
+- sk = sk_alloc(PF_INET, GFP_KERNEL, answer_prot, 1);
++ sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot, 1);
+ if (sk == NULL)
+ goto out;
+
+@@ -344,7 +348,7 @@
+ inet->hdrincl = 1;
+ }
+
+- if (ipv4_config.no_pmtu_disc)
++ if (net->sysctl_ipv4_no_pmtu_disc)
+ inet->pmtudisc = IP_PMTUDISC_DONT;
+ else
+ inet->pmtudisc = IP_PMTUDISC_WANT;
+@@ -423,12 +427,12 @@
+ }
+
+ /* It is off by default, see below. */
+-int sysctl_ip_nonlocal_bind __read_mostly;
+
+ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
+ {
+ struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
+ struct sock *sk = sock->sk;
++ struct net *net = sk->sk_net;
+ struct inet_sock *inet = inet_sk(sk);
+ struct nx_v4_sock_addr nsa;
+ unsigned short snum;
+@@ -448,7 +452,7 @@
+ if (err)
+ goto out;
+
+- chk_addr_ret = inet_addr_type(nsa.saddr);
++ chk_addr_ret = inet_addr_type(net, nsa.saddr);
+
+ /* Not specified by any standard per-se, however it breaks too
+ * many applications when removed. It is unfortunate since
+@@ -458,7 +462,7 @@
+ * is temporarily down)
+ */
+ err = -EADDRNOTAVAIL;
+- if (!sysctl_ip_nonlocal_bind &&
++ if (!net->sysctl_ip_nonlocal_bind &&
+ !inet->freebind &&
+ nsa.saddr != INADDR_ANY &&
+ chk_addr_ret != RTN_LOCAL &&
+@@ -787,6 +791,7 @@
+ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+ {
+ struct sock *sk = sock->sk;
++ struct net *net = sk->sk_net;
+ int err = 0;
+
+ switch (cmd) {
+@@ -799,12 +804,12 @@
+ case SIOCADDRT:
+ case SIOCDELRT:
+ case SIOCRTMSG:
+- err = ip_rt_ioctl(cmd, (void __user *)arg);
++ err = ip_rt_ioctl(net, cmd, (void __user *)arg);
+ break;
+ case SIOCDARP:
+ case SIOCGARP:
+ case SIOCSARP:
+- err = arp_ioctl(cmd, (void __user *)arg);
++ err = arp_ioctl(net, cmd, (void __user *)arg);
+ break;
+ case SIOCGIFADDR:
+ case SIOCSIFADDR:
+@@ -817,7 +822,7 @@
+ case SIOCSIFPFLAGS:
+ case SIOCGIFPFLAGS:
+ case SIOCSIFFLAGS:
+- err = devinet_ioctl(cmd, (void __user *)arg);
++ err = devinet_ioctl(net, cmd, (void __user *)arg);
+ break;
+ default:
+ if (sk->sk_prot->ioctl)
+@@ -927,7 +932,8 @@
+ .capability = -1,
+ .no_check = 0,
+ .flags = INET_PROTOSW_PERMANENT |
+- INET_PROTOSW_ICSK,
++ INET_PROTOSW_ICSK |
++ INET_PROTOSW_NETNS,
+ },
+
+ {
+@@ -937,7 +943,8 @@
+ .ops = &inet_dgram_ops,
+ .capability = -1,
+ .no_check = UDP_CSUM_DEFAULT,
+- .flags = INET_PROTOSW_PERMANENT,
++ .flags = INET_PROTOSW_PERMANENT |
++ INET_PROTOSW_NETNS,
+ },
+
+
+@@ -948,7 +955,8 @@
+ .ops = &inet_sockraw_ops,
+ .capability = CAP_NET_RAW,
+ .no_check = UDP_CSUM_DEFAULT,
+- .flags = INET_PROTOSW_REUSE,
++ .flags = INET_PROTOSW_REUSE |
++ INET_PROTOSW_NETNS,
+ }
+ };
+
+@@ -1029,8 +1037,6 @@
+ * Shall we try to damage output packets if routing dev changes?
+ */
+
+-int sysctl_ip_dynaddr __read_mostly;
+-
+ static int inet_sk_reselect_saddr(struct sock *sk)
+ {
+ struct inet_sock *inet = inet_sk(sk);
+@@ -1059,7 +1065,7 @@
+ if (new_saddr == old_saddr)
+ return 0;
+
+- if (sysctl_ip_dynaddr > 1) {
++ if (sk->sk_net->sysctl_ip_dynaddr > 1) {
+ printk(KERN_INFO "%s(): shifting inet->"
+ "saddr from %d.%d.%d.%d to %d.%d.%d.%d\n",
+ __FUNCTION__,
+@@ -1098,6 +1104,7 @@
+ daddr = inet->opt->faddr;
+ {
+ struct flowi fl = {
++ .fl_net = sk->sk_net,
+ .oif = sk->sk_bound_dev_if,
+ .nl_u = {
+ .ip4_u = {
+@@ -1127,7 +1134,7 @@
+ * Other protocols have to map its equivalent state to TCP_SYN_SENT.
+ * DCCP maps its DCCP_REQUESTING state to TCP_SYN_SENT. -acme
+ */
+- if (!sysctl_ip_dynaddr ||
++ if (!sk->sk_net->sysctl_ip_dynaddr ||
+ sk->sk_state != TCP_SYN_SENT ||
+ (sk->sk_userlocks & SOCK_BINDADDR_LOCK) ||
+ (err = inet_sk_reselect_saddr(sk)) != 0)
+@@ -1183,6 +1190,9 @@
+ int ihl;
+ int id;
+
++ if (!(features & NETIF_F_V4_CSUM))
++ features &= ~NETIF_F_SG;
+
+ if (unlikely(skb_shinfo(skb)->gso_type &
+ ~(SKB_GSO_TCPV4 |
+ SKB_GSO_UDP |
+@@ -1353,6 +1363,24 @@
+ .gso_segment = inet_gso_segment,
+ };
+
+
-+/*
-+ * The peer socket should always be NULL (or else). When we call this
-+ * function we are destroying the object and from then on nobody
-+ * should refer to it.
-+ */
-+int inet_release(struct socket *sock)
++static int inet_net_init(struct net *net)
+{
-+ struct sock *sk = sock->sk;
-+
-+ if (sk) {
-+ long timeout;
++ net->sysctl_ip_default_ttl = IPDEFTTL;
++ net->sysctl_ip_dynaddr = 0;
+
-+ /* Applications forget to leave groups before exiting */
-+ ip_mc_drop_socket(sk);
-+
-+ /* If linger is set, we don't return until the close
-+ * is complete. Otherwise we return immediately. The
-+ * actually closing is done the same either way.
-+ *
-+ * If the close is due to the process exiting, we never
-+ * linger..
-+ */
-+ timeout = 0;
-+ if (sock_flag(sk, SOCK_LINGER) &&
-+ !(current->flags & PF_EXITING))
-+ timeout = sk->sk_lingertime;
-+ sock->sk = NULL;
-+ sk->sk_prot->close(sk, timeout);
-+ }
+ return 0;
+}
+
-+/* It is off by default, see below. */
-+int sysctl_ip_nonlocal_bind __read_mostly;
-+
-+int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
++static void inet_net_exit(struct net *net)
+{
-+ struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
-+ struct sock *sk = sock->sk;
-+ struct inet_sock *inet = inet_sk(sk);
-+ struct nx_v4_sock_addr nsa;
-+ unsigned short snum;
-+ int chk_addr_ret;
-+ int err;
-+
-+ /* If the socket has its own bind function then use it. (RAW) */
-+ if (sk->sk_prot->bind) {
-+ err = sk->sk_prot->bind(sk, uaddr, addr_len);
-+ goto out;
-+ }
-+ err = -EINVAL;
-+ if (addr_len < sizeof(struct sockaddr_in))
-+ goto out;
-+
-+ err = v4_map_sock_addr(inet, addr, &nsa);
-+ if (err)
-+ goto out;
-+
-+ chk_addr_ret = inet_addr_type(nsa.saddr);
-+
-+ /* Not specified by any standard per-se, however it breaks too
-+ * many applications when removed. It is unfortunate since
-+ * allowing applications to make a non-local bind solves
-+ * several problems with systems using dynamic addressing.
-+ * (ie. your servers still start up even if your ISDN link
-+ * is temporarily down)
-+ */
-+ err = -EADDRNOTAVAIL;
-+ if (!sysctl_ip_nonlocal_bind &&
-+ !inet->freebind &&
-+ nsa.saddr != INADDR_ANY &&
-+ chk_addr_ret != RTN_LOCAL &&
-+ chk_addr_ret != RTN_MULTICAST &&
-+ chk_addr_ret != RTN_BROADCAST)
-+ goto out;
-+
-+ snum = ntohs(addr->sin_port);
-+ err = -EACCES;
-+ if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
-+ goto out;
-+
-+ /* We keep a pair of addresses. rcv_saddr is the one
-+ * used by hash lookups, and saddr is used for transmit.
-+ *
-+ * In the BSD API these are the same except where it
-+ * would be illegal to use them (multicast/broadcast) in
-+ * which case the sending device address is used.
-+ */
-+ lock_sock(sk);
-+
-+ /* Check these errors (active socket, double bind). */
-+ err = -EINVAL;
-+ if (sk->sk_state != TCP_CLOSE || inet->num)
-+ goto out_release_sock;
-+
-+ v4_set_sock_addr(inet, &nsa);
-+ if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
-+ inet->saddr = 0; /* Use device */
-+
-+ /* Make sure we are allowed to bind here. */
-+ if (sk->sk_prot->get_port(sk, snum)) {
-+ inet->saddr = inet->rcv_saddr = 0;
-+ err = -EADDRINUSE;
-+ goto out_release_sock;
-+ }
-+
-+ if (inet->rcv_saddr)
-+ sk->sk_userlocks |= SOCK_BINDADDR_LOCK;
-+ if (snum)
-+ sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
-+ inet->sport = htons(inet->num);
-+ inet->daddr = 0;
-+ inet->dport = 0;
-+ sk_dst_reset(sk);
-+ err = 0;
-+out_release_sock:
-+ release_sock(sk);
-+out:
-+ return err;
+}
+
-+int inet_dgram_connect(struct socket *sock, struct sockaddr * uaddr,
-+ int addr_len, int flags)
-+{
-+ struct sock *sk = sock->sk;
++static struct pernet_operations inet_net_ops = {
++ .init = inet_net_init,
++ .exit = inet_net_exit,
++};
+
-+ if (uaddr->sa_family == AF_UNSPEC)
-+ return sk->sk_prot->disconnect(sk, flags);
+ static int __init inet_init(void)
+ {
+ struct sk_buff *dummy_skb;
+@@ -1374,6 +1402,10 @@
+ if (rc)
+ goto out_unregister_udp_proto;
+
++ rc = register_pernet_subsys(&inet_net_ops);
++ if (rc)
++ goto out_unregister_raw_proto;
+
-+ if (!inet_sk(sk)->num && inet_autobind(sk))
-+ return -EAGAIN;
-+ return sk->sk_prot->connect(sk, (struct sockaddr *)uaddr, addr_len);
-+}
+ /*
+ * Tell SOCKET that we are alive...
+ */
+@@ -1450,6 +1482,8 @@
+ rc = 0;
+ out:
+ return rc;
++out_unregister_raw_proto:
++ proto_unregister(&raw_prot);
+ out_unregister_udp_proto:
+ proto_unregister(&udp_prot);
+ out_unregister_tcp_proto:
+@@ -1472,15 +1506,11 @@
+ goto out_tcp;
+ if (udp4_proc_init())
+ goto out_udp;
+- if (fib_proc_init())
+- goto out_fib;
+ if (ip_misc_proc_init())
+ goto out_misc;
+ out:
+ return rc;
+ out_misc:
+- fib_proc_exit();
+-out_fib:
+ udp4_proc_exit();
+ out_udp:
+ tcp4_proc_exit();
+@@ -1516,4 +1546,3 @@
+ EXPORT_SYMBOL(inet_stream_ops);
+ EXPORT_SYMBOL(inet_unregister_protosw);
+ EXPORT_SYMBOL(net_statistics);
+-EXPORT_SYMBOL(sysctl_ip_nonlocal_bind);
+diff -Nurb linux-2.6.22-570/net/ipv4/ah4.c linux-2.6.22-590/net/ipv4/ah4.c
+--- linux-2.6.22-570/net/ipv4/ah4.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/ipv4/ah4.c 2008-01-29 22:12:32.000000000 -0500
+@@ -198,6 +198,9 @@
+ struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+(iph->ihl<<2));
+ struct xfrm_state *x;
+
++ if (skb->dev->nd_net != &init_net)
++ return;
+
-+static long inet_wait_for_connect(struct sock *sk, long timeo)
-+{
-+ DEFINE_WAIT(wait);
+ if (icmp_hdr(skb)->type != ICMP_DEST_UNREACH ||
+ icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
+ return;
+@@ -339,3 +342,4 @@
+ module_init(ah4_init);
+ module_exit(ah4_fini);
+ MODULE_LICENSE("GPL");
++MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_AH);
+diff -Nurb linux-2.6.22-570/net/ipv4/arp.c linux-2.6.22-590/net/ipv4/arp.c
+--- linux-2.6.22-570/net/ipv4/arp.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/arp.c 2008-01-29 22:12:32.000000000 -0500
+@@ -109,6 +109,7 @@
+ #include <net/protocol.h>
+ #include <net/tcp.h>
+ #include <net/sock.h>
++#include <net/net_namespace.h>
+ #include <net/arp.h>
+ #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
+ #include <net/ax25.h>
+@@ -235,10 +236,11 @@
+ {
+ __be32 addr = *(__be32*)neigh->primary_key;
+ struct net_device *dev = neigh->dev;
++ struct net *net = dev->nd_net;
+ struct in_device *in_dev;
+ struct neigh_parms *parms;
+
+- neigh->type = inet_addr_type(addr);
++ neigh->type = inet_addr_type(net, addr);
+
+ rcu_read_lock();
+ in_dev = __in_dev_get_rcu(dev);
+@@ -332,6 +334,7 @@
+ __be32 saddr = 0;
+ u8 *dst_ha = NULL;
+ struct net_device *dev = neigh->dev;
++ struct net *net = dev->nd_net;
+ __be32 target = *(__be32*)neigh->primary_key;
+ int probes = atomic_read(&neigh->probes);
+ struct in_device *in_dev = in_dev_get(dev);
+@@ -342,14 +345,14 @@
+ switch (IN_DEV_ARP_ANNOUNCE(in_dev)) {
+ default:
+ case 0: /* By default announce any local IP */
+- if (skb && inet_addr_type(ip_hdr(skb)->saddr) == RTN_LOCAL)
++ if (skb && inet_addr_type(net, ip_hdr(skb)->saddr) == RTN_LOCAL)
+ saddr = ip_hdr(skb)->saddr;
+ break;
+ case 1: /* Restrict announcements of saddr in same subnet */
+ if (!skb)
+ break;
+ saddr = ip_hdr(skb)->saddr;
+- if (inet_addr_type(saddr) == RTN_LOCAL) {
++ if (inet_addr_type(net, saddr) == RTN_LOCAL) {
+ /* saddr should be known to target */
+ if (inet_addr_onlink(in_dev, target, saddr))
+ break;
+@@ -386,6 +389,7 @@
+ static int arp_ignore(struct in_device *in_dev, struct net_device *dev,
+ __be32 sip, __be32 tip)
+ {
++ struct net *net = dev->nd_net;
+ int scope;
+
+ switch (IN_DEV_ARP_IGNORE(in_dev)) {
+@@ -416,13 +420,15 @@
+ default:
+ return 0;
+ }
+- return !inet_confirm_addr(dev, sip, tip, scope);
++ return !inet_confirm_addr(net, dev, sip, tip, scope);
+ }
+
+ static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev)
+ {
+- struct flowi fl = { .nl_u = { .ip4_u = { .daddr = sip,
+- .saddr = tip } } };
++ struct flowi fl = {
++ .fl_net = dev->nd_net,
++ .nl_u = { .ip4_u = { .daddr = sip, .saddr = tip } }
++ };
+ struct rtable *rt;
+ int flag = 0;
+ /*unsigned long now; */
+@@ -469,6 +475,7 @@
+ int arp_find(unsigned char *haddr, struct sk_buff *skb)
+ {
+ struct net_device *dev = skb->dev;
++ struct net *net = dev->nd_net;
+ __be32 paddr;
+ struct neighbour *n;
+
+@@ -480,7 +487,7 @@
+
+ paddr = ((struct rtable*)skb->dst)->rt_gateway;
+
+- if (arp_set_predefined(inet_addr_type(paddr), haddr, paddr, dev))
++ if (arp_set_predefined(inet_addr_type(net, paddr), haddr, paddr, dev))
+ return 0;
+
+ n = __neigh_lookup(&arp_tbl, &paddr, dev, 1);
+@@ -704,6 +711,7 @@
+ static int arp_process(struct sk_buff *skb)
+ {
+ struct net_device *dev = skb->dev;
++ struct net *net = dev->nd_net;
+ struct in_device *in_dev = in_dev_get(dev);
+ struct arphdr *arp;
+ unsigned char *arp_ptr;
+@@ -824,7 +832,7 @@
+ /* Special case: IPv4 duplicate address detection packet (RFC2131) */
+ if (sip == 0) {
+ if (arp->ar_op == htons(ARPOP_REQUEST) &&
+- inet_addr_type(tip) == RTN_LOCAL &&
++ inet_addr_type(net, tip) == RTN_LOCAL &&
+ !arp_ignore(in_dev,dev,sip,tip))
+ arp_send(ARPOP_REPLY,ETH_P_ARP,tip,dev,tip,sha,dev->dev_addr,dev->dev_addr);
+ goto out;
+@@ -854,7 +862,7 @@
+ } else if (IN_DEV_FORWARD(in_dev)) {
+ if ((rt->rt_flags&RTCF_DNAT) ||
+ (addr_type == RTN_UNICAST && rt->u.dst.dev != dev &&
+- (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, &tip, dev, 0)))) {
++ (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, net, &tip, dev, 0)))) {
+ n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
+ if (n)
+ neigh_release(n);
+@@ -877,14 +885,14 @@
+
+ n = __neigh_lookup(&arp_tbl, &sip, dev, 0);
+
+- if (IPV4_DEVCONF_ALL(ARP_ACCEPT)) {
++ if (IPV4_DEVCONF_ALL(net, ARP_ACCEPT)) {
+ /* Unsolicited ARP is not accepted by default.
+ It is possible, that this option should be enabled for some
+ devices (strip is candidate)
+ */
+ if (n == NULL &&
+ arp->ar_op == htons(ARPOP_REPLY) &&
+- inet_addr_type(sip) == RTN_UNICAST)
++ inet_addr_type(net, sip) == RTN_UNICAST)
+ n = __neigh_lookup(&arp_tbl, &sip, dev, -1);
+ }
+
+@@ -966,7 +974,7 @@
+ * Set (create) an ARP cache entry.
+ */
+
+-static int arp_req_set(struct arpreq *r, struct net_device * dev)
++static int arp_req_set(struct net *net, struct arpreq *r, struct net_device * dev)
+ {
+ __be32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
+ struct neighbour *neigh;
+@@ -977,17 +985,17 @@
+ if (mask && mask != htonl(0xFFFFFFFF))
+ return -EINVAL;
+ if (!dev && (r->arp_flags & ATF_COM)) {
+- dev = dev_getbyhwaddr(r->arp_ha.sa_family, r->arp_ha.sa_data);
++ dev = dev_getbyhwaddr(net, r->arp_ha.sa_family, r->arp_ha.sa_data);
+ if (!dev)
+ return -ENODEV;
+ }
+ if (mask) {
+- if (pneigh_lookup(&arp_tbl, &ip, dev, 1) == NULL)
++ if (pneigh_lookup(&arp_tbl, net, &ip, dev, 1) == NULL)
+ return -ENOBUFS;
+ return 0;
+ }
+ if (dev == NULL) {
+- IPV4_DEVCONF_ALL(PROXY_ARP) = 1;
++ IPV4_DEVCONF_ALL(net, PROXY_ARP) = 1;
+ return 0;
+ }
+ if (__in_dev_get_rtnl(dev)) {
+@@ -1000,8 +1008,10 @@
+ if (r->arp_flags & ATF_PERM)
+ r->arp_flags |= ATF_COM;
+ if (dev == NULL) {
+- struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip,
+- .tos = RTO_ONLINK } } };
++ struct flowi fl = {
++ .fl_net = net,
++ .nl_u = { .ip4_u = { .daddr = ip, .tos = RTO_ONLINK } }
++ };
+ struct rtable * rt;
+ if ((err = ip_route_output_key(&rt, &fl)) != 0)
+ return err;
+@@ -1080,7 +1090,7 @@
+ return err;
+ }
+
+-static int arp_req_delete(struct arpreq *r, struct net_device * dev)
++static int arp_req_delete(struct net *net, struct arpreq *r, struct net_device * dev)
+ {
+ int err;
+ __be32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
+@@ -1090,10 +1100,10 @@
+ __be32 mask =
+ ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr;
+ if (mask == htonl(0xFFFFFFFF))
+- return pneigh_delete(&arp_tbl, &ip, dev);
++ return pneigh_delete(&arp_tbl, net, &ip, dev);
+ if (mask == 0) {
+ if (dev == NULL) {
+- IPV4_DEVCONF_ALL(PROXY_ARP) = 0;
++ IPV4_DEVCONF_ALL(net, PROXY_ARP) = 0;
+ return 0;
+ }
+ if (__in_dev_get_rtnl(dev)) {
+@@ -1107,8 +1117,10 @@
+ }
+
+ if (dev == NULL) {
+- struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip,
+- .tos = RTO_ONLINK } } };
++ struct flowi fl = {
++ .fl_net = net,
++ .nl_u = { .ip4_u = { .daddr = ip, .tos = RTO_ONLINK } }
++ };
+ struct rtable * rt;
+ if ((err = ip_route_output_key(&rt, &fl)) != 0)
+ return err;
+@@ -1133,7 +1145,7 @@
+ * Handle an ARP layer I/O control request.
+ */
+
+-int arp_ioctl(unsigned int cmd, void __user *arg)
++int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg)
+ {
+ int err;
+ struct arpreq r;
+@@ -1165,7 +1177,7 @@
+ rtnl_lock();
+ if (r.arp_dev[0]) {
+ err = -ENODEV;
+- if ((dev = __dev_get_by_name(r.arp_dev)) == NULL)
++ if ((dev = __dev_get_by_name(net, r.arp_dev)) == NULL)
+ goto out;
+
+ /* Mmmm... It is wrong... ARPHRD_NETROM==0 */
+@@ -1181,10 +1193,10 @@
+
+ switch (cmd) {
+ case SIOCDARP:
+- err = arp_req_delete(&r, dev);
++ err = arp_req_delete(net, &r, dev);
+ break;
+ case SIOCSARP:
+- err = arp_req_set(&r, dev);
++ err = arp_req_set(net, &r, dev);
+ break;
+ case SIOCGARP:
+ err = arp_req_get(&r, dev);
+@@ -1201,6 +1213,9 @@
+ {
+ struct net_device *dev = ptr;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
+
-+ prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
+ switch (event) {
+ case NETDEV_CHANGEADDR:
+ neigh_changeaddr(&arp_tbl, dev);
+@@ -1227,6 +1242,54 @@
+ }
+
+
++static int arp_proc_init(struct net *net);
++static void arp_proc_exit(struct net *net);
+
-+ /* Basic assumption: if someone sets sk->sk_err, he _must_
-+ * change state of the socket from TCP_SYN_*.
-+ * Connect() does not allow to get error notifications
-+ * without closing the socket.
-+ */
-+ while ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+ if (signal_pending(current) || !timeo)
-+ break;
-+ prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
-+ }
-+ finish_wait(sk->sk_sleep, &wait);
-+ return timeo;
-+}
+
-+/*
-+ * Connect to a remote host. There is regrettably still a little
-+ * TCP 'magic' in here.
-+ */
-+int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
-+ int addr_len, int flags)
++static int arp_net_init(struct net *net)
+{
-+ struct sock *sk = sock->sk;
-+ int err;
-+ long timeo;
-+
-+ lock_sock(sk);
-+
-+ if (uaddr->sa_family == AF_UNSPEC) {
-+ err = sk->sk_prot->disconnect(sk, flags);
-+ sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED;
-+ goto out;
-+ }
-+
-+ switch (sock->state) {
-+ default:
-+ err = -EINVAL;
-+ goto out;
-+ case SS_CONNECTED:
-+ err = -EISCONN;
-+ goto out;
-+ case SS_CONNECTING:
-+ err = -EALREADY;
-+ /* Fall out of switch with err, set for this state */
-+ break;
-+ case SS_UNCONNECTED:
-+ err = -EISCONN;
-+ if (sk->sk_state != TCP_CLOSE)
-+ goto out;
-+
-+ err = sk->sk_prot->connect(sk, uaddr, addr_len);
-+ if (err < 0)
-+ goto out;
-+
-+ sock->state = SS_CONNECTING;
-+
-+ /* Just entered SS_CONNECTING state; the only
-+ * difference is that return value in non-blocking
-+ * case is EINPROGRESS, rather than EALREADY.
-+ */
-+ err = -EINPROGRESS;
-+ break;
-+ }
-+
-+ timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
-+
-+ if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
-+ /* Error code is set above */
-+ if (!timeo || !inet_wait_for_connect(sk, timeo))
-+ goto out;
-+
-+ err = sock_intr_errno(timeo);
-+ if (signal_pending(current))
-+ goto out;
-+ }
-+
-+ /* Connection was closed by RST, timeout, ICMP error
-+ * or another process disconnected us.
-+ */
-+ if (sk->sk_state == TCP_CLOSE)
-+ goto sock_error;
++ int error;
++ if ((error = arp_proc_init(net)))
++ goto out_proc;
+
-+ /* sk->sk_err may be not zero now, if RECVERR was ordered by user
-+ * and error was received after socket entered established state.
-+ * Hence, it is handled normally after connect() return successfully.
-+ */
++ error = -ENOMEM;
++ net->arp_neigh_parms_default = neigh_parms_alloc_default(&arp_tbl, net);
++ if (!net->arp_neigh_parms_default)
++ goto out_parm;
++
++#ifdef CONFIG_SYSCTL
++ if ((error = neigh_sysctl_register(
++ NULL, net->arp_neigh_parms_default,
++ NET_IPV4, NET_IPV4_NEIGH, "ipv4", NULL, NULL)))
++ goto out_sysctl;
++#endif
+
-+ sock->state = SS_CONNECTED;
-+ err = 0;
+out:
-+ release_sock(sk);
-+ return err;
++ return error;
+
-+sock_error:
-+ err = sock_error(sk) ? : -ECONNABORTED;
-+ sock->state = SS_UNCONNECTED;
-+ if (sk->sk_prot->disconnect(sk, flags))
-+ sock->state = SS_DISCONNECTING;
++#ifdef CONFIG_SYSCTL
++out_sysctl:
++ neigh_parms_release(&arp_tbl, net->arp_neigh_parms_default);
++#endif
++out_parm:
++ arp_proc_exit(net);
++out_proc:
+ goto out;
+}
+
-+/*
-+ * Accept a pending connection. The TCP layer now gives BSD semantics.
-+ */
-+
-+int inet_accept(struct socket *sock, struct socket *newsock, int flags)
++static void arp_net_exit(struct net *net)
+{
-+ struct sock *sk1 = sock->sk;
-+ int err = -EINVAL;
-+ struct sock *sk2 = sk1->sk_prot->accept(sk1, flags, &err);
-+
-+ if (!sk2)
-+ goto do_err;
-+
-+ lock_sock(sk2);
-+
-+ BUG_TRAP((1 << sk2->sk_state) &
-+ (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_CLOSE));
-+
-+ sock_graft(sk2, newsock);
-+
-+ newsock->state = SS_CONNECTED;
-+ err = 0;
-+ release_sock(sk2);
-+do_err:
-+ return err;
++#ifdef CONFIG_SYSCTL
++ neigh_sysctl_unregister(net->arp_neigh_parms_default);
++#endif
++ neigh_parms_release(&arp_tbl, net->arp_neigh_parms_default);
++ arp_proc_exit(net);
+}
+
++static struct pernet_operations arp_net_ops = {
++ .init = arp_net_init,
++ .exit = arp_net_exit,
++};
+ /*
+ * Called once on startup.
+ */
+@@ -1236,18 +1299,12 @@
+ .func = arp_rcv,
+ };
+
+-static int arp_proc_init(void);
+-
+ void __init arp_init(void)
+ {
+ neigh_table_init(&arp_tbl);
+
+ dev_add_pack(&arp_packet_type);
+- arp_proc_init();
+-#ifdef CONFIG_SYSCTL
+- neigh_sysctl_register(NULL, &arp_tbl.parms, NET_IPV4,
+- NET_IPV4_NEIGH, "ipv4", NULL, NULL);
+-#endif
++ register_pernet_subsys(&arp_net_ops);
+ register_netdevice_notifier(&arp_netdev_notifier);
+ }
+
+@@ -1383,6 +1440,8 @@
+
+ seq = file->private_data;
+ seq->private = s;
++ s->net = get_net(PROC_NET(inode));
+
-+/*
-+ * This does both peername and sockname.
-+ */
-+int inet_getname(struct socket *sock, struct sockaddr *uaddr,
-+ int *uaddr_len, int peer)
-+{
-+ struct sock *sk = sock->sk;
-+ struct inet_sock *inet = inet_sk(sk);
-+ struct sockaddr_in *sin = (struct sockaddr_in *)uaddr;
-+
-+ sin->sin_family = AF_INET;
-+ if (peer) {
-+ if (!inet->dport ||
-+ (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_SYN_SENT)) &&
-+ peer == 1))
-+ return -ENOTCONN;
-+ sin->sin_port = inet->dport;
-+ sin->sin_addr.s_addr =
-+ nx_map_sock_lback(sk->sk_nx_info, inet->daddr);
-+ } else {
-+ __be32 addr = inet->rcv_saddr;
-+ if (!addr)
-+ addr = inet->saddr;
-+ addr = nx_map_sock_lback(sk->sk_nx_info, addr);
-+ sin->sin_port = inet->sport;
-+ sin->sin_addr.s_addr = addr;
-+ }
-+ memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
-+ *uaddr_len = sizeof(*sin);
-+ return 0;
-+}
-+
-+int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
-+ size_t size)
+ out:
+ return rc;
+ out_kfree:
+@@ -1390,28 +1449,46 @@
+ goto out;
+ }
+
++static int arp_seq_release(struct inode *inode, struct file *file)
+{
-+ struct sock *sk = sock->sk;
-+
-+ /* We may need to bind the socket. */
-+ if (!inet_sk(sk)->num && inet_autobind(sk))
-+ return -EAGAIN;
-+
-+ return sk->sk_prot->sendmsg(iocb, sk, msg, size);
++ struct seq_file *seq = file->private_data;
++ struct neigh_seq_state *state = seq->private;
++ put_net(state->net);
++ return seq_release_private(inode, file);
+}
+
-+
-+static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags)
+ static const struct file_operations arp_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = arp_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+- .release = seq_release_private,
++ .release = arp_seq_release,
+ };
+
+-static int __init arp_proc_init(void)
++static int arp_proc_init(struct net *net)
+ {
+- if (!proc_net_fops_create("arp", S_IRUGO, &arp_seq_fops))
++ if (!proc_net_fops_create(net, "arp", S_IRUGO, &arp_seq_fops))
+ return -ENOMEM;
+ return 0;
+ }
+
++static void arp_proc_exit(struct net *net)
+{
-+ struct sock *sk = sock->sk;
-+
-+ /* We may need to bind the socket. */
-+ if (!inet_sk(sk)->num && inet_autobind(sk))
-+ return -EAGAIN;
-+
-+ if (sk->sk_prot->sendpage)
-+ return sk->sk_prot->sendpage(sk, page, offset, size, flags);
-+ return sock_no_sendpage(sock, page, offset, size, flags);
++ proc_net_remove(net, "arp");
+}
+
-+
-+int inet_shutdown(struct socket *sock, int how)
+ #else /* CONFIG_PROC_FS */
+
+-static int __init arp_proc_init(void)
++static int arp_proc_init(struct net *net)
+ {
+ return 0;
+ }
+
++static void arp_proc_exit(struct net *net)
+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ /* This should really check to make sure
-+ * the socket is a TCP socket. (WHY AC...)
-+ */
-+ how++; /* maps 0->1 has the advantage of making bit 1 rcvs and
-+ 1->2 bit 2 snds.
-+ 2->3 */
-+ if ((how & ~SHUTDOWN_MASK) || !how) /* MAXINT->0 */
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+ if (sock->state == SS_CONNECTING) {
-+ if ((1 << sk->sk_state) &
-+ (TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_CLOSE))
-+ sock->state = SS_DISCONNECTING;
-+ else
-+ sock->state = SS_CONNECTED;
-+ }
-+
-+ switch (sk->sk_state) {
-+ case TCP_CLOSE:
-+ err = -ENOTCONN;
-+ /* Hack to wake up other listeners, who can poll for
-+ POLLHUP, even on eg. unconnected UDP sockets -- RR */
-+ default:
-+ sk->sk_shutdown |= how;
-+ if (sk->sk_prot->shutdown)
-+ sk->sk_prot->shutdown(sk, how);
-+ break;
-+
-+ /* Remaining two branches are temporary solution for missing
-+ * close() in multithreaded environment. It is _not_ a good idea,
-+ * but we have no choice until close() is repaired at VFS level.
-+ */
-+ case TCP_LISTEN:
-+ if (!(how & RCV_SHUTDOWN))
-+ break;
-+ /* Fall through */
-+ case TCP_SYN_SENT:
-+ err = sk->sk_prot->disconnect(sk, O_NONBLOCK);
-+ sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED;
-+ break;
-+ }
-+
-+ /* Wake up anyone sleeping in poll. */
-+ sk->sk_state_change(sk);
-+ release_sock(sk);
-+ return err;
++ return;
+}
+
-+/*
-+ * ioctl() calls you can issue on an INET socket. Most of these are
-+ * device configuration and stuff and very rarely used. Some ioctls
-+ * pass on to the socket itself.
-+ *
-+ * NOTE: I like the idea of a module for the config stuff. ie ifconfig
-+ * loads the devconfigure module does its configuring and unloads it.
-+ * There's a good 20K of config code hanging around the kernel.
-+ */
-+
-+int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+ #endif /* CONFIG_PROC_FS */
+
+ EXPORT_SYMBOL(arp_broken_ops);
+diff -Nurb linux-2.6.22-570/net/ipv4/devinet.c linux-2.6.22-590/net/ipv4/devinet.c
+--- linux-2.6.22-570/net/ipv4/devinet.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/ipv4/devinet.c 2008-01-29 22:12:32.000000000 -0500
+@@ -63,7 +63,7 @@
+ #include <net/ip_fib.h>
+ #include <net/rtnetlink.h>
+
+-struct ipv4_devconf ipv4_devconf = {
++static struct ipv4_devconf ipv4_devconf_template = {
+ .data = {
+ [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
+ [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
+@@ -72,7 +72,7 @@
+ },
+ };
+
+-static struct ipv4_devconf ipv4_devconf_dflt = {
++static struct ipv4_devconf ipv4_devconf_dflt_template = {
+ .data = {
+ [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
+ [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
+@@ -82,7 +82,7 @@
+ },
+ };
+
+-#define IPV4_DEVCONF_DFLT(attr) IPV4_DEVCONF(ipv4_devconf_dflt, attr)
++#define IPV4_DEVCONF_DFLT(net, attr) IPV4_DEVCONF(*((net)->ipv4_devconf_dflt), attr)
+
+ static const struct nla_policy ifa_ipv4_policy[IFA_MAX+1] = {
+ [IFA_LOCAL] = { .type = NLA_U32 },
+@@ -98,7 +98,7 @@
+ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
+ int destroy);
+ #ifdef CONFIG_SYSCTL
+-static void devinet_sysctl_register(struct in_device *in_dev,
++static void devinet_sysctl_register(struct net *net, struct in_device *in_dev,
+ struct ipv4_devconf *p);
+ static void devinet_sysctl_unregister(struct ipv4_devconf *p);
+ #endif
+@@ -149,6 +149,7 @@
+
+ static struct in_device *inetdev_init(struct net_device *dev)
+ {
++ struct net *net = dev->nd_net;
+ struct in_device *in_dev;
+
+ ASSERT_RTNL();
+@@ -157,7 +158,7 @@
+ if (!in_dev)
+ goto out;
+ INIT_RCU_HEAD(&in_dev->rcu_head);
+- memcpy(&in_dev->cnf, &ipv4_devconf_dflt, sizeof(in_dev->cnf));
++ memcpy(&in_dev->cnf, &net->ipv4_devconf_dflt, sizeof(in_dev->cnf));
+ in_dev->cnf.sysctl = NULL;
+ in_dev->dev = dev;
+ if ((in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl)) == NULL)
+@@ -173,7 +174,7 @@
+ in_dev_hold(in_dev);
+
+ #ifdef CONFIG_SYSCTL
+- devinet_sysctl_register(in_dev, &in_dev->cnf);
++ devinet_sysctl_register(net, in_dev, &in_dev->cnf);
+ #endif
+ ip_mc_init_dev(in_dev);
+ if (dev->flags & IFF_UP)
+@@ -203,8 +204,6 @@
+ ASSERT_RTNL();
+
+ dev = in_dev->dev;
+- if (dev == &loopback_dev)
+- return;
+
+ in_dev->dead = 1;
+
+@@ -415,12 +414,12 @@
+ return inet_insert_ifa(ifa);
+ }
+
+-struct in_device *inetdev_by_index(int ifindex)
++struct in_device *inetdev_by_index(struct net *net, int ifindex)
+ {
+ struct net_device *dev;
+ struct in_device *in_dev = NULL;
+ read_lock(&dev_base_lock);
+- dev = __dev_get_by_index(ifindex);
++ dev = __dev_get_by_index(net, ifindex);
+ if (dev)
+ in_dev = in_dev_get(dev);
+ read_unlock(&dev_base_lock);
+@@ -444,6 +443,7 @@
+
+ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct nlattr *tb[IFA_MAX+1];
+ struct in_device *in_dev;
+ struct ifaddrmsg *ifm;
+@@ -457,7 +457,7 @@
+ goto errout;
+
+ ifm = nlmsg_data(nlh);
+- in_dev = inetdev_by_index(ifm->ifa_index);
++ in_dev = inetdev_by_index(net, ifm->ifa_index);
+ if (in_dev == NULL) {
+ err = -ENODEV;
+ goto errout;
+@@ -488,7 +488,7 @@
+ return err;
+ }
+
+-static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh)
++static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh)
+ {
+ struct nlattr *tb[IFA_MAX+1];
+ struct in_ifaddr *ifa;
+@@ -507,7 +507,7 @@
+ goto errout;
+ }
+
+- dev = __dev_get_by_index(ifm->ifa_index);
++ dev = __dev_get_by_index(net, ifm->ifa_index);
+ if (dev == NULL) {
+ err = -ENODEV;
+ goto errout;
+@@ -564,11 +564,12 @@
+
+ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct in_ifaddr *ifa;
+
+ ASSERT_RTNL();
+
+- ifa = rtm_to_ifaddr(nlh);
++ ifa = rtm_to_ifaddr(net, nlh);
+ if (IS_ERR(ifa))
+ return PTR_ERR(ifa);
+
+@@ -600,7 +601,7 @@
+ }
+
+
+-int devinet_ioctl(unsigned int cmd, void __user *arg)
++int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
+ {
+ struct ifreq ifr;
+ struct sockaddr_in sin_orig;
+@@ -629,7 +630,7 @@
+ *colon = 0;
+
+ #ifdef CONFIG_KMOD
+- dev_load(ifr.ifr_name);
++ dev_load(net, ifr.ifr_name);
+ #endif
+
+ switch (cmd) {
+@@ -670,7 +671,7 @@
+ rtnl_lock();
+
+ ret = -ENODEV;
+- if ((dev = __dev_get_by_name(ifr.ifr_name)) == NULL)
++ if ((dev = __dev_get_by_name(net, ifr.ifr_name)) == NULL)
+ goto done;
+
+ if (colon)
+@@ -889,6 +890,7 @@
+
+ __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
+ {
++ struct net *net = dev->nd_net;
+ __be32 addr = 0;
+ struct in_device *in_dev;
+
+@@ -919,7 +921,7 @@
+ */
+ read_lock(&dev_base_lock);
+ rcu_read_lock();
+- for_each_netdev(dev) {
++ for_each_netdev(net, dev) {
+ if ((in_dev = __in_dev_get_rcu(dev)) == NULL)
+ continue;
+
+@@ -982,7 +984,7 @@
+ * - local: address, 0=autoselect the local address
+ * - scope: maximum allowed scope value for the local address
+ */
+-__be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope)
++__be32 inet_confirm_addr(struct net *net, const struct net_device *dev, __be32 dst, __be32 local, int scope)
+ {
+ __be32 addr = 0;
+ struct in_device *in_dev;
+@@ -998,7 +1000,7 @@
+
+ read_lock(&dev_base_lock);
+ rcu_read_lock();
+- for_each_netdev(dev) {
++ for_each_netdev(net, dev) {
+ if ((in_dev = __in_dev_get_rcu(dev))) {
+ addr = confirm_addr_indev(in_dev, dst, local, scope);
+ if (addr)
+@@ -1059,6 +1061,7 @@
+ void *ptr)
+ {
+ struct net_device *dev = ptr;
++ struct net *net = dev->nd_net;
+ struct in_device *in_dev = __in_dev_get_rtnl(dev);
+
+ ASSERT_RTNL();
+@@ -1066,7 +1069,7 @@
+ if (!in_dev) {
+ if (event == NETDEV_REGISTER) {
+ in_dev = inetdev_init(dev);
+- if (dev == &loopback_dev) {
++ if (dev == &net->loopback_dev) {
+ if (!in_dev)
+ panic("devinet: "
+ "Failed to create loopback\n");
+@@ -1085,7 +1088,7 @@
+ case NETDEV_UP:
+ if (dev->mtu < 68)
+ break;
+- if (dev == &loopback_dev) {
++ if (dev == &net->loopback_dev) {
+ struct in_ifaddr *ifa;
+ if ((ifa = inet_alloc_ifa()) != NULL) {
+ ifa->ifa_local =
+@@ -1122,7 +1125,7 @@
+ neigh_sysctl_unregister(in_dev->arp_parms);
+ neigh_sysctl_register(dev, in_dev->arp_parms, NET_IPV4,
+ NET_IPV4_NEIGH, "ipv4", NULL, NULL);
+- devinet_sysctl_register(in_dev, &in_dev->cnf);
++ devinet_sysctl_register(net, in_dev, &in_dev->cnf);
+ #endif
+ break;
+ }
+@@ -1185,6 +1188,7 @@
+
+ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
+ {
++ struct net *net = skb->sk->sk_net;
+ int idx, ip_idx;
+ struct net_device *dev;
+ struct in_device *in_dev;
+@@ -1194,7 +1198,7 @@
+
+ s_ip_idx = ip_idx = cb->args[1];
+ idx = 0;
+- for_each_netdev(dev) {
++ for_each_netdev(net, dev) {
+ if (idx < s_idx)
+ goto cont;
+ if (idx > s_idx)
+@@ -1228,6 +1232,7 @@
+ u32 pid)
+ {
+ struct sk_buff *skb;
++ struct net *net = ifa->ifa_dev->dev->nd_net;
+ u32 seq = nlh ? nlh->nlmsg_seq : 0;
+ int err = -ENOBUFS;
+
+@@ -1242,25 +1247,25 @@
+ kfree_skb(skb);
+ goto errout;
+ }
+- err = rtnl_notify(skb, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
++ err = rtnl_notify(skb, net, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
+ errout:
+ if (err < 0)
+- rtnl_set_sk_err(RTNLGRP_IPV4_IFADDR, err);
++ rtnl_set_sk_err(net, RTNLGRP_IPV4_IFADDR, err);
+ }
+
+ #ifdef CONFIG_SYSCTL
+
+-static void devinet_copy_dflt_conf(int i)
++static void devinet_copy_dflt_conf(struct net *net, int i)
+ {
+ struct net_device *dev;
+
+ read_lock(&dev_base_lock);
+- for_each_netdev(dev) {
++ for_each_netdev(net, dev) {
+ struct in_device *in_dev;
+ rcu_read_lock();
+ in_dev = __in_dev_get_rcu(dev);
+ if (in_dev && !test_bit(i, in_dev->cnf.state))
+- in_dev->cnf.data[i] = ipv4_devconf_dflt.data[i];
++ in_dev->cnf.data[i] = net->ipv4_devconf_dflt->data[i];
+ rcu_read_unlock();
+ }
+ read_unlock(&dev_base_lock);
+@@ -1274,12 +1279,13 @@
+
+ if (write) {
+ struct ipv4_devconf *cnf = ctl->extra1;
++ struct net *net = ctl->extra2;
+ int i = (int *)ctl->data - cnf->data;
+
+ set_bit(i, cnf->state);
+
+- if (cnf == &ipv4_devconf_dflt)
+- devinet_copy_dflt_conf(i);
++ if (cnf == net->ipv4_devconf_dflt)
++ devinet_copy_dflt_conf(net, i);
+ }
+
+ return ret;
+@@ -1291,6 +1297,7 @@
+ {
+ struct ipv4_devconf *cnf;
+ int *valp = table->data;
++ struct net *net;
+ int new;
+ int i;
+
+@@ -1325,26 +1332,27 @@
+ *valp = new;
+
+ cnf = table->extra1;
++ net = table->extra2;
+ i = (int *)table->data - cnf->data;
+
+ set_bit(i, cnf->state);
+
+- if (cnf == &ipv4_devconf_dflt)
+- devinet_copy_dflt_conf(i);
++ if (cnf == net->ipv4_devconf_dflt)
++ devinet_copy_dflt_conf(net, i);
+
+ return 1;
+ }
+
+-void inet_forward_change(void)
++void inet_forward_change(struct net *net)
+ {
+ struct net_device *dev;
+- int on = IPV4_DEVCONF_ALL(FORWARDING);
++ int on = IPV4_DEVCONF_ALL(net, FORWARDING);
+
+- IPV4_DEVCONF_ALL(ACCEPT_REDIRECTS) = !on;
+- IPV4_DEVCONF_DFLT(FORWARDING) = on;
++ IPV4_DEVCONF_ALL(net, ACCEPT_REDIRECTS) = !on;
++ IPV4_DEVCONF_DFLT(net, FORWARDING) = on;
+
+ read_lock(&dev_base_lock);
+- for_each_netdev(dev) {
++ for_each_netdev(net, dev) {
+ struct in_device *in_dev;
+ rcu_read_lock();
+ in_dev = __in_dev_get_rcu(dev);
+@@ -1364,11 +1372,12 @@
+ int *valp = ctl->data;
+ int val = *valp;
+ int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
++ struct net *net = ctl->extra2;
+
+ if (write && *valp != val) {
+- if (valp == &IPV4_DEVCONF_ALL(FORWARDING))
+- inet_forward_change();
+- else if (valp != &IPV4_DEVCONF_DFLT(FORWARDING))
++ if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING))
++ inet_forward_change(net);
++ else if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING))
+ rt_cache_flush(0);
+ }
+
+@@ -1407,13 +1416,14 @@
+ { \
+ .ctl_name = NET_IPV4_CONF_ ## attr, \
+ .procname = name, \
+- .data = ipv4_devconf.data + \
++ .data = ipv4_devconf_template.data + \
+ NET_IPV4_CONF_ ## attr - 1, \
+ .maxlen = sizeof(int), \
+ .mode = mval, \
+ .proc_handler = proc, \
+ .strategy = sysctl, \
+- .extra1 = &ipv4_devconf, \
++ .extra1 = &ipv4_devconf_template, \
++ .extra2 = &init_net, \
+ }
+
+ #define DEVINET_SYSCTL_RW_ENTRY(attr, name) \
+@@ -1503,25 +1513,29 @@
+ },
+ };
+
+-static void devinet_sysctl_register(struct in_device *in_dev,
++static void devinet_sysctl_register(struct net *net, struct in_device *in_dev,
+ struct ipv4_devconf *p)
+ {
+ int i;
+ struct net_device *dev = in_dev ? in_dev->dev : NULL;
+- struct devinet_sysctl_table *t = kmemdup(&devinet_sysctl, sizeof(*t),
+- GFP_KERNEL);
++ struct devinet_sysctl_table *t;
+ char *dev_name = NULL;
+
++ t = kmemdup(&devinet_sysctl, sizeof(*t), GFP_KERNEL);
+ if (!t)
+ return;
+ for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) {
+- t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf;
++ t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf_template;
+ t->devinet_vars[i].extra1 = p;
++ t->devinet_vars[i].extra2 = net;
+ }
+
+ if (dev) {
+ dev_name = dev->name;
+ t->devinet_dev[0].ctl_name = dev->ifindex;
++ } else if (p == net->ipv4_devconf) {
++ dev_name = "all";
++ t->devinet_dev[0].ctl_name = NET_PROTO_CONF_ALL;
+ } else {
+ dev_name = "default";
+ t->devinet_dev[0].ctl_name = NET_PROTO_CONF_DEFAULT;
+@@ -1542,7 +1556,7 @@
+ t->devinet_proto_dir[0].child = t->devinet_conf_dir;
+ t->devinet_root_dir[0].child = t->devinet_proto_dir;
+
+- t->sysctl_header = register_sysctl_table(t->devinet_root_dir);
++ t->sysctl_header = register_net_sysctl_table(net, t->devinet_root_dir);
+ if (!t->sysctl_header)
+ goto free_procname;
+
+@@ -1562,26 +1576,59 @@
+ if (p->sysctl) {
+ struct devinet_sysctl_table *t = p->sysctl;
+ p->sysctl = NULL;
+- unregister_sysctl_table(t->sysctl_header);
++ unregister_net_sysctl_table(t->sysctl_header);
+ kfree(t->devinet_dev[0].procname);
+ kfree(t);
+ }
+ }
+ #endif
+
++static int devinet_net_init(struct net *net)
+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ switch (cmd) {
-+ case SIOCGSTAMP:
-+ err = sock_get_timestamp(sk, (struct timeval __user *)arg);
-+ break;
-+ case SIOCGSTAMPNS:
-+ err = sock_get_timestampns(sk, (struct timespec __user *)arg);
-+ break;
-+ case SIOCADDRT:
-+ case SIOCDELRT:
-+ case SIOCRTMSG:
-+ err = ip_rt_ioctl(cmd, (void __user *)arg);
-+ break;
-+ case SIOCDARP:
-+ case SIOCGARP:
-+ case SIOCSARP:
-+ err = arp_ioctl(cmd, (void __user *)arg);
-+ break;
-+ case SIOCGIFADDR:
-+ case SIOCSIFADDR:
-+ case SIOCGIFBRDADDR:
-+ case SIOCSIFBRDADDR:
-+ case SIOCGIFNETMASK:
-+ case SIOCSIFNETMASK:
-+ case SIOCGIFDSTADDR:
-+ case SIOCSIFDSTADDR:
-+ case SIOCSIFPFLAGS:
-+ case SIOCGIFPFLAGS:
-+ case SIOCSIFFLAGS:
-+ err = devinet_ioctl(cmd, (void __user *)arg);
-+ break;
-+ default:
-+ if (sk->sk_prot->ioctl)
-+ err = sk->sk_prot->ioctl(sk, cmd, arg);
-+ else
-+ err = -ENOIOCTLCMD;
-+ break;
++#ifdef CONFIG_SYSCTL
++ net->ipv4_devconf = kmemdup(&ipv4_devconf_template,
++ sizeof(ipv4_devconf_template), GFP_KERNEL);
++ if (!net->ipv4_devconf)
++ return -ENOMEM;
++
++ net->ipv4_devconf_dflt = kmemdup(&ipv4_devconf_dflt_template,
++ sizeof(ipv4_devconf_template),
++ GFP_KERNEL);
++ if (!net->ipv4_devconf_dflt) {
++ kfree(net->ipv4_devconf);
++ return -ENOMEM;
+ }
-+ return err;
-+}
+
-+const struct proto_ops inet_stream_ops = {
-+ .family = PF_INET,
-+ .owner = THIS_MODULE,
-+ .release = inet_release,
-+ .bind = inet_bind,
-+ .connect = inet_stream_connect,
-+ .socketpair = sock_no_socketpair,
-+ .accept = inet_accept,
-+ .getname = inet_getname,
-+ .poll = tcp_poll,
-+ .ioctl = inet_ioctl,
-+ .listen = inet_listen,
-+ .shutdown = inet_shutdown,
-+ .setsockopt = sock_common_setsockopt,
-+ .getsockopt = sock_common_getsockopt,
-+ .sendmsg = tcp_sendmsg,
-+ .recvmsg = sock_common_recvmsg,
-+ .mmap = sock_no_mmap,
-+ .sendpage = tcp_sendpage,
-+#ifdef CONFIG_COMPAT
-+ .compat_setsockopt = compat_sock_common_setsockopt,
-+ .compat_getsockopt = compat_sock_common_getsockopt,
-+#endif
-+};
-+
-+const struct proto_ops inet_dgram_ops = {
-+ .family = PF_INET,
-+ .owner = THIS_MODULE,
-+ .release = inet_release,
-+ .bind = inet_bind,
-+ .connect = inet_dgram_connect,
-+ .socketpair = sock_no_socketpair,
-+ .accept = sock_no_accept,
-+ .getname = inet_getname,
-+ .poll = udp_poll,
-+ .ioctl = inet_ioctl,
-+ .listen = sock_no_listen,
-+ .shutdown = inet_shutdown,
-+ .setsockopt = sock_common_setsockopt,
-+ .getsockopt = sock_common_getsockopt,
-+ .sendmsg = inet_sendmsg,
-+ .recvmsg = sock_common_recvmsg,
-+ .mmap = sock_no_mmap,
-+ .sendpage = inet_sendpage,
-+#ifdef CONFIG_COMPAT
-+ .compat_setsockopt = compat_sock_common_setsockopt,
-+ .compat_getsockopt = compat_sock_common_getsockopt,
-+#endif
-+};
++ devinet_sysctl_register(net, NULL, net->ipv4_devconf);
++ devinet_sysctl_register(net, NULL, net->ipv4_devconf_dflt);
+
-+/*
-+ * For SOCK_RAW sockets; should be the same as inet_dgram_ops but without
-+ * udp_poll
-+ */
-+static const struct proto_ops inet_sockraw_ops = {
-+ .family = PF_INET,
-+ .owner = THIS_MODULE,
-+ .release = inet_release,
-+ .bind = inet_bind,
-+ .connect = inet_dgram_connect,
-+ .socketpair = sock_no_socketpair,
-+ .accept = sock_no_accept,
-+ .getname = inet_getname,
-+ .poll = datagram_poll,
-+ .ioctl = inet_ioctl,
-+ .listen = sock_no_listen,
-+ .shutdown = inet_shutdown,
-+ .setsockopt = sock_common_setsockopt,
-+ .getsockopt = sock_common_getsockopt,
-+ .sendmsg = inet_sendmsg,
-+ .recvmsg = sock_common_recvmsg,
-+ .mmap = sock_no_mmap,
-+ .sendpage = inet_sendpage,
-+#ifdef CONFIG_COMPAT
-+ .compat_setsockopt = compat_sock_common_setsockopt,
-+ .compat_getsockopt = compat_sock_common_getsockopt,
++ multi_ipv4_table[0].data = &IPV4_DEVCONF_ALL(net, FORWARDING);
+#endif
-+};
-+
-+static struct net_proto_family inet_family_ops = {
-+ .family = PF_INET,
-+ .create = inet_create,
-+ .owner = THIS_MODULE,
-+};
++ return 0;
++}
+
-+/* Upon startup we insert all the elements in inetsw_array[] into
-+ * the linked list inetsw.
-+ */
-+static struct inet_protosw inetsw_array[] =
++static void devinet_net_exit(struct net *net)
+{
-+ {
-+ .type = SOCK_STREAM,
-+ .protocol = IPPROTO_TCP,
-+ .prot = &tcp_prot,
-+ .ops = &inet_stream_ops,
-+ .capability = -1,
-+ .no_check = 0,
-+ .flags = INET_PROTOSW_PERMANENT |
-+ INET_PROTOSW_ICSK,
-+ },
++#ifdef CONFIG_SYSCTL
++ devinet_sysctl_unregister(net->ipv4_devconf_dflt);
++ devinet_sysctl_unregister(net->ipv4_devconf);
++#endif
++}
+
-+ {
-+ .type = SOCK_DGRAM,
-+ .protocol = IPPROTO_UDP,
-+ .prot = &udp_prot,
-+ .ops = &inet_dgram_ops,
-+ .capability = -1,
-+ .no_check = UDP_CSUM_DEFAULT,
-+ .flags = INET_PROTOSW_PERMANENT,
-+ },
-+
-+
-+ {
-+ .type = SOCK_RAW,
-+ .protocol = IPPROTO_IP, /* wild card */
-+ .prot = &raw_prot,
-+ .ops = &inet_sockraw_ops,
-+ .capability = CAP_NET_RAW,
-+ .no_check = UDP_CSUM_DEFAULT,
-+ .flags = INET_PROTOSW_REUSE,
-+ }
++static struct pernet_operations devinet_net_ops = {
++ .init = devinet_net_init,
++ .exit = devinet_net_exit,
+};
+
-+#define INETSW_ARRAY_LEN (sizeof(inetsw_array) / sizeof(struct inet_protosw))
-+
-+void inet_register_protosw(struct inet_protosw *p)
-+{
-+ struct list_head *lh;
-+ struct inet_protosw *answer;
-+ int protocol = p->protocol;
-+ struct list_head *last_perm;
-+
-+ spin_lock_bh(&inetsw_lock);
-+
-+ if (p->type >= SOCK_MAX)
-+ goto out_illegal;
-+
-+ /* If we are trying to override a permanent protocol, bail. */
-+ answer = NULL;
-+ last_perm = &inetsw[p->type];
-+ list_for_each(lh, &inetsw[p->type]) {
-+ answer = list_entry(lh, struct inet_protosw, list);
+ void __init devinet_init(void)
+ {
++ register_pernet_subsys(&devinet_net_ops);
+ register_gifconf(PF_INET, inet_gifconf);
+ register_netdevice_notifier(&ip_netdev_notifier);
+
+ rtnl_register(PF_INET, RTM_NEWADDR, inet_rtm_newaddr, NULL);
+ rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL);
+ rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr);
+-#ifdef CONFIG_SYSCTL
+- devinet_sysctl.sysctl_header =
+- register_sysctl_table(devinet_sysctl.devinet_root_dir);
+- devinet_sysctl_register(NULL, &ipv4_devconf_dflt);
+-#endif
+ }
+
+ EXPORT_SYMBOL(in_dev_finish_destroy);
+diff -Nurb linux-2.6.22-570/net/ipv4/esp4.c linux-2.6.22-590/net/ipv4/esp4.c
+--- linux-2.6.22-570/net/ipv4/esp4.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/esp4.c 2008-01-29 22:12:32.000000000 -0500
+@@ -307,6 +307,9 @@
+ struct ip_esp_hdr *esph = (struct ip_esp_hdr*)(skb->data+(iph->ihl<<2));
+ struct xfrm_state *x;
+
++ if (skb->dev->nd_net != &init_net)
++ return;
+
-+ /* Check only the non-wild match. */
-+ if (INET_PROTOSW_PERMANENT & answer->flags) {
-+ if (protocol == answer->protocol)
-+ break;
-+ last_perm = lh;
-+ }
+ if (icmp_hdr(skb)->type != ICMP_DEST_UNREACH ||
+ icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
+ return;
+@@ -481,3 +484,4 @@
+ module_init(esp4_init);
+ module_exit(esp4_fini);
+ MODULE_LICENSE("GPL");
++MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_ESP);
+diff -Nurb linux-2.6.22-570/net/ipv4/fib_frontend.c linux-2.6.22-590/net/ipv4/fib_frontend.c
+--- linux-2.6.22-570/net/ipv4/fib_frontend.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/fib_frontend.c 2008-01-29 22:12:32.000000000 -0500
+@@ -51,38 +51,34 @@
+
+ #ifndef CONFIG_IP_MULTIPLE_TABLES
+
+-struct fib_table *ip_fib_local_table;
+-struct fib_table *ip_fib_main_table;
+-
+ #define FIB_TABLE_HASHSZ 1
+-static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ];
+
+ #else
+
+ #define FIB_TABLE_HASHSZ 256
+-static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ];
+
+-struct fib_table *fib_new_table(u32 id)
++struct fib_table *fib_new_table(struct net *net, u32 id)
+ {
+ struct fib_table *tb;
+ unsigned int h;
+
+ if (id == 0)
+ id = RT_TABLE_MAIN;
+- tb = fib_get_table(id);
++ tb = fib_get_table(net, id);
+ if (tb)
+ return tb;
+ tb = fib_hash_init(id);
+ if (!tb)
+ return NULL;
+ h = id & (FIB_TABLE_HASHSZ - 1);
+- hlist_add_head_rcu(&tb->tb_hlist, &fib_table_hash[h]);
++ hlist_add_head_rcu(&tb->tb_hlist, &net->ip_fib_table_hash[h]);
+ return tb;
+ }
+
+-struct fib_table *fib_get_table(u32 id)
++struct fib_table *fib_get_table(struct net *net, u32 id)
+ {
+ struct fib_table *tb;
++ struct hlist_head *head;
+ struct hlist_node *node;
+ unsigned int h;
+
+@@ -90,7 +86,8 @@
+ id = RT_TABLE_MAIN;
+ h = id & (FIB_TABLE_HASHSZ - 1);
+ rcu_read_lock();
+- hlist_for_each_entry_rcu(tb, node, &fib_table_hash[h], tb_hlist) {
++ head = &net->ip_fib_table_hash[h];
++ hlist_for_each_entry_rcu(tb, node, head, tb_hlist) {
+ if (tb->tb_id == id) {
+ rcu_read_unlock();
+ return tb;
+@@ -99,9 +96,10 @@
+ rcu_read_unlock();
+ return NULL;
+ }
+
-+ answer = NULL;
+ #endif /* CONFIG_IP_MULTIPLE_TABLES */
+
+-static void fib_flush(void)
++static void fib_flush(struct net *net)
+ {
+ int flushed = 0;
+ struct fib_table *tb;
+@@ -109,7 +107,8 @@
+ unsigned int h;
+
+ for (h = 0; h < FIB_TABLE_HASHSZ; h++) {
+- hlist_for_each_entry(tb, node, &fib_table_hash[h], tb_hlist)
++ struct hlist_head *head = &net->ip_fib_table_hash[h];
++ hlist_for_each_entry(tb, node, head, tb_hlist)
+ flushed += tb->tb_flush(tb);
+ }
+
+@@ -121,18 +120,23 @@
+ * Find the first device with a given source address.
+ */
+
+-struct net_device * ip_dev_find(__be32 addr)
++struct net_device * ip_dev_find(struct net *net, __be32 addr)
+ {
+- struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
++ struct flowi fl = {
++ .fl_net = net,
++ .nl_u = { .ip4_u = { .daddr = addr } }
++ };
+ struct fib_result res;
+ struct net_device *dev = NULL;
++ struct fib_table *local_table;
+
+ #ifdef CONFIG_IP_MULTIPLE_TABLES
+ res.r = NULL;
+ #endif
+
+- if (!ip_fib_local_table ||
+- ip_fib_local_table->tb_lookup(ip_fib_local_table, &fl, &res))
++ local_table = fib_get_table(net, RT_TABLE_LOCAL);
++ if (!local_table ||
++ local_table->tb_lookup(local_table, &fl, &res))
+ return NULL;
+ if (res.type != RTN_LOCAL)
+ goto out;
+@@ -145,11 +149,15 @@
+ return dev;
+ }
+
+-unsigned inet_addr_type(__be32 addr)
++unsigned inet_addr_type(struct net *net, __be32 addr)
+ {
+- struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
++ struct flowi fl = {
++ .fl_net = net,
++ .nl_u = { .ip4_u = { .daddr = addr } }
++ };
+ struct fib_result res;
+ unsigned ret = RTN_BROADCAST;
++ struct fib_table *local_table;
+
+ if (ZERONET(addr) || BADCLASS(addr))
+ return RTN_BROADCAST;
+@@ -160,10 +168,10 @@
+ res.r = NULL;
+ #endif
+
+- if (ip_fib_local_table) {
++ local_table = fib_get_table(net, RT_TABLE_LOCAL);
++ if (local_table) {
+ ret = RTN_UNICAST;
+- if (!ip_fib_local_table->tb_lookup(ip_fib_local_table,
+- &fl, &res)) {
++ if (!local_table->tb_lookup(local_table, &fl, &res)) {
+ ret = res.type;
+ fib_res_put(&res);
+ }
+@@ -183,7 +191,8 @@
+ struct net_device *dev, __be32 *spec_dst, u32 *itag)
+ {
+ struct in_device *in_dev;
+- struct flowi fl = { .nl_u = { .ip4_u =
++ struct flowi fl = { .fl_net = dev->nd_net,
++ .nl_u = { .ip4_u =
+ { .daddr = src,
+ .saddr = dst,
+ .tos = tos } },
+@@ -267,13 +276,16 @@
+ return len + nla_total_size(4);
+ }
+
+-static int rtentry_to_fib_config(int cmd, struct rtentry *rt,
++static int rtentry_to_fib_config(struct net *net, int cmd, struct rtentry *rt,
+ struct fib_config *cfg)
+ {
+ __be32 addr;
+ int plen;
+
+ memset(cfg, 0, sizeof(*cfg));
++ cfg->fc_nlinfo.pid = 0;
++ cfg->fc_nlinfo.nlh = NULL;
++ cfg->fc_nlinfo.net = net;
+
+ if (rt->rt_dst.sa_family != AF_INET)
+ return -EAFNOSUPPORT;
+@@ -334,7 +346,7 @@
+ colon = strchr(devname, ':');
+ if (colon)
+ *colon = 0;
+- dev = __dev_get_by_name(devname);
++ dev = __dev_get_by_name(net, devname);
+ if (!dev)
+ return -ENODEV;
+ cfg->fc_oif = dev->ifindex;
+@@ -357,7 +369,7 @@
+ if (rt->rt_gateway.sa_family == AF_INET && addr) {
+ cfg->fc_gw = addr;
+ if (rt->rt_flags & RTF_GATEWAY &&
+- inet_addr_type(addr) == RTN_UNICAST)
++ inet_addr_type(net, addr) == RTN_UNICAST)
+ cfg->fc_scope = RT_SCOPE_UNIVERSE;
+ }
+
+@@ -398,7 +410,7 @@
+ * Handle IP routing ioctl calls. These are used to manipulate the routing tables
+ */
+
+-int ip_rt_ioctl(unsigned int cmd, void __user *arg)
++int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg)
+ {
+ struct fib_config cfg;
+ struct rtentry rt;
+@@ -414,18 +426,18 @@
+ return -EFAULT;
+
+ rtnl_lock();
+- err = rtentry_to_fib_config(cmd, &rt, &cfg);
++ err = rtentry_to_fib_config(net, cmd, &rt, &cfg);
+ if (err == 0) {
+ struct fib_table *tb;
+
+ if (cmd == SIOCDELRT) {
+- tb = fib_get_table(cfg.fc_table);
++ tb = fib_get_table(net, cfg.fc_table);
+ if (tb)
+ err = tb->tb_delete(tb, &cfg);
+ else
+ err = -ESRCH;
+ } else {
+- tb = fib_new_table(cfg.fc_table);
++ tb = fib_new_table(net, cfg.fc_table);
+ if (tb)
+ err = tb->tb_insert(tb, &cfg);
+ else
+@@ -453,7 +465,6 @@
+ [RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) },
+ [RTA_PROTOINFO] = { .type = NLA_U32 },
+ [RTA_FLOW] = { .type = NLA_U32 },
+- [RTA_MP_ALGO] = { .type = NLA_U32 },
+ };
+
+ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh,
+@@ -481,6 +492,7 @@
+
+ cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
+ cfg->fc_nlinfo.nlh = nlh;
++ cfg->fc_nlinfo.net = skb->sk->sk_net;
+
+ if (cfg->fc_type > RTN_MAX) {
+ err = -EINVAL;
+@@ -515,9 +527,6 @@
+ case RTA_FLOW:
+ cfg->fc_flow = nla_get_u32(attr);
+ break;
+- case RTA_MP_ALGO:
+- cfg->fc_mp_alg = nla_get_u32(attr);
+- break;
+ case RTA_TABLE:
+ cfg->fc_table = nla_get_u32(attr);
+ break;
+@@ -531,6 +540,7 @@
+
+ static int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct fib_config cfg;
+ struct fib_table *tb;
+ int err;
+@@ -539,7 +549,7 @@
+ if (err < 0)
+ goto errout;
+
+- tb = fib_get_table(cfg.fc_table);
++ tb = fib_get_table(net, cfg.fc_table);
+ if (tb == NULL) {
+ err = -ESRCH;
+ goto errout;
+@@ -552,6 +562,7 @@
+
+ static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct fib_config cfg;
+ struct fib_table *tb;
+ int err;
+@@ -560,7 +571,7 @@
+ if (err < 0)
+ goto errout;
+
+- tb = fib_new_table(cfg.fc_table);
++ tb = fib_new_table(net, cfg.fc_table);
+ if (tb == NULL) {
+ err = -ENOBUFS;
+ goto errout;
+@@ -573,6 +584,7 @@
+
+ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
+ {
++ struct net *net = skb->sk->sk_net;
+ unsigned int h, s_h;
+ unsigned int e = 0, s_e;
+ struct fib_table *tb;
+@@ -587,8 +599,9 @@
+ s_e = cb->args[1];
+
+ for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) {
++ struct hlist_head *head = &net->ip_fib_table_hash[h];
+ e = 0;
+- hlist_for_each_entry(tb, node, &fib_table_hash[h], tb_hlist) {
++ hlist_for_each_entry(tb, node, head, tb_hlist) {
+ if (e < s_e)
+ goto next;
+ if (dumped)
+@@ -617,6 +630,7 @@
+
+ static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifaddr *ifa)
+ {
++ struct net *net = ifa->ifa_dev->dev->nd_net;
+ struct fib_table *tb;
+ struct fib_config cfg = {
+ .fc_protocol = RTPROT_KERNEL,
+@@ -626,12 +640,13 @@
+ .fc_prefsrc = ifa->ifa_local,
+ .fc_oif = ifa->ifa_dev->dev->ifindex,
+ .fc_nlflags = NLM_F_CREATE | NLM_F_APPEND,
++ .fc_nlinfo.net = net,
+ };
+
+ if (type == RTN_UNICAST)
+- tb = fib_new_table(RT_TABLE_MAIN);
++ tb = fib_new_table(net, RT_TABLE_MAIN);
+ else
+- tb = fib_new_table(RT_TABLE_LOCAL);
++ tb = fib_new_table(net, RT_TABLE_LOCAL);
+
+ if (tb == NULL)
+ return;
+@@ -692,6 +707,7 @@
+ {
+ struct in_device *in_dev = ifa->ifa_dev;
+ struct net_device *dev = in_dev->dev;
++ struct net *net = dev->nd_net;
+ struct in_ifaddr *ifa1;
+ struct in_ifaddr *prim = ifa;
+ __be32 brd = ifa->ifa_address|~ifa->ifa_mask;
+@@ -740,15 +756,15 @@
+ fib_magic(RTM_DELROUTE, RTN_LOCAL, ifa->ifa_local, 32, prim);
+
+ /* Check, that this local address finally disappeared. */
+- if (inet_addr_type(ifa->ifa_local) != RTN_LOCAL) {
++ if (inet_addr_type(net, ifa->ifa_local) != RTN_LOCAL) {
+ /* And the last, but not the least thing.
+ We must flush stray FIB entries.
+
+ First of all, we scan fib_info list searching
+ for stray nexthop entries, then ignite fib_flush.
+ */
+- if (fib_sync_down(ifa->ifa_local, NULL, 0))
+- fib_flush();
++ if (fib_sync_down(net, ifa->ifa_local, NULL, 0))
++ fib_flush(net);
+ }
+ }
+ #undef LOCAL_OK
+@@ -757,11 +773,12 @@
+ #undef BRD1_OK
+ }
+
+-static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb )
++static void nl_fib_lookup(struct net *net, struct fib_result_nl *frn, struct fib_table *tb )
+ {
+
+ struct fib_result res;
+- struct flowi fl = { .mark = frn->fl_mark,
++ struct flowi fl = { .fl_net = net,
++ .mark = frn->fl_mark,
+ .nl_u = { .ip4_u = { .daddr = frn->fl_addr,
+ .tos = frn->fl_tos,
+ .scope = frn->fl_scope } } };
+@@ -790,6 +807,7 @@
+
+ static void nl_fib_input(struct sock *sk, int len)
+ {
++ struct net *net = sk->sk_net;
+ struct sk_buff *skb = NULL;
+ struct nlmsghdr *nlh = NULL;
+ struct fib_result_nl *frn;
+@@ -808,9 +826,9 @@
+ }
+
+ frn = (struct fib_result_nl *) NLMSG_DATA(nlh);
+- tb = fib_get_table(frn->tb_id_in);
++ tb = fib_get_table(net, frn->tb_id_in);
+
+- nl_fib_lookup(frn, tb);
++ nl_fib_lookup(net, frn, tb);
+
+ pid = NETLINK_CB(skb).pid; /* pid of sending process */
+ NETLINK_CB(skb).pid = 0; /* from kernel */
+@@ -818,16 +836,36 @@
+ netlink_unicast(sk, skb, pid, MSG_DONTWAIT);
+ }
+
+-static void nl_fib_lookup_init(void)
++static int nl_fib_lookup_init(struct net *net)
+ {
+- netlink_kernel_create(NETLINK_FIB_LOOKUP, 0, nl_fib_input, NULL,
+- THIS_MODULE);
++ int error = -ENOMEM;
++ struct sock *sk;
++ sk = netlink_kernel_create(net, NETLINK_FIB_LOOKUP, 0, nl_fib_input,
++ NULL, THIS_MODULE);
++ if (sk) {
++ /* Don't hold an extra reference on the namespace */
++ put_net(sk->sk_net);
++ net->nlfl = sk;
++ error = 0;
+ }
-+ if (answer)
-+ goto out_permanent;
-+
-+ /* Add the new entry after the last permanent entry if any, so that
-+ * the new entry does not override a permanent entry when matched with
-+ * a wild-card protocol. But it is allowed to override any existing
-+ * non-permanent entry. This means that when we remove this entry, the
-+ * system automatically returns to the old behavior.
-+ */
-+ list_add_rcu(&p->list, last_perm);
-+out:
-+ spin_unlock_bh(&inetsw_lock);
-+
-+ synchronize_net();
-+
-+ return;
-+
-+out_permanent:
-+ printk(KERN_ERR "Attempt to override permanent protocol %d.\n",
-+ protocol);
-+ goto out;
-+
-+out_illegal:
-+ printk(KERN_ERR
-+ "Ignoring attempt to register invalid socket type %d.\n",
-+ p->type);
-+ goto out;
++ return error;
+}
+
-+void inet_unregister_protosw(struct inet_protosw *p)
++static void nl_fib_lookup_exit(struct net *net)
+{
-+ if (INET_PROTOSW_PERMANENT & p->flags) {
-+ printk(KERN_ERR
-+ "Attempt to unregister permanent protocol %d.\n",
-+ p->protocol);
-+ } else {
-+ spin_lock_bh(&inetsw_lock);
-+ list_del_rcu(&p->list);
-+ spin_unlock_bh(&inetsw_lock);
-+
-+ synchronize_net();
-+ }
-+}
-+
-+/*
-+ * Shall we try to damage output packets if routing dev changes?
-+ */
-+
-+int sysctl_ip_dynaddr __read_mostly;
++ /* At the last minute lie and say this is a socket for the
++ * initial network namespace. So the socket will be safe to
++ * free.
++ */
++ net->nlfl->sk_net = get_net(&init_net);
++ sock_put(net->nlfl);
+ }
+
+ static void fib_disable_ip(struct net_device *dev, int force)
+ {
+- if (fib_sync_down(0, dev, force))
+- fib_flush();
++ struct net *net = dev->nd_net;
++ if (fib_sync_down(net, 0, dev, force))
++ fib_flush(net);
+ rt_cache_flush(0);
+ arp_ifdown(dev);
+ }
+@@ -864,6 +902,9 @@
+ struct net_device *dev = ptr;
+ struct in_device *in_dev = __in_dev_get_rtnl(dev);
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
+
-+static int inet_sk_reselect_saddr(struct sock *sk)
+ if (event == NETDEV_UNREGISTER) {
+ fib_disable_ip(dev, 2);
+ return NOTIFY_DONE;
+@@ -893,6 +934,85 @@
+ return NOTIFY_DONE;
+ }
+
++static int ip_fib_net_init(struct net *net)
+{
-+ struct inet_sock *inet = inet_sk(sk);
-+ int err;
-+ struct rtable *rt;
-+ __be32 old_saddr = inet->saddr;
-+ __be32 new_saddr;
-+ __be32 daddr = inet->daddr;
-+
-+ if (inet->opt && inet->opt->srr)
-+ daddr = inet->opt->faddr;
-+
-+ /* Query new route. */
-+ err = ip_route_connect(&rt, daddr, 0,
-+ RT_CONN_FLAGS(sk),
-+ sk->sk_bound_dev_if,
-+ sk->sk_protocol,
-+ inet->sport, inet->dport, sk, 0);
-+ if (err)
-+ return err;
-+
-+ sk_setup_caps(sk, &rt->u.dst);
-+
-+ new_saddr = rt->rt_src;
-+
-+ if (new_saddr == old_saddr)
-+ return 0;
-+
-+ if (sysctl_ip_dynaddr > 1) {
-+ printk(KERN_INFO "%s(): shifting inet->"
-+ "saddr from %d.%d.%d.%d to %d.%d.%d.%d\n",
-+ __FUNCTION__,
-+ NIPQUAD(old_saddr),
-+ NIPQUAD(new_saddr));
-+ }
++ unsigned int i;
+
-+ inet->saddr = inet->rcv_saddr = new_saddr;
++ net->ip_fib_table_hash = kzalloc(
++ sizeof(struct hlist_head)*FIB_TABLE_HASHSZ, GFP_KERNEL);
++ if (!net->ip_fib_table_hash)
++ return -ENOMEM;
+
-+ /*
-+ * XXX The only one ugly spot where we need to
-+ * XXX really change the sockets identity after
-+ * XXX it has entered the hashes. -DaveM
-+ *
-+ * Besides that, it does not check for connection
-+ * uniqueness. Wait for troubles.
-+ */
-+ __sk_prot_rehash(sk);
++ for (i = 0; i < FIB_TABLE_HASHSZ; i++)
++ INIT_HLIST_HEAD(&net->ip_fib_table_hash[i]);
++#ifndef CONFIG_IP_MULTIPLE_TABLES
++ net->ip_fib_local_table = fib_hash_init(RT_TABLE_LOCAL);
++ hlist_add_head_rcu(&net->ip_fib_local_table->tb_hlist,
++ &net->ip_fib_table_hash[0]);
++ net->ip_fib_main_table = fib_hash_init(RT_TABLE_MAIN);
++ hlist_add_head_rcu(&net->ip_fib_main_table->tb_hlist,
++ &net->ip_fib_table_hash[0]);
++#else
++ fib4_rules_init(net);
++#endif
+ return 0;
+}
+
-+int inet_sk_rebuild_header(struct sock *sk)
++static void ip_fib_net_exit(struct net *net)
+{
-+ struct inet_sock *inet = inet_sk(sk);
-+ struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0);
-+ __be32 daddr;
-+ int err;
++ unsigned int i;
+
-+ /* Route is OK, nothing to do. */
-+ if (rt)
-+ return 0;
++#ifdef CONFIG_IP_MULTIPLE_TABLES
++ fib4_rules_exit(net);
++#endif
+
-+ /* Reroute. */
-+ daddr = inet->daddr;
-+ if (inet->opt && inet->opt->srr)
-+ daddr = inet->opt->faddr;
-+{
-+ struct flowi fl = {
-+ .oif = sk->sk_bound_dev_if,
-+ .nl_u = {
-+ .ip4_u = {
-+ .daddr = daddr,
-+ .saddr = inet->saddr,
-+ .tos = RT_CONN_FLAGS(sk),
-+ },
-+ },
-+ .proto = sk->sk_protocol,
-+ .uli_u = {
-+ .ports = {
-+ .sport = inet->sport,
-+ .dport = inet->dport,
-+ },
-+ },
-+ };
++ synchronize_rcu(); /* needed? */
++ for (i = 0; i < FIB_TABLE_HASHSZ; i++) {
++ struct fib_table *tb;
++ struct hlist_head *head;
++ struct hlist_node *node, *tmp;
+
-+ security_sk_classify_flow(sk, &fl);
-+ err = ip_route_output_flow(&rt, &fl, sk, 0);
-+}
-+ if (!err)
-+ sk_setup_caps(sk, &rt->u.dst);
-+ else {
-+ /* Routing failed... */
-+ sk->sk_route_caps = 0;
-+ /*
-+ * Other protocols have to map its equivalent state to TCP_SYN_SENT.
-+ * DCCP maps its DCCP_REQUESTING state to TCP_SYN_SENT. -acme
-+ */
-+ if (!sysctl_ip_dynaddr ||
-+ sk->sk_state != TCP_SYN_SENT ||
-+ (sk->sk_userlocks & SOCK_BINDADDR_LOCK) ||
-+ (err = inet_sk_reselect_saddr(sk)) != 0)
-+ sk->sk_err_soft = -err;
++ head = &net->ip_fib_table_hash[i];
++ hlist_for_each_entry_safe(tb, node, tmp, head, tb_hlist) {
++ hlist_del(node);
++ fib_hash_exit(tb);
++ }
+ }
-+
-+ return err;
++ kfree(net->ip_fib_table_hash);
+}
+
-+EXPORT_SYMBOL(inet_sk_rebuild_header);
-+
-+static int inet_gso_send_check(struct sk_buff *skb)
++static int fib_net_init(struct net *net)
+{
-+ struct iphdr *iph;
-+ struct net_protocol *ops;
-+ int proto;
-+ int ihl;
-+ int err = -EINVAL;
-+
-+ if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))
-+ goto out;
-+
-+ iph = ip_hdr(skb);
-+ ihl = iph->ihl * 4;
-+ if (ihl < sizeof(*iph))
-+ goto out;
++ int error;
+
-+ if (unlikely(!pskb_may_pull(skb, ihl)))
++ error = 0;
++ if ((error = ip_fib_net_init(net)))
+ goto out;
-+
-+ __skb_pull(skb, ihl);
-+ skb_reset_transport_header(skb);
-+ iph = ip_hdr(skb);
-+ proto = iph->protocol & (MAX_INET_PROTOS - 1);
-+ err = -EPROTONOSUPPORT;
-+
-+ rcu_read_lock();
-+ ops = rcu_dereference(inet_protos[proto]);
-+ if (likely(ops && ops->gso_send_check))
-+ err = ops->gso_send_check(skb);
-+ rcu_read_unlock();
-+
++ if ((error = fib_info_init(net)))
++ goto out_info;
++ if ((error = nl_fib_lookup_init(net)))
++ goto out_nlfl;
++ if ((error = fib_proc_init(net)))
++ goto out_proc;
+out:
-+ return err;
++ return error;
++out_proc:
++ nl_fib_lookup_exit(net);
++out_nlfl:
++ fib_info_exit(net);
++out_info:
++ ip_fib_net_exit(net);
++ goto out;
+}
+
-+static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features)
++static void fib_net_exit(struct net *net)
+{
-+ struct sk_buff *segs = ERR_PTR(-EINVAL);
-+ struct iphdr *iph;
-+ struct net_protocol *ops;
-+ int proto;
-+ int ihl;
-+ int id;
-+
-+ if (unlikely(skb_shinfo(skb)->gso_type &
-+ ~(SKB_GSO_TCPV4 |
-+ SKB_GSO_UDP |
-+ SKB_GSO_DODGY |
-+ SKB_GSO_TCP_ECN |
-+ 0)))
-+ goto out;
-+
-+ if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))
-+ goto out;
++ fib_proc_exit(net);
++ nl_fib_lookup_exit(net);
++ fib_info_exit(net);
++ ip_fib_net_exit(net);
++}
+
-+ iph = ip_hdr(skb);
-+ ihl = iph->ihl * 4;
-+ if (ihl < sizeof(*iph))
-+ goto out;
+ static struct notifier_block fib_inetaddr_notifier = {
+ .notifier_call =fib_inetaddr_event,
+ };
+@@ -901,28 +1021,20 @@
+ .notifier_call =fib_netdev_event,
+ };
+
++static struct pernet_operations fib_net_ops = {
++ .init = fib_net_init,
++ .exit = fib_net_exit,
++};
+
-+ if (unlikely(!pskb_may_pull(skb, ihl)))
-+ goto out;
-+
-+ __skb_pull(skb, ihl);
-+ skb_reset_transport_header(skb);
-+ iph = ip_hdr(skb);
-+ id = ntohs(iph->id);
-+ proto = iph->protocol & (MAX_INET_PROTOS - 1);
-+ segs = ERR_PTR(-EPROTONOSUPPORT);
-+
-+ rcu_read_lock();
-+ ops = rcu_dereference(inet_protos[proto]);
-+ if (likely(ops && ops->gso_segment))
-+ segs = ops->gso_segment(skb, features);
-+ rcu_read_unlock();
-+
-+ if (!segs || unlikely(IS_ERR(segs)))
-+ goto out;
-+
-+ skb = segs;
-+ do {
-+ iph = ip_hdr(skb);
-+ iph->id = htons(id++);
-+ iph->tot_len = htons(skb->len - skb->mac_len);
-+ iph->check = 0;
-+ iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl);
-+ } while ((skb = skb->next));
+ void __init ip_fib_init(void)
+ {
+- unsigned int i;
+-
+- for (i = 0; i < FIB_TABLE_HASHSZ; i++)
+- INIT_HLIST_HEAD(&fib_table_hash[i]);
+-#ifndef CONFIG_IP_MULTIPLE_TABLES
+- ip_fib_local_table = fib_hash_init(RT_TABLE_LOCAL);
+- hlist_add_head_rcu(&ip_fib_local_table->tb_hlist, &fib_table_hash[0]);
+- ip_fib_main_table = fib_hash_init(RT_TABLE_MAIN);
+- hlist_add_head_rcu(&ip_fib_main_table->tb_hlist, &fib_table_hash[0]);
+-#else
+- fib4_rules_init();
+-#endif
+-
+- register_netdevice_notifier(&fib_netdev_notifier);
+- register_inetaddr_notifier(&fib_inetaddr_notifier);
+- nl_fib_lookup_init();
+-
+ rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL);
+ rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL);
+ rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib);
+
-+out:
-+ return segs;
++ register_pernet_subsys(&fib_net_ops);
++ register_netdevice_notifier(&fib_netdev_notifier);
++ register_inetaddr_notifier(&fib_inetaddr_notifier);
+ }
+
+ EXPORT_SYMBOL(inet_addr_type);
+diff -Nurb linux-2.6.22-570/net/ipv4/fib_hash.c linux-2.6.22-590/net/ipv4/fib_hash.c
+--- linux-2.6.22-570/net/ipv4/fib_hash.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/ipv4/fib_hash.c 2008-01-29 22:12:32.000000000 -0500
+@@ -40,6 +40,7 @@
+ #include <net/route.h>
+ #include <net/tcp.h>
+ #include <net/sock.h>
++#include <net/net_namespace.h>
+ #include <net/ip_fib.h>
+
+ #include "fib_lookup.h"
+@@ -274,11 +275,10 @@
+ return err;
+ }
+
+-static int fn_hash_last_dflt=-1;
+-
+ static void
+ fn_hash_select_default(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
+ {
++ struct net *net = flp->fl_net;
+ int order, last_idx;
+ struct hlist_node *node;
+ struct fib_node *f;
+@@ -316,12 +316,12 @@
+ if (next_fi != res->fi)
+ break;
+ } else if (!fib_detect_death(fi, order, &last_resort,
+- &last_idx, &fn_hash_last_dflt)) {
++ &last_idx, &net->fn_hash_last_dflt)) {
+ if (res->fi)
+ fib_info_put(res->fi);
+ res->fi = fi;
+ atomic_inc(&fi->fib_clntref);
+- fn_hash_last_dflt = order;
++ net->fn_hash_last_dflt = order;
+ goto out;
+ }
+ fi = next_fi;
+@@ -330,16 +330,16 @@
+ }
+
+ if (order <= 0 || fi == NULL) {
+- fn_hash_last_dflt = -1;
++ net->fn_hash_last_dflt = -1;
+ goto out;
+ }
+
+- if (!fib_detect_death(fi, order, &last_resort, &last_idx, &fn_hash_last_dflt)) {
++ if (!fib_detect_death(fi, order, &last_resort, &last_idx, &net->fn_hash_last_dflt)) {
+ if (res->fi)
+ fib_info_put(res->fi);
+ res->fi = fi;
+ atomic_inc(&fi->fib_clntref);
+- fn_hash_last_dflt = order;
++ net->fn_hash_last_dflt = order;
+ goto out;
+ }
+
+@@ -350,7 +350,7 @@
+ if (last_resort)
+ atomic_inc(&last_resort->fib_clntref);
+ }
+- fn_hash_last_dflt = last_idx;
++ net->fn_hash_last_dflt = last_idx;
+ out:
+ read_unlock(&fib_hash_lock);
+ }
+@@ -759,11 +759,15 @@
+ return skb->len;
+ }
+
+-#ifdef CONFIG_IP_MULTIPLE_TABLES
++void fib_hash_exit(struct fib_table *tb)
++{
++ if (!tb)
++ return;
++ fn_hash_flush(tb);
++ kfree(tb);
+}
+
-+unsigned long snmp_fold_field(void *mib[], int offt)
+ struct fib_table * fib_hash_init(u32 id)
+-#else
+-struct fib_table * __init fib_hash_init(u32 id)
+-#endif
+ {
+ struct fib_table *tb;
+
+@@ -799,6 +803,7 @@
+ #ifdef CONFIG_PROC_FS
+
+ struct fib_iter_state {
++ struct net *net;
+ struct fn_zone *zone;
+ int bucket;
+ struct hlist_head *hash_head;
+@@ -812,7 +817,8 @@
+ static struct fib_alias *fib_get_first(struct seq_file *seq)
+ {
+ struct fib_iter_state *iter = seq->private;
+- struct fn_hash *table = (struct fn_hash *) ip_fib_main_table->tb_data;
++ struct fib_table *main_table = fib_get_table(iter->net, RT_TABLE_MAIN);
++ struct fn_hash *table = (struct fn_hash *) main_table->tb_data;
+
+ iter->bucket = 0;
+ iter->hash_head = NULL;
+@@ -948,10 +954,11 @@
+
+ static void *fib_seq_start(struct seq_file *seq, loff_t *pos)
+ {
++ struct fib_iter_state *iter = seq->private;
+ void *v = NULL;
+
+ read_lock(&fib_hash_lock);
+- if (ip_fib_main_table)
++ if (fib_get_table(iter->net, RT_TABLE_MAIN))
+ v = *pos ? fib_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ return v;
+ }
+@@ -1051,6 +1058,7 @@
+
+ seq = file->private_data;
+ seq->private = s;
++ s->net = get_net(PROC_NET(inode));
+ out:
+ return rc;
+ out_kfree:
+@@ -1058,23 +1066,32 @@
+ goto out;
+ }
+
++static int fib_seq_release(struct inode *inode, struct file *file)
+{
-+ unsigned long res = 0;
-+ int i;
++ struct seq_file *seq = file->private_data;
++ struct fib_iter_state *iter = seq->private;
++ put_net(iter->net);
++ return seq_release_private(inode, file);
++}
+
-+ for_each_possible_cpu(i) {
-+ res += *(((unsigned long *) per_cpu_ptr(mib[0], i)) + offt);
-+ res += *(((unsigned long *) per_cpu_ptr(mib[1], i)) + offt);
+ static const struct file_operations fib_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = fib_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+- .release = seq_release_private,
++ .release = fib_seq_release,
+ };
+
+-int __init fib_proc_init(void)
++int fib_proc_init(struct net *net)
+ {
+- if (!proc_net_fops_create("route", S_IRUGO, &fib_seq_fops))
++ net->fn_hash_last_dflt = -1;
++ if (!proc_net_fops_create(net, "route", S_IRUGO, &fib_seq_fops))
+ return -ENOMEM;
+ return 0;
+ }
+
+-void __init fib_proc_exit(void)
++void fib_proc_exit(struct net *net)
+ {
+- proc_net_remove("route");
++ proc_net_remove(net, "route");
+ }
+ #endif /* CONFIG_PROC_FS */
+diff -Nurb linux-2.6.22-570/net/ipv4/fib_rules.c linux-2.6.22-590/net/ipv4/fib_rules.c
+--- linux-2.6.22-570/net/ipv4/fib_rules.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/fib_rules.c 2008-01-29 22:12:32.000000000 -0500
+@@ -32,8 +32,6 @@
+ #include <net/ip_fib.h>
+ #include <net/fib_rules.h>
+
+-static struct fib_rules_ops fib4_rules_ops;
+-
+ struct fib4_rule
+ {
+ struct fib_rule common;
+@@ -49,35 +47,14 @@
+ #endif
+ };
+
+-static struct fib4_rule default_rule = {
+- .common = {
+- .refcnt = ATOMIC_INIT(2),
+- .pref = 0x7FFF,
+- .table = RT_TABLE_DEFAULT,
+- .action = FR_ACT_TO_TBL,
+- },
++struct fib4_rule_table {
++ struct list_head fib4_rules;
++ struct fib4_rule default_rule;
++ struct fib4_rule main_rule;
++ struct fib4_rule local_rule;
++ struct fib_rules_ops fib4_rules_ops;
+ };
+
+-static struct fib4_rule main_rule = {
+- .common = {
+- .refcnt = ATOMIC_INIT(2),
+- .pref = 0x7FFE,
+- .table = RT_TABLE_MAIN,
+- .action = FR_ACT_TO_TBL,
+- },
+-};
+-
+-static struct fib4_rule local_rule = {
+- .common = {
+- .refcnt = ATOMIC_INIT(2),
+- .table = RT_TABLE_LOCAL,
+- .action = FR_ACT_TO_TBL,
+- .flags = FIB_RULE_PERMANENT,
+- },
+-};
+-
+-static LIST_HEAD(fib4_rules);
+-
+ #ifdef CONFIG_NET_CLS_ROUTE
+ u32 fib_rules_tclass(struct fib_result *res)
+ {
+@@ -87,12 +64,14 @@
+
+ int fib_lookup(struct flowi *flp, struct fib_result *res)
+ {
++ struct net *net = flp->fl_net;
++ struct fib4_rule_table *table = net->fib4_table;
+ struct fib_lookup_arg arg = {
+ .result = res,
+ };
+ int err;
+
+- err = fib_rules_lookup(&fib4_rules_ops, flp, 0, &arg);
++ err = fib_rules_lookup(&table->fib4_rules_ops, flp, 0, &arg);
+ res->r = arg.rule;
+
+ return err;
+@@ -122,7 +101,7 @@
+ goto errout;
+ }
+
+- if ((tbl = fib_get_table(rule->table)) == NULL)
++ if ((tbl = fib_get_table(flp->fl_net, rule->table)) == NULL)
+ goto errout;
+
+ err = tbl->tb_lookup(tbl, flp, (struct fib_result *) arg->result);
+@@ -138,7 +117,7 @@
+ if (res->r && res->r->action == FR_ACT_TO_TBL &&
+ FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) {
+ struct fib_table *tb;
+- if ((tb = fib_get_table(res->r->table)) != NULL)
++ if ((tb = fib_get_table(flp->fl_net, res->r->table)) != NULL)
+ tb->tb_select_default(tb, flp, res);
+ }
+ }
+@@ -159,13 +138,13 @@
+ return 1;
+ }
+
+-static struct fib_table *fib_empty_table(void)
++static struct fib_table *fib_empty_table(struct net *net)
+ {
+ u32 id;
+
+ for (id = 1; id <= RT_TABLE_MAX; id++)
+- if (fib_get_table(id) == NULL)
+- return fib_new_table(id);
++ if (fib_get_table(net, id) == NULL)
++ return fib_new_table(net, id);
+ return NULL;
+ }
+
+@@ -178,6 +157,7 @@
+ struct nlmsghdr *nlh, struct fib_rule_hdr *frh,
+ struct nlattr **tb)
+ {
++ struct net *net = skb->sk->sk_net;
+ int err = -EINVAL;
+ struct fib4_rule *rule4 = (struct fib4_rule *) rule;
+
+@@ -188,7 +168,7 @@
+ if (rule->action == FR_ACT_TO_TBL) {
+ struct fib_table *table;
+
+- table = fib_empty_table();
++ table = fib_empty_table(net);
+ if (table == NULL) {
+ err = -ENOBUFS;
+ goto errout;
+@@ -274,14 +254,15 @@
+ return -ENOBUFS;
+ }
+
+-static u32 fib4_rule_default_pref(void)
++static u32 fib4_rule_default_pref(struct fib_rules_ops *ops)
+ {
+- struct list_head *pos;
++ struct list_head *list, *pos;
+ struct fib_rule *rule;
+
+- if (!list_empty(&fib4_rules)) {
+- pos = fib4_rules.next;
+- if (pos->next != &fib4_rules) {
++ list = ops->rules_list;
++ if (!list_empty(list)) {
++ pos = list->next;
++ if (pos->next != list) {
+ rule = list_entry(pos->next, struct fib_rule, list);
+ if (rule->pref)
+ return rule->pref - 1;
+@@ -298,12 +279,37 @@
+ + nla_total_size(4); /* flow */
+ }
+
+-static void fib4_rule_flush_cache(void)
++static void fib4_rule_flush_cache(struct fib_rules_ops *ops)
+ {
+ rt_cache_flush(-1);
+ }
+
+-static struct fib_rules_ops fib4_rules_ops = {
++static struct fib4_rule_table fib4_rule_table = {
++ .default_rule = {
++ .common = {
++ .refcnt = ATOMIC_INIT(2),
++ .pref = 0x7FFF,
++ .table = RT_TABLE_DEFAULT,
++ .action = FR_ACT_TO_TBL,
++ },
++ },
++ .main_rule = {
++ .common = {
++ .refcnt = ATOMIC_INIT(2),
++ .pref = 0x7FFE,
++ .table = RT_TABLE_MAIN,
++ .action = FR_ACT_TO_TBL,
++ },
++ },
++ .local_rule = {
++ .common = {
++ .refcnt = ATOMIC_INIT(2),
++ .table = RT_TABLE_LOCAL,
++ .action = FR_ACT_TO_TBL,
++ .flags = FIB_RULE_PERMANENT,
++ },
++ },
++ .fib4_rules_ops = {
+ .family = AF_INET,
+ .rule_size = sizeof(struct fib4_rule),
+ .addr_size = sizeof(u32),
+@@ -317,15 +323,34 @@
+ .flush_cache = fib4_rule_flush_cache,
+ .nlgroup = RTNLGRP_IPV4_RULE,
+ .policy = fib4_rule_policy,
+- .rules_list = &fib4_rules,
++ .rules_list = &fib4_rule_table.fib4_rules, /* &fib4_rules, */
+ .owner = THIS_MODULE,
++ },
+ };
+
+-void __init fib4_rules_init(void)
++
++void fib4_rules_init(struct net *net)
+ {
+- list_add_tail(&local_rule.common.list, &fib4_rules);
+- list_add_tail(&main_rule.common.list, &fib4_rules);
+- list_add_tail(&default_rule.common.list, &fib4_rules);
++ struct fib4_rule_table *table;
++ table = kmemdup(&fib4_rule_table, sizeof(*table), GFP_KERNEL);
++ if (!table)
++ return;
++ INIT_LIST_HEAD(&table->fib4_rules);
++ list_add_tail(&table->local_rule.common.list, &table->fib4_rules);
++ list_add_tail(&table->main_rule.common.list, &table->fib4_rules);
++ list_add_tail(&table->default_rule.common.list, &table->fib4_rules);
++ table->fib4_rules_ops.rules_list = &table->fib4_rules;
++ if (fib_rules_register(net, &table->fib4_rules_ops)) {
++ kfree(table);
++ return;
+ }
-+ return res;
++ net->fib4_table = table;
+}
-+EXPORT_SYMBOL_GPL(snmp_fold_field);
+
+- fib_rules_register(&fib4_rules_ops);
++void fib4_rules_exit(struct net *net)
++{
++ struct fib4_rule_table *table = net->fib4_table;
++ if (table)
++ fib_rules_unregister(net, &table->fib4_rules_ops);
++ kfree(table);
+ }
+diff -Nurb linux-2.6.22-570/net/ipv4/fib_semantics.c linux-2.6.22-590/net/ipv4/fib_semantics.c
+--- linux-2.6.22-570/net/ipv4/fib_semantics.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/fib_semantics.c 2008-01-29 22:12:32.000000000 -0500
+@@ -42,7 +42,6 @@
+ #include <net/tcp.h>
+ #include <net/sock.h>
+ #include <net/ip_fib.h>
+-#include <net/ip_mp_alg.h>
+ #include <net/netlink.h>
+ #include <net/nexthop.h>
+
+@@ -51,14 +50,9 @@
+ #define FSprintk(a...)
+
+ static DEFINE_SPINLOCK(fib_info_lock);
+-static struct hlist_head *fib_info_hash;
+-static struct hlist_head *fib_info_laddrhash;
+-static unsigned int fib_hash_size;
+-static unsigned int fib_info_cnt;
+
+ #define DEVINDEX_HASHBITS 8
+ #define DEVINDEX_HASHSIZE (1U << DEVINDEX_HASHBITS)
+-static struct hlist_head fib_info_devhash[DEVINDEX_HASHSIZE];
+
+ #ifdef CONFIG_IP_ROUTE_MULTIPATH
+
+@@ -154,7 +148,8 @@
+ dev_put(nh->nh_dev);
+ nh->nh_dev = NULL;
+ } endfor_nexthops(fi);
+- fib_info_cnt--;
++ fi->fib_net->fib_info_cnt--;
++ release_net(fi->fib_net);
+ kfree(fi);
+ }
+
+@@ -197,9 +192,9 @@
+ return 0;
+ }
+
+-static inline unsigned int fib_info_hashfn(const struct fib_info *fi)
++static inline unsigned int fib_info_hashfn(struct net *net, const struct fib_info *fi)
+ {
+- unsigned int mask = (fib_hash_size - 1);
++ unsigned int mask = net->fib_info_hash_size - 1;
+ unsigned int val = fi->fib_nhs;
+
+ val ^= fi->fib_protocol;
+@@ -209,15 +204,15 @@
+ return (val ^ (val >> 7) ^ (val >> 12)) & mask;
+ }
+
+-static struct fib_info *fib_find_info(const struct fib_info *nfi)
++static struct fib_info *fib_find_info(struct net *net, const struct fib_info *nfi)
+ {
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct fib_info *fi;
+ unsigned int hash;
+
+- hash = fib_info_hashfn(nfi);
+- head = &fib_info_hash[hash];
++ hash = fib_info_hashfn(net, nfi);
++ head = &net->fib_info_hash[hash];
+
+ hlist_for_each_entry(fi, node, head, fib_hash) {
+ if (fi->fib_nhs != nfi->fib_nhs)
+@@ -250,6 +245,7 @@
+
+ int ip_fib_check_default(__be32 gw, struct net_device *dev)
+ {
++ struct net *net = dev->nd_net;
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct fib_nh *nh;
+@@ -258,7 +254,7 @@
+ spin_lock(&fib_info_lock);
+
+ hash = fib_devindex_hashfn(dev->ifindex);
+- head = &fib_info_devhash[hash];
++ head = &net->fib_info_devhash[hash];
+ hlist_for_each_entry(nh, node, head, nh_hash) {
+ if (nh->nh_dev == dev &&
+ nh->nh_gw == gw &&
+@@ -321,11 +317,11 @@
+ kfree_skb(skb);
+ goto errout;
+ }
+- err = rtnl_notify(skb, info->pid, RTNLGRP_IPV4_ROUTE,
++ err = rtnl_notify(skb, info->net, info->pid, RTNLGRP_IPV4_ROUTE,
+ info->nlh, GFP_KERNEL);
+ errout:
+ if (err < 0)
+- rtnl_set_sk_err(RTNLGRP_IPV4_ROUTE, err);
++ rtnl_set_sk_err(info->net, RTNLGRP_IPV4_ROUTE, err);
+ }
+
+ /* Return the first fib alias matching TOS with
+@@ -518,6 +514,7 @@
+ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
+ struct fib_nh *nh)
+ {
++ struct net *net = cfg->fc_nlinfo.net;
+ int err;
+
+ if (nh->nh_gw) {
+@@ -532,9 +529,9 @@
+
+ if (cfg->fc_scope >= RT_SCOPE_LINK)
+ return -EINVAL;
+- if (inet_addr_type(nh->nh_gw) != RTN_UNICAST)
++ if (inet_addr_type(net, nh->nh_gw) != RTN_UNICAST)
+ return -EINVAL;
+- if ((dev = __dev_get_by_index(nh->nh_oif)) == NULL)
++ if ((dev = __dev_get_by_index(net, nh->nh_oif)) == NULL)
+ return -ENODEV;
+ if (!(dev->flags&IFF_UP))
+ return -ENETDOWN;
+@@ -545,6 +542,7 @@
+ }
+ {
+ struct flowi fl = {
++ .fl_net = net,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = nh->nh_gw,
+@@ -581,7 +579,7 @@
+ if (nh->nh_flags&(RTNH_F_PERVASIVE|RTNH_F_ONLINK))
+ return -EINVAL;
+
+- in_dev = inetdev_by_index(nh->nh_oif);
++ in_dev = inetdev_by_index(net, nh->nh_oif);
+ if (in_dev == NULL)
+ return -ENODEV;
+ if (!(in_dev->dev->flags&IFF_UP)) {
+@@ -596,9 +594,9 @@
+ return 0;
+ }
+
+-static inline unsigned int fib_laddr_hashfn(__be32 val)
++static inline unsigned int fib_laddr_hashfn(struct net *net, __be32 val)
+ {
+- unsigned int mask = (fib_hash_size - 1);
++ unsigned int mask = net->fib_info_hash_size - 1;
+
+ return ((__force u32)val ^ ((__force u32)val >> 7) ^ ((__force u32)val >> 14)) & mask;
+ }
+@@ -623,21 +621,22 @@
+ free_pages((unsigned long) hash, get_order(bytes));
+ }
+
+-static void fib_hash_move(struct hlist_head *new_info_hash,
++static void fib_hash_move(struct net *net,
++ struct hlist_head *new_info_hash,
+ struct hlist_head *new_laddrhash,
+ unsigned int new_size)
+ {
+ struct hlist_head *old_info_hash, *old_laddrhash;
+- unsigned int old_size = fib_hash_size;
++ unsigned int old_size = net->fib_info_hash_size;
+ unsigned int i, bytes;
+
+ spin_lock_bh(&fib_info_lock);
+- old_info_hash = fib_info_hash;
+- old_laddrhash = fib_info_laddrhash;
+- fib_hash_size = new_size;
++ old_info_hash = net->fib_info_hash;
++ old_laddrhash = net->fib_info_laddrhash;
++ net->fib_info_hash_size = new_size;
+
+ for (i = 0; i < old_size; i++) {
+- struct hlist_head *head = &fib_info_hash[i];
++ struct hlist_head *head = &net->fib_info_hash[i];
+ struct hlist_node *node, *n;
+ struct fib_info *fi;
+
+@@ -647,15 +646,15 @@
+
+ hlist_del(&fi->fib_hash);
+
+- new_hash = fib_info_hashfn(fi);
++ new_hash = fib_info_hashfn(net, fi);
+ dest = &new_info_hash[new_hash];
+ hlist_add_head(&fi->fib_hash, dest);
+ }
+ }
+- fib_info_hash = new_info_hash;
++ net->fib_info_hash = new_info_hash;
+
+ for (i = 0; i < old_size; i++) {
+- struct hlist_head *lhead = &fib_info_laddrhash[i];
++ struct hlist_head *lhead = &net->fib_info_laddrhash[i];
+ struct hlist_node *node, *n;
+ struct fib_info *fi;
+
+@@ -665,12 +664,12 @@
+
+ hlist_del(&fi->fib_lhash);
+
+- new_hash = fib_laddr_hashfn(fi->fib_prefsrc);
++ new_hash = fib_laddr_hashfn(net, fi->fib_prefsrc);
+ ldest = &new_laddrhash[new_hash];
+ hlist_add_head(&fi->fib_lhash, ldest);
+ }
+ }
+- fib_info_laddrhash = new_laddrhash;
++ net->fib_info_laddrhash = new_laddrhash;
+
+ spin_unlock_bh(&fib_info_lock);
+
+@@ -681,6 +680,7 @@
+
+ struct fib_info *fib_create_info(struct fib_config *cfg)
+ {
++ struct net *net = cfg->fc_nlinfo.net;
+ int err;
+ struct fib_info *fi = NULL;
+ struct fib_info *ofi;
+@@ -697,17 +697,10 @@
+ goto err_inval;
+ }
+ #endif
+-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
+- if (cfg->fc_mp_alg) {
+- if (cfg->fc_mp_alg < IP_MP_ALG_NONE ||
+- cfg->fc_mp_alg > IP_MP_ALG_MAX)
+- goto err_inval;
+- }
+-#endif
+
+ err = -ENOBUFS;
+- if (fib_info_cnt >= fib_hash_size) {
+- unsigned int new_size = fib_hash_size << 1;
++ if (net->fib_info_cnt >= net->fib_info_hash_size) {
++ unsigned int new_size = net->fib_info_hash_size << 1;
+ struct hlist_head *new_info_hash;
+ struct hlist_head *new_laddrhash;
+ unsigned int bytes;
+@@ -724,18 +717,19 @@
+ memset(new_info_hash, 0, bytes);
+ memset(new_laddrhash, 0, bytes);
+
+- fib_hash_move(new_info_hash, new_laddrhash, new_size);
++ fib_hash_move(net, new_info_hash, new_laddrhash, new_size);
+ }
+
+- if (!fib_hash_size)
++ if (!net->fib_info_hash_size)
+ goto failure;
+ }
+
+ fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL);
+ if (fi == NULL)
+ goto failure;
+- fib_info_cnt++;
++ net->fib_info_cnt++;
+
++ fi->fib_net = hold_net(net);
+ fi->fib_protocol = cfg->fc_protocol;
+ fi->fib_flags = cfg->fc_flags;
+ fi->fib_priority = cfg->fc_priority;
+@@ -791,10 +785,6 @@
+ #endif
+ }
+
+-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
+- fi->fib_mp_alg = cfg->fc_mp_alg;
+-#endif
+-
+ if (fib_props[cfg->fc_type].error) {
+ if (cfg->fc_gw || cfg->fc_oif || cfg->fc_mp)
+ goto err_inval;
+@@ -811,7 +801,7 @@
+ if (nhs != 1 || nh->nh_gw)
+ goto err_inval;
+ nh->nh_scope = RT_SCOPE_NOWHERE;
+- nh->nh_dev = dev_get_by_index(fi->fib_nh->nh_oif);
++ nh->nh_dev = dev_get_by_index(net, fi->fib_nh->nh_oif);
+ err = -ENODEV;
+ if (nh->nh_dev == NULL)
+ goto failure;
+@@ -825,12 +815,12 @@
+ if (fi->fib_prefsrc) {
+ if (cfg->fc_type != RTN_LOCAL || !cfg->fc_dst ||
+ fi->fib_prefsrc != cfg->fc_dst)
+- if (inet_addr_type(fi->fib_prefsrc) != RTN_LOCAL)
++ if (inet_addr_type(net, fi->fib_prefsrc) != RTN_LOCAL)
+ goto err_inval;
+ }
+
+ link_it:
+- if ((ofi = fib_find_info(fi)) != NULL) {
++ if ((ofi = fib_find_info(net, fi)) != NULL) {
+ fi->fib_dead = 1;
+ free_fib_info(fi);
+ ofi->fib_treeref++;
+@@ -841,11 +831,13 @@
+ atomic_inc(&fi->fib_clntref);
+ spin_lock_bh(&fib_info_lock);
+ hlist_add_head(&fi->fib_hash,
+- &fib_info_hash[fib_info_hashfn(fi)]);
++ &net->fib_info_hash[fib_info_hashfn(net, fi)]);
+ if (fi->fib_prefsrc) {
+ struct hlist_head *head;
++ unsigned int hash;
+
+- head = &fib_info_laddrhash[fib_laddr_hashfn(fi->fib_prefsrc)];
++ hash = fib_laddr_hashfn(net, fi->fib_prefsrc);
++ head = &net->fib_info_laddrhash[hash];
+ hlist_add_head(&fi->fib_lhash, head);
+ }
+ change_nexthops(fi) {
+@@ -855,7 +847,7 @@
+ if (!nh->nh_dev)
+ continue;
+ hash = fib_devindex_hashfn(nh->nh_dev->ifindex);
+- head = &fib_info_devhash[hash];
++ head = &net->fib_info_devhash[hash];
+ hlist_add_head(&nh->nh_hash, head);
+ } endfor_nexthops(fi)
+ spin_unlock_bh(&fib_info_lock);
+@@ -940,10 +932,6 @@
+ res->type = fa->fa_type;
+ res->scope = fa->fa_scope;
+ res->fi = fa->fa_info;
+-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
+- res->netmask = mask;
+- res->network = zone & inet_make_mask(prefixlen);
+-#endif
+ atomic_inc(&res->fi->fib_clntref);
+ return 0;
+ }
+@@ -1046,7 +1034,7 @@
+ - device went down -> we must shutdown all nexthops going via it.
+ */
+
+-int fib_sync_down(__be32 local, struct net_device *dev, int force)
++int fib_sync_down(struct net *net, __be32 local, struct net_device *dev, int force)
+ {
+ int ret = 0;
+ int scope = RT_SCOPE_NOWHERE;
+@@ -1054,9 +1042,9 @@
+ if (force)
+ scope = -1;
+
+- if (local && fib_info_laddrhash) {
+- unsigned int hash = fib_laddr_hashfn(local);
+- struct hlist_head *head = &fib_info_laddrhash[hash];
++ if (local && net->fib_info_laddrhash) {
++ unsigned int hash = fib_laddr_hashfn(net, local);
++ struct hlist_head *head = &net->fib_info_laddrhash[hash];
+ struct hlist_node *node;
+ struct fib_info *fi;
+
+@@ -1071,7 +1059,7 @@
+ if (dev) {
+ struct fib_info *prev_fi = NULL;
+ unsigned int hash = fib_devindex_hashfn(dev->ifindex);
+- struct hlist_head *head = &fib_info_devhash[hash];
++ struct hlist_head *head = &net->fib_info_devhash[hash];
+ struct hlist_node *node;
+ struct fib_nh *nh;
+
+@@ -1124,6 +1112,7 @@
+
+ int fib_sync_up(struct net_device *dev)
+ {
++ struct net *net = dev->nd_net;
+ struct fib_info *prev_fi;
+ unsigned int hash;
+ struct hlist_head *head;
+@@ -1136,7 +1125,7 @@
+
+ prev_fi = NULL;
+ hash = fib_devindex_hashfn(dev->ifindex);
+- head = &fib_info_devhash[hash];
++ head = &net->fib_info_devhash[hash];
+ ret = 0;
+
+ hlist_for_each_entry(nh, node, head, nh_hash) {
+@@ -1226,3 +1215,17 @@
+ spin_unlock_bh(&fib_multipath_lock);
+ }
+ #endif
+
-+int snmp_mib_init(void *ptr[2], size_t mibsize, size_t mibalign)
++int fib_info_init(struct net *net)
+{
-+ BUG_ON(ptr == NULL);
-+ ptr[0] = __alloc_percpu(mibsize);
-+ if (!ptr[0])
-+ goto err0;
-+ ptr[1] = __alloc_percpu(mibsize);
-+ if (!ptr[1])
-+ goto err1;
++ net->fib_info_devhash = kzalloc(
++ sizeof(struct hlist_head)*DEVINDEX_HASHSIZE, GFP_KERNEL);
++ if (!net->fib_info_devhash)
++ return -ENOMEM;
+ return 0;
-+err1:
-+ free_percpu(ptr[0]);
-+ ptr[0] = NULL;
-+err0:
-+ return -ENOMEM;
+}
-+EXPORT_SYMBOL_GPL(snmp_mib_init);
+
-+void snmp_mib_free(void *ptr[2])
++void fib_info_exit(struct net *net)
+{
-+ BUG_ON(ptr == NULL);
-+ free_percpu(ptr[0]);
-+ free_percpu(ptr[1]);
-+ ptr[0] = ptr[1] = NULL;
++ kfree(net->fib_info_devhash);
++}
+diff -Nurb linux-2.6.22-570/net/ipv4/fib_trie.c linux-2.6.22-590/net/ipv4/fib_trie.c
+--- linux-2.6.22-570/net/ipv4/fib_trie.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/fib_trie.c 2008-01-29 22:12:32.000000000 -0500
+@@ -78,6 +78,7 @@
+ #include <net/route.h>
+ #include <net/tcp.h>
+ #include <net/sock.h>
++#include <net/net_namespace.h>
+ #include <net/ip_fib.h>
+ #include "fib_lookup.h"
+
+@@ -172,7 +173,6 @@
+ static void tnode_free(struct tnode *tn);
+
+ static struct kmem_cache *fn_alias_kmem __read_mostly;
+-static struct trie *trie_local = NULL, *trie_main = NULL;
+
+
+ /* rcu_read_lock needs to be hold by caller from readside */
+@@ -290,11 +290,10 @@
+ WARN_ON(tn && tn->pos+tn->bits > 32);
+ }
+
+-static int halve_threshold = 25;
+-static int inflate_threshold = 50;
+-static int halve_threshold_root = 8;
+-static int inflate_threshold_root = 15;
+-
++static const int halve_threshold = 25;
++static const int inflate_threshold = 50;
++static const int halve_threshold_root = 15;
++static const int inflate_threshold_root = 25;
+
+ static void __alias_free_mem(struct rcu_head *head)
+ {
+@@ -1771,11 +1770,10 @@
+ return found;
+ }
+
+-static int trie_last_dflt = -1;
+-
+ static void
+ fn_trie_select_default(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
+ {
++ struct net *net = flp->fl_net;
+ struct trie *t = (struct trie *) tb->tb_data;
+ int order, last_idx;
+ struct fib_info *fi = NULL;
+@@ -1819,28 +1817,28 @@
+ if (next_fi != res->fi)
+ break;
+ } else if (!fib_detect_death(fi, order, &last_resort,
+- &last_idx, &trie_last_dflt)) {
++ &last_idx, &net->trie_last_dflt)) {
+ if (res->fi)
+ fib_info_put(res->fi);
+ res->fi = fi;
+ atomic_inc(&fi->fib_clntref);
+- trie_last_dflt = order;
++ net->trie_last_dflt = order;
+ goto out;
+ }
+ fi = next_fi;
+ order++;
+ }
+ if (order <= 0 || fi == NULL) {
+- trie_last_dflt = -1;
++ net->trie_last_dflt = -1;
+ goto out;
+ }
+
+- if (!fib_detect_death(fi, order, &last_resort, &last_idx, &trie_last_dflt)) {
++ if (!fib_detect_death(fi, order, &last_resort, &last_idx, &net->trie_last_dflt)) {
+ if (res->fi)
+ fib_info_put(res->fi);
+ res->fi = fi;
+ atomic_inc(&fi->fib_clntref);
+- trie_last_dflt = order;
++ net->trie_last_dflt = order;
+ goto out;
+ }
+ if (last_idx >= 0) {
+@@ -1850,7 +1848,7 @@
+ if (last_resort)
+ atomic_inc(&last_resort->fib_clntref);
+ }
+- trie_last_dflt = last_idx;
++ net->trie_last_dflt = last_idx;
+ out:;
+ rcu_read_unlock();
+ }
+@@ -1957,11 +1955,15 @@
+
+ /* Fix more generic FIB names for init later */
+
+-#ifdef CONFIG_IP_MULTIPLE_TABLES
++void fib_hash_exit(struct fib_table *tb)
++{
++ if (!tb)
++ return;
++ fn_trie_flush(tb);
++ kfree(tb);
+}
-+EXPORT_SYMBOL_GPL(snmp_mib_free);
-+
-+#ifdef CONFIG_IP_MULTICAST
-+static struct net_protocol igmp_protocol = {
-+ .handler = igmp_rcv,
-+};
-+#endif
+
-+static struct net_protocol tcp_protocol = {
-+ .handler = tcp_v4_rcv,
-+ .err_handler = tcp_v4_err,
-+ .gso_send_check = tcp_v4_gso_send_check,
-+ .gso_segment = tcp_tso_segment,
-+ .no_policy = 1,
-+};
+ struct fib_table * fib_hash_init(u32 id)
+-#else
+-struct fib_table * __init fib_hash_init(u32 id)
+-#endif
+ {
+ struct fib_table *tb;
+ struct trie *t;
+@@ -1991,11 +1993,6 @@
+ trie_init(t);
+
+ if (id == RT_TABLE_LOCAL)
+- trie_local = t;
+- else if (id == RT_TABLE_MAIN)
+- trie_main = t;
+-
+- if (id == RT_TABLE_LOCAL)
+ printk(KERN_INFO "IPv4 FIB: Using LC-trie version %s\n", VERSION);
+
+ return tb;
+@@ -2004,6 +2001,8 @@
+ #ifdef CONFIG_PROC_FS
+ /* Depth first Trie walk iterator */
+ struct fib_trie_iter {
++ struct net *net;
++ struct trie *trie_local, *trie_main;
+ struct tnode *tnode;
+ struct trie *trie;
+ unsigned index;
+@@ -2170,7 +2169,21 @@
+
+ static int fib_triestat_seq_show(struct seq_file *seq, void *v)
+ {
++ struct net *net = seq->private;
++ struct trie *trie_local, *trie_main;
+ struct trie_stat *stat;
++ struct fib_table *tb;
+
-+static struct net_protocol udp_protocol = {
-+ .handler = udp_rcv,
-+ .err_handler = udp_err,
-+ .no_policy = 1,
-+};
++ trie_local = NULL;
++ tb = fib_get_table(net, RT_TABLE_LOCAL);
++ if (tb)
++ trie_local = (struct trie *) tb->tb_data;
+
-+static struct net_protocol icmp_protocol = {
-+ .handler = icmp_rcv,
-+};
++ trie_main = NULL;
++ tb = fib_get_table(net, RT_TABLE_MAIN);
++ if (tb)
++ trie_main = (struct trie *) tb->tb_data;
+
-+static int __init init_ipv4_mibs(void)
-+{
-+ if (snmp_mib_init((void **)net_statistics,
-+ sizeof(struct linux_mib),
-+ __alignof__(struct linux_mib)) < 0)
-+ goto err_net_mib;
-+ if (snmp_mib_init((void **)ip_statistics,
-+ sizeof(struct ipstats_mib),
-+ __alignof__(struct ipstats_mib)) < 0)
-+ goto err_ip_mib;
-+ if (snmp_mib_init((void **)icmp_statistics,
-+ sizeof(struct icmp_mib),
-+ __alignof__(struct icmp_mib)) < 0)
-+ goto err_icmp_mib;
-+ if (snmp_mib_init((void **)tcp_statistics,
-+ sizeof(struct tcp_mib),
-+ __alignof__(struct tcp_mib)) < 0)
-+ goto err_tcp_mib;
-+ if (snmp_mib_init((void **)udp_statistics,
-+ sizeof(struct udp_mib),
-+ __alignof__(struct udp_mib)) < 0)
-+ goto err_udp_mib;
-+ if (snmp_mib_init((void **)udplite_statistics,
-+ sizeof(struct udp_mib),
-+ __alignof__(struct udp_mib)) < 0)
-+ goto err_udplite_mib;
-+
-+ tcp_mib_init();
+
+ stat = kmalloc(sizeof(*stat), GFP_KERNEL);
+ if (!stat)
+@@ -2197,7 +2210,15 @@
+
+ static int fib_triestat_seq_open(struct inode *inode, struct file *file)
+ {
+- return single_open(file, fib_triestat_seq_show, NULL);
++ return single_open(file, fib_triestat_seq_show,
++ get_net(PROC_NET(inode)));
++}
+
-+ return 0;
++static int fib_triestat_seq_release(struct inode *inode, struct file *file)
++{
++ struct seq_file *seq = file->private_data;
++ put_net(seq->private);
++ return single_release(inode, file);
+ }
+
+ static const struct file_operations fib_triestat_fops = {
+@@ -2205,7 +2226,7 @@
+ .open = fib_triestat_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+- .release = single_release,
++ .release = fib_triestat_seq_release,
+ };
+
+ static struct node *fib_trie_get_idx(struct fib_trie_iter *iter,
+@@ -2214,13 +2235,13 @@
+ loff_t idx = 0;
+ struct node *n;
+
+- for (n = fib_trie_get_first(iter, trie_local);
++ for (n = fib_trie_get_first(iter, iter->trie_local);
+ n; ++idx, n = fib_trie_get_next(iter)) {
+ if (pos == idx)
+ return n;
+ }
+
+- for (n = fib_trie_get_first(iter, trie_main);
++ for (n = fib_trie_get_first(iter, iter->trie_main);
+ n; ++idx, n = fib_trie_get_next(iter)) {
+ if (pos == idx)
+ return n;
+@@ -2230,10 +2251,23 @@
+
+ static void *fib_trie_seq_start(struct seq_file *seq, loff_t *pos)
+ {
++ struct fib_trie_iter *iter = seq->private;
++ struct fib_table *tb;
+
-+err_udplite_mib:
-+ snmp_mib_free((void **)udp_statistics);
-+err_udp_mib:
-+ snmp_mib_free((void **)tcp_statistics);
-+err_tcp_mib:
-+ snmp_mib_free((void **)icmp_statistics);
-+err_icmp_mib:
-+ snmp_mib_free((void **)ip_statistics);
-+err_ip_mib:
-+ snmp_mib_free((void **)net_statistics);
-+err_net_mib:
-+ return -ENOMEM;
++ if (!iter->trie_local) {
++ tb = fib_get_table(iter->net, RT_TABLE_LOCAL);
++ if (tb)
++ iter->trie_local = (struct trie *) tb->tb_data;
++ }
++ if (!iter->trie_main) {
++ tb = fib_get_table(iter->net, RT_TABLE_MAIN);
++ if (tb)
++ iter->trie_main = (struct trie *) tb->tb_data;
++ }
+ rcu_read_lock();
+ if (*pos == 0)
+ return SEQ_START_TOKEN;
+- return fib_trie_get_idx(seq->private, *pos - 1);
++ return fib_trie_get_idx(iter, *pos - 1);
+ }
+
+ static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -2251,8 +2285,8 @@
+ return v;
+
+ /* continue scan in next trie */
+- if (iter->trie == trie_local)
+- return fib_trie_get_first(iter, trie_main);
++ if (iter->trie == iter->trie_local)
++ return fib_trie_get_first(iter, iter->trie_main);
+
+ return NULL;
+ }
+@@ -2318,7 +2352,7 @@
+ return 0;
+
+ if (!NODE_PARENT(n)) {
+- if (iter->trie == trie_local)
++ if (iter->trie == iter->trie_local)
+ seq_puts(seq, "<local>:\n");
+ else
+ seq_puts(seq, "<main>:\n");
+@@ -2384,6 +2418,7 @@
+ seq = file->private_data;
+ seq->private = s;
+ memset(s, 0, sizeof(*s));
++ s->net = get_net(PROC_NET(inode));
+ out:
+ return rc;
+ out_kfree:
+@@ -2391,12 +2426,20 @@
+ goto out;
+ }
+
++static int fib_trie_seq_release(struct inode *inode, struct file *file)
++{
++ struct seq_file *seq = file->private_data;
++ struct fib_trie_iter *iter = seq->private;
++ put_net(iter->net);
++ return seq_release_private(inode, file);
+}
+
-+static int ipv4_proc_init(void);
-+
-+/*
-+ * IP protocol layer initialiser
-+ */
+ static const struct file_operations fib_trie_fops = {
+ .owner = THIS_MODULE,
+ .open = fib_trie_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+- .release = seq_release_private,
++ .release = fib_trie_seq_release,
+ };
+
+ static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi)
+@@ -2434,7 +2477,7 @@
+ return 0;
+ }
+
+- if (iter->trie == trie_local)
++ if (iter->trie == iter->trie_local)
+ return 0;
+ if (IS_TNODE(l))
+ return 0;
+@@ -2505,6 +2548,7 @@
+ seq = file->private_data;
+ seq->private = s;
+ memset(s, 0, sizeof(*s));
++ s->net = get_net(PROC_NET(inode));
+ out:
+ return rc;
+ out_kfree:
+@@ -2517,35 +2561,37 @@
+ .open = fib_route_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+- .release = seq_release_private,
++ .release = fib_trie_seq_release,
+ };
+
+-int __init fib_proc_init(void)
++int fib_proc_init(struct net *net)
+ {
+- if (!proc_net_fops_create("fib_trie", S_IRUGO, &fib_trie_fops))
++ net->trie_last_dflt = -1;
+
-+static struct packet_type ip_packet_type = {
-+ .type = __constant_htons(ETH_P_IP),
-+ .func = ip_rcv,
-+ .gso_send_check = inet_gso_send_check,
-+ .gso_segment = inet_gso_segment,
-+};
++ if (!proc_net_fops_create(net, "fib_trie", S_IRUGO, &fib_trie_fops))
+ goto out1;
+
+- if (!proc_net_fops_create("fib_triestat", S_IRUGO, &fib_triestat_fops))
++ if (!proc_net_fops_create(net, "fib_triestat", S_IRUGO, &fib_triestat_fops))
+ goto out2;
+
+- if (!proc_net_fops_create("route", S_IRUGO, &fib_route_fops))
++ if (!proc_net_fops_create(net, "route", S_IRUGO, &fib_route_fops))
+ goto out3;
+
+ return 0;
+
+ out3:
+- proc_net_remove("fib_triestat");
++ proc_net_remove(net, "fib_triestat");
+ out2:
+- proc_net_remove("fib_trie");
++ proc_net_remove(net, "fib_trie");
+ out1:
+ return -ENOMEM;
+ }
+
+-void __init fib_proc_exit(void)
++void fib_proc_exit(struct net *net)
+ {
+- proc_net_remove("fib_trie");
+- proc_net_remove("fib_triestat");
+- proc_net_remove("route");
++ proc_net_remove(net, "fib_trie");
++ proc_net_remove(net, "fib_triestat");
++ proc_net_remove(net, "route");
+ }
+
+ #endif /* CONFIG_PROC_FS */
+diff -Nurb linux-2.6.22-570/net/ipv4/icmp.c linux-2.6.22-590/net/ipv4/icmp.c
+--- linux-2.6.22-570/net/ipv4/icmp.c 2008-01-29 22:12:24.000000000 -0500
++++ linux-2.6.22-590/net/ipv4/icmp.c 2008-01-29 22:12:32.000000000 -0500
+@@ -229,14 +229,13 @@
+ *
+ * On SMP we have one ICMP socket per-cpu.
+ */
+-static DEFINE_PER_CPU(struct socket *, __icmp_socket) = NULL;
+-#define icmp_socket __get_cpu_var(__icmp_socket)
++#define icmp_socket(NET) (*per_cpu_ptr((NET)->__icmp_socket, smp_processor_id()))
+
+-static __inline__ int icmp_xmit_lock(void)
++static __inline__ int icmp_xmit_lock(struct net *net)
+ {
+ local_bh_disable();
+
+- if (unlikely(!spin_trylock(&icmp_socket->sk->sk_lock.slock))) {
++ if (unlikely(!spin_trylock(&icmp_socket(net)->sk->sk_lock.slock))) {
+ /* This can happen if the output path signals a
+ * dst_link_failure() for an outgoing ICMP packet.
+ */
+@@ -246,9 +245,9 @@
+ return 0;
+ }
+
+-static void icmp_xmit_unlock(void)
++static void icmp_xmit_unlock(struct net *net)
+ {
+- spin_unlock_bh(&icmp_socket->sk->sk_lock.slock);
++ spin_unlock_bh(&icmp_socket(net)->sk->sk_lock.slock);
+ }
+
+ /*
+@@ -347,19 +346,20 @@
+ static void icmp_push_reply(struct icmp_bxm *icmp_param,
+ struct ipcm_cookie *ipc, struct rtable *rt)
+ {
++ struct net *net = icmp_param->skb->dev->nd_net;
+ struct sk_buff *skb;
+
+- if (ip_append_data(icmp_socket->sk, icmp_glue_bits, icmp_param,
++ if (ip_append_data(icmp_socket(net)->sk, icmp_glue_bits, icmp_param,
+ icmp_param->data_len+icmp_param->head_len,
+ icmp_param->head_len,
+ ipc, rt, MSG_DONTWAIT) < 0)
+- ip_flush_pending_frames(icmp_socket->sk);
+- else if ((skb = skb_peek(&icmp_socket->sk->sk_write_queue)) != NULL) {
++ ip_flush_pending_frames(icmp_socket(net)->sk);
++ else if ((skb = skb_peek(&icmp_socket(net)->sk->sk_write_queue)) != NULL) {
+ struct icmphdr *icmph = icmp_hdr(skb);
+ __wsum csum = 0;
+ struct sk_buff *skb1;
+
+- skb_queue_walk(&icmp_socket->sk->sk_write_queue, skb1) {
++ skb_queue_walk(&icmp_socket(net)->sk->sk_write_queue, skb1) {
+ csum = csum_add(csum, skb1->csum);
+ }
+ csum = csum_partial_copy_nocheck((void *)&icmp_param->data,
+@@ -367,7 +367,7 @@
+ icmp_param->head_len, csum);
+ icmph->checksum = csum_fold(csum);
+ skb->ip_summed = CHECKSUM_NONE;
+- ip_push_pending_frames(icmp_socket->sk);
++ ip_push_pending_frames(icmp_socket(net)->sk);
+ }
+ }
+
+@@ -377,7 +377,8 @@
+
+ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
+ {
+- struct sock *sk = icmp_socket->sk;
++ struct net *net = icmp_param->skb->dev->nd_net;
++ struct sock *sk = icmp_socket(net)->sk;
+ struct inet_sock *inet = inet_sk(sk);
+ struct ipcm_cookie ipc;
+ struct rtable *rt = (struct rtable *)skb->dst;
+@@ -386,7 +387,7 @@
+ if (ip_options_echo(&icmp_param->replyopts, skb))
+ return;
+
+- if (icmp_xmit_lock())
++ if (icmp_xmit_lock(net))
+ return;
+
+ icmp_param->data.icmph.checksum = 0;
+@@ -401,7 +402,8 @@
+ daddr = icmp_param->replyopts.faddr;
+ }
+ {
+- struct flowi fl = { .nl_u = { .ip4_u =
++ struct flowi fl = { .fl_net = net,
++ .nl_u = { .ip4_u =
+ { .daddr = daddr,
+ .saddr = rt->rt_spec_dst,
+ .tos = RT_TOS(ip_hdr(skb)->tos) } },
+@@ -415,7 +417,7 @@
+ icmp_push_reply(icmp_param, &ipc, rt);
+ ip_rt_put(rt);
+ out_unlock:
+- icmp_xmit_unlock();
++ icmp_xmit_unlock(net);
+ }
+
+
+@@ -436,6 +438,7 @@
+ int room;
+ struct icmp_bxm icmp_param;
+ struct rtable *rt = (struct rtable *)skb_in->dst;
++ struct net *net;
+ struct ipcm_cookie ipc;
+ __be32 saddr;
+ u8 tos;
+@@ -443,6 +446,7 @@
+ if (!rt)
+ goto out;
+
++ net = rt->fl.fl_net;
+ /*
+ * Find the original header. It is expected to be valid, of course.
+ * Check this, icmp_send is called from the most obscure devices
+@@ -505,7 +509,7 @@
+ }
+ }
+
+- if (icmp_xmit_lock())
++ if (icmp_xmit_lock(net))
+ return;
+
+ /*
+@@ -517,7 +521,7 @@
+ struct net_device *dev = NULL;
+
+ if (rt->fl.iif && sysctl_icmp_errors_use_inbound_ifaddr)
+- dev = dev_get_by_index(rt->fl.iif);
++ dev = dev_get_by_index(&init_net, rt->fl.iif);
+
+ if (dev) {
+ saddr = inet_select_addr(dev, 0, RT_SCOPE_LINK);
+@@ -545,12 +549,13 @@
+ icmp_param.skb = skb_in;
+ icmp_param.offset = skb_network_offset(skb_in);
+ icmp_out_count(icmp_param.data.icmph.type);
+- inet_sk(icmp_socket->sk)->tos = tos;
++ inet_sk(icmp_socket(net)->sk)->tos = tos;
+ ipc.addr = iph->saddr;
+ ipc.opt = &icmp_param.replyopts;
+
+ {
+ struct flowi fl = {
++ .fl_net = net,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = icmp_param.replyopts.srr ?
+@@ -593,7 +598,7 @@
+ ende:
+ ip_rt_put(rt);
+ out_unlock:
+- icmp_xmit_unlock();
++ icmp_xmit_unlock(net);
+ out:;
+ }
+
+@@ -604,6 +609,7 @@
+
+ static void icmp_unreach(struct sk_buff *skb)
+ {
++ struct net *net = skb->dev->nd_net;
+ struct iphdr *iph;
+ struct icmphdr *icmph;
+ int hash, protocol;
+@@ -634,7 +640,7 @@
+ case ICMP_PORT_UNREACH:
+ break;
+ case ICMP_FRAG_NEEDED:
+- if (ipv4_config.no_pmtu_disc) {
++ if (net->sysctl_ipv4_no_pmtu_disc) {
+ LIMIT_NETDEBUG(KERN_INFO "ICMP: %u.%u.%u.%u: "
+ "fragmentation needed "
+ "and DF set.\n",
+@@ -678,7 +684,7 @@
+ */
+
+ if (!sysctl_icmp_ignore_bogus_error_responses &&
+- inet_addr_type(iph->daddr) == RTN_BROADCAST) {
++ inet_addr_type(net, iph->daddr) == RTN_BROADCAST) {
+ if (net_ratelimit())
+ printk(KERN_WARNING "%u.%u.%u.%u sent an invalid ICMP "
+ "type %u, code %u "
+@@ -707,7 +713,7 @@
+ hash = protocol & (MAX_INET_PROTOS - 1);
+ read_lock(&raw_v4_lock);
+ if ((raw_sk = sk_head(&raw_v4_htable[hash])) != NULL) {
+- while ((raw_sk = __raw_v4_lookup(raw_sk, protocol, iph->daddr,
++ while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol, iph->daddr,
+ iph->saddr,
+ skb->dev->ifindex, skb->skb_tag)) != NULL) {
+ raw_err(raw_sk, skb, info);
+@@ -1179,29 +1185,54 @@
+ },
+ };
+
+-void __init icmp_init(struct net_proto_family *ops)
++static void icmp_net_exit(struct net *net)
+ {
+- struct inet_sock *inet;
++ struct socket **sock;
+ int i;
+
+ for_each_possible_cpu(i) {
++ sock = percpu_ptr(net->__icmp_socket, i);
++ if (!*sock)
++ continue;
++ /* At the last minute lie and say this is a socket for
++ * the initial network namespace. So the socket will
++ * be safe to free.
++ */
++ (*sock)->sk->sk_net = get_net(&init_net);
++ sock_release(*sock);
++ *sock = NULL;
++ }
++ percpu_free(net->__icmp_socket);
++}
+
-+static int __init inet_init(void)
++static int icmp_net_init(struct net *net)
+{
-+ struct sk_buff *dummy_skb;
-+ struct inet_protosw *q;
-+ struct list_head *r;
-+ int rc = -EINVAL;
++ struct socket **sock;
++ struct inet_sock *inet;
+ int err;
++ int i;
+
-+ BUILD_BUG_ON(sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb));
++ net->__icmp_socket = alloc_percpu(struct socket *);
++ if (!net->__icmp_socket)
++ return -ENOMEM;
++
++ for_each_possible_cpu(i) {
+
+- err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP,
+- &per_cpu(__icmp_socket, i));
++ sock = percpu_ptr(net->__icmp_socket, i);
+
++ err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP, sock);
+ if (err < 0)
+- panic("Failed to create the ICMP control socket.\n");
++ goto fail;
+
+- per_cpu(__icmp_socket, i)->sk->sk_allocation = GFP_ATOMIC;
++ (*sock)->sk->sk_allocation = GFP_ATOMIC;
+
+ /* Enough space for 2 64K ICMP packets, including
+ * sk_buff struct overhead.
+ */
+- per_cpu(__icmp_socket, i)->sk->sk_sndbuf =
++ (*sock)->sk->sk_sndbuf =
+ (2 * ((64 * 1024) + sizeof(struct sk_buff)));
+
+- inet = inet_sk(per_cpu(__icmp_socket, i)->sk);
++ inet = inet_sk((*sock)->sk);
+ inet->uc_ttl = -1;
+ inet->pmtudisc = IP_PMTUDISC_DONT;
+
+@@ -1209,8 +1240,27 @@
+ * see it, we do not wish this socket to see incoming
+ * packets.
+ */
+- per_cpu(__icmp_socket, i)->sk->sk_prot->unhash(per_cpu(__icmp_socket, i)->sk);
++ (*sock)->sk->sk_prot->unhash((*sock)->sk);
+
-+ rc = proto_register(&tcp_prot, 1);
-+ if (rc)
-+ goto out;
++ /* Don't hold an extra reference on the namespace */
++ put_net((*sock)->sk->sk_net);
+ }
++ return 0;
++fail:
++ icmp_net_exit(net);
++ return err;
+
-+ rc = proto_register(&udp_prot, 1);
-+ if (rc)
-+ goto out_unregister_tcp_proto;
++}
+
-+ rc = proto_register(&raw_prot, 1);
-+ if (rc)
-+ goto out_unregister_udp_proto;
++static struct pernet_operations icmp_net_ops = {
++ .init = icmp_net_init,
++ .exit = icmp_net_exit,
++};
+
-+ /*
-+ * Tell SOCKET that we are alive...
-+ */
++void __init icmp_init(struct net_proto_family *ops)
++{
++ if (register_pernet_subsys(&icmp_net_ops))
++ panic("Failed to create the ICMP control socket.\n");
+ }
+
+ EXPORT_SYMBOL(icmp_err_convert);
+diff -Nurb linux-2.6.22-570/net/ipv4/igmp.c linux-2.6.22-590/net/ipv4/igmp.c
+--- linux-2.6.22-570/net/ipv4/igmp.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/igmp.c 2008-01-29 22:12:32.000000000 -0500
+@@ -97,6 +97,7 @@
+ #include <net/route.h>
+ #include <net/sock.h>
+ #include <net/checksum.h>
++#include <net/net_namespace.h>
+ #include <linux/netfilter_ipv4.h>
+ #ifdef CONFIG_IP_MROUTE
+ #include <linux/mroute.h>
+@@ -129,12 +130,12 @@
+ */
+
+ #define IGMP_V1_SEEN(in_dev) \
+- (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 1 || \
++ (IPV4_DEVCONF_ALL((in_dev)->dev->nd_net, FORCE_IGMP_VERSION) == 1 || \
+ IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 1 || \
+ ((in_dev)->mr_v1_seen && \
+ time_before(jiffies, (in_dev)->mr_v1_seen)))
+ #define IGMP_V2_SEEN(in_dev) \
+- (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 2 || \
++ (IPV4_DEVCONF_ALL((in_dev)->dev->nd_net, FORCE_IGMP_VERSION) == 2 || \
+ IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 2 || \
+ ((in_dev)->mr_v2_seen && \
+ time_before(jiffies, (in_dev)->mr_v2_seen)))
+@@ -296,7 +297,8 @@
+ return NULL;
+
+ {
+- struct flowi fl = { .oif = dev->ifindex,
++ struct flowi fl = { .fl_net = &init_net,
++ .oif = dev->ifindex,
+ .nl_u = { .ip4_u = {
+ .daddr = IGMPV3_ALL_MCR } },
+ .proto = IPPROTO_IGMP };
+@@ -646,7 +648,8 @@
+ dst = group;
+
+ {
+- struct flowi fl = { .oif = dev->ifindex,
++ struct flowi fl = { .fl_net = &init_net,
++ .oif = dev->ifindex,
+ .nl_u = { .ip4_u = { .daddr = dst } },
+ .proto = IPPROTO_IGMP };
+ if (ip_route_output_key(&rt, &fl))
+@@ -929,6 +932,11 @@
+ struct in_device *in_dev = in_dev_get(skb->dev);
+ int len = skb->len;
+
++ if (skb->dev->nd_net != &init_net) {
++ kfree_skb(skb);
++ return 0;
++ }
+
-+ (void)sock_register(&inet_family_ops);
+ if (in_dev==NULL) {
+ kfree_skb(skb);
+ return 0;
+@@ -1393,20 +1401,22 @@
+
+ static struct in_device * ip_mc_find_dev(struct ip_mreqn *imr)
+ {
+- struct flowi fl = { .nl_u = { .ip4_u =
+- { .daddr = imr->imr_multiaddr.s_addr } } };
++ struct flowi fl = {
++ .fl_net = &init_net,
++ .nl_u = { .ip4_u = { .daddr = imr->imr_multiaddr.s_addr } }
++ };
+ struct rtable *rt;
+ struct net_device *dev = NULL;
+ struct in_device *idev = NULL;
+
+ if (imr->imr_ifindex) {
+- idev = inetdev_by_index(imr->imr_ifindex);
++ idev = inetdev_by_index(&init_net, imr->imr_ifindex);
+ if (idev)
+ __in_dev_put(idev);
+ return idev;
+ }
+ if (imr->imr_address.s_addr) {
+- dev = ip_dev_find(imr->imr_address.s_addr);
++ dev = ip_dev_find(&init_net, imr->imr_address.s_addr);
+ if (!dev)
+ return NULL;
+ dev_put(dev);
+@@ -2234,7 +2244,7 @@
+ struct in_device *in_dev;
+ inet->mc_list = iml->next;
+
+- in_dev = inetdev_by_index(iml->multi.imr_ifindex);
++ in_dev = inetdev_by_index(&init_net, iml->multi.imr_ifindex);
+ (void) ip_mc_leave_src(sk, iml, in_dev);
+ if (in_dev != NULL) {
+ ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr);
+@@ -2291,7 +2301,7 @@
+ struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq);
+
+ state->in_dev = NULL;
+- for_each_netdev(state->dev) {
++ for_each_netdev(&init_net, state->dev) {
+ struct in_device *in_dev;
+ in_dev = in_dev_get(state->dev);
+ if (!in_dev)
+@@ -2453,7 +2463,7 @@
+
+ state->idev = NULL;
+ state->im = NULL;
+- for_each_netdev(state->dev) {
++ for_each_netdev(&init_net, state->dev) {
+ struct in_device *idev;
+ idev = in_dev_get(state->dev);
+ if (unlikely(idev == NULL))
+@@ -2613,8 +2623,8 @@
+
+ int __init igmp_mc_proc_init(void)
+ {
+- proc_net_fops_create("igmp", S_IRUGO, &igmp_mc_seq_fops);
+- proc_net_fops_create("mcfilter", S_IRUGO, &igmp_mcf_seq_fops);
++ proc_net_fops_create(&init_net, "igmp", S_IRUGO, &igmp_mc_seq_fops);
++ proc_net_fops_create(&init_net, "mcfilter", S_IRUGO, &igmp_mcf_seq_fops);
+ return 0;
+ }
+ #endif
+diff -Nurb linux-2.6.22-570/net/ipv4/inet_connection_sock.c linux-2.6.22-590/net/ipv4/inet_connection_sock.c
+--- linux-2.6.22-570/net/ipv4/inet_connection_sock.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/ipv4/inet_connection_sock.c 2008-01-29 22:12:32.000000000 -0500
+@@ -32,7 +32,7 @@
+ /*
+ * This array holds the first and last local port number.
+ */
+-int sysctl_local_port_range[2] = { 32768, 61000 };
++//int sysctl_local_port_range[2] = { 32768, 61000 };
+
+ int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
+ {
+@@ -74,6 +74,7 @@
+
+ sk_for_each_bound(sk2, node, &tb->owners) {
+ if (sk != sk2 &&
++ (sk->sk_net == sk2->sk_net) &&
+ !inet_v6_ipv6only(sk2) &&
+ (!sk->sk_bound_dev_if ||
+ !sk2->sk_bound_dev_if ||
+@@ -98,6 +99,7 @@
+ int (*bind_conflict)(const struct sock *sk,
+ const struct inet_bind_bucket *tb))
+ {
++ struct net *net = sk->sk_net;
+ struct inet_bind_hashbucket *head;
+ struct hlist_node *node;
+ struct inet_bind_bucket *tb;
+@@ -105,16 +107,16 @@
+
+ local_bh_disable();
+ if (!snum) {
+- int low = sysctl_local_port_range[0];
+- int high = sysctl_local_port_range[1];
++ int low = sk->sk_net->sysctl_local_port_range[0];
++ int high = sk->sk_net->sysctl_local_port_range[1];
+ int remaining = (high - low) + 1;
+ int rover = net_random() % (high - low) + low;
+
+ do {
+- head = &hashinfo->bhash[inet_bhashfn(rover, hashinfo->bhash_size)];
++ head = &hashinfo->bhash[inet_bhashfn(net, rover, hashinfo->bhash_size)];
+ spin_lock(&head->lock);
+ inet_bind_bucket_for_each(tb, node, &head->chain)
+- if (tb->port == rover)
++ if ((tb->port == rover) && (tb->net == net))
+ goto next;
+ break;
+ next:
+@@ -138,10 +140,10 @@
+ */
+ snum = rover;
+ } else {
+- head = &hashinfo->bhash[inet_bhashfn(snum, hashinfo->bhash_size)];
++ head = &hashinfo->bhash[inet_bhashfn(net, snum, hashinfo->bhash_size)];
+ spin_lock(&head->lock);
+ inet_bind_bucket_for_each(tb, node, &head->chain)
+- if (tb->port == snum)
++ if ((tb->port == snum) && (tb->net==net))
+ goto tb_found;
+ }
+ tb = NULL;
+@@ -161,7 +163,7 @@
+ }
+ tb_not_found:
+ ret = 1;
+- if (!tb && (tb = inet_bind_bucket_create(hashinfo->bind_bucket_cachep, head, snum)) == NULL)
++ if (!tb && (tb = inet_bind_bucket_create(hashinfo->bind_bucket_cachep, head, net, snum)) == NULL)
+ goto fail_unlock;
+ if (hlist_empty(&tb->owners)) {
+ if (sk->sk_reuse && sk->sk_state != TCP_LISTEN)
+@@ -341,7 +343,8 @@
+ struct rtable *rt;
+ const struct inet_request_sock *ireq = inet_rsk(req);
+ struct ip_options *opt = inet_rsk(req)->opt;
+- struct flowi fl = { .oif = sk->sk_bound_dev_if,
++ struct flowi fl = { .fl_net = sk->sk_net,
++ .oif = sk->sk_bound_dev_if,
+ .nl_u = { .ip4_u =
+ { .daddr = ((opt && opt->srr) ?
+ opt->faddr :
+diff -Nurb linux-2.6.22-570/net/ipv4/inet_diag.c linux-2.6.22-590/net/ipv4/inet_diag.c
+--- linux-2.6.22-570/net/ipv4/inet_diag.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/ipv4/inet_diag.c 2008-01-29 22:12:32.000000000 -0500
+@@ -227,6 +227,7 @@
+ static int inet_diag_get_exact(struct sk_buff *in_skb,
+ const struct nlmsghdr *nlh)
+ {
++ struct net *net = in_skb->sk->sk_net;
+ int err;
+ struct sock *sk;
+ struct inet_diag_req *req = NLMSG_DATA(nlh);
+@@ -242,7 +243,7 @@
+ /* TODO: lback */
+ sk = inet_lookup(hashinfo, req->id.idiag_dst[0],
+ req->id.idiag_dport, req->id.idiag_src[0],
+- req->id.idiag_sport, req->id.idiag_if);
++ req->id.idiag_sport, req->id.idiag_if, net);
+ }
+ #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+ else if (req->idiag_family == AF_INET6) {
+@@ -251,7 +252,7 @@
+ req->id.idiag_dport,
+ (struct in6_addr *)req->id.idiag_src,
+ req->id.idiag_sport,
+- req->id.idiag_if);
++ req->id.idiag_if, net);
+ }
+ #endif
+ else {
+@@ -906,8 +907,8 @@
+ if (!inet_diag_table)
+ goto out;
+
+- idiagnl = netlink_kernel_create(NETLINK_INET_DIAG, 0, inet_diag_rcv,
+- NULL, THIS_MODULE);
++ idiagnl = netlink_kernel_create(&init_net, NETLINK_INET_DIAG, 0,
++ inet_diag_rcv, NULL, THIS_MODULE);
+ if (idiagnl == NULL)
+ goto out_free_table;
+ err = 0;
+diff -Nurb linux-2.6.22-570/net/ipv4/inet_hashtables.c linux-2.6.22-590/net/ipv4/inet_hashtables.c
+--- linux-2.6.22-570/net/ipv4/inet_hashtables.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/ipv4/inet_hashtables.c 2008-01-29 22:12:32.000000000 -0500
+@@ -29,11 +29,13 @@
+ */
+ struct inet_bind_bucket *inet_bind_bucket_create(struct kmem_cache *cachep,
+ struct inet_bind_hashbucket *head,
++ struct net *net,
+ const unsigned short snum)
+ {
+ struct inet_bind_bucket *tb = kmem_cache_alloc(cachep, GFP_ATOMIC);
+
+ if (tb != NULL) {
++ tb->net = net;
+ tb->port = snum;
+ tb->fastreuse = 0;
+ INIT_HLIST_HEAD(&tb->owners);
+@@ -66,7 +68,7 @@
+ */
+ static void __inet_put_port(struct inet_hashinfo *hashinfo, struct sock *sk)
+ {
+- const int bhash = inet_bhashfn(inet_sk(sk)->num, hashinfo->bhash_size);
++ const int bhash = inet_bhashfn(sk->sk_net, inet_sk(sk)->num, hashinfo->bhash_size);
+ struct inet_bind_hashbucket *head = &hashinfo->bhash[bhash];
+ struct inet_bind_bucket *tb;
+
+@@ -127,7 +129,7 @@
+ static struct sock *inet_lookup_listener_slow(const struct hlist_head *head,
+ const __be32 daddr,
+ const unsigned short hnum,
+- const int dif)
++ const int dif, struct net *net)
+ {
+ struct sock *result = NULL, *sk;
+ const struct hlist_node *node;
+@@ -149,6 +151,8 @@
+ continue;
+ score += 2;
+ }
++ if (sk->sk_net != net)
++ continue;
+ if (score == 5)
+ return sk;
+ if (score > hiscore) {
+@@ -163,22 +167,22 @@
+ /* Optimize the common listener case. */
+ struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
+ const __be32 daddr, const unsigned short hnum,
+- const int dif)
++ const int dif, struct net *net)
+ {
+ struct sock *sk = NULL;
+ const struct hlist_head *head;
+
+ read_lock(&hashinfo->lhash_lock);
+- head = &hashinfo->listening_hash[inet_lhashfn(hnum)];
++ head = &hashinfo->listening_hash[net, inet_lhashfn(net, hnum)];
+ if (!hlist_empty(head)) {
+ const struct inet_sock *inet = inet_sk((sk = __sk_head(head)));
+
+ if (inet->num == hnum && !sk->sk_node.next &&
+ v4_inet_addr_match(sk->sk_nx_info, daddr, inet->rcv_saddr) &&
+ (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) &&
+- !sk->sk_bound_dev_if)
++ !sk->sk_bound_dev_if && (sk->sk_net == net))
+ goto sherry_cache;
+- sk = inet_lookup_listener_slow(head, daddr, hnum, dif);
++ sk = inet_lookup_listener_slow(head, daddr, hnum, dif,net );
+ }
+ if (sk) {
+ sherry_cache:
+@@ -196,12 +200,13 @@
+ {
+ struct inet_hashinfo *hinfo = death_row->hashinfo;
+ struct inet_sock *inet = inet_sk(sk);
++ struct net *net = sk->sk_net;
+ __be32 daddr = inet->rcv_saddr;
+ __be32 saddr = inet->daddr;
+ int dif = sk->sk_bound_dev_if;
+ INET_ADDR_COOKIE(acookie, saddr, daddr)
+ const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport);
+- unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport);
++ unsigned int hash = inet_ehashfn(net, daddr, lport, saddr, inet->dport);
+ struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
+ struct sock *sk2;
+ const struct hlist_node *node;
+@@ -214,7 +219,7 @@
+ sk_for_each(sk2, node, &head->twchain) {
+ tw = inet_twsk(sk2);
+
+- if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) {
++ if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif, net)) {
+ if (twsk_unique(sk, sk2, twp))
+ goto unique;
+ else
+@@ -225,7 +230,7 @@
+
+ /* And established part... */
+ sk_for_each(sk2, node, &head->chain) {
+- if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
++ if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif, net))
+ goto not_unique;
+ }
+
+@@ -271,6 +276,7 @@
+ int inet_hash_connect(struct inet_timewait_death_row *death_row,
+ struct sock *sk)
+ {
++ struct net *net = sk->sk_net;
+ struct inet_hashinfo *hinfo = death_row->hashinfo;
+ const unsigned short snum = inet_sk(sk)->num;
+ struct inet_bind_hashbucket *head;
+@@ -278,8 +284,8 @@
+ int ret;
+
+ if (!snum) {
+- int low = sysctl_local_port_range[0];
+- int high = sysctl_local_port_range[1];
++ int low = sk->sk_net->sysctl_local_port_range[0];
++ int high = sk->sk_net->sysctl_local_port_range[1];
+ int range = high - low;
+ int i;
+ int port;
+@@ -291,7 +297,7 @@
+ local_bh_disable();
+ for (i = 1; i <= range; i++) {
+ port = low + (i + offset) % range;
+- head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)];
++ head = &hinfo->bhash[inet_bhashfn(net, port, hinfo->bhash_size)];
+ spin_lock(&head->lock);
+
+ /* Does not bother with rcv_saddr checks,
+@@ -299,7 +305,7 @@
+ * unique enough.
+ */
+ inet_bind_bucket_for_each(tb, node, &head->chain) {
+- if (tb->port == port) {
++ if ((tb->port == port) && (tb->net == net)) {
+ BUG_TRAP(!hlist_empty(&tb->owners));
+ if (tb->fastreuse >= 0)
+ goto next_port;
+@@ -311,7 +317,7 @@
+ }
+ }
+
+- tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep, head, port);
++ tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep, head, net, port);
+ if (!tb) {
+ spin_unlock(&head->lock);
+ break;
+@@ -346,7 +352,7 @@
+ goto out;
+ }
+
+- head = &hinfo->bhash[inet_bhashfn(snum, hinfo->bhash_size)];
++ head = &hinfo->bhash[inet_bhashfn(net, snum, hinfo->bhash_size)];
+ tb = inet_csk(sk)->icsk_bind_hash;
+ spin_lock_bh(&head->lock);
+ if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
+diff -Nurb linux-2.6.22-570/net/ipv4/inet_timewait_sock.c linux-2.6.22-590/net/ipv4/inet_timewait_sock.c
+--- linux-2.6.22-570/net/ipv4/inet_timewait_sock.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/inet_timewait_sock.c 2008-01-29 22:12:32.000000000 -0500
+@@ -31,7 +31,7 @@
+ write_unlock(&ehead->lock);
+
+ /* Disassociate with bind bucket. */
+- bhead = &hashinfo->bhash[inet_bhashfn(tw->tw_num, hashinfo->bhash_size)];
++ bhead = &hashinfo->bhash[inet_bhashfn(tw->tw_net, tw->tw_num, hashinfo->bhash_size)];
+ spin_lock(&bhead->lock);
+ tb = tw->tw_tb;
+ __hlist_del(&tw->tw_bind_node);
+@@ -65,7 +65,7 @@
+ Note, that any socket with inet->num != 0 MUST be bound in
+ binding cache, even if it is closed.
+ */
+- bhead = &hashinfo->bhash[inet_bhashfn(inet->num, hashinfo->bhash_size)];
++ bhead = &hashinfo->bhash[inet_bhashfn(sk->sk_net, inet->num, hashinfo->bhash_size)];
+ spin_lock(&bhead->lock);
+ tw->tw_tb = icsk->icsk_bind_hash;
+ BUG_TRAP(icsk->icsk_bind_hash);
+diff -Nurb linux-2.6.22-570/net/ipv4/inetpeer.c linux-2.6.22-590/net/ipv4/inetpeer.c
+--- linux-2.6.22-570/net/ipv4/inetpeer.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/inetpeer.c 2008-01-29 22:12:32.000000000 -0500
+@@ -81,71 +81,94 @@
+ .avl_height = 0
+ };
+ #define peer_avl_empty (&peer_fake_node)
+-static struct inet_peer *peer_root = peer_avl_empty;
+ static DEFINE_RWLOCK(peer_pool_lock);
+ #define PEER_MAXDEPTH 40 /* sufficient for about 2^27 nodes */
+
+-static int peer_total;
+-/* Exported for sysctl_net_ipv4. */
+-int inet_peer_threshold __read_mostly = 65536 + 128; /* start to throw entries more
+- * aggressively at this stage */
+-int inet_peer_minttl __read_mostly = 120 * HZ; /* TTL under high load: 120 sec */
+-int inet_peer_maxttl __read_mostly = 10 * 60 * HZ; /* usual time to live: 10 min */
+-int inet_peer_gc_mintime __read_mostly = 10 * HZ;
+-int inet_peer_gc_maxtime __read_mostly = 120 * HZ;
+-
+-static struct inet_peer *inet_peer_unused_head;
+-static struct inet_peer **inet_peer_unused_tailp = &inet_peer_unused_head;
+ static DEFINE_SPINLOCK(inet_peer_unused_lock);
+
+ static void peer_check_expire(unsigned long dummy);
+-static DEFINE_TIMER(peer_periodic_timer, peer_check_expire, 0, 0);
+
++static int inet_peers_net_init(struct net *net);
++static void inet_peers_net_exit(struct net *net);
++static struct pernet_operations inet_peers_net_ops = {
++ .init = inet_peers_net_init,
++ .exit = inet_peers_net_exit,
++};
+
+ /* Called from ip_output.c:ip_init */
+ void __init inet_initpeers(void)
+ {
++ peer_cachep = kmem_cache_create("inet_peer_cache",
++ sizeof(struct inet_peer),
++ 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
++ NULL, NULL);
+
-+ /*
-+ * Add all the base protocols.
-+ */
++ register_pernet_subsys(&inet_peers_net_ops);
++}
+
-+ if (inet_add_protocol(&icmp_protocol, IPPROTO_ICMP) < 0)
-+ printk(KERN_CRIT "inet_init: Cannot add ICMP protocol\n");
-+ if (inet_add_protocol(&udp_protocol, IPPROTO_UDP) < 0)
-+ printk(KERN_CRIT "inet_init: Cannot add UDP protocol\n");
-+ if (inet_add_protocol(&tcp_protocol, IPPROTO_TCP) < 0)
-+ printk(KERN_CRIT "inet_init: Cannot add TCP protocol\n");
-+#ifdef CONFIG_IP_MULTICAST
-+ if (inet_add_protocol(&igmp_protocol, IPPROTO_IGMP) < 0)
-+ printk(KERN_CRIT "inet_init: Cannot add IGMP protocol\n");
-+#endif
++static int inet_peers_net_init(struct net *net)
++{
+ struct sysinfo si;
+
++ net->peer_root = peer_avl_empty;
++ net->inet_peer_unused_tailp = &net->inet_peer_unused_head;
+
-+ /* Register the socket-side information for inet_create. */
-+ for (r = &inetsw[0]; r < &inetsw[SOCK_MAX]; ++r)
-+ INIT_LIST_HEAD(r);
++ net->inet_peer_threshold = 65536 + 128; /* start to throw entries more
++ * aggressively at this stage */
++ net->inet_peer_minttl = 120 * HZ; /* TTL under high load: 120 sec */
++ net->inet_peer_maxttl = 10 * 60 * HZ; /* usual time to live: 10 min */
++ net->inet_peer_gc_mintime = 10 * HZ;
++ net->inet_peer_gc_maxtime = 120 * HZ;
+
-+ for (q = inetsw_array; q < &inetsw_array[INETSW_ARRAY_LEN]; ++q)
-+ inet_register_protosw(q);
+ /* Use the straight interface to information about memory. */
+ si_meminfo(&si);
+
-+ /*
-+ * Set the ARP module up
-+ */
+ /* The values below were suggested by Alexey Kuznetsov
+ * <kuznet@ms2.inr.ac.ru>. I don't have any opinion about the values
+ * myself. --SAW
+ */
+ if (si.totalram <= (32768*1024)/PAGE_SIZE)
+- inet_peer_threshold >>= 1; /* max pool size about 1MB on IA32 */
++ net->inet_peer_threshold >>= 1; /* max pool size about 1MB on IA32 */
+ if (si.totalram <= (16384*1024)/PAGE_SIZE)
+- inet_peer_threshold >>= 1; /* about 512KB */
++ net->inet_peer_threshold >>= 1; /* about 512KB */
+ if (si.totalram <= (8192*1024)/PAGE_SIZE)
+- inet_peer_threshold >>= 2; /* about 128KB */
++ net->inet_peer_threshold >>= 2; /* about 128KB */
+
+- peer_cachep = kmem_cache_create("inet_peer_cache",
+- sizeof(struct inet_peer),
+- 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
+- NULL, NULL);
+
++ init_timer(&net->peer_periodic_timer);
++ net->peer_periodic_timer.function = peer_check_expire;
+ /* All the timers, started at system startup tend
+ to synchronize. Perturb it a bit.
+ */
+- peer_periodic_timer.expires = jiffies
+- + net_random() % inet_peer_gc_maxtime
+- + inet_peer_gc_maxtime;
+- add_timer(&peer_periodic_timer);
++ net->peer_periodic_timer.expires = jiffies
++ + net_random() % net->inet_peer_gc_maxtime
++ + net->inet_peer_gc_maxtime;
++ /* Remember our namespace */
++ net->peer_periodic_timer.data = (unsigned long)net;
++ add_timer(&net->peer_periodic_timer);
++
++ return 0;
++}
+
-+ arp_init();
++static void inet_peers_net_exit(struct net *net)
++{
++ del_timer(&net->peer_periodic_timer);
++ /* CHECKME do I need to do something to release all of the peers */
+ }
+
+ /* Called with or without local BH being disabled. */
+-static void unlink_from_unused(struct inet_peer *p)
++static void unlink_from_unused(struct net *net, struct inet_peer *p)
+ {
+ spin_lock_bh(&inet_peer_unused_lock);
+ if (p->unused_prevp != NULL) {
+ /* On unused list. */
+- *p->unused_prevp = p->unused_next;
+- if (p->unused_next != NULL)
+- p->unused_next->unused_prevp = p->unused_prevp;
++ *p->unused_prevp = p->u.unused_next;
++ if (p->u.unused_next != NULL)
++ p->u.unused_next->unused_prevp = p->unused_prevp;
+ else
+- inet_peer_unused_tailp = p->unused_prevp;
++ net->inet_peer_unused_tailp = p->unused_prevp;
+ p->unused_prevp = NULL; /* mark it as removed */
++ p->u.net = hold_net(net); /* Remember the net */
+ }
+ spin_unlock_bh(&inet_peer_unused_lock);
+ }
+@@ -160,9 +183,9 @@
+ struct inet_peer *u, **v; \
+ if (_stack) { \
+ stackptr = _stack; \
+- *stackptr++ = &peer_root; \
++ *stackptr++ = &net->peer_root; \
+ } \
+- for (u = peer_root; u != peer_avl_empty; ) { \
++ for (u = net->peer_root; u != peer_avl_empty; ) { \
+ if (_daddr == u->v4daddr) \
+ break; \
+ if ((__force __u32)_daddr < (__force __u32)u->v4daddr) \
+@@ -279,7 +302,7 @@
+ } while(0)
+
+ /* May be called with local BH enabled. */
+-static void unlink_from_pool(struct inet_peer *p)
++static void unlink_from_pool(struct net *net, struct inet_peer *p)
+ {
+ int do_free;
+
+@@ -317,7 +340,7 @@
+ delp[1] = &t->avl_left; /* was &p->avl_left */
+ }
+ peer_avl_rebalance(stack, stackptr);
+- peer_total--;
++ net->peer_total--;
+ do_free = 1;
+ }
+ write_unlock_bh(&peer_pool_lock);
+@@ -335,13 +358,13 @@
+ }
+
+ /* May be called with local BH enabled. */
+-static int cleanup_once(unsigned long ttl)
++static int cleanup_once(struct net *net, unsigned long ttl)
+ {
+ struct inet_peer *p;
+
+ /* Remove the first entry from the list of unused nodes. */
+ spin_lock_bh(&inet_peer_unused_lock);
+- p = inet_peer_unused_head;
++ p = net->inet_peer_unused_head;
+ if (p != NULL) {
+ __u32 delta = (__u32)jiffies - p->dtime;
+ if (delta < ttl) {
+@@ -349,12 +372,13 @@
+ spin_unlock_bh(&inet_peer_unused_lock);
+ return -1;
+ }
+- inet_peer_unused_head = p->unused_next;
+- if (p->unused_next != NULL)
+- p->unused_next->unused_prevp = p->unused_prevp;
++ net->inet_peer_unused_head = p->u.unused_next;
++ if (p->u.unused_next != NULL)
++ p->u.unused_next->unused_prevp = p->unused_prevp;
+ else
+- inet_peer_unused_tailp = p->unused_prevp;
++ net->inet_peer_unused_tailp = p->unused_prevp;
+ p->unused_prevp = NULL; /* mark as not on the list */
++ p->u.net = hold_net(net);
+ /* Grab an extra reference to prevent node disappearing
+ * before unlink_from_pool() call. */
+ atomic_inc(&p->refcnt);
+@@ -367,12 +391,12 @@
+ * happen because of entry limits in route cache. */
+ return -1;
+
+- unlink_from_pool(p);
++ unlink_from_pool(net, p);
+ return 0;
+ }
+
+ /* Called with or without local BH being disabled. */
+-struct inet_peer *inet_getpeer(__be32 daddr, int create)
++struct inet_peer *inet_getpeer(struct net *net, __be32 daddr, int create)
+ {
+ struct inet_peer *p, *n;
+ struct inet_peer **stack[PEER_MAXDEPTH], ***stackptr;
+@@ -387,7 +411,7 @@
+ if (p != peer_avl_empty) {
+ /* The existing node has been found. */
+ /* Remove the entry from unused list if it was there. */
+- unlink_from_unused(p);
++ unlink_from_unused(net, p);
+ return p;
+ }
+
+@@ -413,13 +437,13 @@
+ /* Link the node. */
+ link_to_pool(n);
+ n->unused_prevp = NULL; /* not on the list */
+- peer_total++;
++ n->u.net = hold_net(net); /* Remember the net */
++ net->peer_total++;
+ write_unlock_bh(&peer_pool_lock);
+
+- if (peer_total >= inet_peer_threshold)
++ if (net->peer_total >= net->inet_peer_threshold)
+ /* Remove one less-recently-used entry. */
+- cleanup_once(0);
+-
++ cleanup_once(net, 0);
+ return n;
+
+ out_free:
+@@ -427,25 +451,26 @@
+ atomic_inc(&p->refcnt);
+ write_unlock_bh(&peer_pool_lock);
+ /* Remove the entry from unused list if it was there. */
+- unlink_from_unused(p);
++ unlink_from_unused(net, p);
+ /* Free preallocated the preallocated node. */
+ kmem_cache_free(peer_cachep, n);
+ return p;
+ }
+
+ /* Called with local BH disabled. */
+-static void peer_check_expire(unsigned long dummy)
++static void peer_check_expire(unsigned long arg)
+ {
++ struct net *net = (void *)arg;
+ unsigned long now = jiffies;
+ int ttl;
+
+- if (peer_total >= inet_peer_threshold)
+- ttl = inet_peer_minttl;
++ if (net->peer_total >= net->inet_peer_threshold)
++ ttl = net->inet_peer_minttl;
+ else
+- ttl = inet_peer_maxttl
+- - (inet_peer_maxttl - inet_peer_minttl) / HZ *
+- peer_total / inet_peer_threshold * HZ;
+- while (!cleanup_once(ttl)) {
++ ttl = net->inet_peer_maxttl
++ - (net->inet_peer_maxttl - net->inet_peer_minttl) / HZ *
++ net->peer_total / net->inet_peer_threshold * HZ;
++ while (!cleanup_once(net, ttl)) {
+ if (jiffies != now)
+ break;
+ }
+@@ -453,25 +478,30 @@
+ /* Trigger the timer after inet_peer_gc_mintime .. inet_peer_gc_maxtime
+ * interval depending on the total number of entries (more entries,
+ * less interval). */
+- if (peer_total >= inet_peer_threshold)
+- peer_periodic_timer.expires = jiffies + inet_peer_gc_mintime;
++ if (net->peer_total >= net->inet_peer_threshold)
++ net->peer_periodic_timer.expires = jiffies
++ + net->inet_peer_gc_mintime;
+ else
+- peer_periodic_timer.expires = jiffies
+- + inet_peer_gc_maxtime
+- - (inet_peer_gc_maxtime - inet_peer_gc_mintime) / HZ *
+- peer_total / inet_peer_threshold * HZ;
+- add_timer(&peer_periodic_timer);
++ net->peer_periodic_timer.expires = jiffies
++ + net->inet_peer_gc_maxtime
++ - (net->inet_peer_gc_maxtime - net->inet_peer_gc_mintime) / HZ *
++ net->peer_total / net->inet_peer_threshold * HZ;
++ add_timer(&net->peer_periodic_timer);
+ }
+
+ void inet_putpeer(struct inet_peer *p)
+ {
+ spin_lock_bh(&inet_peer_unused_lock);
+ if (atomic_dec_and_test(&p->refcnt)) {
+- p->unused_prevp = inet_peer_unused_tailp;
+- p->unused_next = NULL;
+- *inet_peer_unused_tailp = p;
+- inet_peer_unused_tailp = &p->unused_next;
++ struct net *net = p->u.net;
++
++ p->unused_prevp = net->inet_peer_unused_tailp;
++ p->u.unused_next = NULL;
++ *net->inet_peer_unused_tailp = p;
++ net->inet_peer_unused_tailp = &p->u.unused_next;
+ p->dtime = (__u32)jiffies;
++
++ release_net(net);
+ }
+ spin_unlock_bh(&inet_peer_unused_lock);
+ }
+diff -Nurb linux-2.6.22-570/net/ipv4/ip_fragment.c linux-2.6.22-590/net/ipv4/ip_fragment.c
+--- linux-2.6.22-570/net/ipv4/ip_fragment.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/ip_fragment.c 2008-01-29 22:12:32.000000000 -0500
+@@ -49,21 +49,6 @@
+ * as well. Or notify me, at least. --ANK
+ */
+
+-/* Fragment cache limits. We will commit 256K at one time. Should we
+- * cross that limit we will prune down to 192K. This should cope with
+- * even the most extreme cases without allowing an attacker to measurably
+- * harm machine performance.
+- */
+-int sysctl_ipfrag_high_thresh __read_mostly = 256*1024;
+-int sysctl_ipfrag_low_thresh __read_mostly = 192*1024;
+-
+-int sysctl_ipfrag_max_dist __read_mostly = 64;
+-
+-/* Important NOTE! Fragment queue must be destroyed before MSL expires.
+- * RFC791 is wrong proposing to prolongate timer each fragment arrival by TTL.
+- */
+-int sysctl_ipfrag_time __read_mostly = IP_FRAG_TIME;
+-
+ struct ipfrag_skb_cb
+ {
+ struct inet_skb_parm h;
+@@ -96,6 +81,7 @@
+ int iif;
+ unsigned int rid;
+ struct inet_peer *peer;
++ struct net *net;
+ };
+
+ /* Hash table. */
+@@ -103,17 +89,13 @@
+ #define IPQ_HASHSZ 64
+
+ /* Per-bucket lock is easy to add now. */
+-static struct hlist_head ipq_hash[IPQ_HASHSZ];
+ static DEFINE_RWLOCK(ipfrag_lock);
+-static u32 ipfrag_hash_rnd;
+-static LIST_HEAD(ipq_lru_list);
+-int ip_frag_nqueues = 0;
+
+ static __inline__ void __ipq_unlink(struct ipq *qp)
+ {
+ hlist_del(&qp->list);
+ list_del(&qp->lru_list);
+- ip_frag_nqueues--;
++ qp->net->ip_frag_nqueues--;
+ }
+
+ static __inline__ void ipq_unlink(struct ipq *ipq)
+@@ -123,70 +105,71 @@
+ write_unlock(&ipfrag_lock);
+ }
+
+-static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot)
++static unsigned int ipqhashfn(struct net *net, __be16 id, __be32 saddr, __be32 daddr, u8 prot)
+ {
+ return jhash_3words((__force u32)id << 16 | prot,
+ (__force u32)saddr, (__force u32)daddr,
+- ipfrag_hash_rnd) & (IPQ_HASHSZ - 1);
++ net->ipfrag_hash_rnd) & (IPQ_HASHSZ - 1);
+ }
+
+-static struct timer_list ipfrag_secret_timer;
+-int sysctl_ipfrag_secret_interval __read_mostly = 10 * 60 * HZ;
+-
+-static void ipfrag_secret_rebuild(unsigned long dummy)
++static void ipfrag_secret_rebuild(unsigned long arg)
+ {
++ struct net *net = (void *)arg;
+ unsigned long now = jiffies;
+ int i;
+
+ write_lock(&ipfrag_lock);
+- get_random_bytes(&ipfrag_hash_rnd, sizeof(u32));
++ get_random_bytes(&net->ipfrag_hash_rnd, sizeof(u32));
+ for (i = 0; i < IPQ_HASHSZ; i++) {
+ struct ipq *q;
++ struct hlist_head *head;
+ struct hlist_node *p, *n;
+
+- hlist_for_each_entry_safe(q, p, n, &ipq_hash[i], list) {
+- unsigned int hval = ipqhashfn(q->id, q->saddr,
++ head = &net->ipq_hash[i];
++ hlist_for_each_entry_safe(q, p, n, head, list) {
++ unsigned int hval = ipqhashfn(net, q->id, q->saddr,
+ q->daddr, q->protocol);
+
+ if (hval != i) {
+ hlist_del(&q->list);
+
+ /* Relink to new hash chain. */
+- hlist_add_head(&q->list, &ipq_hash[hval]);
++ hlist_add_head(&q->list, &net->ipq_hash[hval]);
+ }
+ }
+ }
+ write_unlock(&ipfrag_lock);
+
+- mod_timer(&ipfrag_secret_timer, now + sysctl_ipfrag_secret_interval);
++ mod_timer(&net->ipfrag_secret_timer,
++ now + net->sysctl_ipfrag_secret_interval);
+ }
+
+-atomic_t ip_frag_mem = ATOMIC_INIT(0); /* Memory used for fragments */
+-
+ /* Memory Tracking Functions. */
+-static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work)
++static __inline__ void frag_kfree_skb(struct net *net, struct sk_buff *skb, int *work)
+ {
+ if (work)
+ *work -= skb->truesize;
+- atomic_sub(skb->truesize, &ip_frag_mem);
++ atomic_sub(skb->truesize, &net->ip_frag_mem);
+ kfree_skb(skb);
+ }
+
+ static __inline__ void frag_free_queue(struct ipq *qp, int *work)
+ {
++ struct net *net = qp->net;
+ if (work)
+ *work -= sizeof(struct ipq);
+- atomic_sub(sizeof(struct ipq), &ip_frag_mem);
++ atomic_sub(sizeof(struct ipq), &net->ip_frag_mem);
++ release_net(net);
+ kfree(qp);
+ }
+
+-static __inline__ struct ipq *frag_alloc_queue(void)
++static __inline__ struct ipq *frag_alloc_queue(struct net *net)
+ {
+ struct ipq *qp = kmalloc(sizeof(struct ipq), GFP_ATOMIC);
+
+ if (!qp)
+ return NULL;
+- atomic_add(sizeof(struct ipq), &ip_frag_mem);
++ atomic_add(sizeof(struct ipq), &net->ip_frag_mem);
+ return qp;
+ }
+
+@@ -209,7 +192,7 @@
+ while (fp) {
+ struct sk_buff *xp = fp->next;
+
+- frag_kfree_skb(fp, work);
++ frag_kfree_skb(qp->net, fp, work);
+ fp = xp;
+ }
+
+@@ -241,23 +224,23 @@
+ /* Memory limiting on fragments. Evictor trashes the oldest
+ * fragment queue until we are back under the threshold.
+ */
+-static void ip_evictor(void)
++static void ip_evictor(struct net *net)
+ {
+ struct ipq *qp;
+ struct list_head *tmp;
+ int work;
+
+- work = atomic_read(&ip_frag_mem) - sysctl_ipfrag_low_thresh;
++ work = atomic_read(&net->ip_frag_mem) - net->sysctl_ipfrag_low_thresh;
+ if (work <= 0)
+ return;
+
+ while (work > 0) {
+ read_lock(&ipfrag_lock);
+- if (list_empty(&ipq_lru_list)) {
++ if (list_empty(&net->ipq_lru_list)) {
+ read_unlock(&ipfrag_lock);
+ return;
+ }
+- tmp = ipq_lru_list.next;
++ tmp = net->ipq_lru_list.next;
+ qp = list_entry(tmp, struct ipq, lru_list);
+ atomic_inc(&qp->refcnt);
+ read_unlock(&ipfrag_lock);
+@@ -292,7 +275,7 @@
+ if ((qp->last_in&FIRST_IN) && qp->fragments != NULL) {
+ struct sk_buff *head = qp->fragments;
+ /* Send an ICMP "Fragment Reassembly Timeout" message. */
+- if ((head->dev = dev_get_by_index(qp->iif)) != NULL) {
++ if ((head->dev = dev_get_by_index(qp->net, qp->iif)) != NULL) {
+ icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0);
+ dev_put(head->dev);
+ }
+@@ -304,7 +287,7 @@
+
+ /* Creation primitives. */
+
+-static struct ipq *ip_frag_intern(struct ipq *qp_in)
++static struct ipq *ip_frag_intern(struct net *net, struct ipq *qp_in)
+ {
+ struct ipq *qp;
+ #ifdef CONFIG_SMP
+@@ -313,14 +296,14 @@
+ unsigned int hash;
+
+ write_lock(&ipfrag_lock);
+- hash = ipqhashfn(qp_in->id, qp_in->saddr, qp_in->daddr,
++ hash = ipqhashfn(net, qp_in->id, qp_in->saddr, qp_in->daddr,
+ qp_in->protocol);
+ #ifdef CONFIG_SMP
+ /* With SMP race we have to recheck hash table, because
+ * such entry could be created on other cpu, while we
+ * promoted read lock to write lock.
+ */
+- hlist_for_each_entry(qp, n, &ipq_hash[hash], list) {
++ hlist_for_each_entry(qp, n, &net->ipq_hash[hash], list) {
+ if (qp->id == qp_in->id &&
+ qp->saddr == qp_in->saddr &&
+ qp->daddr == qp_in->daddr &&
+@@ -336,26 +319,27 @@
+ #endif
+ qp = qp_in;
+
+- if (!mod_timer(&qp->timer, jiffies + sysctl_ipfrag_time))
++ if (!mod_timer(&qp->timer, jiffies + net->sysctl_ipfrag_time))
+ atomic_inc(&qp->refcnt);
+
+ atomic_inc(&qp->refcnt);
+- hlist_add_head(&qp->list, &ipq_hash[hash]);
++ hlist_add_head(&qp->list, &net->ipq_hash[hash]);
+ INIT_LIST_HEAD(&qp->lru_list);
+- list_add_tail(&qp->lru_list, &ipq_lru_list);
+- ip_frag_nqueues++;
++ list_add_tail(&qp->lru_list, &net->ipq_lru_list);
++ net->ip_frag_nqueues++;
+ write_unlock(&ipfrag_lock);
+ return qp;
+ }
+
+ /* Add an entry to the 'ipq' queue for a newly received IP datagram. */
+-static struct ipq *ip_frag_create(struct iphdr *iph, u32 user)
++static struct ipq *ip_frag_create(struct net *net, struct iphdr *iph, u32 user)
+ {
+ struct ipq *qp;
+
+- if ((qp = frag_alloc_queue()) == NULL)
++ if ((qp = frag_alloc_queue(net)) == NULL)
+ goto out_nomem;
+
++ qp->net = hold_net(net);
+ qp->protocol = iph->protocol;
+ qp->last_in = 0;
+ qp->id = iph->id;
+@@ -366,7 +350,8 @@
+ qp->meat = 0;
+ qp->fragments = NULL;
+ qp->iif = 0;
+- qp->peer = sysctl_ipfrag_max_dist ? inet_getpeer(iph->saddr, 1) : NULL;
++ qp->peer = net->sysctl_ipfrag_max_dist ?
++ inet_getpeer(net, iph->saddr, 1) : NULL;
+
+ /* Initialize a timer for this entry. */
+ init_timer(&qp->timer);
+@@ -375,7 +360,7 @@
+ spin_lock_init(&qp->lock);
+ atomic_set(&qp->refcnt, 1);
+
+- return ip_frag_intern(qp);
++ return ip_frag_intern(net, qp);
+
+ out_nomem:
+ LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n");
+@@ -385,7 +370,7 @@
+ /* Find the correct entry in the "incomplete datagrams" queue for
+ * this IP datagram, and create new one, if nothing is found.
+ */
+-static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
++static inline struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user)
+ {
+ __be16 id = iph->id;
+ __be32 saddr = iph->saddr;
+@@ -396,8 +381,8 @@
+ struct hlist_node *n;
+
+ read_lock(&ipfrag_lock);
+- hash = ipqhashfn(id, saddr, daddr, protocol);
+- hlist_for_each_entry(qp, n, &ipq_hash[hash], list) {
++ hash = ipqhashfn(net, id, saddr, daddr, protocol);
++ hlist_for_each_entry(qp, n, &net->ipq_hash[hash], list) {
+ if (qp->id == id &&
+ qp->saddr == saddr &&
+ qp->daddr == daddr &&
+@@ -410,14 +395,14 @@
+ }
+ read_unlock(&ipfrag_lock);
+
+- return ip_frag_create(iph, user);
++ return ip_frag_create(net, iph, user);
+ }
+
+ /* Is the fragment too far ahead to be part of ipq? */
+ static inline int ip_frag_too_far(struct ipq *qp)
+ {
+ struct inet_peer *peer = qp->peer;
+- unsigned int max = sysctl_ipfrag_max_dist;
++ unsigned int max = qp->net->sysctl_ipfrag_max_dist;
+ unsigned int start, end;
+
+ int rc;
+@@ -442,7 +427,7 @@
+ {
+ struct sk_buff *fp;
+
+- if (!mod_timer(&qp->timer, jiffies + sysctl_ipfrag_time)) {
++ if (!mod_timer(&qp->timer, jiffies + qp->net->sysctl_ipfrag_time)) {
+ atomic_inc(&qp->refcnt);
+ return -ETIMEDOUT;
+ }
+@@ -450,7 +435,7 @@
+ fp = qp->fragments;
+ do {
+ struct sk_buff *xp = fp->next;
+- frag_kfree_skb(fp, NULL);
++ frag_kfree_skb(qp->net, fp, NULL);
+ fp = xp;
+ } while (fp);
+
+@@ -466,6 +451,7 @@
+ /* Add new segment to existing queue. */
+ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
+ {
++ struct net *net = qp->net;
+ struct sk_buff *prev, *next;
+ int flags, offset;
+ int ihl, end;
+@@ -576,7 +562,7 @@
+ qp->fragments = next;
+
+ qp->meat -= free_it->len;
+- frag_kfree_skb(free_it, NULL);
++ frag_kfree_skb(net, free_it, NULL);
+ }
+ }
+
+@@ -594,12 +580,12 @@
+ skb->dev = NULL;
+ qp->stamp = skb->tstamp;
+ qp->meat += skb->len;
+- atomic_add(skb->truesize, &ip_frag_mem);
++ atomic_add(skb->truesize, &net->ip_frag_mem);
+ if (offset == 0)
+ qp->last_in |= FIRST_IN;
+
+ write_lock(&ipfrag_lock);
+- list_move_tail(&qp->lru_list, &ipq_lru_list);
++ list_move_tail(&qp->lru_list, &net->ipq_lru_list);
+ write_unlock(&ipfrag_lock);
+
+ return;
+@@ -613,6 +599,7 @@
+
+ static struct sk_buff *ip_frag_reasm(struct ipq *qp, struct net_device *dev)
+ {
++ struct net *net = qp->net;
+ struct iphdr *iph;
+ struct sk_buff *fp, *head = qp->fragments;
+ int len;
+@@ -654,12 +641,12 @@
+ head->len -= clone->len;
+ clone->csum = 0;
+ clone->ip_summed = head->ip_summed;
+- atomic_add(clone->truesize, &ip_frag_mem);
++ atomic_add(clone->truesize, &net->ip_frag_mem);
+ }
+
+ skb_shinfo(head)->frag_list = head->next;
+ skb_push(head, head->data - skb_network_header(head));
+- atomic_sub(head->truesize, &ip_frag_mem);
++ atomic_sub(head->truesize, &net->ip_frag_mem);
+
+ for (fp=head->next; fp; fp = fp->next) {
+ head->data_len += fp->len;
+@@ -669,7 +656,7 @@
+ else if (head->ip_summed == CHECKSUM_COMPLETE)
+ head->csum = csum_add(head->csum, fp->csum);
+ head->truesize += fp->truesize;
+- atomic_sub(fp->truesize, &ip_frag_mem);
++ atomic_sub(fp->truesize, &net->ip_frag_mem);
+ }
+
+ head->next = NULL;
+@@ -700,19 +687,20 @@
+ /* Process an incoming IP datagram fragment. */
+ struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user)
+ {
++ struct net *net = skb->dev->nd_net;
+ struct ipq *qp;
+ struct net_device *dev;
+
+ IP_INC_STATS_BH(IPSTATS_MIB_REASMREQDS);
+
+ /* Start by cleaning up the memory. */
+- if (atomic_read(&ip_frag_mem) > sysctl_ipfrag_high_thresh)
+- ip_evictor();
++ if (atomic_read(&net->ip_frag_mem) > net->sysctl_ipfrag_high_thresh)
++ ip_evictor(net);
+
+ dev = skb->dev;
+
+ /* Lookup (or create) queue header */
+- if ((qp = ip_find(ip_hdr(skb), user)) != NULL) {
++ if ((qp = ip_find(net, ip_hdr(skb), user)) != NULL) {
+ struct sk_buff *ret = NULL;
+
+ spin_lock(&qp->lock);
+@@ -733,15 +721,70 @@
+ return NULL;
+ }
+
+-void __init ipfrag_init(void)
++static int ipfrag_net_init(struct net *net)
+ {
+- ipfrag_hash_rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^
++ struct timer_list *secret_timer;
++ int i;
+
-+ /*
-+ * Set the IP module up
++ /* Fragment cache limits. We will commit 256K at one time. Should we
++ * cross that limit we will prune down to 192K. This should cope with
++ * even the most extreme cases without allowing an attacker to measurably
++ * harm machine performance.
+ */
++ net->sysctl_ipfrag_high_thresh = 256*1024;
++ net->sysctl_ipfrag_low_thresh = 192*1024;
++ net->sysctl_ipfrag_max_dist = 64;
+
-+ ip_init();
-+
-+ tcp_v4_init(&inet_family_ops);
-+
-+ /* Setup TCP slab cache for open requests. */
-+ tcp_init();
-+
-+ /* Add UDP-Lite (RFC 3828) */
-+ udplite4_register();
-+
-+ /*
-+ * Set the ICMP layer up
++ /* Important NOTE! Fragment queue must be destroyed before MSL expires.
++ * RFC791 is wrong proposing to prolongate timer each fragment arrival by TTL.
+ */
++ net->sysctl_ipfrag_time = IP_FRAG_TIME;
+
-+ icmp_init(&inet_family_ops);
-+
-+ /*
-+ * Initialise the multicast router
-+ */
-+#if defined(CONFIG_IP_MROUTE)
-+ ip_mr_init();
-+#endif
-+ /*
-+ * Initialise per-cpu ipv4 mibs
-+ */
++ net->sysctl_ipfrag_secret_interval = 10 * 60 * HZ;
+
-+ if (init_ipv4_mibs())
-+ printk(KERN_CRIT "inet_init: Cannot init ipv4 mibs\n"); ;
++ net->ipq_hash = kzalloc(sizeof(*net->ipq_hash)*IPQ_HASHSZ, GFP_KERNEL);
++ if (!net->ipq_hash)
++ return -ENOMEM;
+
-+ ipv4_proc_init();
++ for (i = 0; i < IPQ_HASHSZ; i++)
++ INIT_HLIST_HEAD(&net->ipq_hash[i]);
++ INIT_LIST_HEAD(&net->ipq_lru_list);
++ net->ip_frag_nqueues = 0;
++ atomic_set(&net->ip_frag_mem, 0);
+
-+ ipfrag_init();
+
-+ dev_add_pack(&ip_packet_type);
++ net->ipfrag_hash_rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^
+ (jiffies ^ (jiffies >> 6)));
+
+- init_timer(&ipfrag_secret_timer);
+- ipfrag_secret_timer.function = ipfrag_secret_rebuild;
+- ipfrag_secret_timer.expires = jiffies + sysctl_ipfrag_secret_interval;
+- add_timer(&ipfrag_secret_timer);
++ secret_timer = &net->ipfrag_secret_timer;
++ init_timer(secret_timer);
++ secret_timer->function = ipfrag_secret_rebuild;
++ secret_timer->expires = jiffies + net->sysctl_ipfrag_secret_interval;
++ secret_timer->data = (unsigned long)net;
++ add_timer(secret_timer);
+
-+ rc = 0;
-+out:
-+ return rc;
-+out_unregister_udp_proto:
-+ proto_unregister(&udp_prot);
-+out_unregister_tcp_proto:
-+ proto_unregister(&tcp_prot);
-+ goto out;
++ return 0;
+}
+
-+fs_initcall(inet_init);
-+
-+/* ------------------------------------------------------------------------ */
-+
-+#ifdef CONFIG_PROC_FS
-+static int __init ipv4_proc_init(void)
++static void ipfrag_net_exit(struct net *net)
+{
-+ int rc = 0;
++ del_timer(&net->ipfrag_secret_timer);
+
-+ if (raw_proc_init())
-+ goto out_raw;
-+ if (tcp4_proc_init())
-+ goto out_tcp;
-+ if (udp4_proc_init())
-+ goto out_udp;
-+ if (fib_proc_init())
-+ goto out_fib;
-+ if (ip_misc_proc_init())
-+ goto out_misc;
-+out:
-+ return rc;
-+out_misc:
-+ fib_proc_exit();
-+out_fib:
-+ udp4_proc_exit();
-+out_udp:
-+ tcp4_proc_exit();
-+out_tcp:
-+ raw_proc_exit();
-+out_raw:
-+ rc = -ENOMEM;
-+ goto out;
++ net->sysctl_ipfrag_low_thresh = 0;
++ while (atomic_read(&net->ip_frag_mem))
++ ip_evictor(net);
++
++ kfree(net->ipq_hash);
+}
+
-+#else /* CONFIG_PROC_FS */
-+static int __init ipv4_proc_init(void)
++static struct pernet_operations ipfrag_net_ops = {
++ .init = ipfrag_net_init,
++ .exit = ipfrag_net_exit,
++};
++
++void ipfrag_init(void)
+{
-+ return 0;
-+}
-+#endif /* CONFIG_PROC_FS */
++ register_pernet_subsys(&ipfrag_net_ops);
+ }
+
+ EXPORT_SYMBOL(ip_defrag);
+diff -Nurb linux-2.6.22-570/net/ipv4/ip_gre.c linux-2.6.22-590/net/ipv4/ip_gre.c
+--- linux-2.6.22-570/net/ipv4/ip_gre.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/ip_gre.c 2008-01-29 22:12:32.000000000 -0500
+@@ -262,7 +262,7 @@
+ int i;
+ for (i=1; i<100; i++) {
+ sprintf(name, "gre%d", i);
+- if (__dev_get_by_name(name) == NULL)
++ if (__dev_get_by_name(&init_net, name) == NULL)
+ break;
+ }
+ if (i==100)
+@@ -397,6 +397,9 @@
+ struct flowi fl;
+ struct rtable *rt;
+
++ if (skb->dev->nd_net != &init_net)
++ return;
+
-+MODULE_ALIAS_NETPROTO(PF_INET);
-+
-+EXPORT_SYMBOL(inet_accept);
-+EXPORT_SYMBOL(inet_bind);
-+EXPORT_SYMBOL(inet_dgram_connect);
-+EXPORT_SYMBOL(inet_dgram_ops);
-+EXPORT_SYMBOL(inet_getname);
-+EXPORT_SYMBOL(inet_ioctl);
-+EXPORT_SYMBOL(inet_listen);
-+EXPORT_SYMBOL(inet_register_protosw);
-+EXPORT_SYMBOL(inet_release);
-+EXPORT_SYMBOL(inet_sendmsg);
-+EXPORT_SYMBOL(inet_shutdown);
-+EXPORT_SYMBOL(inet_sock_destruct);
-+EXPORT_SYMBOL(inet_stream_connect);
-+EXPORT_SYMBOL(inet_stream_ops);
-+EXPORT_SYMBOL(inet_unregister_protosw);
-+EXPORT_SYMBOL(net_statistics);
-+EXPORT_SYMBOL(sysctl_ip_nonlocal_bind);
-diff -Nurb linux-2.6.22-570/net/ipv4/ah4.c linux-2.6.22-590/net/ipv4/ah4.c
---- linux-2.6.22-570/net/ipv4/ah4.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/net/ipv4/ah4.c 2008-03-15 10:35:47.000000000 -0400
-@@ -339,3 +339,4 @@
- module_init(ah4_init);
- module_exit(ah4_fini);
- MODULE_LICENSE("GPL");
-+MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_AH);
-diff -Nurb linux-2.6.22-570/net/ipv4/esp4.c linux-2.6.22-590/net/ipv4/esp4.c
---- linux-2.6.22-570/net/ipv4/esp4.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/ipv4/esp4.c 2008-03-15 10:35:47.000000000 -0400
-@@ -481,3 +481,4 @@
- module_init(esp4_init);
- module_exit(esp4_fini);
- MODULE_LICENSE("GPL");
-+MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_ESP);
-diff -Nurb linux-2.6.22-570/net/ipv4/fib_frontend.c linux-2.6.22-590/net/ipv4/fib_frontend.c
---- linux-2.6.22-570/net/ipv4/fib_frontend.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/ipv4/fib_frontend.c 2008-03-15 10:35:47.000000000 -0400
-@@ -453,7 +453,6 @@
- [RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) },
- [RTA_PROTOINFO] = { .type = NLA_U32 },
- [RTA_FLOW] = { .type = NLA_U32 },
-- [RTA_MP_ALGO] = { .type = NLA_U32 },
- };
+ if (p[1] != htons(ETH_P_IP))
+ return;
- static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh,
-@@ -515,9 +514,6 @@
- case RTA_FLOW:
- cfg->fc_flow = nla_get_u32(attr);
- break;
-- case RTA_MP_ALGO:
-- cfg->fc_mp_alg = nla_get_u32(attr);
-- break;
- case RTA_TABLE:
- cfg->fc_table = nla_get_u32(attr);
- break;
-diff -Nurb linux-2.6.22-570/net/ipv4/fib_semantics.c linux-2.6.22-590/net/ipv4/fib_semantics.c
---- linux-2.6.22-570/net/ipv4/fib_semantics.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/ipv4/fib_semantics.c 2008-03-15 10:35:47.000000000 -0400
-@@ -42,7 +42,6 @@
- #include <net/tcp.h>
- #include <net/sock.h>
- #include <net/ip_fib.h>
--#include <net/ip_mp_alg.h>
- #include <net/netlink.h>
- #include <net/nexthop.h>
+@@ -475,6 +478,7 @@
-@@ -697,13 +696,6 @@
- goto err_inval;
- }
- #endif
--#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-- if (cfg->fc_mp_alg) {
-- if (cfg->fc_mp_alg < IP_MP_ALG_NONE ||
-- cfg->fc_mp_alg > IP_MP_ALG_MAX)
-- goto err_inval;
-- }
--#endif
+ /* Try to guess incoming interface */
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ fl.fl4_dst = eiph->saddr;
+ fl.fl4_tos = RT_TOS(eiph->tos);
+ fl.proto = IPPROTO_GRE;
+@@ -559,6 +563,10 @@
+ struct ip_tunnel *tunnel;
+ int offset = 4;
- err = -ENOBUFS;
- if (fib_info_cnt >= fib_hash_size) {
-@@ -791,10 +783,6 @@
- #endif
++ if (skb->dev->nd_net != &init_net) {
++ kfree_skb(skb);
++ return 0;
++ }
+ if (!pskb_may_pull(skb, 16))
+ goto drop_nolock;
+
+@@ -740,7 +748,8 @@
}
--#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-- fi->fib_mp_alg = cfg->fc_mp_alg;
--#endif
--
- if (fib_props[cfg->fc_type].error) {
- if (cfg->fc_gw || cfg->fc_oif || cfg->fc_mp)
- goto err_inval;
-@@ -940,10 +928,6 @@
- res->type = fa->fa_type;
- res->scope = fa->fa_scope;
- res->fi = fa->fa_info;
--#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-- res->netmask = mask;
-- res->network = zone & inet_make_mask(prefixlen);
--#endif
- atomic_inc(&res->fi->fib_clntref);
- return 0;
- }
+ {
+- struct flowi fl = { .oif = tunnel->parms.link,
++ struct flowi fl = { .fl_net = &init_net,
++ .oif = tunnel->parms.link,
+ .nl_u = { .ip4_u =
+ { .daddr = dst,
+ .saddr = tiph->saddr,
+@@ -1095,7 +1104,8 @@
+ struct ip_tunnel *t = netdev_priv(dev);
+
+ if (MULTICAST(t->parms.iph.daddr)) {
+- struct flowi fl = { .oif = t->parms.link,
++ struct flowi fl = { .fl_net = &init_net,
++ .oif = t->parms.link,
+ .nl_u = { .ip4_u =
+ { .daddr = t->parms.iph.daddr,
+ .saddr = t->parms.iph.saddr,
+@@ -1118,7 +1128,7 @@
+ {
+ struct ip_tunnel *t = netdev_priv(dev);
+ if (MULTICAST(t->parms.iph.daddr) && t->mlink) {
+- struct in_device *in_dev = inetdev_by_index(t->mlink);
++ struct in_device *in_dev = inetdev_by_index(&init_net, t->mlink);
+ if (in_dev) {
+ ip_mc_dec_group(in_dev, t->parms.iph.daddr);
+ in_dev_put(in_dev);
+@@ -1168,7 +1178,8 @@
+ /* Guess output device to choose reasonable mtu and hard_header_len */
+
+ if (iph->daddr) {
+- struct flowi fl = { .oif = tunnel->parms.link,
++ struct flowi fl = { .fl_net = &init_net,
++ .oif = tunnel->parms.link,
+ .nl_u = { .ip4_u =
+ { .daddr = iph->daddr,
+ .saddr = iph->saddr,
+@@ -1195,7 +1206,7 @@
+ }
+
+ if (!tdev && tunnel->parms.link)
+- tdev = __dev_get_by_index(tunnel->parms.link);
++ tdev = __dev_get_by_index(&init_net, tunnel->parms.link);
+
+ if (tdev) {
+ hlen = tdev->hard_header_len;
+diff -Nurb linux-2.6.22-570/net/ipv4/ip_input.c linux-2.6.22-590/net/ipv4/ip_input.c
+--- linux-2.6.22-570/net/ipv4/ip_input.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/ip_input.c 2008-01-29 22:12:32.000000000 -0500
+@@ -280,6 +280,10 @@
+ struct iphdr *iph;
+ struct net_device *dev = skb->dev;
+
++
++ if (skb->dev->nd_net != &init_net)
++ goto drop;
++
+ /* It looks as overkill, because not all
+ IP options require packet mangling.
+ But it is the easiest for now, especially taking
+diff -Nurb linux-2.6.22-570/net/ipv4/ip_options.c linux-2.6.22-590/net/ipv4/ip_options.c
+--- linux-2.6.22-570/net/ipv4/ip_options.c 2008-01-29 22:12:24.000000000 -0500
++++ linux-2.6.22-590/net/ipv4/ip_options.c 2008-01-29 22:12:32.000000000 -0500
+@@ -151,7 +151,7 @@
+ __be32 addr;
+
+ memcpy(&addr, sptr+soffset-1, 4);
+- if (inet_addr_type(addr) != RTN_LOCAL) {
++ if (inet_addr_type(&init_net, addr) != RTN_LOCAL) {
+ dopt->ts_needtime = 1;
+ soffset += 8;
+ }
+@@ -400,7 +400,7 @@
+ {
+ __be32 addr;
+ memcpy(&addr, &optptr[optptr[2]-1], 4);
+- if (inet_addr_type(addr) == RTN_UNICAST)
++ if (inet_addr_type(&init_net, addr) == RTN_UNICAST)
+ break;
+ if (skb)
+ timeptr = (__be32*)&optptr[optptr[2]+3];
diff -Nurb linux-2.6.22-570/net/ipv4/ip_output.c linux-2.6.22-590/net/ipv4/ip_output.c
--- linux-2.6.22-570/net/ipv4/ip_output.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/ipv4/ip_output.c 2008-03-15 10:35:47.000000000 -0400
-@@ -837,7 +837,7 @@
++++ linux-2.6.22-590/net/ipv4/ip_output.c 2008-01-29 22:12:32.000000000 -0500
+@@ -83,8 +83,6 @@
+ #include <linux/netlink.h>
+ #include <linux/tcp.h>
+
+-int sysctl_ip_default_ttl __read_mostly = IPDEFTTL;
+-
+ /* Generate a checksum for an outgoing IP datagram. */
+ __inline__ void ip_send_check(struct iphdr *iph)
+ {
+@@ -317,7 +315,8 @@
+ daddr = opt->faddr;
+
+ {
+- struct flowi fl = { .oif = sk->sk_bound_dev_if,
++ struct flowi fl = { .fl_net = sk->sk_net,
++ .oif = sk->sk_bound_dev_if,
+ .nl_u = { .ip4_u =
+ { .daddr = daddr,
+ .saddr = inet->saddr,
+@@ -837,7 +836,7 @@
*/
if (transhdrlen &&
length + fragheaderlen <= mtu &&
!exthdrlen)
csummode = CHECKSUM_PARTIAL;
+@@ -1352,7 +1351,8 @@
+ }
+
+ {
+- struct flowi fl = { .oif = arg->bound_dev_if,
++ struct flowi fl = { .fl_net = sk->sk_net,
++ .oif = arg->bound_dev_if,
+ .nl_u = { .ip4_u =
+ { .daddr = daddr,
+ .saddr = rt->rt_spec_dst,
+diff -Nurb linux-2.6.22-570/net/ipv4/ip_sockglue.c linux-2.6.22-590/net/ipv4/ip_sockglue.c
+--- linux-2.6.22-570/net/ipv4/ip_sockglue.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/ip_sockglue.c 2008-01-29 22:12:32.000000000 -0500
+@@ -411,6 +411,7 @@
+ static int do_ip_setsockopt(struct sock *sk, int level,
+ int optname, char __user *optval, int optlen)
+ {
++ struct net *net = sk->sk_net;
+ struct inet_sock *inet = inet_sk(sk);
+ int val=0,err;
+
+@@ -596,13 +597,13 @@
+ err = 0;
+ break;
+ }
+- dev = ip_dev_find(mreq.imr_address.s_addr);
++ dev = ip_dev_find(net, mreq.imr_address.s_addr);
+ if (dev) {
+ mreq.imr_ifindex = dev->ifindex;
+ dev_put(dev);
+ }
+ } else
+- dev = __dev_get_by_index(mreq.imr_ifindex);
++ dev = __dev_get_by_index(net, mreq.imr_ifindex);
+
+
+ err = -EADDRNOTAVAIL;
+@@ -956,6 +957,7 @@
+ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
+ char __user *optval, int __user *optlen)
+ {
++ struct net *net = sk->sk_net;
+ struct inet_sock *inet = inet_sk(sk);
+ int val;
+ int len;
+@@ -1023,7 +1025,7 @@
+ break;
+ case IP_TTL:
+ val = (inet->uc_ttl == -1 ?
+- sysctl_ip_default_ttl :
++ net->sysctl_ip_default_ttl :
+ inet->uc_ttl);
+ break;
+ case IP_HDRINCL:
diff -Nurb linux-2.6.22-570/net/ipv4/ipcomp.c linux-2.6.22-590/net/ipv4/ipcomp.c
---- linux-2.6.22-570/net/ipv4/ipcomp.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/net/ipv4/ipcomp.c 2008-03-15 10:35:47.000000000 -0400
-@@ -486,3 +486,4 @@
+--- linux-2.6.22-570/net/ipv4/ipcomp.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/ipv4/ipcomp.c 2008-01-29 22:12:32.000000000 -0500
+@@ -175,6 +175,9 @@
+ struct ip_comp_hdr *ipch = (struct ip_comp_hdr *)(skb->data+(iph->ihl<<2));
+ struct xfrm_state *x;
+
++ if (skb->dev->nd_net != &init_net)
++ return;
++
+ if (icmp_hdr(skb)->type != ICMP_DEST_UNREACH ||
+ icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
+ return;
+@@ -486,3 +489,4 @@
MODULE_DESCRIPTION("IP Payload Compression Protocol (IPComp) - RFC3173");
MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
+MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_COMP);
+diff -Nurb linux-2.6.22-570/net/ipv4/ipconfig.c linux-2.6.22-590/net/ipv4/ipconfig.c
+--- linux-2.6.22-570/net/ipv4/ipconfig.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/ipconfig.c 2008-01-29 22:12:32.000000000 -0500
+@@ -59,6 +59,7 @@
+ #include <net/ip.h>
+ #include <net/ipconfig.h>
+ #include <net/route.h>
++#include <net/net_namespace.h>
+
+ #include <asm/uaccess.h>
+ #include <net/checksum.h>
+@@ -184,16 +185,18 @@
+ struct ic_device *d, **last;
+ struct net_device *dev;
+ unsigned short oflags;
++ struct net_device *lo;
+
+ last = &ic_first_dev;
+ rtnl_lock();
+
+ /* bring loopback device up first */
+- if (dev_change_flags(&loopback_dev, loopback_dev.flags | IFF_UP) < 0)
+- printk(KERN_ERR "IP-Config: Failed to open %s\n", loopback_dev.name);
++ lo = &init_net.loopback_dev;
++ if (dev_change_flags(lo, lo->flags | IFF_UP) < 0)
++ printk(KERN_ERR "IP-Config: Failed to open %s\n", lo->name);
+
+- for_each_netdev(dev) {
+- if (dev == &loopback_dev)
++ for_each_netdev(&init_net, dev) {
++ if (dev == lo)
+ continue;
+ if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
+ (!(dev->flags & IFF_LOOPBACK) &&
+@@ -283,7 +286,7 @@
+
+ mm_segment_t oldfs = get_fs();
+ set_fs(get_ds());
+- res = devinet_ioctl(cmd, (struct ifreq __user *) arg);
++ res = devinet_ioctl(&init_net, cmd, (struct ifreq __user *) arg);
+ set_fs(oldfs);
+ return res;
+ }
+@@ -294,7 +297,7 @@
+
+ mm_segment_t oldfs = get_fs();
+ set_fs(get_ds());
+- res = ip_rt_ioctl(cmd, (void __user *) arg);
++ res = ip_rt_ioctl(&init_net, cmd, (void __user *) arg);
+ set_fs(oldfs);
+ return res;
+ }
+@@ -425,6 +428,9 @@
+ unsigned char *sha, *tha; /* s for "source", t for "target" */
+ struct ic_device *d;
+
++ if (dev->nd_net != &init_net)
++ goto drop;
++
+ if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
+ return NET_RX_DROP;
+
+@@ -834,6 +840,9 @@
+ struct ic_device *d;
+ int len, ext_len;
+
++ if (dev->nd_net != &init_net)
++ goto drop;
++
+ /* Perform verifications before taking the lock. */
+ if (skb->pkt_type == PACKET_OTHERHOST)
+ goto drop;
+@@ -1253,7 +1262,7 @@
+ __be32 addr;
+
+ #ifdef CONFIG_PROC_FS
+- proc_net_fops_create("pnp", S_IRUGO, &pnp_seq_fops);
++ proc_net_fops_create(&init_net, "pnp", S_IRUGO, &pnp_seq_fops);
+ #endif /* CONFIG_PROC_FS */
+
+ if (!ic_enable)
+diff -Nurb linux-2.6.22-570/net/ipv4/ipip.c linux-2.6.22-590/net/ipv4/ipip.c
+--- linux-2.6.22-570/net/ipv4/ipip.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/ipip.c 2008-01-29 22:12:32.000000000 -0500
+@@ -225,7 +225,7 @@
+ int i;
+ for (i=1; i<100; i++) {
+ sprintf(name, "tunl%d", i);
+- if (__dev_get_by_name(name) == NULL)
++ if (__dev_get_by_name(&init_net, name) == NULL)
+ break;
+ }
+ if (i==100)
+@@ -403,6 +403,7 @@
+
+ /* Try to guess incoming interface */
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ fl.fl4_daddr = eiph->saddr;
+ fl.fl4_tos = RT_TOS(eiph->tos);
+ fl.proto = IPPROTO_IPIP;
+@@ -542,7 +543,8 @@
+ }
+
+ {
+- struct flowi fl = { .oif = tunnel->parms.link,
++ struct flowi fl = { .fl_net = &init_net,
++ .oif = tunnel->parms.link,
+ .nl_u = { .ip4_u =
+ { .daddr = dst,
+ .saddr = tiph->saddr,
+@@ -806,7 +808,8 @@
+ memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
+
+ if (iph->daddr) {
+- struct flowi fl = { .oif = tunnel->parms.link,
++ struct flowi fl = { .fl_net = &init_net,
++ .oif = tunnel->parms.link,
+ .nl_u = { .ip4_u =
+ { .daddr = iph->daddr,
+ .saddr = iph->saddr,
+@@ -821,7 +824,7 @@
+ }
+
+ if (!tdev && tunnel->parms.link)
+- tdev = __dev_get_by_index(tunnel->parms.link);
++ tdev = __dev_get_by_index(&init_net, tunnel->parms.link);
+
+ if (tdev) {
+ dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
+diff -Nurb linux-2.6.22-570/net/ipv4/ipmr.c linux-2.6.22-590/net/ipv4/ipmr.c
+--- linux-2.6.22-570/net/ipv4/ipmr.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/ipmr.c 2008-01-29 22:12:32.000000000 -0500
+@@ -62,6 +62,7 @@
+ #include <linux/netfilter_ipv4.h>
+ #include <net/ipip.h>
+ #include <net/checksum.h>
++#include <net/net_namespace.h>
+ #include <net/netlink.h>
+
+ #if defined(CONFIG_IP_PIMSM_V1) || defined(CONFIG_IP_PIMSM_V2)
+@@ -124,7 +125,7 @@
+ {
+ struct net_device *dev;
+
+- dev = __dev_get_by_name("tunl0");
++ dev = __dev_get_by_name(&init_net, "tunl0");
+
+ if (dev) {
+ int err;
+@@ -148,7 +149,7 @@
+
+ dev = NULL;
+
+- if (err == 0 && (dev = __dev_get_by_name(p.name)) != NULL) {
++ if (err == 0 && (dev = __dev_get_by_name(&init_net, p.name)) != NULL) {
+ dev->flags |= IFF_MULTICAST;
+
+ in_dev = __in_dev_get_rtnl(dev);
+@@ -320,7 +321,7 @@
+ e->error = -ETIMEDOUT;
+ memset(&e->msg, 0, sizeof(e->msg));
+
+- rtnl_unicast(skb, NETLINK_CB(skb).pid);
++ rtnl_unicast(skb, &init_net, NETLINK_CB(skb).pid);
+ } else
+ kfree_skb(skb);
+ }
+@@ -422,7 +423,7 @@
+ return -ENOBUFS;
+ break;
+ case 0:
+- dev = ip_dev_find(vifc->vifc_lcl_addr.s_addr);
++ dev = ip_dev_find(&init_net, vifc->vifc_lcl_addr.s_addr);
+ if (!dev)
+ return -EADDRNOTAVAIL;
+ dev_put(dev);
+@@ -532,7 +533,7 @@
+ memset(&e->msg, 0, sizeof(e->msg));
+ }
+
+- rtnl_unicast(skb, NETLINK_CB(skb).pid);
++ rtnl_unicast(skb, &init_net, NETLINK_CB(skb).pid);
+ } else
+ ip_mr_forward(skb, c, 0);
+ }
+@@ -848,7 +849,7 @@
+ {
+ rtnl_lock();
+ if (sk == mroute_socket) {
+- IPV4_DEVCONF_ALL(MC_FORWARDING)--;
++ IPV4_DEVCONF_ALL(sk->sk_net, MC_FORWARDING)--;
+
+ write_lock_bh(&mrt_lock);
+ mroute_socket=NULL;
+@@ -897,7 +898,7 @@
+ mroute_socket=sk;
+ write_unlock_bh(&mrt_lock);
+
+- IPV4_DEVCONF_ALL(MC_FORWARDING)++;
++ IPV4_DEVCONF_ALL(sk->sk_net, MC_FORWARDING)++;
+ }
+ rtnl_unlock();
+ return ret;
+@@ -1082,13 +1083,18 @@
+
+ static int ipmr_device_event(struct notifier_block *this, unsigned long event, void *ptr)
+ {
++ struct net_device *dev = ptr;
+ struct vif_device *v;
+ int ct;
++
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ if (event != NETDEV_UNREGISTER)
+ return NOTIFY_DONE;
+ v=&vif_table[0];
+ for (ct=0;ct<maxvif;ct++,v++) {
+- if (v->dev==ptr)
++ if (v->dev==dev)
+ vif_delete(ct);
+ }
+ return NOTIFY_DONE;
+@@ -1171,7 +1177,8 @@
+ #endif
+
+ if (vif->flags&VIFF_TUNNEL) {
+- struct flowi fl = { .oif = vif->link,
++ struct flowi fl = { .fl_net = &init_net,
++ .oif = vif->link,
+ .nl_u = { .ip4_u =
+ { .daddr = vif->remote,
+ .saddr = vif->local,
+@@ -1181,7 +1188,8 @@
+ goto out_free;
+ encap = sizeof(struct iphdr);
+ } else {
+- struct flowi fl = { .oif = vif->link,
++ struct flowi fl = { .fl_net = &init_net,
++ .oif = vif->link,
+ .nl_u = { .ip4_u =
+ { .daddr = iph->daddr,
+ .tos = RT_TOS(iph->tos) } },
+@@ -1498,6 +1506,10 @@
+ struct iphdr *encap;
+ struct net_device *reg_dev = NULL;
+
++ if (skb->dev->nd_net != &init_net) {
++ kfree_skb(skb);
++ return 0;
++ }
+ if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap)))
+ goto drop;
+
+@@ -1922,7 +1934,7 @@
+ ipmr_expire_timer.function=ipmr_expire_process;
+ register_netdevice_notifier(&ip_mr_notifier);
+ #ifdef CONFIG_PROC_FS
+- proc_net_fops_create("ip_mr_vif", 0, &ipmr_vif_fops);
+- proc_net_fops_create("ip_mr_cache", 0, &ipmr_mfc_fops);
++ proc_net_fops_create(&init_net, "ip_mr_vif", 0, &ipmr_vif_fops);
++ proc_net_fops_create(&init_net, "ip_mr_cache", 0, &ipmr_mfc_fops);
+ #endif
+ }
+diff -Nurb linux-2.6.22-570/net/ipv4/ipvs/ip_vs_app.c linux-2.6.22-590/net/ipv4/ipvs/ip_vs_app.c
+--- linux-2.6.22-570/net/ipv4/ipvs/ip_vs_app.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/ipvs/ip_vs_app.c 2008-01-29 22:12:32.000000000 -0500
+@@ -32,6 +32,7 @@
+ #include <linux/proc_fs.h>
+ #include <linux/seq_file.h>
+ #include <linux/mutex.h>
++#include <net/net_namespace.h>
+
+ #include <net/ip_vs.h>
+
+@@ -616,12 +617,12 @@
+ int ip_vs_app_init(void)
+ {
+ /* we will replace it with proc_net_ipvs_create() soon */
+- proc_net_fops_create("ip_vs_app", 0, &ip_vs_app_fops);
++ proc_net_fops_create(&init_net, "ip_vs_app", 0, &ip_vs_app_fops);
+ return 0;
+ }
+
+
+ void ip_vs_app_cleanup(void)
+ {
+- proc_net_remove("ip_vs_app");
++ proc_net_remove(&init_net, "ip_vs_app");
+ }
+diff -Nurb linux-2.6.22-570/net/ipv4/ipvs/ip_vs_conn.c linux-2.6.22-590/net/ipv4/ipvs/ip_vs_conn.c
+--- linux-2.6.22-570/net/ipv4/ipvs/ip_vs_conn.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/ipvs/ip_vs_conn.c 2008-01-29 22:12:32.000000000 -0500
+@@ -34,6 +34,7 @@
+ #include <linux/seq_file.h>
+ #include <linux/jhash.h>
+ #include <linux/random.h>
++#include <net/net_namespace.h>
+
+ #include <net/ip_vs.h>
+
+@@ -922,7 +923,7 @@
+ rwlock_init(&__ip_vs_conntbl_lock_array[idx].l);
+ }
+
+- proc_net_fops_create("ip_vs_conn", 0, &ip_vs_conn_fops);
++ proc_net_fops_create(&init_net, "ip_vs_conn", 0, &ip_vs_conn_fops);
+
+ /* calculate the random value for connection hash */
+ get_random_bytes(&ip_vs_conn_rnd, sizeof(ip_vs_conn_rnd));
+@@ -938,6 +939,6 @@
+
+ /* Release the empty cache */
+ kmem_cache_destroy(ip_vs_conn_cachep);
+- proc_net_remove("ip_vs_conn");
++ proc_net_remove(&init_net, "ip_vs_conn");
+ vfree(ip_vs_conn_tab);
+ }
+diff -Nurb linux-2.6.22-570/net/ipv4/ipvs/ip_vs_core.c linux-2.6.22-590/net/ipv4/ipvs/ip_vs_core.c
+--- linux-2.6.22-570/net/ipv4/ipvs/ip_vs_core.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/ipvs/ip_vs_core.c 2008-01-29 22:12:32.000000000 -0500
+@@ -460,7 +460,7 @@
+ and the destination is RTN_UNICAST (and not local), then create
+ a cache_bypass connection entry */
+ if (sysctl_ip_vs_cache_bypass && svc->fwmark
+- && (inet_addr_type(iph->daddr) == RTN_UNICAST)) {
++ && (inet_addr_type(&init_net, iph->daddr) == RTN_UNICAST)) {
+ int ret, cs;
+ struct ip_vs_conn *cp;
+
+@@ -530,6 +530,10 @@
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ if (!((*pskb)->ipvs_property))
+ return NF_ACCEPT;
+ /* The packet was sent from IPVS, exit this chain */
+@@ -734,6 +738,10 @@
+ struct ip_vs_conn *cp;
+ int ihl;
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ EnterFunction(11);
+
+ if (skb->ipvs_property)
+@@ -818,7 +826,7 @@
+ * if it came from this machine itself. So re-compute
+ * the routing information.
+ */
+- if (ip_route_me_harder(pskb, RTN_LOCAL) != 0)
++ if (ip_route_me_harder(&init_net, pskb, RTN_LOCAL) != 0)
+ goto drop;
+ skb = *pskb;
+
+@@ -956,12 +964,16 @@
+ int ret, restart;
+ int ihl;
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ /*
+ * Big tappo: only PACKET_HOST (neither loopback nor mcasts)
+ * ... don't know why 1st test DOES NOT include 2nd (?)
+ */
+ if (unlikely(skb->pkt_type != PACKET_HOST
+- || skb->dev == &loopback_dev || skb->sk)) {
++ || skb->dev == &init_net.loopback_dev || skb->sk)) {
+ IP_VS_DBG(12, "packet type=%d proto=%d daddr=%d.%d.%d.%d ignored\n",
+ skb->pkt_type,
+ ip_hdr(skb)->protocol,
+@@ -1062,6 +1074,10 @@
+ {
+ int r;
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ if (ip_hdr(*pskb)->protocol != IPPROTO_ICMP)
+ return NF_ACCEPT;
+
+diff -Nurb linux-2.6.22-570/net/ipv4/ipvs/ip_vs_ctl.c linux-2.6.22-590/net/ipv4/ipvs/ip_vs_ctl.c
+--- linux-2.6.22-570/net/ipv4/ipvs/ip_vs_ctl.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/ipvs/ip_vs_ctl.c 2008-01-29 22:12:32.000000000 -0500
+@@ -39,6 +39,7 @@
+ #include <net/ip.h>
+ #include <net/route.h>
+ #include <net/sock.h>
++#include <net/net_namespace.h>
+
+ #include <asm/uaccess.h>
+
+@@ -679,7 +680,7 @@
+ conn_flags = udest->conn_flags | IP_VS_CONN_F_INACTIVE;
+
+ /* check if local node and update the flags */
+- if (inet_addr_type(udest->addr) == RTN_LOCAL) {
++ if (inet_addr_type(&init_net, udest->addr) == RTN_LOCAL) {
+ conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK)
+ | IP_VS_CONN_F_LOCALNODE;
+ }
+@@ -731,7 +732,7 @@
+
+ EnterFunction(2);
+
+- atype = inet_addr_type(udest->addr);
++ atype = inet_addr_type(&init_net, udest->addr);
+ if (atype != RTN_LOCAL && atype != RTN_UNICAST)
+ return -EINVAL;
+
+@@ -1932,6 +1933,9 @@
+ struct ip_vs_service *svc;
+ struct ip_vs_dest_user *udest;
+
++ if (sk->sk_net != &init_net)
++ return -ENOPROTOOPT;
++
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+@@ -2196,6 +2200,9 @@
+ unsigned char arg[128];
+ int ret = 0;
+
++ if (sk->sk_net != &init_net)
++ return -ENOPROTOOPT;
++
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+@@ -2356,8 +2363,8 @@
+ return ret;
+ }
+
+- proc_net_fops_create("ip_vs", 0, &ip_vs_info_fops);
+- proc_net_fops_create("ip_vs_stats",0, &ip_vs_stats_fops);
++ proc_net_fops_create(&init_net, "ip_vs", 0, &ip_vs_info_fops);
++ proc_net_fops_create(&init_net, "ip_vs_stats",0, &ip_vs_stats_fops);
+
+ sysctl_header = register_sysctl_table(vs_root_table);
+
+@@ -2390,8 +2397,8 @@
+ cancel_work_sync(&defense_work.work);
+ ip_vs_kill_estimator(&ip_vs_stats);
+ unregister_sysctl_table(sysctl_header);
+- proc_net_remove("ip_vs_stats");
+- proc_net_remove("ip_vs");
++ proc_net_remove(&init_net, "ip_vs_stats");
++ proc_net_remove(&init_net, "ip_vs");
+ nf_unregister_sockopt(&ip_vs_sockopts);
+ LeaveFunction(2);
+ }
+diff -Nurb linux-2.6.22-570/net/ipv4/ipvs/ip_vs_lblcr.c linux-2.6.22-590/net/ipv4/ipvs/ip_vs_lblcr.c
+--- linux-2.6.22-570/net/ipv4/ipvs/ip_vs_lblcr.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/ipvs/ip_vs_lblcr.c 2008-01-29 22:12:32.000000000 -0500
+@@ -843,7 +843,7 @@
+ INIT_LIST_HEAD(&ip_vs_lblcr_scheduler.n_list);
+ sysctl_header = register_sysctl_table(lblcr_root_table);
+ #ifdef CONFIG_IP_VS_LBLCR_DEBUG
+- proc_net_create("ip_vs_lblcr", 0, ip_vs_lblcr_getinfo);
++ proc_net_create(&init_net, "ip_vs_lblcr", 0, ip_vs_lblcr_getinfo);
+ #endif
+ return register_ip_vs_scheduler(&ip_vs_lblcr_scheduler);
+ }
+@@ -852,7 +852,7 @@
+ static void __exit ip_vs_lblcr_cleanup(void)
+ {
+ #ifdef CONFIG_IP_VS_LBLCR_DEBUG
+- proc_net_remove("ip_vs_lblcr");
++ proc_net_remove(&init_net, "ip_vs_lblcr");
+ #endif
+ unregister_sysctl_table(sysctl_header);
+ unregister_ip_vs_scheduler(&ip_vs_lblcr_scheduler);
+diff -Nurb linux-2.6.22-570/net/ipv4/ipvs/ip_vs_sync.c linux-2.6.22-590/net/ipv4/ipvs/ip_vs_sync.c
+--- linux-2.6.22-570/net/ipv4/ipvs/ip_vs_sync.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/ipvs/ip_vs_sync.c 2008-01-29 22:12:32.000000000 -0500
+@@ -387,7 +387,7 @@
+ struct net_device *dev;
+ struct inet_sock *inet = inet_sk(sk);
+
+- if ((dev = __dev_get_by_name(ifname)) == NULL)
++ if ((dev = __dev_get_by_name(&init_net, ifname)) == NULL)
+ return -ENODEV;
+
+ if (sk->sk_bound_dev_if && dev->ifindex != sk->sk_bound_dev_if)
+@@ -412,7 +412,7 @@
+ int num;
+
+ if (sync_state == IP_VS_STATE_MASTER) {
+- if ((dev = __dev_get_by_name(ip_vs_master_mcast_ifn)) == NULL)
++ if ((dev = __dev_get_by_name(&init_net, ip_vs_master_mcast_ifn)) == NULL)
+ return -ENODEV;
+
+ num = (dev->mtu - sizeof(struct iphdr) -
+@@ -423,7 +423,7 @@
+ IP_VS_DBG(7, "setting the maximum length of sync sending "
+ "message %d.\n", sync_send_mesg_maxlen);
+ } else if (sync_state == IP_VS_STATE_BACKUP) {
+- if ((dev = __dev_get_by_name(ip_vs_backup_mcast_ifn)) == NULL)
++ if ((dev = __dev_get_by_name(&init_net, ip_vs_backup_mcast_ifn)) == NULL)
+ return -ENODEV;
+
+ sync_recv_mesg_maxlen = dev->mtu -
+@@ -451,7 +451,7 @@
+ memset(&mreq, 0, sizeof(mreq));
+ memcpy(&mreq.imr_multiaddr, addr, sizeof(struct in_addr));
+
+- if ((dev = __dev_get_by_name(ifname)) == NULL)
++ if ((dev = __dev_get_by_name(&init_net, ifname)) == NULL)
+ return -ENODEV;
+ if (sk->sk_bound_dev_if && dev->ifindex != sk->sk_bound_dev_if)
+ return -EINVAL;
+@@ -472,7 +472,7 @@
+ __be32 addr;
+ struct sockaddr_in sin;
+
+- if ((dev = __dev_get_by_name(ifname)) == NULL)
++ if ((dev = __dev_get_by_name(&init_net, ifname)) == NULL)
+ return -ENODEV;
+
+ addr = inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE);
+diff -Nurb linux-2.6.22-570/net/ipv4/ipvs/ip_vs_xmit.c linux-2.6.22-590/net/ipv4/ipvs/ip_vs_xmit.c
+--- linux-2.6.22-570/net/ipv4/ipvs/ip_vs_xmit.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/ipvs/ip_vs_xmit.c 2008-01-29 22:12:32.000000000 -0500
+@@ -70,6 +70,7 @@
+ if (!(rt = (struct rtable *)
+ __ip_vs_dst_check(dest, rtos, 0))) {
+ struct flowi fl = {
++ .fl_net = &init_net,
+ .oif = 0,
+ .nl_u = {
+ .ip4_u = {
+@@ -93,6 +94,7 @@
+ spin_unlock(&dest->dst_lock);
+ } else {
+ struct flowi fl = {
++ .fl_net = &init_net,
+ .oif = 0,
+ .nl_u = {
+ .ip4_u = {
+@@ -160,6 +162,7 @@
+ u8 tos = iph->tos;
+ int mtu;
+ struct flowi fl = {
++ .fl_net = &init_net,
+ .oif = 0,
+ .nl_u = {
+ .ip4_u = {
diff -Nurb linux-2.6.22-570/net/ipv4/multipath.c linux-2.6.22-590/net/ipv4/multipath.c
--- linux-2.6.22-570/net/ipv4/multipath.c 2007-07-08 19:32:17.000000000 -0400
+++ linux-2.6.22-590/net/ipv4/multipath.c 1969-12-31 19:00:00.000000000 -0500
-module_init(wrandom_init);
-module_exit(wrandom_exit);
-MODULE_LICENSE("GPL");
-diff -Nurb linux-2.6.22-570/net/ipv4/netfilter/nf_nat_helper.c linux-2.6.22-590/net/ipv4/netfilter/nf_nat_helper.c
---- linux-2.6.22-570/net/ipv4/netfilter/nf_nat_helper.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/ipv4/netfilter/nf_nat_helper.c 2008-03-15 10:35:47.000000000 -0400
-@@ -178,7 +178,7 @@
- datalen = (*pskb)->len - iph->ihl*4;
- if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
- if (!(rt->rt_flags & RTCF_LOCAL) &&
-- (*pskb)->dev->features & NETIF_F_ALL_CSUM) {
-+ (*pskb)->dev->features & NETIF_F_V4_CSUM) {
- (*pskb)->ip_summed = CHECKSUM_PARTIAL;
- (*pskb)->csum_start = skb_headroom(*pskb) +
- skb_network_offset(*pskb) +
-@@ -265,7 +265,7 @@
+diff -Nurb linux-2.6.22-570/net/ipv4/netfilter/arp_tables.c linux-2.6.22-590/net/ipv4/netfilter/arp_tables.c
+--- linux-2.6.22-570/net/ipv4/netfilter/arp_tables.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/netfilter/arp_tables.c 2008-01-29 22:12:32.000000000 -0500
+@@ -19,6 +19,7 @@
+ #include <linux/proc_fs.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
++#include <net/sock.h>
- if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
- if (!(rt->rt_flags & RTCF_LOCAL) &&
-- (*pskb)->dev->features & NETIF_F_ALL_CSUM) {
-+ (*pskb)->dev->features & NETIF_F_V4_CSUM) {
- (*pskb)->ip_summed = CHECKSUM_PARTIAL;
- (*pskb)->csum_start = skb_headroom(*pskb) +
- skb_network_offset(*pskb) +
-diff -Nurb linux-2.6.22-570/net/ipv4/route.c linux-2.6.22-590/net/ipv4/route.c
---- linux-2.6.22-570/net/ipv4/route.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/ipv4/route.c 2008-03-15 10:35:47.000000000 -0400
-@@ -101,7 +101,6 @@
- #include <net/tcp.h>
- #include <net/icmp.h>
- #include <net/xfrm.h>
--#include <net/ip_mp_alg.h>
- #include <net/netevent.h>
- #include <net/rtnetlink.h>
- #ifdef CONFIG_SYSCTL
-@@ -495,13 +494,11 @@
+ #include <asm/uaccess.h>
+ #include <linux/mutex.h>
+@@ -773,7 +774,7 @@
+ int ret;
+ struct arpt_table *t;
- static __inline__ void rt_free(struct rtable *rt)
+- t = xt_find_table_lock(NF_ARP, entries->name);
++ t = xt_find_table_lock(&init_net, NF_ARP, entries->name);
+ if (t && !IS_ERR(t)) {
+ struct xt_table_info *private = t->private;
+ duprintf("t->private->number = %u\n",
+@@ -843,7 +844,7 @@
+
+ duprintf("arp_tables: Translated table\n");
+
+- t = try_then_request_module(xt_find_table_lock(NF_ARP, tmp.name),
++ t = try_then_request_module(xt_find_table_lock(&init_net, NF_ARP, tmp.name),
+ "arptable_%s", tmp.name);
+ if (!t || IS_ERR(t)) {
+ ret = t ? PTR_ERR(t) : -ENOENT;
+@@ -936,7 +937,7 @@
+ goto free;
+ }
+
+- t = xt_find_table_lock(NF_ARP, tmp.name);
++ t = xt_find_table_lock(&init_net, NF_ARP, tmp.name);
+ if (!t || IS_ERR(t)) {
+ ret = t ? PTR_ERR(t) : -ENOENT;
+ goto free;
+@@ -971,6 +972,9 @@
{
-- multipath_remove(rt);
- call_rcu_bh(&rt->u.dst.rcu_head, dst_rcu_free);
- }
+ int ret;
- static __inline__ void rt_drop(struct rtable *rt)
++ if (sk->sk_net != &init_net)
++ return -ENOPROTOOPT;
++
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+@@ -995,6 +999,9 @@
{
-- multipath_remove(rt);
- ip_rt_put(rt);
- call_rcu_bh(&rt->u.dst.rcu_head, dst_rcu_free);
- }
-@@ -574,52 +571,6 @@
- (fl1->iif ^ fl2->iif)) == 0;
+ int ret;
+
++ if (sk->sk_net != &init_net)
++ return -ENOPROTOOPT;
++
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+@@ -1016,7 +1023,7 @@
+ }
+ name[ARPT_TABLE_MAXNAMELEN-1] = '\0';
+
+- t = try_then_request_module(xt_find_table_lock(NF_ARP, name),
++ t = try_then_request_module(xt_find_table_lock(&init_net, NF_ARP, name),
+ "arptable_%s", name);
+ if (t && !IS_ERR(t)) {
+ struct arpt_getinfo info;
+@@ -1116,7 +1123,7 @@
+ return ret;
+ }
+
+- ret = xt_register_table(table, &bootstrap, newinfo);
++ ret = xt_register_table(&init_net, table, &bootstrap, newinfo);
+ if (ret != 0) {
+ xt_free_table_info(newinfo);
+ return ret;
+diff -Nurb linux-2.6.22-570/net/ipv4/netfilter/arptable_filter.c linux-2.6.22-590/net/ipv4/netfilter/arptable_filter.c
+--- linux-2.6.22-570/net/ipv4/netfilter/arptable_filter.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/netfilter/arptable_filter.c 2008-01-29 22:12:32.000000000 -0500
+@@ -61,6 +61,10 @@
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ return arpt_do_table(pskb, hook, in, out, &packet_filter);
+ }
+
+diff -Nurb linux-2.6.22-570/net/ipv4/netfilter/ip_queue.c linux-2.6.22-590/net/ipv4/netfilter/ip_queue.c
+--- linux-2.6.22-570/net/ipv4/netfilter/ip_queue.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/netfilter/ip_queue.c 2008-01-29 22:12:32.000000000 -0500
+@@ -26,6 +26,7 @@
+ #include <linux/mutex.h>
+ #include <net/sock.h>
+ #include <net/route.h>
++#include <net/net_namespace.h>
+
+ #define IPQ_QMAX_DEFAULT 1024
+ #define IPQ_PROC_FS_NAME "ip_queue"
+@@ -556,6 +557,9 @@
+ {
+ struct net_device *dev = ptr;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ /* Drop any packets associated with the downed device */
+ if (event == NETDEV_DOWN)
+ ipq_dev_drop(dev->ifindex);
+@@ -575,7 +579,7 @@
+ if (event == NETLINK_URELEASE &&
+ n->protocol == NETLINK_FIREWALL && n->pid) {
+ write_lock_bh(&queue_lock);
+- if (n->pid == peer_pid)
++ if ((n->net == &init_net) && (n->pid == peer_pid))
+ __ipq_reset();
+ write_unlock_bh(&queue_lock);
+ }
+@@ -667,14 +671,14 @@
+ struct proc_dir_entry *proc;
+
+ netlink_register_notifier(&ipq_nl_notifier);
+- ipqnl = netlink_kernel_create(NETLINK_FIREWALL, 0, ipq_rcv_sk,
+- NULL, THIS_MODULE);
++ ipqnl = netlink_kernel_create(&init_net, NETLINK_FIREWALL, 0,
++ ipq_rcv_sk, NULL, THIS_MODULE);
+ if (ipqnl == NULL) {
+ printk(KERN_ERR "ip_queue: failed to create netlink socket\n");
+ goto cleanup_netlink_notifier;
+ }
+
+- proc = proc_net_create(IPQ_PROC_FS_NAME, 0, ipq_get_info);
++ proc = proc_net_create(&init_net, IPQ_PROC_FS_NAME, 0, ipq_get_info);
+ if (proc)
+ proc->owner = THIS_MODULE;
+ else {
+@@ -695,8 +699,7 @@
+ cleanup_sysctl:
+ unregister_sysctl_table(ipq_sysctl_header);
+ unregister_netdevice_notifier(&ipq_dev_notifier);
+- proc_net_remove(IPQ_PROC_FS_NAME);
+-
++ proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
+ cleanup_ipqnl:
+ sock_release(ipqnl->sk_socket);
+ mutex_lock(&ipqnl_mutex);
+@@ -715,7 +718,7 @@
+
+ unregister_sysctl_table(ipq_sysctl_header);
+ unregister_netdevice_notifier(&ipq_dev_notifier);
+- proc_net_remove(IPQ_PROC_FS_NAME);
++ proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
+
+ sock_release(ipqnl->sk_socket);
+ mutex_lock(&ipqnl_mutex);
+diff -Nurb linux-2.6.22-570/net/ipv4/netfilter/ip_tables.c linux-2.6.22-590/net/ipv4/netfilter/ip_tables.c
+--- linux-2.6.22-570/net/ipv4/netfilter/ip_tables.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/netfilter/ip_tables.c 2008-01-29 22:12:32.000000000 -0500
+@@ -1039,7 +1039,7 @@
+ }
+ #endif
+
+-static int get_info(void __user *user, int *len, int compat)
++static int get_info(struct net *net, void __user *user, int *len, int compat)
+ {
+ char name[IPT_TABLE_MAXNAMELEN];
+ struct xt_table *t;
+@@ -1059,7 +1059,7 @@
+ if (compat)
+ xt_compat_lock(AF_INET);
+ #endif
+- t = try_then_request_module(xt_find_table_lock(AF_INET, name),
++ t = try_then_request_module(xt_find_table_lock(net, AF_INET, name),
+ "iptable_%s", name);
+ if (t && !IS_ERR(t)) {
+ struct ipt_getinfo info;
+@@ -1099,7 +1099,7 @@
+ }
+
+ static int
+-get_entries(struct ipt_get_entries __user *uptr, int *len)
++get_entries(struct net *net, struct ipt_get_entries __user *uptr, int *len)
+ {
+ int ret;
+ struct ipt_get_entries get;
+@@ -1119,7 +1119,7 @@
+ return -EINVAL;
+ }
+
+- t = xt_find_table_lock(AF_INET, get.name);
++ t = xt_find_table_lock(net, AF_INET, get.name);
+ if (t && !IS_ERR(t)) {
+ struct xt_table_info *private = t->private;
+ duprintf("t->private->number = %u\n",
+@@ -1142,7 +1142,7 @@
+ }
+
+ static int
+-__do_replace(const char *name, unsigned int valid_hooks,
++__do_replace(struct net *net, const char *name, unsigned int valid_hooks,
+ struct xt_table_info *newinfo, unsigned int num_counters,
+ void __user *counters_ptr)
+ {
+@@ -1159,7 +1159,7 @@
+ goto out;
+ }
+
+- t = try_then_request_module(xt_find_table_lock(AF_INET, name),
++ t = try_then_request_module(xt_find_table_lock(net, AF_INET, name),
+ "iptable_%s", name);
+ if (!t || IS_ERR(t)) {
+ ret = t ? PTR_ERR(t) : -ENOENT;
+@@ -1211,7 +1211,7 @@
+ }
+
+ static int
+-do_replace(void __user *user, unsigned int len)
++do_replace(struct net *net, void __user *user, unsigned int len)
+ {
+ int ret;
+ struct ipt_replace tmp;
+@@ -1252,7 +1252,7 @@
+
+ duprintf("ip_tables: Translated table\n");
+
+- ret = __do_replace(tmp.name, tmp.valid_hooks,
++ ret = __do_replace(net, tmp.name, tmp.valid_hooks,
+ newinfo, tmp.num_counters,
+ tmp.counters);
+ if (ret)
+@@ -1289,7 +1289,7 @@
+ }
+
+ static int
+-do_add_counters(void __user *user, unsigned int len, int compat)
++do_add_counters(struct net *net, void __user *user, unsigned int len, int compat)
+ {
+ unsigned int i;
+ struct xt_counters_info tmp;
+@@ -1341,7 +1341,7 @@
+ goto free;
+ }
+
+- t = xt_find_table_lock(AF_INET, name);
++ t = xt_find_table_lock(net, AF_INET, name);
+ if (!t || IS_ERR(t)) {
+ ret = t ? PTR_ERR(t) : -ENOENT;
+ goto free;
+@@ -1745,7 +1745,7 @@
+ }
+
+ static int
+-compat_do_replace(void __user *user, unsigned int len)
++compat_do_replace(struct net *net, void __user *user, unsigned int len)
+ {
+ int ret;
+ struct compat_ipt_replace tmp;
+@@ -1786,7 +1786,7 @@
+
+ duprintf("compat_do_replace: Translated table\n");
+
+- ret = __do_replace(tmp.name, tmp.valid_hooks,
++ ret = __do_replace(net, tmp.name, tmp.valid_hooks,
+ newinfo, tmp.num_counters,
+ compat_ptr(tmp.counters));
+ if (ret)
+@@ -1811,11 +1811,11 @@
+
+ switch (cmd) {
+ case IPT_SO_SET_REPLACE:
+- ret = compat_do_replace(user, len);
++ ret = compat_do_replace(sk->sk_net, user, len);
+ break;
+
+ case IPT_SO_SET_ADD_COUNTERS:
+- ret = do_add_counters(user, len, 1);
++ ret = do_add_counters(sk->sk_net, user, len, 1);
+ break;
+
+ default:
+@@ -1904,7 +1904,7 @@
+ }
+
+ static int
+-compat_get_entries(struct compat_ipt_get_entries __user *uptr, int *len)
++compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr, int *len)
+ {
+ int ret;
+ struct compat_ipt_get_entries get;
+@@ -1928,7 +1928,7 @@
+ }
+
+ xt_compat_lock(AF_INET);
+- t = xt_find_table_lock(AF_INET, get.name);
++ t = xt_find_table_lock(net, AF_INET, get.name);
+ if (t && !IS_ERR(t)) {
+ struct xt_table_info *private = t->private;
+ struct xt_table_info info;
+@@ -1966,10 +1966,10 @@
+
+ switch (cmd) {
+ case IPT_SO_GET_INFO:
+- ret = get_info(user, len, 1);
++ ret = get_info(sk->sk_net, user, len, 1);
+ break;
+ case IPT_SO_GET_ENTRIES:
+- ret = compat_get_entries(user, len);
++ ret = compat_get_entries(sk->sk_net, user, len);
+ break;
+ default:
+ ret = do_ipt_get_ctl(sk, cmd, user, len);
+@@ -1988,11 +1988,11 @@
+
+ switch (cmd) {
+ case IPT_SO_SET_REPLACE:
+- ret = do_replace(user, len);
++ ret = do_replace(sk->sk_net, user, len);
+ break;
+
+ case IPT_SO_SET_ADD_COUNTERS:
+- ret = do_add_counters(user, len, 0);
++ ret = do_add_counters(sk->sk_net, user, len, 0);
+ break;
+
+ default:
+@@ -2013,11 +2013,11 @@
+
+ switch (cmd) {
+ case IPT_SO_GET_INFO:
+- ret = get_info(user, len, 0);
++ ret = get_info(sk->sk_net, user, len, 0);
+ break;
+
+ case IPT_SO_GET_ENTRIES:
+- ret = get_entries(user, len);
++ ret = get_entries(sk->sk_net, user, len);
+ break;
+
+ case IPT_SO_GET_REVISION_MATCH:
+@@ -2054,7 +2054,7 @@
+ return ret;
+ }
+
+-int ipt_register_table(struct xt_table *table, const struct ipt_replace *repl)
++int ipt_register_table(struct net *net, struct xt_table *table, const struct ipt_replace *repl)
+ {
+ int ret;
+ struct xt_table_info *newinfo;
+@@ -2082,7 +2082,7 @@
+ return ret;
+ }
+
+- ret = xt_register_table(table, &bootstrap, newinfo);
++ ret = xt_register_table(net, table, &bootstrap, newinfo);
+ if (ret != 0) {
+ xt_free_table_info(newinfo);
+ return ret;
+diff -Nurb linux-2.6.22-570/net/ipv4/netfilter/ipt_CLUSTERIP.c linux-2.6.22-590/net/ipv4/netfilter/ipt_CLUSTERIP.c
+--- linux-2.6.22-570/net/ipv4/netfilter/ipt_CLUSTERIP.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/netfilter/ipt_CLUSTERIP.c 2008-01-29 22:12:32.000000000 -0500
+@@ -27,6 +27,7 @@
+ #include <linux/netfilter_ipv4/ipt_CLUSTERIP.h>
+ #include <net/netfilter/nf_conntrack.h>
+ #include <net/checksum.h>
++#include <net/net_namespace.h>
+
+ #define CLUSTERIP_VERSION "0.8"
+
+@@ -427,7 +428,7 @@
+ return 0;
+ }
+
+- dev = dev_get_by_name(e->ip.iniface);
++ dev = dev_get_by_name(&init_net, e->ip.iniface);
+ if (!dev) {
+ printk(KERN_WARNING "CLUSTERIP: no such interface %s\n", e->ip.iniface);
+ return 0;
+@@ -523,6 +524,10 @@
+ struct arp_payload *payload;
+ struct clusterip_config *c;
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ /* we don't care about non-ethernet and non-ipv4 ARP */
+ if (arp->ar_hrd != htons(ARPHRD_ETHER)
+ || arp->ar_pro != htons(ETH_P_IP)
+@@ -735,7 +740,7 @@
+ goto cleanup_target;
+
+ #ifdef CONFIG_PROC_FS
+- clusterip_procdir = proc_mkdir("ipt_CLUSTERIP", proc_net);
++ clusterip_procdir = proc_mkdir("ipt_CLUSTERIP", init_net.proc_net);
+ if (!clusterip_procdir) {
+ printk(KERN_ERR "CLUSTERIP: Unable to proc dir entry\n");
+ ret = -ENOMEM;
+diff -Nurb linux-2.6.22-570/net/ipv4/netfilter/ipt_MASQUERADE.c linux-2.6.22-590/net/ipv4/netfilter/ipt_MASQUERADE.c
+--- linux-2.6.22-570/net/ipv4/netfilter/ipt_MASQUERADE.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/netfilter/ipt_MASQUERADE.c 2008-01-29 22:12:32.000000000 -0500
+@@ -131,6 +131,9 @@
+ {
+ struct net_device *dev = ptr;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ if (event == NETDEV_DOWN) {
+ /* Device was downed. Search entire table for
+ conntracks which were associated with that device,
+diff -Nurb linux-2.6.22-570/net/ipv4/netfilter/ipt_REJECT.c linux-2.6.22-590/net/ipv4/netfilter/ipt_REJECT.c
+--- linux-2.6.22-570/net/ipv4/netfilter/ipt_REJECT.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/netfilter/ipt_REJECT.c 2008-01-29 22:12:32.000000000 -0500
+@@ -137,7 +137,7 @@
+ )
+ addr_type = RTN_LOCAL;
+
+- if (ip_route_me_harder(&nskb, addr_type))
++ if (ip_route_me_harder(&init_net, &nskb, addr_type))
+ goto free_nskb;
+
+ nskb->ip_summed = CHECKSUM_NONE;
+diff -Nurb linux-2.6.22-570/net/ipv4/netfilter/ipt_ULOG.c linux-2.6.22-590/net/ipv4/netfilter/ipt_ULOG.c
+--- linux-2.6.22-570/net/ipv4/netfilter/ipt_ULOG.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/netfilter/ipt_ULOG.c 2008-01-29 22:12:32.000000000 -0500
+@@ -419,7 +419,8 @@
+ for (i = 0; i < ULOG_MAXNLGROUPS; i++)
+ setup_timer(&ulog_buffers[i].timer, ulog_timer, i);
+
+- nflognl = netlink_kernel_create(NETLINK_NFLOG, ULOG_MAXNLGROUPS, NULL,
++ nflognl = netlink_kernel_create(&init_net,
++ NETLINK_NFLOG, ULOG_MAXNLGROUPS, NULL,
+ NULL, THIS_MODULE);
+ if (!nflognl)
+ return -ENOMEM;
+diff -Nurb linux-2.6.22-570/net/ipv4/netfilter/ipt_addrtype.c linux-2.6.22-590/net/ipv4/netfilter/ipt_addrtype.c
+--- linux-2.6.22-570/net/ipv4/netfilter/ipt_addrtype.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/netfilter/ipt_addrtype.c 2008-01-29 22:12:32.000000000 -0500
+@@ -24,7 +24,7 @@
+
+ static inline int match_type(__be32 addr, u_int16_t mask)
+ {
+- return !!(mask & (1 << inet_addr_type(addr)));
++ return !!(mask & (1 << inet_addr_type(&init_net, addr)));
+ }
+
+ static int match(const struct sk_buff *skb,
+diff -Nurb linux-2.6.22-570/net/ipv4/netfilter/ipt_recent.c linux-2.6.22-590/net/ipv4/netfilter/ipt_recent.c
+--- linux-2.6.22-570/net/ipv4/netfilter/ipt_recent.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/netfilter/ipt_recent.c 2008-01-29 22:12:32.000000000 -0500
+@@ -24,6 +24,7 @@
+ #include <linux/bitops.h>
+ #include <linux/skbuff.h>
+ #include <linux/inet.h>
++#include <net/net_namespace.h>
+
+ #include <linux/netfilter/x_tables.h>
+ #include <linux/netfilter_ipv4/ipt_recent.h>
+@@ -485,7 +486,7 @@
+ #ifdef CONFIG_PROC_FS
+ if (err)
+ return err;
+- proc_dir = proc_mkdir("ipt_recent", proc_net);
++ proc_dir = proc_mkdir("ipt_recent", init_net.proc_net);
+ if (proc_dir == NULL) {
+ xt_unregister_match(&recent_match);
+ err = -ENOMEM;
+@@ -499,7 +500,7 @@
+ BUG_ON(!list_empty(&tables));
+ xt_unregister_match(&recent_match);
+ #ifdef CONFIG_PROC_FS
+- remove_proc_entry("ipt_recent", proc_net);
++ remove_proc_entry("ipt_recent", init_net.proc_net);
+ #endif
+ }
+
+diff -Nurb linux-2.6.22-570/net/ipv4/netfilter/iptable_filter.c linux-2.6.22-590/net/ipv4/netfilter/iptable_filter.c
+--- linux-2.6.22-570/net/ipv4/netfilter/iptable_filter.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/netfilter/iptable_filter.c 2008-01-29 22:12:32.000000000 -0500
+@@ -26,7 +26,7 @@
+ struct ipt_replace repl;
+ struct ipt_standard entries[3];
+ struct ipt_error term;
+-} initial_table __initdata = {
++} initial_table = {
+ .repl = {
+ .name = "filter",
+ .valid_hooks = FILTER_VALID_HOOKS,
+@@ -51,7 +51,7 @@
+ .term = IPT_ERROR_INIT, /* ERROR */
+ };
+
+-static struct xt_table packet_filter = {
++static struct xt_table ip_packet_filter_dflt = {
+ .name = "filter",
+ .valid_hooks = FILTER_VALID_HOOKS,
+ .lock = RW_LOCK_UNLOCKED,
+@@ -67,7 +67,9 @@
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
+- return ipt_do_table(pskb, hook, in, out, &packet_filter);
++ struct net *net = (in?in:out)->nd_net;
++
++ return ipt_do_table(pskb, hook, in, out, net->ip_packet_filter);
+ }
+
+ static unsigned int
+@@ -77,6 +79,8 @@
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++ struct net *net = (in?in:out)->nd_net;
++
+ /* root is playing with raw sockets. */
+ if ((*pskb)->len < sizeof(struct iphdr)
+ || ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
+@@ -86,7 +90,7 @@
+ return NF_ACCEPT;
+ }
+
+- return ipt_do_table(pskb, hook, in, out, &packet_filter);
++ return ipt_do_table(pskb, hook, in, out, net->ip_packet_filter);
+ }
+
+ static struct nf_hook_ops ipt_ops[] = {
+@@ -117,6 +121,30 @@
+ static int forward = NF_ACCEPT;
+ module_param(forward, bool, 0000);
+
++static int iptable_filter_net_init(struct net *net)
++{
++ /* Allocate the table */
++ net->ip_packet_filter = kmemdup(&ip_packet_filter_dflt,
++ sizeof(*net->ip_packet_filter),
++ GFP_KERNEL);
++ if (!net->ip_packet_filter)
++ return -ENOMEM;
++
++ /* Register table */
++ return ipt_register_table(net, net->ip_packet_filter, &initial_table.repl);
++}
++
++static void iptable_filter_net_exit(struct net *net)
++{
++ ipt_unregister_table(net->ip_packet_filter);
++ kfree(net->ip_packet_filter);
++}
++
++static struct pernet_operations iptable_filter_net_ops = {
++ .init = iptable_filter_net_init,
++ .exit = iptable_filter_net_exit,
++};
++
+ static int __init iptable_filter_init(void)
+ {
+ int ret;
+@@ -130,7 +158,7 @@
+ initial_table.entries[1].target.verdict = -forward - 1;
+
+ /* Register table */
+- ret = ipt_register_table(&packet_filter, &initial_table.repl);
++ ret = register_pernet_subsys(&iptable_filter_net_ops);
+ if (ret < 0)
+ return ret;
+
+@@ -142,14 +170,14 @@
+ return ret;
+
+ cleanup_table:
+- ipt_unregister_table(&packet_filter);
++ unregister_pernet_subsys(&iptable_filter_net_ops);
+ return ret;
+ }
+
+ static void __exit iptable_filter_fini(void)
+ {
+ nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops));
+- ipt_unregister_table(&packet_filter);
++ unregister_pernet_subsys(&iptable_filter_net_ops);
+ }
+
+ module_init(iptable_filter_init);
+diff -Nurb linux-2.6.22-570/net/ipv4/netfilter/iptable_mangle.c linux-2.6.22-590/net/ipv4/netfilter/iptable_mangle.c
+--- linux-2.6.22-570/net/ipv4/netfilter/iptable_mangle.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/netfilter/iptable_mangle.c 2008-01-29 22:12:32.000000000 -0500
+@@ -80,6 +80,10 @@
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ return ipt_do_table(pskb, hook, in, out, &packet_mangler);
+ }
+
+@@ -96,6 +100,10 @@
+ __be32 saddr, daddr;
+ u_int32_t mark;
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ /* root is playing with raw sockets. */
+ if ((*pskb)->len < sizeof(struct iphdr)
+ || ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
+@@ -121,7 +129,7 @@
+ iph->daddr != daddr ||
+ (*pskb)->mark != mark ||
+ iph->tos != tos)
+- if (ip_route_me_harder(pskb, RTN_UNSPEC))
++ if (ip_route_me_harder(&init_net, pskb, RTN_UNSPEC))
+ ret = NF_DROP;
+ }
+
+@@ -171,7 +179,7 @@
+ int ret;
+
+ /* Register table */
+- ret = ipt_register_table(&packet_mangler, &initial_table.repl);
++ ret = ipt_register_table(&init_net, &packet_mangler, &initial_table.repl);
+ if (ret < 0)
+ return ret;
+
+diff -Nurb linux-2.6.22-570/net/ipv4/netfilter/iptable_raw.c linux-2.6.22-590/net/ipv4/netfilter/iptable_raw.c
+--- linux-2.6.22-570/net/ipv4/netfilter/iptable_raw.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/netfilter/iptable_raw.c 2008-01-29 22:12:32.000000000 -0500
+@@ -52,6 +52,10 @@
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ return ipt_do_table(pskb, hook, in, out, &packet_raw);
+ }
+
+@@ -96,7 +100,7 @@
+ int ret;
+
+ /* Register table */
+- ret = ipt_register_table(&packet_raw, &initial_table.repl);
++ ret = ipt_register_table(&init_net, &packet_raw, &initial_table.repl);
+ if (ret < 0)
+ return ret;
+
+diff -Nurb linux-2.6.22-570/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c linux-2.6.22-590/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+--- linux-2.6.22-570/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c 2008-01-29 22:12:32.000000000 -0500
+@@ -120,6 +120,10 @@
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ /* We've seen it coming out the other side: confirm it */
+ return nf_conntrack_confirm(pskb);
+ }
+@@ -135,6 +139,10 @@
+ struct nf_conn_help *help;
+ struct nf_conntrack_helper *helper;
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ /* This is where we call the helper: as the packet goes out. */
+ ct = nf_ct_get(*pskb, &ctinfo);
+ if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)
+@@ -157,6 +165,10 @@
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ /* Previously seen (loopback)? Ignore. Do this before
+ fragment check. */
+ if ((*pskb)->nfct)
+@@ -180,6 +192,10 @@
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ return nf_conntrack_in(PF_INET, hooknum, pskb);
+ }
+
+@@ -189,6 +205,10 @@
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ /* root is playing with raw sockets. */
+ if ((*pskb)->len < sizeof(struct iphdr)
+ || ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
+@@ -325,6 +345,9 @@
+ struct nf_conntrack_tuple_hash *h;
+ struct nf_conntrack_tuple tuple;
+
++ if (sk->sk_net != &init_net)
++ return -ENOPROTOOPT;
++
+ NF_CT_TUPLE_U_BLANK(&tuple);
+ tuple.src.u3.ip = inet->rcv_saddr;
+ tuple.src.u.tcp.port = inet->sport;
+diff -Nurb linux-2.6.22-570/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c linux-2.6.22-590/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+--- linux-2.6.22-570/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c 2008-01-29 22:12:32.000000000 -0500
+@@ -11,6 +11,7 @@
+ #include <linux/proc_fs.h>
+ #include <linux/seq_file.h>
+ #include <linux/percpu.h>
++#include <net/net_namespace.h>
+
+ #include <linux/netfilter.h>
+ #include <net/netfilter/nf_conntrack_core.h>
+@@ -378,16 +379,16 @@
+ {
+ struct proc_dir_entry *proc, *proc_exp, *proc_stat;
+
+- proc = proc_net_fops_create("ip_conntrack", 0440, &ct_file_ops);
++ proc = proc_net_fops_create(&init_net, "ip_conntrack", 0440, &ct_file_ops);
+ if (!proc)
+ goto err1;
+
+- proc_exp = proc_net_fops_create("ip_conntrack_expect", 0440,
++ proc_exp = proc_net_fops_create(&init_net, "ip_conntrack_expect", 0440,
+ &ip_exp_file_ops);
+ if (!proc_exp)
+ goto err2;
+
+- proc_stat = create_proc_entry("ip_conntrack", S_IRUGO, proc_net_stat);
++ proc_stat = create_proc_entry("ip_conntrack", S_IRUGO, init_net.proc_net_stat);
+ if (!proc_stat)
+ goto err3;
+
+@@ -397,16 +398,16 @@
+ return 0;
+
+ err3:
+- proc_net_remove("ip_conntrack_expect");
++ proc_net_remove(&init_net, "ip_conntrack_expect");
+ err2:
+- proc_net_remove("ip_conntrack");
++ proc_net_remove(&init_net, "ip_conntrack");
+ err1:
+ return -ENOMEM;
+ }
+
+ void __exit nf_conntrack_ipv4_compat_fini(void)
+ {
+- remove_proc_entry("ip_conntrack", proc_net_stat);
+- proc_net_remove("ip_conntrack_expect");
+- proc_net_remove("ip_conntrack");
++ remove_proc_entry("ip_conntrack", init_net.proc_net_stat);
++ proc_net_remove(&init_net, "ip_conntrack_expect");
++ proc_net_remove(&init_net, "ip_conntrack");
+ }
+diff -Nurb linux-2.6.22-570/net/ipv4/netfilter/nf_nat_helper.c linux-2.6.22-590/net/ipv4/netfilter/nf_nat_helper.c
+--- linux-2.6.22-570/net/ipv4/netfilter/nf_nat_helper.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/netfilter/nf_nat_helper.c 2008-01-29 22:12:32.000000000 -0500
+@@ -178,7 +178,7 @@
+ datalen = (*pskb)->len - iph->ihl*4;
+ if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
+ if (!(rt->rt_flags & RTCF_LOCAL) &&
+- (*pskb)->dev->features & NETIF_F_ALL_CSUM) {
++ (*pskb)->dev->features & NETIF_F_V4_CSUM) {
+ (*pskb)->ip_summed = CHECKSUM_PARTIAL;
+ (*pskb)->csum_start = skb_headroom(*pskb) +
+ skb_network_offset(*pskb) +
+@@ -265,7 +265,7 @@
+
+ if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
+ if (!(rt->rt_flags & RTCF_LOCAL) &&
+- (*pskb)->dev->features & NETIF_F_ALL_CSUM) {
++ (*pskb)->dev->features & NETIF_F_V4_CSUM) {
+ (*pskb)->ip_summed = CHECKSUM_PARTIAL;
+ (*pskb)->csum_start = skb_headroom(*pskb) +
+ skb_network_offset(*pskb) +
+diff -Nurb linux-2.6.22-570/net/ipv4/netfilter/nf_nat_rule.c linux-2.6.22-590/net/ipv4/netfilter/nf_nat_rule.c
+--- linux-2.6.22-570/net/ipv4/netfilter/nf_nat_rule.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/netfilter/nf_nat_rule.c 2008-01-29 22:12:32.000000000 -0500
+@@ -98,7 +98,10 @@
+ static void warn_if_extra_mangle(__be32 dstip, __be32 srcip)
+ {
+ static int warned = 0;
+- struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } };
++ struct flowi fl = {
++ .fl_net = &init_net,
++ .nl_u = { .ip4_u = { .daddr = dstip } }
++ };
+ struct rtable *rt;
+
+ if (ip_route_output_key(&rt, &fl) != 0)
+@@ -252,7 +255,7 @@
+ {
+ int ret;
+
+- ret = ipt_register_table(&nat_table, &nat_initial_table.repl);
++ ret = ipt_register_table(&init_net, &nat_table, &nat_initial_table.repl);
+ if (ret != 0)
+ return ret;
+ ret = xt_register_target(&ipt_snat_reg);
+diff -Nurb linux-2.6.22-570/net/ipv4/netfilter/nf_nat_standalone.c linux-2.6.22-590/net/ipv4/netfilter/nf_nat_standalone.c
+--- linux-2.6.22-570/net/ipv4/netfilter/nf_nat_standalone.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/netfilter/nf_nat_standalone.c 2008-01-29 22:12:32.000000000 -0500
+@@ -83,6 +83,10 @@
+ /* maniptype == SRC for postrouting. */
+ enum nf_nat_manip_type maniptype = HOOK2MANIP(hooknum);
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ /* We never see fragments: conntrack defrags on pre-routing
+ and local-out, and nf_nat_out protects post-routing. */
+ NF_CT_ASSERT(!(ip_hdr(*pskb)->frag_off & htons(IP_MF | IP_OFFSET)));
+@@ -172,6 +176,10 @@
+ unsigned int ret;
+ __be32 daddr = ip_hdr(*pskb)->daddr;
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ ret = nf_nat_fn(hooknum, pskb, in, out, okfn);
+ if (ret != NF_DROP && ret != NF_STOLEN &&
+ daddr != ip_hdr(*pskb)->daddr) {
+@@ -194,6 +202,10 @@
+ #endif
+ unsigned int ret;
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ /* root is playing with raw sockets. */
+ if ((*pskb)->len < sizeof(struct iphdr) ||
+ ip_hdrlen(*pskb) < sizeof(struct iphdr))
+@@ -227,6 +239,10 @@
+ enum ip_conntrack_info ctinfo;
+ unsigned int ret;
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ /* root is playing with raw sockets. */
+ if ((*pskb)->len < sizeof(struct iphdr) ||
+ ip_hdrlen(*pskb) < sizeof(struct iphdr))
+@@ -239,7 +255,7 @@
+
+ if (ct->tuplehash[dir].tuple.dst.u3.ip !=
+ ct->tuplehash[!dir].tuple.src.u3.ip) {
+- if (ip_route_me_harder(pskb, RTN_UNSPEC))
++ if (ip_route_me_harder(&init_net, pskb, RTN_UNSPEC))
+ ret = NF_DROP;
+ }
+ #ifdef CONFIG_XFRM
+@@ -262,6 +278,10 @@
+ struct nf_conn *ct;
+ enum ip_conntrack_info ctinfo;
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ ct = nf_ct_get(*pskb, &ctinfo);
+ if (ct && test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
+ DEBUGP("nf_nat_standalone: adjusting sequence number\n");
+diff -Nurb linux-2.6.22-570/net/ipv4/netfilter.c linux-2.6.22-590/net/ipv4/netfilter.c
+--- linux-2.6.22-570/net/ipv4/netfilter.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/netfilter.c 2008-01-29 22:12:32.000000000 -0500
+@@ -8,7 +8,7 @@
+ #include <net/ip.h>
+
+ /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
+-int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type)
++int ip_route_me_harder(struct net *net, struct sk_buff **pskb, unsigned addr_type)
+ {
+ const struct iphdr *iph = ip_hdr(*pskb);
+ struct rtable *rt;
+@@ -17,7 +17,8 @@
+ unsigned int hh_len;
+ unsigned int type;
+
+- type = inet_addr_type(iph->saddr);
++ fl.fl_net = net;
++ type = inet_addr_type(net, iph->saddr);
+ if (addr_type == RTN_UNSPEC)
+ addr_type = type;
+
+@@ -155,12 +156,13 @@
+ const struct ip_rt_info *rt_info = nf_info_reroute(info);
+
+ if (info->hook == NF_IP_LOCAL_OUT) {
++ struct net *net = (info->indev?info->indev:info->outdev)->nd_net;
+ const struct iphdr *iph = ip_hdr(*pskb);
+
+ if (!(iph->tos == rt_info->tos
+ && iph->daddr == rt_info->daddr
+ && iph->saddr == rt_info->saddr))
+- return ip_route_me_harder(pskb, RTN_UNSPEC);
++ return ip_route_me_harder(net, pskb, RTN_UNSPEC);
+ }
+ return 0;
+ }
+diff -Nurb linux-2.6.22-570/net/ipv4/proc.c linux-2.6.22-590/net/ipv4/proc.c
+--- linux-2.6.22-570/net/ipv4/proc.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/proc.c 2008-01-29 22:12:32.000000000 -0500
+@@ -44,6 +44,7 @@
+ #include <linux/seq_file.h>
+ #include <net/sock.h>
+ #include <net/raw.h>
++#include <net/net_namespace.h>
+
+ static int fold_prot_inuse(struct proto *proto)
+ {
+@@ -69,8 +70,9 @@
+ seq_printf(seq, "UDP: inuse %d\n", fold_prot_inuse(&udp_prot));
+ seq_printf(seq, "UDPLITE: inuse %d\n", fold_prot_inuse(&udplite_prot));
+ seq_printf(seq, "RAW: inuse %d\n", fold_prot_inuse(&raw_prot));
+- seq_printf(seq, "FRAG: inuse %d memory %d\n", ip_frag_nqueues,
+- atomic_read(&ip_frag_mem));
++ seq_printf(seq, "FRAG: inuse %d memory %d\n",
++ init_net.ip_frag_nqueues,
++ atomic_read(&init_net.ip_frag_mem));
+ return 0;
+ }
+
+@@ -260,7 +262,8 @@
+ seq_printf(seq, " %s", snmp4_ipstats_list[i].name);
+
+ seq_printf(seq, "\nIp: %d %d",
+- IPV4_DEVCONF_ALL(FORWARDING) ? 1 : 2, sysctl_ip_default_ttl);
++ IPV4_DEVCONF_ALL(&init_net, FORWARDING) ? 1 : 2,
++ init_net.sysctl_ip_default_ttl);
+
+ for (i = 0; snmp4_ipstats_list[i].name != NULL; i++)
+ seq_printf(seq, " %lu",
+@@ -380,20 +383,20 @@
+ {
+ int rc = 0;
+
+- if (!proc_net_fops_create("netstat", S_IRUGO, &netstat_seq_fops))
++ if (!proc_net_fops_create(&init_net, "netstat", S_IRUGO, &netstat_seq_fops))
+ goto out_netstat;
+
+- if (!proc_net_fops_create("snmp", S_IRUGO, &snmp_seq_fops))
++ if (!proc_net_fops_create(&init_net, "snmp", S_IRUGO, &snmp_seq_fops))
+ goto out_snmp;
+
+- if (!proc_net_fops_create("sockstat", S_IRUGO, &sockstat_seq_fops))
++ if (!proc_net_fops_create(&init_net, "sockstat", S_IRUGO, &sockstat_seq_fops))
+ goto out_sockstat;
+ out:
+ return rc;
+ out_sockstat:
+- proc_net_remove("snmp");
++ proc_net_remove(&init_net, "snmp");
+ out_snmp:
+- proc_net_remove("netstat");
++ proc_net_remove(&init_net, "netstat");
+ out_netstat:
+ rc = -ENOMEM;
+ goto out;
+diff -Nurb linux-2.6.22-570/net/ipv4/raw.c linux-2.6.22-590/net/ipv4/raw.c
+--- linux-2.6.22-570/net/ipv4/raw.c 2008-01-29 22:12:24.000000000 -0500
++++ linux-2.6.22-590/net/ipv4/raw.c 2008-01-29 22:12:32.000000000 -0500
+@@ -73,6 +73,7 @@
+ #include <net/inet_common.h>
+ #include <net/checksum.h>
+ #include <net/xfrm.h>
++#include <net/net_namespace.h>
+ #include <linux/rtnetlink.h>
+ #include <linux/proc_fs.h>
+ #include <linux/seq_file.h>
+@@ -101,7 +102,7 @@
+ write_unlock_bh(&raw_v4_lock);
+ }
+
+-struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
++struct sock *__raw_v4_lookup(struct net *net, struct sock *sk, unsigned short num,
+ __be32 raddr, __be32 laddr,
+ int dif, int tag)
+ {
+@@ -110,6 +111,9 @@
+ sk_for_each_from(sk, node) {
+ struct inet_sock *inet = inet_sk(sk);
+
++ if (sk->sk_net != net)
++ continue;
++
+ if (inet->num == num &&
+ !(inet->daddr && inet->daddr != raddr) &&
+ (!sk->sk_nx_info || tag == 1 || sk->sk_nid == tag) &&
+@@ -152,6 +156,7 @@
+ */
+ int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
+ {
++ struct net *net = skb->dev->nd_net;
+ struct sock *sk;
+ struct hlist_head *head;
+ int delivered = 0;
+@@ -160,7 +165,7 @@
+ head = &raw_v4_htable[hash];
+ if (hlist_empty(head))
+ goto out;
+- sk = __raw_v4_lookup(__sk_head(head), iph->protocol,
++ sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol,
+ iph->saddr, iph->daddr,
+ skb->dev->ifindex, skb->skb_tag);
+
+@@ -173,7 +178,7 @@
+ if (clone)
+ raw_rcv(sk, clone);
+ }
+- sk = __raw_v4_lookup(sk_next(sk), iph->protocol,
++ sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol,
+ iph->saddr, iph->daddr,
+ skb->dev->ifindex, skb->skb_tag);
+ }
+@@ -484,7 +489,8 @@
+ }
+
+ {
+- struct flowi fl = { .oif = ipc.oif,
++ struct flowi fl = { .fl_net = sk->sk_net,
++ .oif = ipc.oif,
+ .nl_u = { .ip4_u =
+ { .daddr = daddr,
+ .saddr = saddr,
+@@ -574,7 +580,7 @@
+ if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in))
+ goto out;
+ v4_map_sock_addr(inet, addr, &nsa);
+- chk_addr_ret = inet_addr_type(nsa.saddr);
++ chk_addr_ret = inet_addr_type(sk->sk_net, nsa.saddr);
+ ret = -EADDRNOTAVAIL;
+ if (nsa.saddr && chk_addr_ret != RTN_LOCAL &&
+ chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
+@@ -798,6 +804,7 @@
+
+ #ifdef CONFIG_PROC_FS
+ struct raw_iter_state {
++ struct net *net;
+ int bucket;
+ };
+
+@@ -811,11 +818,14 @@
+ for (state->bucket = 0; state->bucket < RAWV4_HTABLE_SIZE; ++state->bucket) {
+ struct hlist_node *node;
+
+- sk_for_each(sk, node, &raw_v4_htable[state->bucket])
++ sk_for_each(sk, node, &raw_v4_htable[state->bucket]) {
++ if (sk->sk_net != state->net)
++ continue;
+ if (sk->sk_family == PF_INET &&
+ nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
+ goto found;
+ }
++ }
+ sk = NULL;
+ found:
+ return sk;
+@@ -830,7 +840,7 @@
+ try_again:
+ ;
+ } while (sk && (sk->sk_family != PF_INET ||
+- !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
++ !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT) || (sk->sk_net != state->net)));
+
+ if (!sk && ++state->bucket < RAWV4_HTABLE_SIZE) {
+ sk = sk_head(&raw_v4_htable[state->bucket]);
+@@ -933,6 +943,7 @@
+ seq = file->private_data;
+ seq->private = s;
+ memset(s, 0, sizeof(*s));
++ s->net = get_net(PROC_NET(inode));
+ out:
+ return rc;
+ out_kfree:
+@@ -940,23 +951,46 @@
+ goto out;
+ }
+
++static int raw_seq_release(struct inode *inode, struct file *file)
++{
++ struct seq_file *seq = file->private_data;
++ struct raw_iter_state *state = seq->private;
++ put_net(state->net);
++ return seq_release_private(inode, file);
++}
++
+ static const struct file_operations raw_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = raw_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+- .release = seq_release_private,
++ .release = raw_seq_release,
+ };
+
+-int __init raw_proc_init(void)
++static int raw_proc_net_init(struct net *net)
+ {
+- if (!proc_net_fops_create("raw", S_IRUGO, &raw_seq_fops))
++ if (!proc_net_fops_create(net, "raw", S_IRUGO, &raw_seq_fops))
+ return -ENOMEM;
+ return 0;
+ }
+
++static void raw_proc_net_exit(struct net *net)
++{
++ proc_net_remove(net, "raw");
++}
++
++static struct pernet_operations raw_proc_net_ops = {
++ .init = raw_proc_net_init,
++ .exit = raw_proc_net_exit,
++};
++
++int __init raw_proc_init(void)
++{
++ return register_pernet_subsys(&raw_proc_net_ops);
++}
++
+ void __init raw_proc_exit(void)
+ {
+- proc_net_remove("raw");
++ unregister_pernet_subsys(&raw_proc_net_ops);
+ }
+ #endif /* CONFIG_PROC_FS */
+diff -Nurb linux-2.6.22-570/net/ipv4/route.c linux-2.6.22-590/net/ipv4/route.c
+--- linux-2.6.22-570/net/ipv4/route.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/route.c 2008-01-29 22:12:32.000000000 -0500
+@@ -101,8 +101,8 @@
+ #include <net/tcp.h>
+ #include <net/icmp.h>
+ #include <net/xfrm.h>
+-#include <net/ip_mp_alg.h>
+ #include <net/netevent.h>
++#include <net/net_namespace.h>
+ #include <net/rtnetlink.h>
+ #ifdef CONFIG_SYSCTL
+ #include <linux/sysctl.h>
+@@ -266,6 +266,7 @@
+
+ #ifdef CONFIG_PROC_FS
+ struct rt_cache_iter_state {
++ struct net *net;
+ int bucket;
+ };
+
+@@ -334,6 +335,7 @@
+
+ static int rt_cache_seq_show(struct seq_file *seq, void *v)
+ {
++ struct rt_cache_iter_state *st = seq->private;
+ if (v == SEQ_START_TOKEN)
+ seq_printf(seq, "%-127s\n",
+ "Iface\tDestination\tGateway \tFlags\t\tRefCnt\tUse\t"
+@@ -343,6 +345,9 @@
+ struct rtable *r = v;
+ char temp[256];
+
++ if (r->fl.fl_net != st->net)
++ return 0;
++
+ sprintf(temp, "%s\t%08lX\t%08lX\t%8X\t%d\t%u\t%d\t"
+ "%08lX\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X",
+ r->u.dst.dev ? r->u.dst.dev->name : "*",
+@@ -385,6 +390,7 @@
+ seq = file->private_data;
+ seq->private = s;
+ memset(s, 0, sizeof(*s));
++ s->net = get_net(PROC_NET(inode));
+ out:
+ return rc;
+ out_kfree:
+@@ -392,12 +398,20 @@
+ goto out;
+ }
+
++static int rt_cache_seq_release(struct inode *inode, struct file *file)
++{
++ struct seq_file *seq = file->private_data;
++ struct rt_cache_iter_state *st = seq->private;
++ put_net(st->net);
++ return seq_release_private(inode, file);
++}
++
+ static const struct file_operations rt_cache_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = rt_cache_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+- .release = seq_release_private,
++ .release = rt_cache_seq_release,
+ };
+
+
+@@ -495,13 +509,11 @@
+
+ static __inline__ void rt_free(struct rtable *rt)
+ {
+- multipath_remove(rt);
+ call_rcu_bh(&rt->u.dst.rcu_head, dst_rcu_free);
+ }
+
+ static __inline__ void rt_drop(struct rtable *rt)
+ {
+- multipath_remove(rt);
+ ip_rt_put(rt);
+ call_rcu_bh(&rt->u.dst.rcu_head, dst_rcu_free);
+ }
+@@ -565,61 +577,16 @@
+
+ static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
+ {
+- return ((__force u32)((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) |
++ return (((__force u32)((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) |
+ (fl1->nl_u.ip4_u.saddr ^ fl2->nl_u.ip4_u.saddr)) |
+ (fl1->mark ^ fl2->mark) |
+ (*(u16 *)&fl1->nl_u.ip4_u.tos ^
+ *(u16 *)&fl2->nl_u.ip4_u.tos) |
+ (fl1->oif ^ fl2->oif) |
+- (fl1->iif ^ fl2->iif)) == 0;
++ (fl1->iif ^ fl2->iif)) == 0) &&
++ fl1->fl_net == fl2->fl_net;
}
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
/* This runs via a timer and thus is always in BH context. */
static void rt_check_expire(unsigned long dummy)
{
-@@ -658,22 +609,8 @@
+@@ -658,23 +625,9 @@
}
/* Cleanup aged off entries. */
- if (!rthp)
- break;
- } else {
-- *rthp = rth->u.dst.rt_next;
-- rt_free(rth);
-- }
+ *rthp = rth->u.dst.rt_next;
+ rt_free(rth);
+ }
-#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
- *rthp = rth->u.dst.rt_next;
- rt_free(rth);
+- *rthp = rth->u.dst.rt_next;
+- rt_free(rth);
-#endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
- }
+- }
spin_unlock(rt_hash_lock_addr(i));
-@@ -721,9 +658,6 @@
+ /* Fallback loop breaker. */
+@@ -721,9 +674,6 @@
if (delay < 0)
delay = ip_rt_min_delay;
spin_lock_bh(&rt_flush_lock);
if (del_timer(&rt_flush_timer) && delay > 0 && rt_deadline) {
-@@ -842,30 +776,9 @@
+@@ -842,31 +792,10 @@
rthp = &rth->u.dst.rt_next;
continue;
}
- if (!rthp)
- break;
- } else {
-- *rthp = rth->u.dst.rt_next;
-- rt_free(rth);
-- goal--;
-- }
+ *rthp = rth->u.dst.rt_next;
+ rt_free(rth);
+ goal--;
+ }
-#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
- *rthp = rth->u.dst.rt_next;
- rt_free(rth);
- goal--;
+- *rthp = rth->u.dst.rt_next;
+- rt_free(rth);
+- goal--;
-#endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
- }
+- }
spin_unlock_bh(rt_hash_lock_addr(k));
if (goal <= 0)
-@@ -939,12 +852,7 @@
+ break;
+@@ -939,12 +868,7 @@
spin_lock_bh(rt_hash_lock_addr(hash));
while ((rth = *rthp) != NULL) {
/* Put it first */
*rthp = rth->u.dst.rt_next;
/*
-@@ -1774,10 +1682,6 @@
+@@ -1055,7 +979,7 @@
+ static DEFINE_SPINLOCK(rt_peer_lock);
+ struct inet_peer *peer;
+
+- peer = inet_getpeer(rt->rt_dst, create);
++ peer = inet_getpeer(rt->fl.fl_net, rt->rt_dst, create);
+
+ spin_lock_bh(&rt_peer_lock);
+ if (rt->peer == NULL) {
+@@ -1148,7 +1072,7 @@
+ if (IN_DEV_SEC_REDIRECTS(in_dev) && ip_fib_check_default(new_gw, dev))
+ goto reject_redirect;
+ } else {
+- if (inet_addr_type(new_gw) != RTN_UNICAST)
++ if (inet_addr_type(dev->nd_net, new_gw) != RTN_UNICAST)
+ goto reject_redirect;
+ }
+
+@@ -1189,6 +1113,7 @@
+
+ /* Copy all the information. */
+ *rt = *rth;
++ hold_net(rt->fl.fl_net);
+ INIT_RCU_HEAD(&rt->u.dst.rcu_head);
+ rt->u.dst.__use = 1;
+ atomic_set(&rt->u.dst.__refcnt, 1);
+@@ -1407,7 +1332,7 @@
+ __be32 daddr = iph->daddr;
+ unsigned short est_mtu = 0;
+
+- if (ipv4_config.no_pmtu_disc)
++ if (init_net.sysctl_ipv4_no_pmtu_disc)
+ return 0;
+
+ for (i = 0; i < 2; i++) {
+@@ -1489,6 +1414,7 @@
+ rt->idev = NULL;
+ in_dev_put(idev);
+ }
++ release_net(rt->fl.fl_net);
+ }
+
+ static void ipv4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
+@@ -1496,8 +1422,9 @@
+ {
+ struct rtable *rt = (struct rtable *) dst;
+ struct in_device *idev = rt->idev;
+- if (dev != &loopback_dev && idev && idev->dev == dev) {
+- struct in_device *loopback_idev = in_dev_get(&loopback_dev);
++ struct net *net = dev->nd_net;
++ if (dev != &net->loopback_dev && idev && idev->dev == dev) {
++ struct in_device *loopback_idev = in_dev_get(&net->loopback_dev);
+ if (loopback_idev) {
+ rt->idev = loopback_idev;
+ in_dev_put(idev);
+@@ -1584,7 +1511,7 @@
+ rt->u.dst.metrics[RTAX_MTU-1]= rt->u.dst.dev->mtu;
+
+ if (rt->u.dst.metrics[RTAX_HOPLIMIT-1] == 0)
+- rt->u.dst.metrics[RTAX_HOPLIMIT-1] = sysctl_ip_default_ttl;
++ rt->u.dst.metrics[RTAX_HOPLIMIT-1] = init_net.sysctl_ip_default_ttl;
+ if (rt->u.dst.metrics[RTAX_MTU-1] > IP_MAX_MTU)
+ rt->u.dst.metrics[RTAX_MTU-1] = IP_MAX_MTU;
+ if (rt->u.dst.metrics[RTAX_ADVMSS-1] == 0)
+@@ -1605,6 +1532,7 @@
+ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
+ u8 tos, struct net_device *dev, int our)
+ {
++ struct net *net = dev->nd_net;
+ unsigned hash;
+ struct rtable *rth;
+ __be32 spec_dst;
+@@ -1638,6 +1566,7 @@
+ rth->u.dst.flags= DST_HOST;
+ if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
+ rth->u.dst.flags |= DST_NOPOLICY;
++ rth->fl.fl_net = hold_net(net);
+ rth->fl.fl4_dst = daddr;
+ rth->rt_dst = daddr;
+ rth->fl.fl4_tos = tos;
+@@ -1649,7 +1578,7 @@
+ #endif
+ rth->rt_iif =
+ rth->fl.iif = dev->ifindex;
+- rth->u.dst.dev = &loopback_dev;
++ rth->u.dst.dev = &net->loopback_dev;
+ dev_hold(rth->u.dst.dev);
+ rth->idev = in_dev_get(rth->u.dst.dev);
+ rth->fl.oif = 0;
+@@ -1774,14 +1703,11 @@
atomic_set(&rth->u.dst.__refcnt, 1);
rth->u.dst.flags= DST_HOST;
if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
rth->u.dst.flags |= DST_NOPOLICY;
if (IN_DEV_CONF_GET(out_dev, NOXFRM))
-@@ -1812,7 +1716,7 @@
+ rth->u.dst.flags |= DST_NOXFRM;
++ rth->fl.fl_net = hold_net(in_dev->dev->nd_net);
+ rth->fl.fl4_dst = daddr;
+ rth->rt_dst = daddr;
+ rth->fl.fl4_tos = tos;
+@@ -1812,7 +1738,7 @@
return err;
}
struct fib_result* res,
const struct flowi *fl,
struct in_device *in_dev,
-@@ -1837,63 +1741,6 @@
+@@ -1837,63 +1763,6 @@
return rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);
}
/*
* NOTE. We drop all the packets that has local source
* addresses, because every properly looped back packet
-@@ -2211,13 +2058,6 @@
+@@ -1907,9 +1776,11 @@
+ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
+ u8 tos, struct net_device *dev)
+ {
++ struct net *net = dev->nd_net;
+ struct fib_result res;
+ struct in_device *in_dev = in_dev_get(dev);
+- struct flowi fl = { .nl_u = { .ip4_u =
++ struct flowi fl = { .fl_net = net,
++ .nl_u = { .ip4_u =
+ { .daddr = daddr,
+ .saddr = saddr,
+ .tos = tos,
+@@ -1967,7 +1838,7 @@
+ if (res.type == RTN_LOCAL) {
+ int result;
+ result = fib_validate_source(saddr, daddr, tos,
+- loopback_dev.ifindex,
++ net->loopback_dev.ifindex,
+ dev, &spec_dst, &itag);
+ if (result < 0)
+ goto martian_source;
+@@ -2023,6 +1894,7 @@
+ rth->u.dst.flags= DST_HOST;
+ if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
+ rth->u.dst.flags |= DST_NOPOLICY;
++ rth->fl.fl_net = hold_net(net);
+ rth->fl.fl4_dst = daddr;
+ rth->rt_dst = daddr;
+ rth->fl.fl4_tos = tos;
+@@ -2034,7 +1906,7 @@
+ #endif
+ rth->rt_iif =
+ rth->fl.iif = dev->ifindex;
+- rth->u.dst.dev = &loopback_dev;
++ rth->u.dst.dev = &net->loopback_dev;
+ dev_hold(rth->u.dst.dev);
+ rth->idev = in_dev_get(rth->u.dst.dev);
+ rth->rt_gateway = daddr;
+@@ -2092,6 +1964,7 @@
+ struct rtable * rth;
+ unsigned hash;
+ int iif = dev->ifindex;
++ struct net *net = dev->nd_net;
+
+ tos &= IPTOS_RT_MASK;
+ hash = rt_hash(daddr, saddr, iif);
+@@ -2104,7 +1977,8 @@
+ rth->fl.iif == iif &&
+ rth->fl.oif == 0 &&
+ rth->fl.mark == skb->mark &&
+- rth->fl.fl4_tos == tos) {
++ rth->fl.fl4_tos == tos &&
++ rth->fl.fl_net == net) {
+ rth->u.dst.lastuse = jiffies;
+ dst_hold(&rth->u.dst);
+ rth->u.dst.__use++;
+@@ -2211,18 +2085,12 @@
atomic_set(&rth->u.dst.__refcnt, 1);
rth->u.dst.flags= DST_HOST;
if (IN_DEV_CONF_GET(in_dev, NOXFRM))
rth->u.dst.flags |= DST_NOXFRM;
if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
-@@ -2277,7 +2117,7 @@
+ rth->u.dst.flags |= DST_NOPOLICY;
+
++ rth->fl.fl_net = hold_net(oldflp->fl_net);
+ rth->fl.fl4_dst = oldflp->fl4_dst;
+ rth->fl.fl4_tos = tos;
+ rth->fl.fl4_src = oldflp->fl4_src;
+@@ -2277,7 +2145,7 @@
return err;
}
struct fib_result* res,
const struct flowi *fl,
const struct flowi *oldflp,
-@@ -2295,68 +2135,6 @@
+@@ -2295,68 +2163,6 @@
return err;
}
/*
* Major route resolver routine.
*/
-@@ -2570,17 +2348,6 @@
+@@ -2364,7 +2170,9 @@
+ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
+ {
+ u32 tos = RT_FL_TOS(oldflp);
+- struct flowi fl = { .nl_u = { .ip4_u =
++ struct net *net = oldflp->fl_net;
++ struct flowi fl = { .fl_net = net,
++ .nl_u = { .ip4_u =
+ { .daddr = oldflp->fl4_dst,
+ .saddr = oldflp->fl4_src,
+ .tos = tos & IPTOS_RT_MASK,
+@@ -2373,7 +2181,7 @@
+ RT_SCOPE_UNIVERSE),
+ } },
+ .mark = oldflp->mark,
+- .iif = loopback_dev.ifindex,
++ .iif = net->loopback_dev.ifindex,
+ .oif = oldflp->oif };
+ struct fib_result res;
+ unsigned flags = 0;
+@@ -2395,7 +2203,7 @@
+ goto out;
+
+ /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
+- dev_out = ip_dev_find(oldflp->fl4_src);
++ dev_out = ip_dev_find(net, oldflp->fl4_src);
+ if (dev_out == NULL)
+ goto out;
+
+@@ -2434,7 +2242,7 @@
+
+
+ if (oldflp->oif) {
+- dev_out = dev_get_by_index(oldflp->oif);
++ dev_out = dev_get_by_index(net, oldflp->oif);
+ err = -ENODEV;
+ if (dev_out == NULL)
+ goto out;
+@@ -2467,9 +2275,9 @@
+ fl.fl4_dst = fl.fl4_src = htonl(INADDR_LOOPBACK);
+ if (dev_out)
+ dev_put(dev_out);
+- dev_out = &loopback_dev;
++ dev_out = &net->loopback_dev;
+ dev_hold(dev_out);
+- fl.oif = loopback_dev.ifindex;
++ fl.oif = net->loopback_dev.ifindex;
+ res.type = RTN_LOCAL;
+ flags |= RTCF_LOCAL;
+ goto make_route;
+@@ -2514,7 +2322,7 @@
+ fl.fl4_src = fl.fl4_dst;
+ if (dev_out)
+ dev_put(dev_out);
+- dev_out = &loopback_dev;
++ dev_out = &net->loopback_dev;
+ dev_hold(dev_out);
+ fl.oif = dev_out->ifindex;
+ if (res.fi)
+@@ -2568,19 +2376,9 @@
+ rth->fl.iif == 0 &&
+ rth->fl.oif == flp->oif &&
rth->fl.mark == flp->mark &&
++ rth->fl.fl_net == flp->fl_net &&
!((rth->fl.fl4_tos ^ flp->fl4_tos) &
(IPTOS_RT_MASK | RTO_ONLINK))) {
-
rth->u.dst.lastuse = jiffies;
dst_hold(&rth->u.dst);
rth->u.dst.__use++;
-@@ -2729,10 +2496,6 @@
+@@ -2729,10 +2527,6 @@
if (rt->u.dst.tclassid)
NLA_PUT_U32(skb, RTA_FLOW, rt->u.dst.tclassid);
#endif
if (rt->fl.iif)
NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_spec_dst);
else if (rt->rt_src != rt->fl.fl4_src)
+@@ -2759,7 +2553,7 @@
+ __be32 dst = rt->rt_dst;
+
+ if (MULTICAST(dst) && !LOCAL_MCAST(dst) &&
+- IPV4_DEVCONF_ALL(MC_FORWARDING)) {
++ IPV4_DEVCONF_ALL(&init_net, MC_FORWARDING)) {
+ int err = ipmr_get_route(skb, r, nowait);
+ if (err <= 0) {
+ if (!nowait) {
+@@ -2790,6 +2584,7 @@
+
+ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
+ {
++ struct net *net = in_skb->sk->sk_net;
+ struct rtmsg *rtm;
+ struct nlattr *tb[RTA_MAX+1];
+ struct rtable *rt = NULL;
+@@ -2828,7 +2623,7 @@
+ if (iif) {
+ struct net_device *dev;
+
+- dev = __dev_get_by_index(iif);
++ dev = __dev_get_by_index(net, iif);
+ if (dev == NULL) {
+ err = -ENODEV;
+ goto errout_free;
+@@ -2845,6 +2640,7 @@
+ err = -rt->u.dst.error;
+ } else {
+ struct flowi fl = {
++ .fl_net = net,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = dst,
+@@ -2869,7 +2665,7 @@
+ if (err <= 0)
+ goto errout_free;
+
+- err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
++ err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid);
+ errout:
+ return err;
+
+@@ -3182,6 +2978,48 @@
+ }
+ __setup("rhash_entries=", set_rhash_entries);
+
++
++static void ip_rt_net_exit(struct net *net)
++{
++#ifdef CONFIG_PROC_FS
++# ifdef CONFIG_NET_CLS_ROUTE
++ proc_net_remove(net, "rt_acct");
++# endif
++ remove_proc_entry("rt_cache", net->proc_net_stat);
++ proc_net_remove(net, "rt_cache");
++#endif
++ rt_run_flush(0);
++}
++
++static int ip_rt_net_init(struct net *net)
++{
++ int error = -ENOMEM;
++#ifdef CONFIG_PROC_FS
++ struct proc_dir_entry *rtstat_pde;
++ if (!proc_net_fops_create(net, "rt_cache", S_IRUGO, &rt_cache_seq_fops))
++ goto out;
++ if (!(rtstat_pde = create_proc_entry("rt_cache", S_IRUGO,
++ net->proc_net_stat)))
++ goto out;
++ rtstat_pde->proc_fops = &rt_cpu_seq_fops;
++# ifdef CONFIG_NET_CLS_ROUTE
++ if (!create_proc_read_entry("rt_acct", 0, net->proc_net,
++ ip_rt_acct_read, NULL))
++ goto out;
++# endif
++#endif
++ error = 0;
++out:
++ if (error)
++ ip_rt_net_exit(net);
++ return error;
++}
++
++struct pernet_operations ip_rt_net_ops = {
++ .init = ip_rt_net_init,
++ .exit = ip_rt_net_exit,
++};
++
+ int __init ip_rt_init(void)
+ {
+ int rc = 0;
+@@ -3245,20 +3083,7 @@
+ ip_rt_secret_interval;
+ add_timer(&rt_secret_timer);
+
+-#ifdef CONFIG_PROC_FS
+- {
+- struct proc_dir_entry *rtstat_pde = NULL; /* keep gcc happy */
+- if (!proc_net_fops_create("rt_cache", S_IRUGO, &rt_cache_seq_fops) ||
+- !(rtstat_pde = create_proc_entry("rt_cache", S_IRUGO,
+- proc_net_stat))) {
+- return -ENOMEM;
+- }
+- rtstat_pde->proc_fops = &rt_cpu_seq_fops;
+- }
+-#ifdef CONFIG_NET_CLS_ROUTE
+- create_proc_read_entry("rt_acct", 0, proc_net, ip_rt_acct_read, NULL);
+-#endif
+-#endif
++ register_pernet_subsys(&ip_rt_net_ops);
+ #ifdef CONFIG_XFRM
+ xfrm_init();
+ xfrm4_init();
+diff -Nurb linux-2.6.22-570/net/ipv4/syncookies.c linux-2.6.22-590/net/ipv4/syncookies.c
+--- linux-2.6.22-570/net/ipv4/syncookies.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/syncookies.c 2008-01-29 22:12:32.000000000 -0500
+@@ -253,7 +253,8 @@
+ * no easy way to do this.
+ */
+ {
+- struct flowi fl = { .nl_u = { .ip4_u =
++ struct flowi fl = { .fl_net = &init_net,
++ .nl_u = { .ip4_u =
+ { .daddr = ((opt && opt->srr) ?
+ opt->faddr :
+ ireq->rmt_addr),
+diff -Nurb linux-2.6.22-570/net/ipv4/sysctl_net_ipv4.c linux-2.6.22-590/net/ipv4/sysctl_net_ipv4.c
+--- linux-2.6.22-570/net/ipv4/sysctl_net_ipv4.c 2008-01-29 22:12:23.000000000 -0500
++++ linux-2.6.22-590/net/ipv4/sysctl_net_ipv4.c 2008-01-29 22:12:32.000000000 -0500
+@@ -29,21 +29,21 @@
+ static int ip_local_port_range_max[] = { 65535, 65535 };
+ #endif
+
+-struct ipv4_config ipv4_config;
+-
+ #ifdef CONFIG_SYSCTL
+
+ static
+ int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+ {
+- int val = IPV4_DEVCONF_ALL(FORWARDING);
++ struct net *net = ctl->extra2;
++ int *valp = ctl->data;
++ int old = *valp;
+ int ret;
+
+ ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
+
+- if (write && IPV4_DEVCONF_ALL(FORWARDING) != val)
+- inet_forward_change();
++ if (write && *valp != old)
++ inet_forward_change(net);
+
+ return ret;
+ }
+@@ -53,6 +53,7 @@
+ void __user *oldval, size_t __user *oldlenp,
+ void __user *newval, size_t newlen)
+ {
++ struct net *net = table->extra2;
+ int *valp = table->data;
+ int new;
+
+@@ -85,7 +86,7 @@
+ }
+
+ *valp = new;
+- inet_forward_change();
++ inet_forward_change(net);
+ return 1;
+ }
+
+@@ -188,22 +189,6 @@
+
+ ctl_table ipv4_table[] = {
+ {
+- .ctl_name = NET_IPV4_TCP_TIMESTAMPS,
+- .procname = "tcp_timestamps",
+- .data = &sysctl_tcp_timestamps,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec
+- },
+- {
+- .ctl_name = NET_IPV4_TCP_WINDOW_SCALING,
+- .procname = "tcp_window_scaling",
+- .data = &sysctl_tcp_window_scaling,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec
+- },
+- {
+ .ctl_name = NET_IPV4_TCP_SACK,
+ .procname = "tcp_sack",
+ .data = &sysctl_tcp_sack,
+@@ -220,40 +205,6 @@
+ .proc_handler = &proc_dointvec
+ },
+ {
+- .ctl_name = NET_IPV4_FORWARD,
+- .procname = "ip_forward",
+- .data = &IPV4_DEVCONF_ALL(FORWARDING),
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &ipv4_sysctl_forward,
+- .strategy = &ipv4_sysctl_forward_strategy
+- },
+- {
+- .ctl_name = NET_IPV4_DEFAULT_TTL,
+- .procname = "ip_default_ttl",
+- .data = &sysctl_ip_default_ttl,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &ipv4_doint_and_flush,
+- .strategy = &ipv4_doint_and_flush_strategy,
+- },
+- {
+- .ctl_name = NET_IPV4_NO_PMTU_DISC,
+- .procname = "ip_no_pmtu_disc",
+- .data = &ipv4_config.no_pmtu_disc,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec
+- },
+- {
+- .ctl_name = NET_IPV4_NONLOCAL_BIND,
+- .procname = "ip_nonlocal_bind",
+- .data = &sysctl_ip_nonlocal_bind,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec
+- },
+- {
+ .ctl_name = NET_IPV4_TCP_SYN_RETRIES,
+ .procname = "tcp_syn_retries",
+ .data = &sysctl_tcp_syn_retries,
+@@ -286,39 +237,6 @@
+ .proc_handler = &proc_dointvec
+ },
+ {
+- .ctl_name = NET_IPV4_IPFRAG_HIGH_THRESH,
+- .procname = "ipfrag_high_thresh",
+- .data = &sysctl_ipfrag_high_thresh,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec
+- },
+- {
+- .ctl_name = NET_IPV4_IPFRAG_LOW_THRESH,
+- .procname = "ipfrag_low_thresh",
+- .data = &sysctl_ipfrag_low_thresh,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec
+- },
+- {
+- .ctl_name = NET_IPV4_DYNADDR,
+- .procname = "ip_dynaddr",
+- .data = &sysctl_ip_dynaddr,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec
+- },
+- {
+- .ctl_name = NET_IPV4_IPFRAG_TIME,
+- .procname = "ipfrag_time",
+- .data = &sysctl_ipfrag_time,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec_jiffies,
+- .strategy = &sysctl_jiffies
+- },
+- {
+ .ctl_name = NET_IPV4_TCP_KEEPALIVE_TIME,
+ .procname = "tcp_keepalive_time",
+ .data = &sysctl_tcp_keepalive_time,
+@@ -422,17 +340,6 @@
+ .proc_handler = &proc_dointvec
+ },
+ {
+- .ctl_name = NET_IPV4_LOCAL_PORT_RANGE,
+- .procname = "ip_local_port_range",
+- .data = &sysctl_local_port_range,
+- .maxlen = sizeof(sysctl_local_port_range),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec_minmax,
+- .strategy = &sysctl_intvec,
+- .extra1 = ip_local_port_range_min,
+- .extra2 = ip_local_port_range_max
+- },
+- {
+ .ctl_name = NET_IPV4_ICMP_ECHO_IGNORE_ALL,
+ .procname = "icmp_echo_ignore_all",
+ .data = &sysctl_icmp_echo_ignore_all,
+@@ -534,50 +441,6 @@
+ .proc_handler = &proc_dointvec
+ },
+ {
+- .ctl_name = NET_IPV4_INET_PEER_THRESHOLD,
+- .procname = "inet_peer_threshold",
+- .data = &inet_peer_threshold,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec
+- },
+- {
+- .ctl_name = NET_IPV4_INET_PEER_MINTTL,
+- .procname = "inet_peer_minttl",
+- .data = &inet_peer_minttl,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec_jiffies,
+- .strategy = &sysctl_jiffies
+- },
+- {
+- .ctl_name = NET_IPV4_INET_PEER_MAXTTL,
+- .procname = "inet_peer_maxttl",
+- .data = &inet_peer_maxttl,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec_jiffies,
+- .strategy = &sysctl_jiffies
+- },
+- {
+- .ctl_name = NET_IPV4_INET_PEER_GC_MINTIME,
+- .procname = "inet_peer_gc_mintime",
+- .data = &inet_peer_gc_mintime,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec_jiffies,
+- .strategy = &sysctl_jiffies
+- },
+- {
+- .ctl_name = NET_IPV4_INET_PEER_GC_MAXTIME,
+- .procname = "inet_peer_gc_maxtime",
+- .data = &inet_peer_gc_maxtime,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec_jiffies,
+- .strategy = &sysctl_jiffies
+- },
+- {
+ .ctl_name = NET_TCP_ORPHAN_RETRIES,
+ .procname = "tcp_orphan_retries",
+ .data = &sysctl_tcp_orphan_retries,
+@@ -706,24 +569,6 @@
+ .proc_handler = &proc_dointvec
+ },
+ {
+- .ctl_name = NET_IPV4_IPFRAG_SECRET_INTERVAL,
+- .procname = "ipfrag_secret_interval",
+- .data = &sysctl_ipfrag_secret_interval,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec_jiffies,
+- .strategy = &sysctl_jiffies
+- },
+- {
+- .ctl_name = NET_IPV4_IPFRAG_MAX_DIST,
+- .procname = "ipfrag_max_dist",
+- .data = &sysctl_ipfrag_max_dist,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec_minmax,
+- .extra1 = &zero
+- },
+- {
+ .ctl_name = NET_TCP_NO_METRICS_SAVE,
+ .procname = "tcp_no_metrics_save",
+ .data = &sysctl_tcp_nometrics_save,
+@@ -865,6 +710,181 @@
+ { .ctl_name = 0 }
+ };
+
+-#endif /* CONFIG_SYSCTL */
++struct ctl_table multi_ipv4_table[] = {
++ {
++ /* .data is filled in by devinet_net_init.
++ * As a consequence this table entry must be the first
++ * entry in multi_ipv4_table.
++ */
++ .ctl_name = NET_IPV4_FORWARD,
++ .procname = "ip_forward",
++ .data = NULL,
++ .extra2 = &init_net,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &ipv4_sysctl_forward,
++ .strategy = &ipv4_sysctl_forward_strategy
++ },
++ {
++ .ctl_name = NET_IPV4_DEFAULT_TTL,
++ .procname = "ip_default_ttl",
++ .data = &init_net.sysctl_ip_default_ttl,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &ipv4_doint_and_flush,
++ .strategy = &ipv4_doint_and_flush_strategy,
++ },
++ {
++ .ctl_name = NET_IPV4_NO_PMTU_DISC,
++ .procname = "ip_no_pmtu_disc",
++ .data = &init_net.sysctl_ipv4_no_pmtu_disc,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec
++ },
++ {
++ .ctl_name = NET_IPV4_NONLOCAL_BIND,
++ .procname = "ip_nonlocal_bind",
++ .data = &init_net.sysctl_ip_nonlocal_bind,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec
++ },
++ {
++ .ctl_name = NET_IPV4_LOCAL_PORT_RANGE,
++ .procname = "ip_local_port_range",
++ .data = &init_net.sysctl_local_port_range,
++ .maxlen = sizeof(init_net.sysctl_local_port_range),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec_minmax,
++ .strategy = &sysctl_intvec,
++ .extra1 = ip_local_port_range_min,
++ .extra2 = ip_local_port_range_max
++ },
++ {
++ .ctl_name = NET_IPV4_IPFRAG_HIGH_THRESH,
++ .procname = "ipfrag_high_thresh",
++ .data = &init_net.sysctl_ipfrag_high_thresh,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec
++ },
++ {
++ .ctl_name = NET_IPV4_IPFRAG_LOW_THRESH,
++ .procname = "ipfrag_low_thresh",
++ .data = &init_net.sysctl_ipfrag_low_thresh,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec
++ },
++ {
++ .ctl_name = NET_IPV4_IPFRAG_TIME,
++ .procname = "ipfrag_time",
++ .data = &init_net.sysctl_ipfrag_time,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec_jiffies,
++ .strategy = &sysctl_jiffies
++ },
++ {
++ .ctl_name = NET_IPV4_IPFRAG_SECRET_INTERVAL,
++ .procname = "ipfrag_secret_interval",
++ .data = &init_net.sysctl_ipfrag_secret_interval,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec_jiffies,
++ .strategy = &sysctl_jiffies
++ },
++ {
++ .ctl_name = NET_IPV4_IPFRAG_MAX_DIST,
++ .procname = "ipfrag_max_dist",
++ .data = &init_net.sysctl_ipfrag_max_dist,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec_minmax,
++ .extra1 = &zero
++ },
++ {
++ .ctl_name = NET_IPV4_DYNADDR,
++ .procname = "ip_dynaddr",
++ .data = &init_net.sysctl_ip_dynaddr,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec
++ },
++ {
++ .ctl_name = NET_IPV4_LOCAL_PORT_RANGE,
++ .procname = "ip_local_port_range",
++ .data = &init_net.sysctl_local_port_range,
++ .maxlen = sizeof(init_net.sysctl_local_port_range),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec_minmax,
++ .strategy = &sysctl_intvec,
++ .extra1 = ip_local_port_range_min,
++ .extra2 = ip_local_port_range_max
++ },
++ {
++ .ctl_name = NET_IPV4_INET_PEER_THRESHOLD,
++ .procname = "inet_peer_threshold",
++ .data = &init_net.inet_peer_threshold,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec
++ },
++ {
++ .ctl_name = NET_IPV4_INET_PEER_MINTTL,
++ .procname = "inet_peer_minttl",
++ .data = &init_net.inet_peer_minttl,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec_jiffies,
++ .strategy = &sysctl_jiffies
++ },
++ {
++ .ctl_name = NET_IPV4_INET_PEER_MAXTTL,
++ .procname = "inet_peer_maxttl",
++ .data = &init_net.inet_peer_maxttl,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec_jiffies,
++ .strategy = &sysctl_jiffies
++ },
++ {
++ .ctl_name = NET_IPV4_INET_PEER_GC_MINTIME,
++ .procname = "inet_peer_gc_mintime",
++ .data = &init_net.inet_peer_gc_mintime,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec_jiffies,
++ .strategy = &sysctl_jiffies
++ },
++ {
++ .ctl_name = NET_IPV4_INET_PEER_GC_MAXTIME,
++ .procname = "inet_peer_gc_maxtime",
++ .data = &init_net.inet_peer_gc_maxtime,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec_jiffies,
++ .strategy = &sysctl_jiffies
++ },
++ {
++ .ctl_name = NET_IPV4_TCP_TIMESTAMPS,
++ .procname = "tcp_timestamps",
++ .data = &init_net.sysctl_tcp_timestamps,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec
++
++ },
++ {
++ .ctl_name = NET_IPV4_TCP_WINDOW_SCALING,
++ .procname = "tcp_window_scaling",
++ .data = &init_net.sysctl_tcp_window_scaling,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = &proc_dointvec
++ },
++ {}
++};
+
+-EXPORT_SYMBOL(ipv4_config);
++#endif /* CONFIG_SYSCTL */
+diff -Nurb linux-2.6.22-570/net/ipv4/tcp.c linux-2.6.22-590/net/ipv4/tcp.c
+--- linux-2.6.22-570/net/ipv4/tcp.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/ipv4/tcp.c 2008-01-29 22:12:32.000000000 -0500
+@@ -2409,6 +2409,23 @@
+ }
+ __setup("thash_entries=", set_thash_entries);
+
++static int tcp_net_init(struct net *net)
++{
++ /*
++ * This array holds the first and last local port number.
++ */
++ net->sysctl_local_port_range[0] = 32768;
++ net->sysctl_local_port_range[1] = 61000;
++
++ net->sysctl_tcp_timestamps = 1;
++ net->sysctl_tcp_window_scaling = 1;
++ return 0;
++}
++
++static struct pernet_operations tcp_net_ops = {
++ .init = tcp_net_init,
++};
++
+ void __init tcp_init(void)
+ {
+ struct sk_buff *skb = NULL;
+@@ -2502,6 +2519,8 @@
+ sysctl_tcp_rmem[1] = 87380;
+ sysctl_tcp_rmem[2] = max(87380, max_share);
+
++ register_pernet_subsys(&tcp_net_ops);
++
+ printk(KERN_INFO "TCP: Hash tables configured "
+ "(established %d bind %d)\n",
+ tcp_hashinfo.ehash_size, tcp_hashinfo.bhash_size);
+diff -Nurb linux-2.6.22-570/net/ipv4/tcp_input.c linux-2.6.22-590/net/ipv4/tcp_input.c
+--- linux-2.6.22-570/net/ipv4/tcp_input.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/ipv4/tcp_input.c 2008-01-29 22:12:32.000000000 -0500
+@@ -72,8 +72,6 @@
+ #include <asm/unaligned.h>
+ #include <net/netdma.h>
+
+-int sysctl_tcp_timestamps __read_mostly = 1;
+-int sysctl_tcp_window_scaling __read_mostly = 1;
+ int sysctl_tcp_sack __read_mostly = 1;
+ int sysctl_tcp_fack __read_mostly = 1;
+ int sysctl_tcp_reordering __read_mostly = TCP_FASTRETRANS_THRESH;
+@@ -2922,7 +2920,7 @@
+ break;
+ case TCPOPT_WINDOW:
+ if (opsize==TCPOLEN_WINDOW && th->syn && !estab)
+- if (sysctl_tcp_window_scaling) {
++ if (init_net.sysctl_tcp_window_scaling) {
+ __u8 snd_wscale = *(__u8 *) ptr;
+ opt_rx->wscale_ok = 1;
+ if (snd_wscale > 14) {
+@@ -2938,7 +2936,7 @@
+ case TCPOPT_TIMESTAMP:
+ if (opsize==TCPOLEN_TIMESTAMP) {
+ if ((estab && opt_rx->tstamp_ok) ||
+- (!estab && sysctl_tcp_timestamps)) {
++ (!estab && init_net.sysctl_tcp_timestamps)) {
+ opt_rx->saw_tstamp = 1;
+ opt_rx->rcv_tsval = ntohl(get_unaligned((__be32 *)ptr));
+ opt_rx->rcv_tsecr = ntohl(get_unaligned((__be32 *)(ptr+4)));
diff -Nurb linux-2.6.22-570/net/ipv4/tcp_ipv4.c linux-2.6.22-590/net/ipv4/tcp_ipv4.c
---- linux-2.6.22-570/net/ipv4/tcp_ipv4.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/net/ipv4/tcp_ipv4.c 2008-03-15 10:35:47.000000000 -0400
-@@ -2054,10 +2054,7 @@
+--- linux-2.6.22-570/net/ipv4/tcp_ipv4.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/ipv4/tcp_ipv4.c 2008-01-29 22:12:32.000000000 -0500
+@@ -71,6 +71,7 @@
+ #include <net/timewait_sock.h>
+ #include <net/xfrm.h>
+ #include <net/netdma.h>
++#include <net/net_namespace.h>
+
+ #include <linux/inet.h>
+ #include <linux/ipv6.h>
+@@ -353,6 +354,7 @@
+
+ void tcp_v4_err(struct sk_buff *skb, u32 info)
+ {
++ struct net *net = skb->dev->nd_net;
+ struct iphdr *iph = (struct iphdr *)skb->data;
+ struct tcphdr *th = (struct tcphdr *)(skb->data + (iph->ihl << 2));
+ struct tcp_sock *tp;
+@@ -369,7 +371,7 @@
+ }
+
+ sk = inet_lookup(&tcp_hashinfo, iph->daddr, th->dest, iph->saddr,
+- th->source, inet_iif(skb));
++ th->source, inet_iif(skb), net);
+ if (!sk) {
+ ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
+ return;
+@@ -1499,7 +1501,8 @@
+ return tcp_check_req(sk, skb, req, prev);
+
+ nsk = inet_lookup_established(&tcp_hashinfo, iph->saddr, th->source,
+- iph->daddr, th->dest, inet_iif(skb));
++ iph->daddr, th->dest, inet_iif(skb),
++ sk->sk_net);
+
+ if (nsk) {
+ if (nsk->sk_state != TCP_TIME_WAIT) {
+@@ -1618,6 +1621,7 @@
+
+ int tcp_v4_rcv(struct sk_buff *skb)
+ {
++ struct net *net = skb->dev->nd_net;
+ const struct iphdr *iph;
+ struct tcphdr *th;
+ struct sock *sk;
+@@ -1657,7 +1661,7 @@
+ TCP_SKB_CB(skb)->sacked = 0;
+
+ sk = __inet_lookup(&tcp_hashinfo, iph->saddr, th->source,
+- iph->daddr, th->dest, inet_iif(skb));
++ iph->daddr, th->dest, inet_iif(skb), net);
+ if (!sk)
+ goto no_tcp_socket;
+
+@@ -1732,7 +1736,7 @@
+ case TCP_TW_SYN: {
+ struct sock *sk2 = inet_lookup_listener(&tcp_hashinfo,
+ iph->daddr, th->dest,
+- inet_iif(skb));
++ inet_iif(skb), net);
+ if (sk2) {
+ inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row);
+ inet_twsk_put(inet_twsk(sk));
+@@ -1766,7 +1770,7 @@
+ int release_it = 0;
+
+ if (!rt || rt->rt_dst != inet->daddr) {
+- peer = inet_getpeer(inet->daddr, 1);
++ peer = inet_getpeer(sk->sk_net, inet->daddr, 1);
+ release_it = 1;
+ } else {
+ if (!rt->peer)
+@@ -1791,7 +1795,7 @@
+
+ int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw)
+ {
+- struct inet_peer *peer = inet_getpeer(tw->tw_daddr, 1);
++ struct inet_peer *peer = inet_getpeer(tw->tw_net, tw->tw_daddr, 1);
+
+ if (peer) {
+ const struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw);
+@@ -1980,7 +1984,8 @@
+ if (req->sk &&
+ !nx_check(req->sk->sk_nid, VS_WATCH_P | VS_IDENT))
+ continue;
+- if (req->rsk_ops->family == st->family) {
++ if ((req->rsk_ops->family == st->family) &&
++ (req->sk->sk_net == st->net)) {
+ cur = req;
+ goto out;
+ }
+@@ -2004,6 +2009,8 @@
+ }
+ get_sk:
+ sk_for_each_from(sk, node) {
++ if (sk->sk_net != st->net)
++ continue;
+ vxdprintk(VXD_CBIT(net, 6), "sk: %p [#%d] (from %d)",
+ sk, sk->sk_nid, nx_current_nid());
+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
+@@ -2054,11 +2061,10 @@
struct hlist_node *node;
struct inet_timewait_sock *tw;
- read_lock(&tcp_hashinfo.ehash[st->bucket].lock);
+ read_lock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
++ if (sk->sk_net != st->net)
++ continue;
vxdprintk(VXD_CBIT(net, 6),
"sk,egf: %p [#%d] (from %d)",
-@@ -2082,7 +2079,7 @@
+ sk, sk->sk_nid, nx_current_nid());
+@@ -2072,6 +2078,8 @@
+ st->state = TCP_SEQ_STATE_TIME_WAIT;
+ inet_twsk_for_each(tw, node,
+ &tcp_hashinfo.ehash[st->bucket].twchain) {
++ if (tw->tw_net != st->net)
++ continue;
+ vxdprintk(VXD_CBIT(net, 6),
+ "tw: %p [#%d] (from %d)",
+ tw, tw->tw_nid, nx_current_nid());
+@@ -2082,7 +2090,7 @@
rc = tw;
goto out;
}
st->state = TCP_SEQ_STATE_ESTABLISHED;
}
out:
-@@ -2110,14 +2107,11 @@
+@@ -2102,7 +2110,8 @@
+ tw = cur;
+ tw = tw_next(tw);
+ get_tw:
+- while (tw && (tw->tw_family != st->family ||
++ while (tw && ((tw->tw_net != st->net) ||
++ (tw->tw_family != st->family) ||
+ !nx_check(tw->tw_nid, VS_WATCH_P | VS_IDENT))) {
+ tw = tw_next(tw);
+ }
+@@ -2110,14 +2119,11 @@
cur = tw;
goto out;
}
sk = sk_head(&tcp_hashinfo.ehash[st->bucket].chain);
} else {
cur = NULL;
-@@ -2167,7 +2161,6 @@
+@@ -2130,6 +2136,8 @@
+ vxdprintk(VXD_CBIT(net, 6),
+ "sk,egn: %p [#%d] (from %d)",
+ sk, sk->sk_nid, nx_current_nid());
++ if (sk->sk_net != st->net)
++ continue;
+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
+ continue;
+ if (sk->sk_family == st->family)
+@@ -2167,7 +2175,6 @@
if (!rc) {
inet_listen_unlock(&tcp_hashinfo);
st->state = TCP_SEQ_STATE_ESTABLISHED;
rc = established_get_idx(seq, pos);
}
-@@ -2200,7 +2193,6 @@
+@@ -2200,7 +2207,6 @@
rc = listening_get_next(seq, v);
if (!rc) {
inet_listen_unlock(&tcp_hashinfo);
st->state = TCP_SEQ_STATE_ESTABLISHED;
rc = established_get_first(seq);
}
-@@ -2232,8 +2224,7 @@
+@@ -2232,8 +2238,7 @@
case TCP_SEQ_STATE_TIME_WAIT:
case TCP_SEQ_STATE_ESTABLISHED:
if (v)
break;
}
}
-diff -Nurb linux-2.6.22-570/net/ipv4/xfrm4_tunnel.c linux-2.6.22-590/net/ipv4/xfrm4_tunnel.c
---- linux-2.6.22-570/net/ipv4/xfrm4_tunnel.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/ipv4/xfrm4_tunnel.c 2008-03-15 10:35:47.000000000 -0400
-@@ -109,3 +109,4 @@
- module_init(ipip_init);
- module_exit(ipip_fini);
- MODULE_LICENSE("GPL");
-+MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_IPIP);
-diff -Nurb linux-2.6.22-570/net/ipv6/Kconfig linux-2.6.22-590/net/ipv6/Kconfig
---- linux-2.6.22-570/net/ipv6/Kconfig 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/net/ipv6/Kconfig 2008-03-15 10:35:47.000000000 -0400
-@@ -109,7 +109,7 @@
- If unsure, say Y.
-
- config IPV6_MIP6
-- bool "IPv6: Mobility (EXPERIMENTAL)"
-+ tristate "IPv6: Mobility (EXPERIMENTAL)"
- depends on IPV6 && EXPERIMENTAL
- select XFRM
- ---help---
-diff -Nurb linux-2.6.22-570/net/ipv6/Makefile linux-2.6.22-590/net/ipv6/Makefile
---- linux-2.6.22-570/net/ipv6/Makefile 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/ipv6/Makefile 2008-03-15 10:35:47.000000000 -0400
-@@ -14,7 +14,6 @@
- xfrm6_output.o
- ipv6-$(CONFIG_NETFILTER) += netfilter.o
- ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o
--ipv6-$(CONFIG_IPV6_MIP6) += mip6.o
- ipv6-$(CONFIG_PROC_FS) += proc.o
-
- ipv6-objs += $(ipv6-y)
-@@ -28,6 +27,7 @@
- obj-$(CONFIG_INET6_XFRM_MODE_TUNNEL) += xfrm6_mode_tunnel.o
- obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o
- obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o
-+obj-$(CONFIG_IPV6_MIP6) += mip6.o
- obj-$(CONFIG_NETFILTER) += netfilter/
-
- obj-$(CONFIG_IPV6_SIT) += sit.o
-diff -Nurb linux-2.6.22-570/net/ipv6/addrconf.c linux-2.6.22-590/net/ipv6/addrconf.c
---- linux-2.6.22-570/net/ipv6/addrconf.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/net/ipv6/addrconf.c 2008-03-15 10:35:47.000000000 -0400
-@@ -1047,7 +1047,7 @@
- }
-
- /* Rule 4: Prefer home address */
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- if (hiscore.rule < 4) {
- if (ifa_result->flags & IFA_F_HOMEADDRESS)
- hiscore.attrs |= IPV6_SADDR_SCORE_HOA;
-@@ -2861,7 +2861,7 @@
+@@ -2262,6 +2267,7 @@
+ goto out_kfree;
+ seq = file->private_data;
+ seq->private = s;
++ s->net = get_net(PROC_NET(inode));
+ out:
+ return rc;
+ out_kfree:
+@@ -2269,20 +2275,30 @@
+ goto out;
}
- #endif /* CONFIG_PROC_FS */
-
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- /* Check if address is a home address configured on any interface. */
- int ipv6_chk_home_addr(struct in6_addr *addr)
- {
-diff -Nurb linux-2.6.22-570/net/ipv6/af_inet6.c linux-2.6.22-590/net/ipv6/af_inet6.c
---- linux-2.6.22-570/net/ipv6/af_inet6.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/net/ipv6/af_inet6.c 2008-03-15 10:35:47.000000000 -0400
-@@ -59,9 +59,6 @@
- #ifdef CONFIG_IPV6_TUNNEL
- #include <net/ip6_tunnel.h>
- #endif
--#ifdef CONFIG_IPV6_MIP6
--#include <net/mip6.h>
--#endif
-
- #include <asm/uaccess.h>
- #include <asm/system.h>
-@@ -876,9 +873,6 @@
- ipv6_frag_init();
- ipv6_nodata_init();
- ipv6_destopt_init();
--#ifdef CONFIG_IPV6_MIP6
-- mip6_init();
--#endif
-
- /* Init v6 transport protocols. */
- udpv6_init();
-@@ -944,9 +938,7 @@
- /* Cleanup code parts. */
- ipv6_packet_cleanup();
--#ifdef CONFIG_IPV6_MIP6
-- mip6_fini();
--#endif
+-int tcp_proc_register(struct tcp_seq_afinfo *afinfo)
++static int tcp_seq_release(struct inode *inode, struct file *file)
++{
++ struct seq_file *seq = file->private_data;
++ struct tcp_iter_state *st = seq->private;
++ put_net(st->net);
++ return seq_release_private(inode, file);
++}
+
- addrconf_cleanup();
- ip6_flowlabel_cleanup();
- ip6_route_cleanup();
-diff -Nurb linux-2.6.22-570/net/ipv6/ah6.c linux-2.6.22-590/net/ipv6/ah6.c
---- linux-2.6.22-570/net/ipv6/ah6.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/ipv6/ah6.c 2008-03-15 10:35:47.000000000 -0400
-@@ -74,7 +74,7 @@
- return 0;
- }
-
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- /**
- * ipv6_rearrange_destopt - rearrange IPv6 destination options header
- * @iph: IPv6 header
-@@ -132,6 +132,8 @@
- bad:
- return;
- }
-+#else
-+static void ipv6_rearrange_destopt(struct ipv6hdr *iph, struct ipv6_opt_hdr *destopt) {}
- #endif
-
- /**
-@@ -189,10 +191,8 @@
- while (exthdr.raw < end) {
- switch (nexthdr) {
- case NEXTHDR_DEST:
--#ifdef CONFIG_IPV6_MIP6
- if (dir == XFRM_POLICY_OUT)
- ipv6_rearrange_destopt(iph, exthdr.opth);
--#endif
- case NEXTHDR_HOP:
- if (!zero_out_mutable_opts(exthdr.opth)) {
- LIMIT_NETDEBUG(
-@@ -228,7 +228,7 @@
- u8 nexthdr;
- char tmp_base[8];
- struct {
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- struct in6_addr saddr;
- #endif
- struct in6_addr daddr;
-@@ -255,7 +255,7 @@
- err = -ENOMEM;
- goto error;
- }
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- memcpy(tmp_ext, &top_iph->saddr, extlen);
- #else
- memcpy(tmp_ext, &top_iph->daddr, extlen);
-@@ -294,7 +294,7 @@
-
- memcpy(top_iph, tmp_base, sizeof(tmp_base));
- if (tmp_ext) {
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- memcpy(&top_iph->saddr, tmp_ext, extlen);
- #else
- memcpy(&top_iph->daddr, tmp_ext, extlen);
-@@ -554,3 +554,4 @@
- module_exit(ah6_fini);
-
- MODULE_LICENSE("GPL");
-+MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_AH);
-diff -Nurb linux-2.6.22-570/net/ipv6/datagram.c linux-2.6.22-590/net/ipv6/datagram.c
---- linux-2.6.22-570/net/ipv6/datagram.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/ipv6/datagram.c 2008-03-15 10:35:47.000000000 -0400
-@@ -658,7 +658,7 @@
-
- switch (rthdr->type) {
- case IPV6_SRCRT_TYPE_0:
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- case IPV6_SRCRT_TYPE_2:
- #endif
- break;
-diff -Nurb linux-2.6.22-570/net/ipv6/esp6.c linux-2.6.22-590/net/ipv6/esp6.c
---- linux-2.6.22-570/net/ipv6/esp6.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/ipv6/esp6.c 2008-03-15 10:35:47.000000000 -0400
-@@ -421,3 +421,4 @@
- module_exit(esp6_fini);
-
- MODULE_LICENSE("GPL");
-+MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_ESP);
-diff -Nurb linux-2.6.22-570/net/ipv6/exthdrs.c linux-2.6.22-590/net/ipv6/exthdrs.c
---- linux-2.6.22-570/net/ipv6/exthdrs.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/ipv6/exthdrs.c 2008-03-15 10:35:47.000000000 -0400
-@@ -42,7 +42,7 @@
- #include <net/ndisc.h>
- #include <net/ip6_route.h>
- #include <net/addrconf.h>
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- #include <net/xfrm.h>
- #endif
-
-@@ -90,6 +90,7 @@
- bad:
- return -1;
- }
-+EXPORT_SYMBOL_GPL(ipv6_find_tlv);
-
- /*
- * Parsing tlv encoded headers.
-@@ -196,7 +197,7 @@
- Destination options header.
- *****************************/
-
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
- {
- struct sk_buff *skb = *skbp;
-@@ -270,7 +271,7 @@
- #endif
-
- static struct tlvtype_proc tlvprocdestopt_lst[] = {
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- {
- .type = IPV6_TLV_HAO,
- .func = ipv6_dest_hao,
-@@ -283,7 +284,7 @@
++int tcp_proc_register(struct net *net, struct tcp_seq_afinfo *afinfo)
{
- struct sk_buff *skb = *skbp;
- struct inet6_skb_parm *opt = IP6CB(skb);
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- __u16 dstbuf;
- #endif
- struct dst_entry *dst;
-@@ -298,7 +299,7 @@
- }
-
- opt->lastopt = opt->dst1 = skb_network_header_len(skb);
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- dstbuf = opt->dst1;
- #endif
-
-@@ -308,7 +309,7 @@
- skb = *skbp;
- skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3;
- opt = IP6CB(skb);
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- opt->nhoff = dstbuf;
- #else
- opt->nhoff = opt->dst1;
-@@ -427,7 +428,7 @@
- looped_back:
- if (hdr->segments_left == 0) {
- switch (hdr->type) {
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- case IPV6_SRCRT_TYPE_2:
- /* Silently discard type 2 header unless it was
- * processed by own
-@@ -463,7 +464,7 @@
- return -1;
- }
- break;
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- case IPV6_SRCRT_TYPE_2:
- /* Silently discard invalid RTH type 2 */
- if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
-@@ -520,7 +521,7 @@
- addr += i - 1;
+ int rc = 0;
+ struct proc_dir_entry *p;
- switch (hdr->type) {
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- case IPV6_SRCRT_TYPE_2:
- if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
- (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
-diff -Nurb linux-2.6.22-570/net/ipv6/icmp.c linux-2.6.22-590/net/ipv6/icmp.c
---- linux-2.6.22-570/net/ipv6/icmp.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/net/ipv6/icmp.c 2008-03-15 10:35:47.000000000 -0400
-@@ -272,7 +272,7 @@
- return 0;
+ if (!afinfo)
+ return -EINVAL;
++ if (net == &init_net) {
+ afinfo->seq_fops->owner = afinfo->owner;
+ afinfo->seq_fops->open = tcp_seq_open;
+ afinfo->seq_fops->read = seq_read;
+ afinfo->seq_fops->llseek = seq_lseek;
+- afinfo->seq_fops->release = seq_release_private;
++ afinfo->seq_fops->release = tcp_seq_release;
++ }
+
+- p = proc_net_fops_create(afinfo->name, S_IRUGO, afinfo->seq_fops);
++ p = proc_net_fops_create(net, afinfo->name, S_IRUGO, afinfo->seq_fops);
+ if (p)
+ p->data = afinfo;
+ else
+@@ -2290,11 +2306,12 @@
+ return rc;
}
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- static void mip6_addr_swap(struct sk_buff *skb)
+-void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo)
++void tcp_proc_unregister(struct net *net, struct tcp_seq_afinfo *afinfo)
{
- struct ipv6hdr *iph = ipv6_hdr(skb);
-diff -Nurb linux-2.6.22-570/net/ipv6/ip6_output.c linux-2.6.22-590/net/ipv6/ip6_output.c
---- linux-2.6.22-570/net/ipv6/ip6_output.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/net/ipv6/ip6_output.c 2008-03-15 10:35:47.000000000 -0400
-@@ -543,7 +543,7 @@
- found_rhdr = 1;
- break;
- case NEXTHDR_DEST:
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0)
- break;
- #endif
-diff -Nurb linux-2.6.22-570/net/ipv6/ipcomp6.c linux-2.6.22-590/net/ipv6/ipcomp6.c
---- linux-2.6.22-570/net/ipv6/ipcomp6.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/net/ipv6/ipcomp6.c 2008-03-15 10:35:47.000000000 -0400
-@@ -501,4 +501,4 @@
- MODULE_DESCRIPTION("IP Payload Compression Protocol (IPComp) for IPv6 - RFC3173");
- MODULE_AUTHOR("Mitsuru KANDA <mk@linux-ipv6.org>");
-
--
-+MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_COMP);
-diff -Nurb linux-2.6.22-570/net/ipv6/ipv6_sockglue.c linux-2.6.22-590/net/ipv6/ipv6_sockglue.c
---- linux-2.6.22-570/net/ipv6/ipv6_sockglue.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/net/ipv6/ipv6_sockglue.c 2008-03-15 10:35:47.000000000 -0400
-@@ -123,7 +123,7 @@
- struct ipv6hdr *ipv6h;
- struct inet6_protocol *ops;
-
-- if (!(features & NETIF_F_HW_CSUM))
-+ if (!(features & NETIF_F_V6_CSUM))
- features &= ~NETIF_F_SG;
-
- if (unlikely(skb_shinfo(skb)->gso_type &
-@@ -417,7 +417,7 @@
- struct ipv6_rt_hdr *rthdr = opt->srcrt;
- switch (rthdr->type) {
- case IPV6_SRCRT_TYPE_0:
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- case IPV6_SRCRT_TYPE_2:
- #endif
- break;
-diff -Nurb linux-2.6.22-570/net/ipv6/mip6.c linux-2.6.22-590/net/ipv6/mip6.c
---- linux-2.6.22-570/net/ipv6/mip6.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/ipv6/mip6.c 2008-03-15 10:35:47.000000000 -0400
-@@ -30,6 +30,7 @@
- #include <net/sock.h>
- #include <net/ipv6.h>
- #include <net/ip6_checksum.h>
-+#include <net/rawv6.h>
- #include <net/xfrm.h>
- #include <net/mip6.h>
-
-@@ -86,7 +87,7 @@
- return len;
+ if (!afinfo)
+ return;
+- proc_net_remove(afinfo->name);
++ proc_net_remove(net, afinfo->name);
++ if (net == &init_net)
+ memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops));
}
--int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
-+static int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
- {
- struct ip6_mh *mh;
-
-@@ -471,7 +472,7 @@
- .remote_addr = mip6_xfrm_addr,
+@@ -2439,14 +2456,29 @@
+ .seq_fops = &tcp4_seq_fops,
};
--int __init mip6_init(void)
-+static int __init mip6_init(void)
- {
- printk(KERN_INFO "Mobile IPv6\n");
-
-@@ -483,18 +484,35 @@
- printk(KERN_INFO "%s: can't add xfrm type(rthdr)\n", __FUNCTION__);
- goto mip6_rthdr_xfrm_fail;
- }
-+ if (rawv6_mh_filter_register(mip6_mh_filter) < 0) {
-+ printk(KERN_INFO "%s: can't add rawv6 mh filter\n", __FUNCTION__);
-+ goto mip6_rawv6_mh_fail;
-+ }
++static int tcp4_proc_net_init(struct net *net)
++{
++ return tcp_proc_register(net, &tcp4_seq_afinfo);
++}
+
++static void tcp4_proc_net_exit(struct net *net)
++{
++ tcp_proc_unregister(net, &tcp4_seq_afinfo);
++}
+
- return 0;
-
-+ mip6_rawv6_mh_fail:
-+ xfrm_unregister_type(&mip6_rthdr_type, AF_INET6);
- mip6_rthdr_xfrm_fail:
- xfrm_unregister_type(&mip6_destopt_type, AF_INET6);
- mip6_destopt_xfrm_fail:
- return -EAGAIN;
++static struct pernet_operations tcp4_proc_net_ops = {
++ .init = tcp4_proc_net_init,
++ .exit = tcp4_proc_net_exit,
++};
++
+ int __init tcp4_proc_init(void)
+ {
+- return tcp_proc_register(&tcp4_seq_afinfo);
++ return register_pernet_subsys(&tcp4_proc_net_ops);
}
--void __exit mip6_fini(void)
-+static void __exit mip6_fini(void)
+ void tcp4_proc_exit(void)
{
-+ if (rawv6_mh_filter_unregister(mip6_mh_filter) < 0)
-+ printk(KERN_INFO "%s: can't remove rawv6 mh filter\n", __FUNCTION__);
- if (xfrm_unregister_type(&mip6_rthdr_type, AF_INET6) < 0)
- printk(KERN_INFO "%s: can't remove xfrm type(rthdr)\n", __FUNCTION__);
- if (xfrm_unregister_type(&mip6_destopt_type, AF_INET6) < 0)
- printk(KERN_INFO "%s: can't remove xfrm type(destopt)\n", __FUNCTION__);
+- tcp_proc_unregister(&tcp4_seq_afinfo);
++ unregister_pernet_subsys(&tcp4_proc_net_ops);
}
-+
-+module_init(mip6_init);
-+module_exit(mip6_fini);
-+
-+MODULE_LICENSE("GPL");
+ #endif /* CONFIG_PROC_FS */
+
+@@ -2508,6 +2540,5 @@
+ EXPORT_SYMBOL(tcp_proc_register);
+ EXPORT_SYMBOL(tcp_proc_unregister);
+ #endif
+-EXPORT_SYMBOL(sysctl_local_port_range);
+ EXPORT_SYMBOL(sysctl_tcp_low_latency);
+
+diff -Nurb linux-2.6.22-570/net/ipv4/tcp_ipv4.c.orig linux-2.6.22-590/net/ipv4/tcp_ipv4.c.orig
+--- linux-2.6.22-570/net/ipv4/tcp_ipv4.c.orig 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/ipv4/tcp_ipv4.c.orig 1969-12-31 19:00:00.000000000 -0500
+@@ -1,2483 +0,0 @@
+-/*
+- * INET An implementation of the TCP/IP protocol suite for the LINUX
+- * operating system. INET is implemented using the BSD Socket
+- * interface as the means of communication with the user level.
+- *
+- * Implementation of the Transmission Control Protocol(TCP).
+- *
+- * Version: $Id: tcp_ipv4.c,v 1.240 2002/02/01 22:01:04 davem Exp $
+- *
+- * IPv4 specific functions
+- *
+- *
+- * code split from:
+- * linux/ipv4/tcp.c
+- * linux/ipv4/tcp_input.c
+- * linux/ipv4/tcp_output.c
+- *
+- * See tcp.c for author information
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-
+-/*
+- * Changes:
+- * David S. Miller : New socket lookup architecture.
+- * This code is dedicated to John Dyson.
+- * David S. Miller : Change semantics of established hash,
+- * half is devoted to TIME_WAIT sockets
+- * and the rest go in the other half.
+- * Andi Kleen : Add support for syncookies and fixed
+- * some bugs: ip options weren't passed to
+- * the TCP layer, missed a check for an
+- * ACK bit.
+- * Andi Kleen : Implemented fast path mtu discovery.
+- * Fixed many serious bugs in the
+- * request_sock handling and moved
+- * most of it into the af independent code.
+- * Added tail drop and some other bugfixes.
+- * Added new listen semantics.
+- * Mike McLagan : Routing by source
+- * Juan Jose Ciarlante: ip_dynaddr bits
+- * Andi Kleen: various fixes.
+- * Vitaly E. Lavrov : Transparent proxy revived after year
+- * coma.
+- * Andi Kleen : Fix new listen.
+- * Andi Kleen : Fix accept error reporting.
+- * YOSHIFUJI Hideaki @USAGI and: Support IPV6_V6ONLY socket option, which
+- * Alexey Kuznetsov allow both IPv4 and IPv6 sockets to bind
+- * a single port at the same time.
+- */
+-
+-
+-#include <linux/types.h>
+-#include <linux/fcntl.h>
+-#include <linux/module.h>
+-#include <linux/random.h>
+-#include <linux/cache.h>
+-#include <linux/jhash.h>
+-#include <linux/init.h>
+-#include <linux/times.h>
+-
+-#include <net/icmp.h>
+-#include <net/inet_hashtables.h>
+-#include <net/tcp.h>
+-#include <net/transp_v6.h>
+-#include <net/ipv6.h>
+-#include <net/inet_common.h>
+-#include <net/timewait_sock.h>
+-#include <net/xfrm.h>
+-#include <net/netdma.h>
+-
+-#include <linux/inet.h>
+-#include <linux/ipv6.h>
+-#include <linux/stddef.h>
+-#include <linux/proc_fs.h>
+-#include <linux/seq_file.h>
+-
+-#include <linux/crypto.h>
+-#include <linux/scatterlist.h>
+-
+-int sysctl_tcp_tw_reuse __read_mostly;
+-int sysctl_tcp_low_latency __read_mostly;
+-
+-/* Check TCP sequence numbers in ICMP packets. */
+-#define ICMP_MIN_LENGTH 8
+-
+-/* Socket used for sending RSTs */
+-static struct socket *tcp_socket __read_mostly;
+-
+-void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb);
+-
+-#ifdef CONFIG_TCP_MD5SIG
+-static struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk,
+- __be32 addr);
+-static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
+- __be32 saddr, __be32 daddr,
+- struct tcphdr *th, int protocol,
+- int tcplen);
+-#endif
+-
+-struct inet_hashinfo __cacheline_aligned tcp_hashinfo = {
+- .lhash_lock = __RW_LOCK_UNLOCKED(tcp_hashinfo.lhash_lock),
+- .lhash_users = ATOMIC_INIT(0),
+- .lhash_wait = __WAIT_QUEUE_HEAD_INITIALIZER(tcp_hashinfo.lhash_wait),
+-};
+-
+-static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
+-{
+- return inet_csk_get_port(&tcp_hashinfo, sk, snum,
+- inet_csk_bind_conflict);
+-}
+-
+-static void tcp_v4_hash(struct sock *sk)
+-{
+- inet_hash(&tcp_hashinfo, sk);
+-}
+-
+-void tcp_unhash(struct sock *sk)
+-{
+- inet_unhash(&tcp_hashinfo, sk);
+-}
+-
+-static inline __u32 tcp_v4_init_sequence(struct sk_buff *skb)
+-{
+- return secure_tcp_sequence_number(ip_hdr(skb)->daddr,
+- ip_hdr(skb)->saddr,
+- tcp_hdr(skb)->dest,
+- tcp_hdr(skb)->source);
+-}
+-
+-int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
+-{
+- const struct tcp_timewait_sock *tcptw = tcp_twsk(sktw);
+- struct tcp_sock *tp = tcp_sk(sk);
+-
+- /* With PAWS, it is safe from the viewpoint
+- of data integrity. Even without PAWS it is safe provided sequence
+- spaces do not overlap i.e. at data rates <= 80Mbit/sec.
+-
+- Actually, the idea is close to VJ's one, only timestamp cache is
+- held not per host, but per port pair and TW bucket is used as state
+- holder.
+-
+- If TW bucket has been already destroyed we fall back to VJ's scheme
+- and use initial timestamp retrieved from peer table.
+- */
+- if (tcptw->tw_ts_recent_stamp &&
+- (twp == NULL || (sysctl_tcp_tw_reuse &&
+- get_seconds() - tcptw->tw_ts_recent_stamp > 1))) {
+- tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2;
+- if (tp->write_seq == 0)
+- tp->write_seq = 1;
+- tp->rx_opt.ts_recent = tcptw->tw_ts_recent;
+- tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
+- sock_hold(sktw);
+- return 1;
+- }
+-
+- return 0;
+-}
+-
+-EXPORT_SYMBOL_GPL(tcp_twsk_unique);
+-
+-/* This will initiate an outgoing connection. */
+-int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+-{
+- struct inet_sock *inet = inet_sk(sk);
+- struct tcp_sock *tp = tcp_sk(sk);
+- struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
+- struct rtable *rt;
+- __be32 daddr, nexthop;
+- int tmp;
+- int err;
+-
+- if (addr_len < sizeof(struct sockaddr_in))
+- return -EINVAL;
+-
+- if (usin->sin_family != AF_INET)
+- return -EAFNOSUPPORT;
+-
+- nexthop = daddr = usin->sin_addr.s_addr;
+- if (inet->opt && inet->opt->srr) {
+- if (!daddr)
+- return -EINVAL;
+- nexthop = inet->opt->faddr;
+- }
+-
+- tmp = ip_route_connect(&rt, nexthop, inet->saddr,
+- RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,
+- IPPROTO_TCP,
+- inet->sport, usin->sin_port, sk, 1);
+- if (tmp < 0) {
+- if (tmp == -ENETUNREACH)
+- IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES);
+- return tmp;
+- }
+-
+- if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) {
+- ip_rt_put(rt);
+- return -ENETUNREACH;
+- }
+-
+- if (!inet->opt || !inet->opt->srr)
+- daddr = rt->rt_dst;
+-
+- if (!inet->saddr)
+- inet->saddr = rt->rt_src;
+- inet->rcv_saddr = inet->saddr;
+-
+- if (tp->rx_opt.ts_recent_stamp && inet->daddr != daddr) {
+- /* Reset inherited state */
+- tp->rx_opt.ts_recent = 0;
+- tp->rx_opt.ts_recent_stamp = 0;
+- tp->write_seq = 0;
+- }
+-
+- if (tcp_death_row.sysctl_tw_recycle &&
+- !tp->rx_opt.ts_recent_stamp && rt->rt_dst == daddr) {
+- struct inet_peer *peer = rt_get_peer(rt);
+- /*
+- * VJ's idea. We save last timestamp seen from
+- * the destination in peer table, when entering state
+- * TIME-WAIT * and initialize rx_opt.ts_recent from it,
+- * when trying new connection.
+- */
+- if (peer != NULL &&
+- peer->tcp_ts_stamp + TCP_PAWS_MSL >= get_seconds()) {
+- tp->rx_opt.ts_recent_stamp = peer->tcp_ts_stamp;
+- tp->rx_opt.ts_recent = peer->tcp_ts;
+- }
+- }
+-
+- inet->dport = usin->sin_port;
+- inet->daddr = daddr;
+-
+- inet_csk(sk)->icsk_ext_hdr_len = 0;
+- if (inet->opt)
+- inet_csk(sk)->icsk_ext_hdr_len = inet->opt->optlen;
+-
+- tp->rx_opt.mss_clamp = 536;
+-
+- /* Socket identity is still unknown (sport may be zero).
+- * However we set state to SYN-SENT and not releasing socket
+- * lock select source port, enter ourselves into the hash tables and
+- * complete initialization after this.
+- */
+- tcp_set_state(sk, TCP_SYN_SENT);
+- err = inet_hash_connect(&tcp_death_row, sk);
+- if (err)
+- goto failure;
+-
+- err = ip_route_newports(&rt, IPPROTO_TCP,
+- inet->sport, inet->dport, sk);
+- if (err)
+- goto failure;
+-
+- /* OK, now commit destination to socket. */
+- sk->sk_gso_type = SKB_GSO_TCPV4;
+- sk_setup_caps(sk, &rt->u.dst);
+-
+- if (!tp->write_seq)
+- tp->write_seq = secure_tcp_sequence_number(inet->saddr,
+- inet->daddr,
+- inet->sport,
+- usin->sin_port);
+-
+- inet->id = tp->write_seq ^ jiffies;
+-
+- err = tcp_connect(sk);
+- rt = NULL;
+- if (err)
+- goto failure;
+-
+- return 0;
+-
+-failure:
+- /*
+- * This unhashes the socket and releases the local port,
+- * if necessary.
+- */
+- tcp_set_state(sk, TCP_CLOSE);
+- ip_rt_put(rt);
+- sk->sk_route_caps = 0;
+- inet->dport = 0;
+- return err;
+-}
+-
+-/*
+- * This routine does path mtu discovery as defined in RFC1191.
+- */
+-static void do_pmtu_discovery(struct sock *sk, struct iphdr *iph, u32 mtu)
+-{
+- struct dst_entry *dst;
+- struct inet_sock *inet = inet_sk(sk);
+-
+- /* We are not interested in TCP_LISTEN and open_requests (SYN-ACKs
+- * send out by Linux are always <576bytes so they should go through
+- * unfragmented).
+- */
+- if (sk->sk_state == TCP_LISTEN)
+- return;
+-
+- /* We don't check in the destentry if pmtu discovery is forbidden
+- * on this route. We just assume that no packet_to_big packets
+- * are send back when pmtu discovery is not active.
+- * There is a small race when the user changes this flag in the
+- * route, but I think that's acceptable.
+- */
+- if ((dst = __sk_dst_check(sk, 0)) == NULL)
+- return;
+-
+- dst->ops->update_pmtu(dst, mtu);
+-
+- /* Something is about to be wrong... Remember soft error
+- * for the case, if this connection will not able to recover.
+- */
+- if (mtu < dst_mtu(dst) && ip_dont_fragment(sk, dst))
+- sk->sk_err_soft = EMSGSIZE;
+-
+- mtu = dst_mtu(dst);
+-
+- if (inet->pmtudisc != IP_PMTUDISC_DONT &&
+- inet_csk(sk)->icsk_pmtu_cookie > mtu) {
+- tcp_sync_mss(sk, mtu);
+-
+- /* Resend the TCP packet because it's
+- * clear that the old packet has been
+- * dropped. This is the new "fast" path mtu
+- * discovery.
+- */
+- tcp_simple_retransmit(sk);
+- } /* else let the usual retransmit timer handle it */
+-}
+-
+-/*
+- * This routine is called by the ICMP module when it gets some
+- * sort of error condition. If err < 0 then the socket should
+- * be closed and the error returned to the user. If err > 0
+- * it's just the icmp type << 8 | icmp code. After adjustment
+- * header points to the first 8 bytes of the tcp header. We need
+- * to find the appropriate port.
+- *
+- * The locking strategy used here is very "optimistic". When
+- * someone else accesses the socket the ICMP is just dropped
+- * and for some paths there is no check at all.
+- * A more general error queue to queue errors for later handling
+- * is probably better.
+- *
+- */
+-
+-void tcp_v4_err(struct sk_buff *skb, u32 info)
+-{
+- struct iphdr *iph = (struct iphdr *)skb->data;
+- struct tcphdr *th = (struct tcphdr *)(skb->data + (iph->ihl << 2));
+- struct tcp_sock *tp;
+- struct inet_sock *inet;
+- const int type = icmp_hdr(skb)->type;
+- const int code = icmp_hdr(skb)->code;
+- struct sock *sk;
+- __u32 seq;
+- int err;
+-
+- if (skb->len < (iph->ihl << 2) + 8) {
+- ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
+- return;
+- }
+-
+- sk = inet_lookup(&tcp_hashinfo, iph->daddr, th->dest, iph->saddr,
+- th->source, inet_iif(skb));
+- if (!sk) {
+- ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
+- return;
+- }
+- if (sk->sk_state == TCP_TIME_WAIT) {
+- inet_twsk_put(inet_twsk(sk));
+- return;
+- }
+-
+- bh_lock_sock(sk);
+- /* If too many ICMPs get dropped on busy
+- * servers this needs to be solved differently.
+- */
+- if (sock_owned_by_user(sk))
+- NET_INC_STATS_BH(LINUX_MIB_LOCKDROPPEDICMPS);
+-
+- if (sk->sk_state == TCP_CLOSE)
+- goto out;
+-
+- tp = tcp_sk(sk);
+- seq = ntohl(th->seq);
+- if (sk->sk_state != TCP_LISTEN &&
+- !between(seq, tp->snd_una, tp->snd_nxt)) {
+- NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS);
+- goto out;
+- }
+-
+- switch (type) {
+- case ICMP_SOURCE_QUENCH:
+- /* Just silently ignore these. */
+- goto out;
+- case ICMP_PARAMETERPROB:
+- err = EPROTO;
+- break;
+- case ICMP_DEST_UNREACH:
+- if (code > NR_ICMP_UNREACH)
+- goto out;
+-
+- if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */
+- if (!sock_owned_by_user(sk))
+- do_pmtu_discovery(sk, iph, info);
+- goto out;
+- }
+-
+- err = icmp_err_convert[code].errno;
+- break;
+- case ICMP_TIME_EXCEEDED:
+- err = EHOSTUNREACH;
+- break;
+- default:
+- goto out;
+- }
+-
+- switch (sk->sk_state) {
+- struct request_sock *req, **prev;
+- case TCP_LISTEN:
+- if (sock_owned_by_user(sk))
+- goto out;
+-
+- req = inet_csk_search_req(sk, &prev, th->dest,
+- iph->daddr, iph->saddr);
+- if (!req)
+- goto out;
+-
+- /* ICMPs are not backlogged, hence we cannot get
+- an established socket here.
+- */
+- BUG_TRAP(!req->sk);
+-
+- if (seq != tcp_rsk(req)->snt_isn) {
+- NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS);
+- goto out;
+- }
+-
+- /*
+- * Still in SYN_RECV, just remove it silently.
+- * There is no good way to pass the error to the newly
+- * created socket, and POSIX does not want network
+- * errors returned from accept().
+- */
+- inet_csk_reqsk_queue_drop(sk, req, prev);
+- goto out;
+-
+- case TCP_SYN_SENT:
+- case TCP_SYN_RECV: /* Cannot happen.
+- It can f.e. if SYNs crossed.
+- */
+- if (!sock_owned_by_user(sk)) {
+- sk->sk_err = err;
+-
+- sk->sk_error_report(sk);
+-
+- tcp_done(sk);
+- } else {
+- sk->sk_err_soft = err;
+- }
+- goto out;
+- }
+-
+- /* If we've already connected we will keep trying
+- * until we time out, or the user gives up.
+- *
+- * rfc1122 4.2.3.9 allows to consider as hard errors
+- * only PROTO_UNREACH and PORT_UNREACH (well, FRAG_FAILED too,
+- * but it is obsoleted by pmtu discovery).
+- *
+- * Note, that in modern internet, where routing is unreliable
+- * and in each dark corner broken firewalls sit, sending random
+- * errors ordered by their masters even this two messages finally lose
+- * their original sense (even Linux sends invalid PORT_UNREACHs)
+- *
+- * Now we are in compliance with RFCs.
+- * --ANK (980905)
+- */
+-
+- inet = inet_sk(sk);
+- if (!sock_owned_by_user(sk) && inet->recverr) {
+- sk->sk_err = err;
+- sk->sk_error_report(sk);
+- } else { /* Only an error on timeout */
+- sk->sk_err_soft = err;
+- }
+-
+-out:
+- bh_unlock_sock(sk);
+- sock_put(sk);
+-}
+-
+-/* This routine computes an IPv4 TCP checksum. */
+-void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb)
+-{
+- struct inet_sock *inet = inet_sk(sk);
+- struct tcphdr *th = tcp_hdr(skb);
+-
+- if (skb->ip_summed == CHECKSUM_PARTIAL) {
+- th->check = ~tcp_v4_check(len, inet->saddr,
+- inet->daddr, 0);
+- skb->csum_start = skb_transport_header(skb) - skb->head;
+- skb->csum_offset = offsetof(struct tcphdr, check);
+- } else {
+- th->check = tcp_v4_check(len, inet->saddr, inet->daddr,
+- csum_partial((char *)th,
+- th->doff << 2,
+- skb->csum));
+- }
+-}
+-
+-int tcp_v4_gso_send_check(struct sk_buff *skb)
+-{
+- const struct iphdr *iph;
+- struct tcphdr *th;
+-
+- if (!pskb_may_pull(skb, sizeof(*th)))
+- return -EINVAL;
+-
+- iph = ip_hdr(skb);
+- th = tcp_hdr(skb);
+-
+- th->check = 0;
+- th->check = ~tcp_v4_check(skb->len, iph->saddr, iph->daddr, 0);
+- skb->csum_start = skb_transport_header(skb) - skb->head;
+- skb->csum_offset = offsetof(struct tcphdr, check);
+- skb->ip_summed = CHECKSUM_PARTIAL;
+- return 0;
+-}
+-
+-/*
+- * This routine will send an RST to the other tcp.
+- *
+- * Someone asks: why I NEVER use socket parameters (TOS, TTL etc.)
+- * for reset.
+- * Answer: if a packet caused RST, it is not for a socket
+- * existing in our system, if it is matched to a socket,
+- * it is just duplicate segment or bug in other side's TCP.
+- * So that we build reply only basing on parameters
+- * arrived with segment.
+- * Exception: precedence violation. We do not implement it in any case.
+- */
+-
+-static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
+-{
+- struct tcphdr *th = tcp_hdr(skb);
+- struct {
+- struct tcphdr th;
+-#ifdef CONFIG_TCP_MD5SIG
+- __be32 opt[(TCPOLEN_MD5SIG_ALIGNED >> 2)];
+-#endif
+- } rep;
+- struct ip_reply_arg arg;
+-#ifdef CONFIG_TCP_MD5SIG
+- struct tcp_md5sig_key *key;
+-#endif
+-
+- /* Never send a reset in response to a reset. */
+- if (th->rst)
+- return;
+-
+- if (((struct rtable *)skb->dst)->rt_type != RTN_LOCAL)
+- return;
+-
+- /* Swap the send and the receive. */
+- memset(&rep, 0, sizeof(rep));
+- rep.th.dest = th->source;
+- rep.th.source = th->dest;
+- rep.th.doff = sizeof(struct tcphdr) / 4;
+- rep.th.rst = 1;
+-
+- if (th->ack) {
+- rep.th.seq = th->ack_seq;
+- } else {
+- rep.th.ack = 1;
+- rep.th.ack_seq = htonl(ntohl(th->seq) + th->syn + th->fin +
+- skb->len - (th->doff << 2));
+- }
+-
+- memset(&arg, 0, sizeof(arg));
+- arg.iov[0].iov_base = (unsigned char *)&rep;
+- arg.iov[0].iov_len = sizeof(rep.th);
+-
+-#ifdef CONFIG_TCP_MD5SIG
+- key = sk ? tcp_v4_md5_do_lookup(sk, ip_hdr(skb)->daddr) : NULL;
+- if (key) {
+- rep.opt[0] = htonl((TCPOPT_NOP << 24) |
+- (TCPOPT_NOP << 16) |
+- (TCPOPT_MD5SIG << 8) |
+- TCPOLEN_MD5SIG);
+- /* Update length and the length the header thinks exists */
+- arg.iov[0].iov_len += TCPOLEN_MD5SIG_ALIGNED;
+- rep.th.doff = arg.iov[0].iov_len / 4;
+-
+- tcp_v4_do_calc_md5_hash((__u8 *)&rep.opt[1],
+- key,
+- ip_hdr(skb)->daddr,
+- ip_hdr(skb)->saddr,
+- &rep.th, IPPROTO_TCP,
+- arg.iov[0].iov_len);
+- }
+-#endif
+- arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr,
+- ip_hdr(skb)->saddr, /* XXX */
+- sizeof(struct tcphdr), IPPROTO_TCP, 0);
+- arg.csumoffset = offsetof(struct tcphdr, check) / 2;
+-
+- ip_send_reply(tcp_socket->sk, skb, &arg, arg.iov[0].iov_len);
+-
+- TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
+- TCP_INC_STATS_BH(TCP_MIB_OUTRSTS);
+-}
+-
+-/* The code following below sending ACKs in SYN-RECV and TIME-WAIT states
+- outside socket context is ugly, certainly. What can I do?
+- */
+-
+-static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
+- struct sk_buff *skb, u32 seq, u32 ack,
+- u32 win, u32 ts)
+-{
+- struct tcphdr *th = tcp_hdr(skb);
+- struct {
+- struct tcphdr th;
+- __be32 opt[(TCPOLEN_TSTAMP_ALIGNED >> 2)
+-#ifdef CONFIG_TCP_MD5SIG
+- + (TCPOLEN_MD5SIG_ALIGNED >> 2)
+-#endif
+- ];
+- } rep;
+- struct ip_reply_arg arg;
+-#ifdef CONFIG_TCP_MD5SIG
+- struct tcp_md5sig_key *key;
+- struct tcp_md5sig_key tw_key;
+-#endif
+-
+- memset(&rep.th, 0, sizeof(struct tcphdr));
+- memset(&arg, 0, sizeof(arg));
+-
+- arg.iov[0].iov_base = (unsigned char *)&rep;
+- arg.iov[0].iov_len = sizeof(rep.th);
+- if (ts) {
+- rep.opt[0] = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
+- (TCPOPT_TIMESTAMP << 8) |
+- TCPOLEN_TIMESTAMP);
+- rep.opt[1] = htonl(tcp_time_stamp);
+- rep.opt[2] = htonl(ts);
+- arg.iov[0].iov_len += TCPOLEN_TSTAMP_ALIGNED;
+- }
+-
+- /* Swap the send and the receive. */
+- rep.th.dest = th->source;
+- rep.th.source = th->dest;
+- rep.th.doff = arg.iov[0].iov_len / 4;
+- rep.th.seq = htonl(seq);
+- rep.th.ack_seq = htonl(ack);
+- rep.th.ack = 1;
+- rep.th.window = htons(win);
+-
+-#ifdef CONFIG_TCP_MD5SIG
+- /*
+- * The SKB holds an imcoming packet, but may not have a valid ->sk
+- * pointer. This is especially the case when we're dealing with a
+- * TIME_WAIT ack, because the sk structure is long gone, and only
+- * the tcp_timewait_sock remains. So the md5 key is stashed in that
+- * structure, and we use it in preference. I believe that (twsk ||
+- * skb->sk) holds true, but we program defensively.
+- */
+- if (!twsk && skb->sk) {
+- key = tcp_v4_md5_do_lookup(skb->sk, ip_hdr(skb)->daddr);
+- } else if (twsk && twsk->tw_md5_keylen) {
+- tw_key.key = twsk->tw_md5_key;
+- tw_key.keylen = twsk->tw_md5_keylen;
+- key = &tw_key;
+- } else
+- key = NULL;
+-
+- if (key) {
+- int offset = (ts) ? 3 : 0;
+-
+- rep.opt[offset++] = htonl((TCPOPT_NOP << 24) |
+- (TCPOPT_NOP << 16) |
+- (TCPOPT_MD5SIG << 8) |
+- TCPOLEN_MD5SIG);
+- arg.iov[0].iov_len += TCPOLEN_MD5SIG_ALIGNED;
+- rep.th.doff = arg.iov[0].iov_len/4;
+-
+- tcp_v4_do_calc_md5_hash((__u8 *)&rep.opt[offset],
+- key,
+- ip_hdr(skb)->daddr,
+- ip_hdr(skb)->saddr,
+- &rep.th, IPPROTO_TCP,
+- arg.iov[0].iov_len);
+- }
+-#endif
+- arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr,
+- ip_hdr(skb)->saddr, /* XXX */
+- arg.iov[0].iov_len, IPPROTO_TCP, 0);
+- arg.csumoffset = offsetof(struct tcphdr, check) / 2;
+- if (twsk)
+- arg.bound_dev_if = twsk->tw_sk.tw_bound_dev_if;
+-
+- ip_send_reply(tcp_socket->sk, skb, &arg, arg.iov[0].iov_len);
+-
+- TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
+-}
+-
+-static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
+-{
+- struct inet_timewait_sock *tw = inet_twsk(sk);
+- struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
+-
+- tcp_v4_send_ack(tcptw, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
+- tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
+- tcptw->tw_ts_recent);
+-
+- inet_twsk_put(tw);
+-}
+-
+-static void tcp_v4_reqsk_send_ack(struct sk_buff *skb,
+- struct request_sock *req)
+-{
+- tcp_v4_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1,
+- tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd,
+- req->ts_recent);
+-}
+-
+-/*
+- * Send a SYN-ACK after having received an ACK.
+- * This still operates on a request_sock only, not on a big
+- * socket.
+- */
+-static int tcp_v4_send_synack(struct sock *sk, struct request_sock *req,
+- struct dst_entry *dst)
+-{
+- const struct inet_request_sock *ireq = inet_rsk(req);
+- int err = -1;
+- struct sk_buff * skb;
+-
+- /* First, grab a route. */
+- if (!dst && (dst = inet_csk_route_req(sk, req)) == NULL)
+- goto out;
+-
+- skb = tcp_make_synack(sk, dst, req);
+-
+- if (skb) {
+- struct tcphdr *th = tcp_hdr(skb);
+-
+- th->check = tcp_v4_check(skb->len,
+- ireq->loc_addr,
+- ireq->rmt_addr,
+- csum_partial((char *)th, skb->len,
+- skb->csum));
+-
+- err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr,
+- ireq->rmt_addr,
+- ireq->opt);
+- err = net_xmit_eval(err);
+- }
+-
+-out:
+- dst_release(dst);
+- return err;
+-}
+-
+-/*
+- * IPv4 request_sock destructor.
+- */
+-static void tcp_v4_reqsk_destructor(struct request_sock *req)
+-{
+- kfree(inet_rsk(req)->opt);
+-}
+-
+-#ifdef CONFIG_SYN_COOKIES
+-static void syn_flood_warning(struct sk_buff *skb)
+-{
+- static unsigned long warntime;
+-
+- if (time_after(jiffies, (warntime + HZ * 60))) {
+- warntime = jiffies;
+- printk(KERN_INFO
+- "possible SYN flooding on port %d. Sending cookies.\n",
+- ntohs(tcp_hdr(skb)->dest));
+- }
+-}
+-#endif
+-
+-/*
+- * Save and compile IPv4 options into the request_sock if needed.
+- */
+-static struct ip_options *tcp_v4_save_options(struct sock *sk,
+- struct sk_buff *skb)
+-{
+- struct ip_options *opt = &(IPCB(skb)->opt);
+- struct ip_options *dopt = NULL;
+-
+- if (opt && opt->optlen) {
+- int opt_size = optlength(opt);
+- dopt = kmalloc(opt_size, GFP_ATOMIC);
+- if (dopt) {
+- if (ip_options_echo(dopt, skb)) {
+- kfree(dopt);
+- dopt = NULL;
+- }
+- }
+- }
+- return dopt;
+-}
+-
+-#ifdef CONFIG_TCP_MD5SIG
+-/*
+- * RFC2385 MD5 checksumming requires a mapping of
+- * IP address->MD5 Key.
+- * We need to maintain these in the sk structure.
+- */
+-
+-/* Find the Key structure for an address. */
+-static struct tcp_md5sig_key *
+- tcp_v4_md5_do_lookup(struct sock *sk, __be32 addr)
+-{
+- struct tcp_sock *tp = tcp_sk(sk);
+- int i;
+-
+- if (!tp->md5sig_info || !tp->md5sig_info->entries4)
+- return NULL;
+- for (i = 0; i < tp->md5sig_info->entries4; i++) {
+- if (tp->md5sig_info->keys4[i].addr == addr)
+- return &tp->md5sig_info->keys4[i].base;
+- }
+- return NULL;
+-}
+-
+-struct tcp_md5sig_key *tcp_v4_md5_lookup(struct sock *sk,
+- struct sock *addr_sk)
+-{
+- return tcp_v4_md5_do_lookup(sk, inet_sk(addr_sk)->daddr);
+-}
+-
+-EXPORT_SYMBOL(tcp_v4_md5_lookup);
+-
+-static struct tcp_md5sig_key *tcp_v4_reqsk_md5_lookup(struct sock *sk,
+- struct request_sock *req)
+-{
+- return tcp_v4_md5_do_lookup(sk, inet_rsk(req)->rmt_addr);
+-}
+-
+-/* This can be called on a newly created socket, from other files */
+-int tcp_v4_md5_do_add(struct sock *sk, __be32 addr,
+- u8 *newkey, u8 newkeylen)
+-{
+- /* Add Key to the list */
+- struct tcp4_md5sig_key *key;
+- struct tcp_sock *tp = tcp_sk(sk);
+- struct tcp4_md5sig_key *keys;
+-
+- key = (struct tcp4_md5sig_key *)tcp_v4_md5_do_lookup(sk, addr);
+- if (key) {
+- /* Pre-existing entry - just update that one. */
+- kfree(key->base.key);
+- key->base.key = newkey;
+- key->base.keylen = newkeylen;
+- } else {
+- struct tcp_md5sig_info *md5sig;
+-
+- if (!tp->md5sig_info) {
+- tp->md5sig_info = kzalloc(sizeof(*tp->md5sig_info),
+- GFP_ATOMIC);
+- if (!tp->md5sig_info) {
+- kfree(newkey);
+- return -ENOMEM;
+- }
+- sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
+- }
+- if (tcp_alloc_md5sig_pool() == NULL) {
+- kfree(newkey);
+- return -ENOMEM;
+- }
+- md5sig = tp->md5sig_info;
+-
+- if (md5sig->alloced4 == md5sig->entries4) {
+- keys = kmalloc((sizeof(*keys) *
+- (md5sig->entries4 + 1)), GFP_ATOMIC);
+- if (!keys) {
+- kfree(newkey);
+- tcp_free_md5sig_pool();
+- return -ENOMEM;
+- }
+-
+- if (md5sig->entries4)
+- memcpy(keys, md5sig->keys4,
+- sizeof(*keys) * md5sig->entries4);
+-
+- /* Free old key list, and reference new one */
+- if (md5sig->keys4)
+- kfree(md5sig->keys4);
+- md5sig->keys4 = keys;
+- md5sig->alloced4++;
+- }
+- md5sig->entries4++;
+- md5sig->keys4[md5sig->entries4 - 1].addr = addr;
+- md5sig->keys4[md5sig->entries4 - 1].base.key = newkey;
+- md5sig->keys4[md5sig->entries4 - 1].base.keylen = newkeylen;
+- }
+- return 0;
+-}
+-
+-EXPORT_SYMBOL(tcp_v4_md5_do_add);
+-
+-static int tcp_v4_md5_add_func(struct sock *sk, struct sock *addr_sk,
+- u8 *newkey, u8 newkeylen)
+-{
+- return tcp_v4_md5_do_add(sk, inet_sk(addr_sk)->daddr,
+- newkey, newkeylen);
+-}
+-
+-int tcp_v4_md5_do_del(struct sock *sk, __be32 addr)
+-{
+- struct tcp_sock *tp = tcp_sk(sk);
+- int i;
+-
+- for (i = 0; i < tp->md5sig_info->entries4; i++) {
+- if (tp->md5sig_info->keys4[i].addr == addr) {
+- /* Free the key */
+- kfree(tp->md5sig_info->keys4[i].base.key);
+- tp->md5sig_info->entries4--;
+-
+- if (tp->md5sig_info->entries4 == 0) {
+- kfree(tp->md5sig_info->keys4);
+- tp->md5sig_info->keys4 = NULL;
+- tp->md5sig_info->alloced4 = 0;
+- } else if (tp->md5sig_info->entries4 != i) {
+- /* Need to do some manipulation */
+- memcpy(&tp->md5sig_info->keys4[i],
+- &tp->md5sig_info->keys4[i+1],
+- (tp->md5sig_info->entries4 - i) *
+- sizeof(struct tcp4_md5sig_key));
+- }
+- tcp_free_md5sig_pool();
+- return 0;
+- }
+- }
+- return -ENOENT;
+-}
+-
+-EXPORT_SYMBOL(tcp_v4_md5_do_del);
+-
+-static void tcp_v4_clear_md5_list(struct sock *sk)
+-{
+- struct tcp_sock *tp = tcp_sk(sk);
+-
+- /* Free each key, then the set of key keys,
+- * the crypto element, and then decrement our
+- * hold on the last resort crypto.
+- */
+- if (tp->md5sig_info->entries4) {
+- int i;
+- for (i = 0; i < tp->md5sig_info->entries4; i++)
+- kfree(tp->md5sig_info->keys4[i].base.key);
+- tp->md5sig_info->entries4 = 0;
+- tcp_free_md5sig_pool();
+- }
+- if (tp->md5sig_info->keys4) {
+- kfree(tp->md5sig_info->keys4);
+- tp->md5sig_info->keys4 = NULL;
+- tp->md5sig_info->alloced4 = 0;
+- }
+-}
+-
+-static int tcp_v4_parse_md5_keys(struct sock *sk, char __user *optval,
+- int optlen)
+-{
+- struct tcp_md5sig cmd;
+- struct sockaddr_in *sin = (struct sockaddr_in *)&cmd.tcpm_addr;
+- u8 *newkey;
+-
+- if (optlen < sizeof(cmd))
+- return -EINVAL;
+-
+- if (copy_from_user(&cmd, optval, sizeof(cmd)))
+- return -EFAULT;
+-
+- if (sin->sin_family != AF_INET)
+- return -EINVAL;
+-
+- if (!cmd.tcpm_key || !cmd.tcpm_keylen) {
+- if (!tcp_sk(sk)->md5sig_info)
+- return -ENOENT;
+- return tcp_v4_md5_do_del(sk, sin->sin_addr.s_addr);
+- }
+-
+- if (cmd.tcpm_keylen > TCP_MD5SIG_MAXKEYLEN)
+- return -EINVAL;
+-
+- if (!tcp_sk(sk)->md5sig_info) {
+- struct tcp_sock *tp = tcp_sk(sk);
+- struct tcp_md5sig_info *p = kzalloc(sizeof(*p), GFP_KERNEL);
+-
+- if (!p)
+- return -EINVAL;
+-
+- tp->md5sig_info = p;
+- sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
+- }
+-
+- newkey = kmemdup(cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL);
+- if (!newkey)
+- return -ENOMEM;
+- return tcp_v4_md5_do_add(sk, sin->sin_addr.s_addr,
+- newkey, cmd.tcpm_keylen);
+-}
+-
+-static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
+- __be32 saddr, __be32 daddr,
+- struct tcphdr *th, int protocol,
+- int tcplen)
+-{
+- struct scatterlist sg[4];
+- __u16 data_len;
+- int block = 0;
+- __sum16 old_checksum;
+- struct tcp_md5sig_pool *hp;
+- struct tcp4_pseudohdr *bp;
+- struct hash_desc *desc;
+- int err;
+- unsigned int nbytes = 0;
+-
+- /*
+- * Okay, so RFC2385 is turned on for this connection,
+- * so we need to generate the MD5 hash for the packet now.
+- */
+-
+- hp = tcp_get_md5sig_pool();
+- if (!hp)
+- goto clear_hash_noput;
+-
+- bp = &hp->md5_blk.ip4;
+- desc = &hp->md5_desc;
+-
+- /*
+- * 1. the TCP pseudo-header (in the order: source IP address,
+- * destination IP address, zero-padded protocol number, and
+- * segment length)
+- */
+- bp->saddr = saddr;
+- bp->daddr = daddr;
+- bp->pad = 0;
+- bp->protocol = protocol;
+- bp->len = htons(tcplen);
+- sg_set_buf(&sg[block++], bp, sizeof(*bp));
+- nbytes += sizeof(*bp);
+-
+- /* 2. the TCP header, excluding options, and assuming a
+- * checksum of zero/
+- */
+- old_checksum = th->check;
+- th->check = 0;
+- sg_set_buf(&sg[block++], th, sizeof(struct tcphdr));
+- nbytes += sizeof(struct tcphdr);
+-
+- /* 3. the TCP segment data (if any) */
+- data_len = tcplen - (th->doff << 2);
+- if (data_len > 0) {
+- unsigned char *data = (unsigned char *)th + (th->doff << 2);
+- sg_set_buf(&sg[block++], data, data_len);
+- nbytes += data_len;
+- }
+-
+- /* 4. an independently-specified key or password, known to both
+- * TCPs and presumably connection-specific
+- */
+- sg_set_buf(&sg[block++], key->key, key->keylen);
+- nbytes += key->keylen;
+-
+- /* Now store the Hash into the packet */
+- err = crypto_hash_init(desc);
+- if (err)
+- goto clear_hash;
+- err = crypto_hash_update(desc, sg, nbytes);
+- if (err)
+- goto clear_hash;
+- err = crypto_hash_final(desc, md5_hash);
+- if (err)
+- goto clear_hash;
+-
+- /* Reset header, and free up the crypto */
+- tcp_put_md5sig_pool();
+- th->check = old_checksum;
+-
+-out:
+- return 0;
+-clear_hash:
+- tcp_put_md5sig_pool();
+-clear_hash_noput:
+- memset(md5_hash, 0, 16);
+- goto out;
+-}
+-
+-int tcp_v4_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
+- struct sock *sk,
+- struct dst_entry *dst,
+- struct request_sock *req,
+- struct tcphdr *th, int protocol,
+- int tcplen)
+-{
+- __be32 saddr, daddr;
+-
+- if (sk) {
+- saddr = inet_sk(sk)->saddr;
+- daddr = inet_sk(sk)->daddr;
+- } else {
+- struct rtable *rt = (struct rtable *)dst;
+- BUG_ON(!rt);
+- saddr = rt->rt_src;
+- daddr = rt->rt_dst;
+- }
+- return tcp_v4_do_calc_md5_hash(md5_hash, key,
+- saddr, daddr,
+- th, protocol, tcplen);
+-}
+-
+-EXPORT_SYMBOL(tcp_v4_calc_md5_hash);
+-
+-static int tcp_v4_inbound_md5_hash(struct sock *sk, struct sk_buff *skb)
+-{
+- /*
+- * This gets called for each TCP segment that arrives
+- * so we want to be efficient.
+- * We have 3 drop cases:
+- * o No MD5 hash and one expected.
+- * o MD5 hash and we're not expecting one.
+- * o MD5 hash and its wrong.
+- */
+- __u8 *hash_location = NULL;
+- struct tcp_md5sig_key *hash_expected;
+- const struct iphdr *iph = ip_hdr(skb);
+- struct tcphdr *th = tcp_hdr(skb);
+- int length = (th->doff << 2) - sizeof(struct tcphdr);
+- int genhash;
+- unsigned char *ptr;
+- unsigned char newhash[16];
+-
+- hash_expected = tcp_v4_md5_do_lookup(sk, iph->saddr);
+-
+- /*
+- * If the TCP option length is less than the TCP_MD5SIG
+- * option length, then we can shortcut
+- */
+- if (length < TCPOLEN_MD5SIG) {
+- if (hash_expected)
+- return 1;
+- else
+- return 0;
+- }
+-
+- /* Okay, we can't shortcut - we have to grub through the options */
+- ptr = (unsigned char *)(th + 1);
+- while (length > 0) {
+- int opcode = *ptr++;
+- int opsize;
+-
+- switch (opcode) {
+- case TCPOPT_EOL:
+- goto done_opts;
+- case TCPOPT_NOP:
+- length--;
+- continue;
+- default:
+- opsize = *ptr++;
+- if (opsize < 2)
+- goto done_opts;
+- if (opsize > length)
+- goto done_opts;
+-
+- if (opcode == TCPOPT_MD5SIG) {
+- hash_location = ptr;
+- goto done_opts;
+- }
+- }
+- ptr += opsize-2;
+- length -= opsize;
+- }
+-done_opts:
+- /* We've parsed the options - do we have a hash? */
+- if (!hash_expected && !hash_location)
+- return 0;
+-
+- if (hash_expected && !hash_location) {
+- LIMIT_NETDEBUG(KERN_INFO "MD5 Hash expected but NOT found "
+- "(" NIPQUAD_FMT ", %d)->(" NIPQUAD_FMT ", %d)\n",
+- NIPQUAD(iph->saddr), ntohs(th->source),
+- NIPQUAD(iph->daddr), ntohs(th->dest));
+- return 1;
+- }
+-
+- if (!hash_expected && hash_location) {
+- LIMIT_NETDEBUG(KERN_INFO "MD5 Hash NOT expected but found "
+- "(" NIPQUAD_FMT ", %d)->(" NIPQUAD_FMT ", %d)\n",
+- NIPQUAD(iph->saddr), ntohs(th->source),
+- NIPQUAD(iph->daddr), ntohs(th->dest));
+- return 1;
+- }
+-
+- /* Okay, so this is hash_expected and hash_location -
+- * so we need to calculate the checksum.
+- */
+- genhash = tcp_v4_do_calc_md5_hash(newhash,
+- hash_expected,
+- iph->saddr, iph->daddr,
+- th, sk->sk_protocol,
+- skb->len);
+-
+- if (genhash || memcmp(hash_location, newhash, 16) != 0) {
+- if (net_ratelimit()) {
+- printk(KERN_INFO "MD5 Hash failed for "
+- "(" NIPQUAD_FMT ", %d)->(" NIPQUAD_FMT ", %d)%s\n",
+- NIPQUAD(iph->saddr), ntohs(th->source),
+- NIPQUAD(iph->daddr), ntohs(th->dest),
+- genhash ? " tcp_v4_calc_md5_hash failed" : "");
+- }
+- return 1;
+- }
+- return 0;
+-}
+-
+-#endif
+-
+-struct request_sock_ops tcp_request_sock_ops __read_mostly = {
+- .family = PF_INET,
+- .obj_size = sizeof(struct tcp_request_sock),
+- .rtx_syn_ack = tcp_v4_send_synack,
+- .send_ack = tcp_v4_reqsk_send_ack,
+- .destructor = tcp_v4_reqsk_destructor,
+- .send_reset = tcp_v4_send_reset,
+-};
+-
+-#ifdef CONFIG_TCP_MD5SIG
+-static struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = {
+- .md5_lookup = tcp_v4_reqsk_md5_lookup,
+-};
+-#endif
+-
+-static struct timewait_sock_ops tcp_timewait_sock_ops = {
+- .twsk_obj_size = sizeof(struct tcp_timewait_sock),
+- .twsk_unique = tcp_twsk_unique,
+- .twsk_destructor= tcp_twsk_destructor,
+-};
+-
+-int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
+-{
+- struct inet_request_sock *ireq;
+- struct tcp_options_received tmp_opt;
+- struct request_sock *req;
+- __be32 saddr = ip_hdr(skb)->saddr;
+- __be32 daddr = ip_hdr(skb)->daddr;
+- __u32 isn = TCP_SKB_CB(skb)->when;
+- struct dst_entry *dst = NULL;
+-#ifdef CONFIG_SYN_COOKIES
+- int want_cookie = 0;
+-#else
+-#define want_cookie 0 /* Argh, why doesn't gcc optimize this :( */
+-#endif
+-
+- /* Never answer to SYNs send to broadcast or multicast */
+- if (((struct rtable *)skb->dst)->rt_flags &
+- (RTCF_BROADCAST | RTCF_MULTICAST))
+- goto drop;
+-
+- /* TW buckets are converted to open requests without
+- * limitations, they conserve resources and peer is
+- * evidently real one.
+- */
+- if (inet_csk_reqsk_queue_is_full(sk) && !isn) {
+-#ifdef CONFIG_SYN_COOKIES
+- if (sysctl_tcp_syncookies) {
+- want_cookie = 1;
+- } else
+-#endif
+- goto drop;
+- }
+-
+- /* Accept backlog is full. If we have already queued enough
+- * of warm entries in syn queue, drop request. It is better than
+- * clogging syn queue with openreqs with exponentially increasing
+- * timeout.
+- */
+- if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
+- goto drop;
+-
+- req = reqsk_alloc(&tcp_request_sock_ops);
+- if (!req)
+- goto drop;
+-
+-#ifdef CONFIG_TCP_MD5SIG
+- tcp_rsk(req)->af_specific = &tcp_request_sock_ipv4_ops;
+-#endif
+-
+- tcp_clear_options(&tmp_opt);
+- tmp_opt.mss_clamp = 536;
+- tmp_opt.user_mss = tcp_sk(sk)->rx_opt.user_mss;
+-
+- tcp_parse_options(skb, &tmp_opt, 0);
+-
+- if (want_cookie) {
+- tcp_clear_options(&tmp_opt);
+- tmp_opt.saw_tstamp = 0;
+- }
+-
+- if (tmp_opt.saw_tstamp && !tmp_opt.rcv_tsval) {
+- /* Some OSes (unknown ones, but I see them on web server, which
+- * contains information interesting only for windows'
+- * users) do not send their stamp in SYN. It is easy case.
+- * We simply do not advertise TS support.
+- */
+- tmp_opt.saw_tstamp = 0;
+- tmp_opt.tstamp_ok = 0;
+- }
+- tmp_opt.tstamp_ok = tmp_opt.saw_tstamp;
+-
+- tcp_openreq_init(req, &tmp_opt, skb);
+-
+- if (security_inet_conn_request(sk, skb, req))
+- goto drop_and_free;
+-
+- ireq = inet_rsk(req);
+- ireq->loc_addr = daddr;
+- ireq->rmt_addr = saddr;
+- ireq->opt = tcp_v4_save_options(sk, skb);
+- if (!want_cookie)
+- TCP_ECN_create_request(req, tcp_hdr(skb));
+-
+- if (want_cookie) {
+-#ifdef CONFIG_SYN_COOKIES
+- syn_flood_warning(skb);
+-#endif
+- isn = cookie_v4_init_sequence(sk, skb, &req->mss);
+- } else if (!isn) {
+- struct inet_peer *peer = NULL;
+-
+- /* VJ's idea. We save last timestamp seen
+- * from the destination in peer table, when entering
+- * state TIME-WAIT, and check against it before
+- * accepting new connection request.
+- *
+- * If "isn" is not zero, this request hit alive
+- * timewait bucket, so that all the necessary checks
+- * are made in the function processing timewait state.
+- */
+- if (tmp_opt.saw_tstamp &&
+- tcp_death_row.sysctl_tw_recycle &&
+- (dst = inet_csk_route_req(sk, req)) != NULL &&
+- (peer = rt_get_peer((struct rtable *)dst)) != NULL &&
+- peer->v4daddr == saddr) {
+- if (get_seconds() < peer->tcp_ts_stamp + TCP_PAWS_MSL &&
+- (s32)(peer->tcp_ts - req->ts_recent) >
+- TCP_PAWS_WINDOW) {
+- NET_INC_STATS_BH(LINUX_MIB_PAWSPASSIVEREJECTED);
+- dst_release(dst);
+- goto drop_and_free;
+- }
+- }
+- /* Kill the following clause, if you dislike this way. */
+- else if (!sysctl_tcp_syncookies &&
+- (sysctl_max_syn_backlog - inet_csk_reqsk_queue_len(sk) <
+- (sysctl_max_syn_backlog >> 2)) &&
+- (!peer || !peer->tcp_ts_stamp) &&
+- (!dst || !dst_metric(dst, RTAX_RTT))) {
+- /* Without syncookies last quarter of
+- * backlog is filled with destinations,
+- * proven to be alive.
+- * It means that we continue to communicate
+- * to destinations, already remembered
+- * to the moment of synflood.
+- */
+- LIMIT_NETDEBUG(KERN_DEBUG "TCP: drop open "
+- "request from %u.%u.%u.%u/%u\n",
+- NIPQUAD(saddr),
+- ntohs(tcp_hdr(skb)->source));
+- dst_release(dst);
+- goto drop_and_free;
+- }
+-
+- isn = tcp_v4_init_sequence(skb);
+- }
+- tcp_rsk(req)->snt_isn = isn;
+-
+- if (tcp_v4_send_synack(sk, req, dst))
+- goto drop_and_free;
+-
+- if (want_cookie) {
+- reqsk_free(req);
+- } else {
+- inet_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
+- }
+- return 0;
+-
+-drop_and_free:
+- reqsk_free(req);
+-drop:
+- return 0;
+-}
+-
+-
+-/*
+- * The three way handshake has completed - we got a valid synack -
+- * now create the new socket.
+- */
+-struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
+- struct request_sock *req,
+- struct dst_entry *dst)
+-{
+- struct inet_request_sock *ireq;
+- struct inet_sock *newinet;
+- struct tcp_sock *newtp;
+- struct sock *newsk;
+-#ifdef CONFIG_TCP_MD5SIG
+- struct tcp_md5sig_key *key;
+-#endif
+-
+- if (sk_acceptq_is_full(sk))
+- goto exit_overflow;
+-
+- if (!dst && (dst = inet_csk_route_req(sk, req)) == NULL)
+- goto exit;
+-
+- newsk = tcp_create_openreq_child(sk, req, skb);
+- if (!newsk)
+- goto exit;
+-
+- newsk->sk_gso_type = SKB_GSO_TCPV4;
+- sk_setup_caps(newsk, dst);
+-
+- newtp = tcp_sk(newsk);
+- newinet = inet_sk(newsk);
+- ireq = inet_rsk(req);
+- newinet->daddr = ireq->rmt_addr;
+- newinet->rcv_saddr = ireq->loc_addr;
+- newinet->saddr = ireq->loc_addr;
+- newinet->opt = ireq->opt;
+- ireq->opt = NULL;
+- newinet->mc_index = inet_iif(skb);
+- newinet->mc_ttl = ip_hdr(skb)->ttl;
+- inet_csk(newsk)->icsk_ext_hdr_len = 0;
+- if (newinet->opt)
+- inet_csk(newsk)->icsk_ext_hdr_len = newinet->opt->optlen;
+- newinet->id = newtp->write_seq ^ jiffies;
+-
+- tcp_mtup_init(newsk);
+- tcp_sync_mss(newsk, dst_mtu(dst));
+- newtp->advmss = dst_metric(dst, RTAX_ADVMSS);
+- tcp_initialize_rcv_mss(newsk);
+-
+-#ifdef CONFIG_TCP_MD5SIG
+- /* Copy over the MD5 key from the original socket */
+- if ((key = tcp_v4_md5_do_lookup(sk, newinet->daddr)) != NULL) {
+- /*
+- * We're using one, so create a matching key
+- * on the newsk structure. If we fail to get
+- * memory, then we end up not copying the key
+- * across. Shucks.
+- */
+- char *newkey = kmemdup(key->key, key->keylen, GFP_ATOMIC);
+- if (newkey != NULL)
+- tcp_v4_md5_do_add(newsk, inet_sk(sk)->daddr,
+- newkey, key->keylen);
+- }
+-#endif
+-
+- __inet_hash(&tcp_hashinfo, newsk, 0);
+- __inet_inherit_port(&tcp_hashinfo, sk, newsk);
+-
+- return newsk;
+-
+-exit_overflow:
+- NET_INC_STATS_BH(LINUX_MIB_LISTENOVERFLOWS);
+-exit:
+- NET_INC_STATS_BH(LINUX_MIB_LISTENDROPS);
+- dst_release(dst);
+- return NULL;
+-}
+-
+-static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
+-{
+- struct tcphdr *th = tcp_hdr(skb);
+- const struct iphdr *iph = ip_hdr(skb);
+- struct sock *nsk;
+- struct request_sock **prev;
+- /* Find possible connection requests. */
+- struct request_sock *req = inet_csk_search_req(sk, &prev, th->source,
+- iph->saddr, iph->daddr);
+- if (req)
+- return tcp_check_req(sk, skb, req, prev);
+-
+- nsk = inet_lookup_established(&tcp_hashinfo, iph->saddr, th->source,
+- iph->daddr, th->dest, inet_iif(skb));
+-
+- if (nsk) {
+- if (nsk->sk_state != TCP_TIME_WAIT) {
+- bh_lock_sock(nsk);
+- return nsk;
+- }
+- inet_twsk_put(inet_twsk(nsk));
+- return NULL;
+- }
+-
+-#ifdef CONFIG_SYN_COOKIES
+- if (!th->rst && !th->syn && th->ack)
+- sk = cookie_v4_check(sk, skb, &(IPCB(skb)->opt));
+-#endif
+- return sk;
+-}
+-
+-static __sum16 tcp_v4_checksum_init(struct sk_buff *skb)
+-{
+- const struct iphdr *iph = ip_hdr(skb);
+-
+- if (skb->ip_summed == CHECKSUM_COMPLETE) {
+- if (!tcp_v4_check(skb->len, iph->saddr,
+- iph->daddr, skb->csum)) {
+- skb->ip_summed = CHECKSUM_UNNECESSARY;
+- return 0;
+- }
+- }
+-
+- skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
+- skb->len, IPPROTO_TCP, 0);
+-
+- if (skb->len <= 76) {
+- return __skb_checksum_complete(skb);
+- }
+- return 0;
+-}
+-
+-
+-/* The socket must have it's spinlock held when we get
+- * here.
+- *
+- * We have a potential double-lock case here, so even when
+- * doing backlog processing we use the BH locking scheme.
+- * This is because we cannot sleep with the original spinlock
+- * held.
+- */
+-int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
+-{
+- struct sock *rsk;
+-#ifdef CONFIG_TCP_MD5SIG
+- /*
+- * We really want to reject the packet as early as possible
+- * if:
+- * o We're expecting an MD5'd packet and this is no MD5 tcp option
+- * o There is an MD5 option and we're not expecting one
+- */
+- if (tcp_v4_inbound_md5_hash(sk, skb))
+- goto discard;
+-#endif
+-
+- if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
+- TCP_CHECK_TIMER(sk);
+- if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) {
+- rsk = sk;
+- goto reset;
+- }
+- TCP_CHECK_TIMER(sk);
+- return 0;
+- }
+-
+- if (skb->len < tcp_hdrlen(skb) || tcp_checksum_complete(skb))
+- goto csum_err;
+-
+- if (sk->sk_state == TCP_LISTEN) {
+- struct sock *nsk = tcp_v4_hnd_req(sk, skb);
+- if (!nsk)
+- goto discard;
+-
+- if (nsk != sk) {
+- if (tcp_child_process(sk, nsk, skb)) {
+- rsk = nsk;
+- goto reset;
+- }
+- return 0;
+- }
+- }
+-
+- TCP_CHECK_TIMER(sk);
+- if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len)) {
+- rsk = sk;
+- goto reset;
+- }
+- TCP_CHECK_TIMER(sk);
+- return 0;
+-
+-reset:
+- tcp_v4_send_reset(rsk, skb);
+-discard:
+- kfree_skb(skb);
+- /* Be careful here. If this function gets more complicated and
+- * gcc suffers from register pressure on the x86, sk (in %ebx)
+- * might be destroyed here. This current version compiles correctly,
+- * but you have been warned.
+- */
+- return 0;
+-
+-csum_err:
+- TCP_INC_STATS_BH(TCP_MIB_INERRS);
+- goto discard;
+-}
+-
+-/*
+- * From tcp_input.c
+- */
+-
+-int tcp_v4_rcv(struct sk_buff *skb)
+-{
+- const struct iphdr *iph;
+- struct tcphdr *th;
+- struct sock *sk;
+- int ret;
+-
+- if (skb->pkt_type != PACKET_HOST)
+- goto discard_it;
+-
+- /* Count it even if it's bad */
+- TCP_INC_STATS_BH(TCP_MIB_INSEGS);
+-
+- if (!pskb_may_pull(skb, sizeof(struct tcphdr)))
+- goto discard_it;
+-
+- th = tcp_hdr(skb);
+-
+- if (th->doff < sizeof(struct tcphdr) / 4)
+- goto bad_packet;
+- if (!pskb_may_pull(skb, th->doff * 4))
+- goto discard_it;
+-
+- /* An explanation is required here, I think.
+- * Packet length and doff are validated by header prediction,
+- * provided case of th->doff==0 is eliminated.
+- * So, we defer the checks. */
+- if (!skb_csum_unnecessary(skb) && tcp_v4_checksum_init(skb))
+- goto bad_packet;
+-
+- th = tcp_hdr(skb);
+- iph = ip_hdr(skb);
+- TCP_SKB_CB(skb)->seq = ntohl(th->seq);
+- TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
+- skb->len - th->doff * 4);
+- TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
+- TCP_SKB_CB(skb)->when = 0;
+- TCP_SKB_CB(skb)->flags = iph->tos;
+- TCP_SKB_CB(skb)->sacked = 0;
+-
+- sk = __inet_lookup(&tcp_hashinfo, iph->saddr, th->source,
+- iph->daddr, th->dest, inet_iif(skb));
+- if (!sk)
+- goto no_tcp_socket;
+-
+-process:
+- if (sk->sk_state == TCP_TIME_WAIT)
+- goto do_time_wait;
+-
+- if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
+- goto discard_and_relse;
+- nf_reset(skb);
+-
+- if (sk_filter(sk, skb))
+- goto discard_and_relse;
+-
+- skb->dev = NULL;
+-
+- bh_lock_sock_nested(sk);
+- ret = 0;
+- if (!sock_owned_by_user(sk)) {
+-#ifdef CONFIG_NET_DMA
+- struct tcp_sock *tp = tcp_sk(sk);
+- if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list)
+- tp->ucopy.dma_chan = get_softnet_dma();
+- if (tp->ucopy.dma_chan)
+- ret = tcp_v4_do_rcv(sk, skb);
+- else
+-#endif
+- {
+- if (!tcp_prequeue(sk, skb))
+- ret = tcp_v4_do_rcv(sk, skb);
+- }
+- } else
+- sk_add_backlog(sk, skb);
+- bh_unlock_sock(sk);
+-
+- sock_put(sk);
+-
+- return ret;
+-
+-no_tcp_socket:
+- if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
+- goto discard_it;
+-
+- if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) {
+-bad_packet:
+- TCP_INC_STATS_BH(TCP_MIB_INERRS);
+- } else {
+- tcp_v4_send_reset(NULL, skb);
+- }
+-
+-discard_it:
+- /* Discard frame. */
+- kfree_skb(skb);
+- return 0;
+-
+-discard_and_relse:
+- sock_put(sk);
+- goto discard_it;
+-
+-do_time_wait:
+- if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+- inet_twsk_put(inet_twsk(sk));
+- goto discard_it;
+- }
+-
+- if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) {
+- TCP_INC_STATS_BH(TCP_MIB_INERRS);
+- inet_twsk_put(inet_twsk(sk));
+- goto discard_it;
+- }
+- switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) {
+- case TCP_TW_SYN: {
+- struct sock *sk2 = inet_lookup_listener(&tcp_hashinfo,
+- iph->daddr, th->dest,
+- inet_iif(skb));
+- if (sk2) {
+- inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row);
+- inet_twsk_put(inet_twsk(sk));
+- sk = sk2;
+- goto process;
+- }
+- /* Fall through to ACK */
+- }
+- case TCP_TW_ACK:
+- tcp_v4_timewait_ack(sk, skb);
+- break;
+- case TCP_TW_RST:
+- goto no_tcp_socket;
+- case TCP_TW_SUCCESS:;
+- }
+- goto discard_it;
+-}
+-
+-/* VJ's idea. Save last timestamp seen from this destination
+- * and hold it at least for normal timewait interval to use for duplicate
+- * segment detection in subsequent connections, before they enter synchronized
+- * state.
+- */
+-
+-int tcp_v4_remember_stamp(struct sock *sk)
+-{
+- struct inet_sock *inet = inet_sk(sk);
+- struct tcp_sock *tp = tcp_sk(sk);
+- struct rtable *rt = (struct rtable *)__sk_dst_get(sk);
+- struct inet_peer *peer = NULL;
+- int release_it = 0;
+-
+- if (!rt || rt->rt_dst != inet->daddr) {
+- peer = inet_getpeer(inet->daddr, 1);
+- release_it = 1;
+- } else {
+- if (!rt->peer)
+- rt_bind_peer(rt, 1);
+- peer = rt->peer;
+- }
+-
+- if (peer) {
+- if ((s32)(peer->tcp_ts - tp->rx_opt.ts_recent) <= 0 ||
+- (peer->tcp_ts_stamp + TCP_PAWS_MSL < get_seconds() &&
+- peer->tcp_ts_stamp <= tp->rx_opt.ts_recent_stamp)) {
+- peer->tcp_ts_stamp = tp->rx_opt.ts_recent_stamp;
+- peer->tcp_ts = tp->rx_opt.ts_recent;
+- }
+- if (release_it)
+- inet_putpeer(peer);
+- return 1;
+- }
+-
+- return 0;
+-}
+-
+-int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw)
+-{
+- struct inet_peer *peer = inet_getpeer(tw->tw_daddr, 1);
+-
+- if (peer) {
+- const struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw);
+-
+- if ((s32)(peer->tcp_ts - tcptw->tw_ts_recent) <= 0 ||
+- (peer->tcp_ts_stamp + TCP_PAWS_MSL < get_seconds() &&
+- peer->tcp_ts_stamp <= tcptw->tw_ts_recent_stamp)) {
+- peer->tcp_ts_stamp = tcptw->tw_ts_recent_stamp;
+- peer->tcp_ts = tcptw->tw_ts_recent;
+- }
+- inet_putpeer(peer);
+- return 1;
+- }
+-
+- return 0;
+-}
+-
+-struct inet_connection_sock_af_ops ipv4_specific = {
+- .queue_xmit = ip_queue_xmit,
+- .send_check = tcp_v4_send_check,
+- .rebuild_header = inet_sk_rebuild_header,
+- .conn_request = tcp_v4_conn_request,
+- .syn_recv_sock = tcp_v4_syn_recv_sock,
+- .remember_stamp = tcp_v4_remember_stamp,
+- .net_header_len = sizeof(struct iphdr),
+- .setsockopt = ip_setsockopt,
+- .getsockopt = ip_getsockopt,
+- .addr2sockaddr = inet_csk_addr2sockaddr,
+- .sockaddr_len = sizeof(struct sockaddr_in),
+-#ifdef CONFIG_COMPAT
+- .compat_setsockopt = compat_ip_setsockopt,
+- .compat_getsockopt = compat_ip_getsockopt,
+-#endif
+-};
+-
+-#ifdef CONFIG_TCP_MD5SIG
+-static struct tcp_sock_af_ops tcp_sock_ipv4_specific = {
+- .md5_lookup = tcp_v4_md5_lookup,
+- .calc_md5_hash = tcp_v4_calc_md5_hash,
+- .md5_add = tcp_v4_md5_add_func,
+- .md5_parse = tcp_v4_parse_md5_keys,
+-};
+-#endif
+-
+-/* NOTE: A lot of things set to zero explicitly by call to
+- * sk_alloc() so need not be done here.
+- */
+-static int tcp_v4_init_sock(struct sock *sk)
+-{
+- struct inet_connection_sock *icsk = inet_csk(sk);
+- struct tcp_sock *tp = tcp_sk(sk);
+-
+- skb_queue_head_init(&tp->out_of_order_queue);
+- tcp_init_xmit_timers(sk);
+- tcp_prequeue_init(tp);
+-
+- icsk->icsk_rto = TCP_TIMEOUT_INIT;
+- tp->mdev = TCP_TIMEOUT_INIT;
+-
+- /* So many TCP implementations out there (incorrectly) count the
+- * initial SYN frame in their delayed-ACK and congestion control
+- * algorithms that we must have the following bandaid to talk
+- * efficiently to them. -DaveM
+- */
+- tp->snd_cwnd = 2;
+-
+- /* See draft-stevens-tcpca-spec-01 for discussion of the
+- * initialization of these values.
+- */
+- tp->snd_ssthresh = 0x7fffffff; /* Infinity */
+- tp->snd_cwnd_clamp = ~0;
+- tp->mss_cache = 536;
+-
+- tp->reordering = sysctl_tcp_reordering;
+- icsk->icsk_ca_ops = &tcp_init_congestion_ops;
+-
+- sk->sk_state = TCP_CLOSE;
+-
+- sk->sk_write_space = sk_stream_write_space;
+- sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
+-
+- icsk->icsk_af_ops = &ipv4_specific;
+- icsk->icsk_sync_mss = tcp_sync_mss;
+-#ifdef CONFIG_TCP_MD5SIG
+- tp->af_specific = &tcp_sock_ipv4_specific;
+-#endif
+-
+- sk->sk_sndbuf = sysctl_tcp_wmem[1];
+- sk->sk_rcvbuf = sysctl_tcp_rmem[1];
+-
+- atomic_inc(&tcp_sockets_allocated);
+-
+- return 0;
+-}
+-
+-int tcp_v4_destroy_sock(struct sock *sk)
+-{
+- struct tcp_sock *tp = tcp_sk(sk);
+-
+- tcp_clear_xmit_timers(sk);
+-
+- tcp_cleanup_congestion_control(sk);
+-
+- /* Cleanup up the write buffer. */
+- tcp_write_queue_purge(sk);
+-
+- /* Cleans up our, hopefully empty, out_of_order_queue. */
+- __skb_queue_purge(&tp->out_of_order_queue);
+-
+-#ifdef CONFIG_TCP_MD5SIG
+- /* Clean up the MD5 key list, if any */
+- if (tp->md5sig_info) {
+- tcp_v4_clear_md5_list(sk);
+- kfree(tp->md5sig_info);
+- tp->md5sig_info = NULL;
+- }
+-#endif
+-
+-#ifdef CONFIG_NET_DMA
+- /* Cleans up our sk_async_wait_queue */
+- __skb_queue_purge(&sk->sk_async_wait_queue);
+-#endif
+-
+- /* Clean prequeue, it must be empty really */
+- __skb_queue_purge(&tp->ucopy.prequeue);
+-
+- /* Clean up a referenced TCP bind bucket. */
+- if (inet_csk(sk)->icsk_bind_hash)
+- inet_put_port(&tcp_hashinfo, sk);
+-
+- /*
+- * If sendmsg cached page exists, toss it.
+- */
+- if (sk->sk_sndmsg_page) {
+- __free_page(sk->sk_sndmsg_page);
+- sk->sk_sndmsg_page = NULL;
+- }
+-
+- atomic_dec(&tcp_sockets_allocated);
+-
+- return 0;
+-}
+-
+-EXPORT_SYMBOL(tcp_v4_destroy_sock);
+-
+-#ifdef CONFIG_PROC_FS
+-/* Proc filesystem TCP sock list dumping. */
+-
+-static inline struct inet_timewait_sock *tw_head(struct hlist_head *head)
+-{
+- return hlist_empty(head) ? NULL :
+- list_entry(head->first, struct inet_timewait_sock, tw_node);
+-}
+-
+-static inline struct inet_timewait_sock *tw_next(struct inet_timewait_sock *tw)
+-{
+- return tw->tw_node.next ?
+- hlist_entry(tw->tw_node.next, typeof(*tw), tw_node) : NULL;
+-}
+-
+-static void *listening_get_next(struct seq_file *seq, void *cur)
+-{
+- struct inet_connection_sock *icsk;
+- struct hlist_node *node;
+- struct sock *sk = cur;
+- struct tcp_iter_state* st = seq->private;
+-
+- if (!sk) {
+- st->bucket = 0;
+- sk = sk_head(&tcp_hashinfo.listening_hash[0]);
+- goto get_sk;
+- }
+-
+- ++st->num;
+-
+- if (st->state == TCP_SEQ_STATE_OPENREQ) {
+- struct request_sock *req = cur;
+-
+- icsk = inet_csk(st->syn_wait_sk);
+- req = req->dl_next;
+- while (1) {
+- while (req) {
+- if (req->rsk_ops->family == st->family) {
+- cur = req;
+- goto out;
+- }
+- req = req->dl_next;
+- }
+- if (++st->sbucket >= icsk->icsk_accept_queue.listen_opt->nr_table_entries)
+- break;
+-get_req:
+- req = icsk->icsk_accept_queue.listen_opt->syn_table[st->sbucket];
+- }
+- sk = sk_next(st->syn_wait_sk);
+- st->state = TCP_SEQ_STATE_LISTENING;
+- read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock);
+- } else {
+- icsk = inet_csk(sk);
+- read_lock_bh(&icsk->icsk_accept_queue.syn_wait_lock);
+- if (reqsk_queue_len(&icsk->icsk_accept_queue))
+- goto start_req;
+- read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock);
+- sk = sk_next(sk);
+- }
+-get_sk:
+- sk_for_each_from(sk, node) {
+- if (sk->sk_family == st->family) {
+- cur = sk;
+- goto out;
+- }
+- icsk = inet_csk(sk);
+- read_lock_bh(&icsk->icsk_accept_queue.syn_wait_lock);
+- if (reqsk_queue_len(&icsk->icsk_accept_queue)) {
+-start_req:
+- st->uid = sock_i_uid(sk);
+- st->syn_wait_sk = sk;
+- st->state = TCP_SEQ_STATE_OPENREQ;
+- st->sbucket = 0;
+- goto get_req;
+- }
+- read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock);
+- }
+- if (++st->bucket < INET_LHTABLE_SIZE) {
+- sk = sk_head(&tcp_hashinfo.listening_hash[st->bucket]);
+- goto get_sk;
+- }
+- cur = NULL;
+-out:
+- return cur;
+-}
+-
+-static void *listening_get_idx(struct seq_file *seq, loff_t *pos)
+-{
+- void *rc = listening_get_next(seq, NULL);
+-
+- while (rc && *pos) {
+- rc = listening_get_next(seq, rc);
+- --*pos;
+- }
+- return rc;
+-}
+-
+-static void *established_get_first(struct seq_file *seq)
+-{
+- struct tcp_iter_state* st = seq->private;
+- void *rc = NULL;
+-
+- for (st->bucket = 0; st->bucket < tcp_hashinfo.ehash_size; ++st->bucket) {
+- struct sock *sk;
+- struct hlist_node *node;
+- struct inet_timewait_sock *tw;
+-
+- /* We can reschedule _before_ having picked the target: */
+- cond_resched_softirq();
+-
+- read_lock(&tcp_hashinfo.ehash[st->bucket].lock);
+- sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
+- if (sk->sk_family != st->family) {
+- continue;
+- }
+- rc = sk;
+- goto out;
+- }
+- st->state = TCP_SEQ_STATE_TIME_WAIT;
+- inet_twsk_for_each(tw, node,
+- &tcp_hashinfo.ehash[st->bucket].twchain) {
+- if (tw->tw_family != st->family) {
+- continue;
+- }
+- rc = tw;
+- goto out;
+- }
+- read_unlock(&tcp_hashinfo.ehash[st->bucket].lock);
+- st->state = TCP_SEQ_STATE_ESTABLISHED;
+- }
+-out:
+- return rc;
+-}
+-
+-static void *established_get_next(struct seq_file *seq, void *cur)
+-{
+- struct sock *sk = cur;
+- struct inet_timewait_sock *tw;
+- struct hlist_node *node;
+- struct tcp_iter_state* st = seq->private;
+-
+- ++st->num;
+-
+- if (st->state == TCP_SEQ_STATE_TIME_WAIT) {
+- tw = cur;
+- tw = tw_next(tw);
+-get_tw:
+- while (tw && tw->tw_family != st->family) {
+- tw = tw_next(tw);
+- }
+- if (tw) {
+- cur = tw;
+- goto out;
+- }
+- read_unlock(&tcp_hashinfo.ehash[st->bucket].lock);
+- st->state = TCP_SEQ_STATE_ESTABLISHED;
+-
+- /* We can reschedule between buckets: */
+- cond_resched_softirq();
+-
+- if (++st->bucket < tcp_hashinfo.ehash_size) {
+- read_lock(&tcp_hashinfo.ehash[st->bucket].lock);
+- sk = sk_head(&tcp_hashinfo.ehash[st->bucket].chain);
+- } else {
+- cur = NULL;
+- goto out;
+- }
+- } else
+- sk = sk_next(sk);
+-
+- sk_for_each_from(sk, node) {
+- if (sk->sk_family == st->family)
+- goto found;
+- }
+-
+- st->state = TCP_SEQ_STATE_TIME_WAIT;
+- tw = tw_head(&tcp_hashinfo.ehash[st->bucket].twchain);
+- goto get_tw;
+-found:
+- cur = sk;
+-out:
+- return cur;
+-}
+-
+-static void *established_get_idx(struct seq_file *seq, loff_t pos)
+-{
+- void *rc = established_get_first(seq);
+-
+- while (rc && pos) {
+- rc = established_get_next(seq, rc);
+- --pos;
+- }
+- return rc;
+-}
+-
+-static void *tcp_get_idx(struct seq_file *seq, loff_t pos)
+-{
+- void *rc;
+- struct tcp_iter_state* st = seq->private;
+-
+- inet_listen_lock(&tcp_hashinfo);
+- st->state = TCP_SEQ_STATE_LISTENING;
+- rc = listening_get_idx(seq, &pos);
+-
+- if (!rc) {
+- inet_listen_unlock(&tcp_hashinfo);
+- local_bh_disable();
+- st->state = TCP_SEQ_STATE_ESTABLISHED;
+- rc = established_get_idx(seq, pos);
+- }
+-
+- return rc;
+-}
+-
+-static void *tcp_seq_start(struct seq_file *seq, loff_t *pos)
+-{
+- struct tcp_iter_state* st = seq->private;
+- st->state = TCP_SEQ_STATE_LISTENING;
+- st->num = 0;
+- return *pos ? tcp_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+-}
+-
+-static void *tcp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+-{
+- void *rc = NULL;
+- struct tcp_iter_state* st;
+-
+- if (v == SEQ_START_TOKEN) {
+- rc = tcp_get_idx(seq, 0);
+- goto out;
+- }
+- st = seq->private;
+-
+- switch (st->state) {
+- case TCP_SEQ_STATE_OPENREQ:
+- case TCP_SEQ_STATE_LISTENING:
+- rc = listening_get_next(seq, v);
+- if (!rc) {
+- inet_listen_unlock(&tcp_hashinfo);
+- local_bh_disable();
+- st->state = TCP_SEQ_STATE_ESTABLISHED;
+- rc = established_get_first(seq);
+- }
+- break;
+- case TCP_SEQ_STATE_ESTABLISHED:
+- case TCP_SEQ_STATE_TIME_WAIT:
+- rc = established_get_next(seq, v);
+- break;
+- }
+-out:
+- ++*pos;
+- return rc;
+-}
+-
+-static void tcp_seq_stop(struct seq_file *seq, void *v)
+-{
+- struct tcp_iter_state* st = seq->private;
+-
+- switch (st->state) {
+- case TCP_SEQ_STATE_OPENREQ:
+- if (v) {
+- struct inet_connection_sock *icsk = inet_csk(st->syn_wait_sk);
+- read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock);
+- }
+- case TCP_SEQ_STATE_LISTENING:
+- if (v != SEQ_START_TOKEN)
+- inet_listen_unlock(&tcp_hashinfo);
+- break;
+- case TCP_SEQ_STATE_TIME_WAIT:
+- case TCP_SEQ_STATE_ESTABLISHED:
+- if (v)
+- read_unlock(&tcp_hashinfo.ehash[st->bucket].lock);
+- local_bh_enable();
+- break;
+- }
+-}
+-
+-static int tcp_seq_open(struct inode *inode, struct file *file)
+-{
+- struct tcp_seq_afinfo *afinfo = PDE(inode)->data;
+- struct seq_file *seq;
+- struct tcp_iter_state *s;
+- int rc;
+-
+- if (unlikely(afinfo == NULL))
+- return -EINVAL;
+-
+- s = kzalloc(sizeof(*s), GFP_KERNEL);
+- if (!s)
+- return -ENOMEM;
+- s->family = afinfo->family;
+- s->seq_ops.start = tcp_seq_start;
+- s->seq_ops.next = tcp_seq_next;
+- s->seq_ops.show = afinfo->seq_show;
+- s->seq_ops.stop = tcp_seq_stop;
+-
+- rc = seq_open(file, &s->seq_ops);
+- if (rc)
+- goto out_kfree;
+- seq = file->private_data;
+- seq->private = s;
+-out:
+- return rc;
+-out_kfree:
+- kfree(s);
+- goto out;
+-}
+-
+-int tcp_proc_register(struct tcp_seq_afinfo *afinfo)
+-{
+- int rc = 0;
+- struct proc_dir_entry *p;
+-
+- if (!afinfo)
+- return -EINVAL;
+- afinfo->seq_fops->owner = afinfo->owner;
+- afinfo->seq_fops->open = tcp_seq_open;
+- afinfo->seq_fops->read = seq_read;
+- afinfo->seq_fops->llseek = seq_lseek;
+- afinfo->seq_fops->release = seq_release_private;
+-
+- p = proc_net_fops_create(afinfo->name, S_IRUGO, afinfo->seq_fops);
+- if (p)
+- p->data = afinfo;
+- else
+- rc = -ENOMEM;
+- return rc;
+-}
+-
+-void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo)
+-{
+- if (!afinfo)
+- return;
+- proc_net_remove(afinfo->name);
+- memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops));
+-}
+-
+-static void get_openreq4(struct sock *sk, struct request_sock *req,
+- char *tmpbuf, int i, int uid)
+-{
+- const struct inet_request_sock *ireq = inet_rsk(req);
+- int ttd = req->expires - jiffies;
+-
+- sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
+- " %02X %08X:%08X %02X:%08lX %08X %5d %8d %u %d %p",
+- i,
+- ireq->loc_addr,
+- ntohs(inet_sk(sk)->sport),
+- ireq->rmt_addr,
+- ntohs(ireq->rmt_port),
+- TCP_SYN_RECV,
+- 0, 0, /* could print option size, but that is af dependent. */
+- 1, /* timers active (only the expire timer) */
+- jiffies_to_clock_t(ttd),
+- req->retrans,
+- uid,
+- 0, /* non standard timer */
+- 0, /* open_requests have no inode */
+- atomic_read(&sk->sk_refcnt),
+- req);
+-}
+-
+-static void get_tcp4_sock(struct sock *sk, char *tmpbuf, int i)
+-{
+- int timer_active;
+- unsigned long timer_expires;
+- struct tcp_sock *tp = tcp_sk(sk);
+- const struct inet_connection_sock *icsk = inet_csk(sk);
+- struct inet_sock *inet = inet_sk(sk);
+- __be32 dest = inet->daddr;
+- __be32 src = inet->rcv_saddr;
+- __u16 destp = ntohs(inet->dport);
+- __u16 srcp = ntohs(inet->sport);
+-
+- if (icsk->icsk_pending == ICSK_TIME_RETRANS) {
+- timer_active = 1;
+- timer_expires = icsk->icsk_timeout;
+- } else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
+- timer_active = 4;
+- timer_expires = icsk->icsk_timeout;
+- } else if (timer_pending(&sk->sk_timer)) {
+- timer_active = 2;
+- timer_expires = sk->sk_timer.expires;
+- } else {
+- timer_active = 0;
+- timer_expires = jiffies;
+- }
+-
+- sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX "
+- "%08X %5d %8d %lu %d %p %u %u %u %u %d",
+- i, src, srcp, dest, destp, sk->sk_state,
+- tp->write_seq - tp->snd_una,
+- sk->sk_state == TCP_LISTEN ? sk->sk_ack_backlog :
+- (tp->rcv_nxt - tp->copied_seq),
+- timer_active,
+- jiffies_to_clock_t(timer_expires - jiffies),
+- icsk->icsk_retransmits,
+- sock_i_uid(sk),
+- icsk->icsk_probes_out,
+- sock_i_ino(sk),
+- atomic_read(&sk->sk_refcnt), sk,
+- icsk->icsk_rto,
+- icsk->icsk_ack.ato,
+- (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong,
+- tp->snd_cwnd,
+- tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh);
+-}
+-
+-static void get_timewait4_sock(struct inet_timewait_sock *tw,
+- char *tmpbuf, int i)
+-{
+- __be32 dest, src;
+- __u16 destp, srcp;
+- int ttd = tw->tw_ttd - jiffies;
+-
+- if (ttd < 0)
+- ttd = 0;
+-
+- dest = tw->tw_daddr;
+- src = tw->tw_rcv_saddr;
+- destp = ntohs(tw->tw_dport);
+- srcp = ntohs(tw->tw_sport);
+-
+- sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
+- " %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p",
+- i, src, srcp, dest, destp, tw->tw_substate, 0, 0,
+- 3, jiffies_to_clock_t(ttd), 0, 0, 0, 0,
+- atomic_read(&tw->tw_refcnt), tw);
+-}
+-
+-#define TMPSZ 150
+-
+-static int tcp4_seq_show(struct seq_file *seq, void *v)
+-{
+- struct tcp_iter_state* st;
+- char tmpbuf[TMPSZ + 1];
+-
+- if (v == SEQ_START_TOKEN) {
+- seq_printf(seq, "%-*s\n", TMPSZ - 1,
+- " sl local_address rem_address st tx_queue "
+- "rx_queue tr tm->when retrnsmt uid timeout "
+- "inode");
+- goto out;
+- }
+- st = seq->private;
+-
+- switch (st->state) {
+- case TCP_SEQ_STATE_LISTENING:
+- case TCP_SEQ_STATE_ESTABLISHED:
+- get_tcp4_sock(v, tmpbuf, st->num);
+- break;
+- case TCP_SEQ_STATE_OPENREQ:
+- get_openreq4(st->syn_wait_sk, v, tmpbuf, st->num, st->uid);
+- break;
+- case TCP_SEQ_STATE_TIME_WAIT:
+- get_timewait4_sock(v, tmpbuf, st->num);
+- break;
+- }
+- seq_printf(seq, "%-*s\n", TMPSZ - 1, tmpbuf);
+-out:
+- return 0;
+-}
+-
+-static struct file_operations tcp4_seq_fops;
+-static struct tcp_seq_afinfo tcp4_seq_afinfo = {
+- .owner = THIS_MODULE,
+- .name = "tcp",
+- .family = AF_INET,
+- .seq_show = tcp4_seq_show,
+- .seq_fops = &tcp4_seq_fops,
+-};
+-
+-int __init tcp4_proc_init(void)
+-{
+- return tcp_proc_register(&tcp4_seq_afinfo);
+-}
+-
+-void tcp4_proc_exit(void)
+-{
+- tcp_proc_unregister(&tcp4_seq_afinfo);
+-}
+-#endif /* CONFIG_PROC_FS */
+-
+-struct proto tcp_prot = {
+- .name = "TCP",
+- .owner = THIS_MODULE,
+- .close = tcp_close,
+- .connect = tcp_v4_connect,
+- .disconnect = tcp_disconnect,
+- .accept = inet_csk_accept,
+- .ioctl = tcp_ioctl,
+- .init = tcp_v4_init_sock,
+- .destroy = tcp_v4_destroy_sock,
+- .shutdown = tcp_shutdown,
+- .setsockopt = tcp_setsockopt,
+- .getsockopt = tcp_getsockopt,
+- .recvmsg = tcp_recvmsg,
+- .backlog_rcv = tcp_v4_do_rcv,
+- .hash = tcp_v4_hash,
+- .unhash = tcp_unhash,
+- .get_port = tcp_v4_get_port,
+- .enter_memory_pressure = tcp_enter_memory_pressure,
+- .sockets_allocated = &tcp_sockets_allocated,
+- .orphan_count = &tcp_orphan_count,
+- .memory_allocated = &tcp_memory_allocated,
+- .memory_pressure = &tcp_memory_pressure,
+- .sysctl_mem = sysctl_tcp_mem,
+- .sysctl_wmem = sysctl_tcp_wmem,
+- .sysctl_rmem = sysctl_tcp_rmem,
+- .max_header = MAX_TCP_HEADER,
+- .obj_size = sizeof(struct tcp_sock),
+- .twsk_prot = &tcp_timewait_sock_ops,
+- .rsk_prot = &tcp_request_sock_ops,
+-#ifdef CONFIG_COMPAT
+- .compat_setsockopt = compat_tcp_setsockopt,
+- .compat_getsockopt = compat_tcp_getsockopt,
+-#endif
+-};
+-
+-void __init tcp_v4_init(struct net_proto_family *ops)
+-{
+- if (inet_csk_ctl_sock_create(&tcp_socket, PF_INET, SOCK_RAW,
+- IPPROTO_TCP) < 0)
+- panic("Failed to create the TCP control socket.\n");
+-}
+-
+-EXPORT_SYMBOL(ipv4_specific);
+-EXPORT_SYMBOL(tcp_hashinfo);
+-EXPORT_SYMBOL(tcp_prot);
+-EXPORT_SYMBOL(tcp_unhash);
+-EXPORT_SYMBOL(tcp_v4_conn_request);
+-EXPORT_SYMBOL(tcp_v4_connect);
+-EXPORT_SYMBOL(tcp_v4_do_rcv);
+-EXPORT_SYMBOL(tcp_v4_remember_stamp);
+-EXPORT_SYMBOL(tcp_v4_send_check);
+-EXPORT_SYMBOL(tcp_v4_syn_recv_sock);
+-
+-#ifdef CONFIG_PROC_FS
+-EXPORT_SYMBOL(tcp_proc_register);
+-EXPORT_SYMBOL(tcp_proc_unregister);
+-#endif
+-EXPORT_SYMBOL(sysctl_local_port_range);
+-EXPORT_SYMBOL(sysctl_tcp_low_latency);
+-
+diff -Nurb linux-2.6.22-570/net/ipv4/tcp_output.c linux-2.6.22-590/net/ipv4/tcp_output.c
+--- linux-2.6.22-570/net/ipv4/tcp_output.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/tcp_output.c 2008-01-29 22:12:32.000000000 -0500
+@@ -432,11 +432,11 @@
+ sysctl_flags = 0;
+ if (unlikely(tcb->flags & TCPCB_FLAG_SYN)) {
+ tcp_header_size = sizeof(struct tcphdr) + TCPOLEN_MSS;
+- if (sysctl_tcp_timestamps) {
++ if (sk->sk_net->sysctl_tcp_timestamps) {
+ tcp_header_size += TCPOLEN_TSTAMP_ALIGNED;
+ sysctl_flags |= SYSCTL_FLAG_TSTAMPS;
+ }
+- if (sysctl_tcp_window_scaling) {
++ if (sk->sk_net->sysctl_tcp_window_scaling) {
+ tcp_header_size += TCPOLEN_WSCALE_ALIGNED;
+ sysctl_flags |= SYSCTL_FLAG_WSCALE;
+ }
+@@ -2215,7 +2215,7 @@
+ * See tcp_input.c:tcp_rcv_state_process case TCP_SYN_SENT.
+ */
+ tp->tcp_header_len = sizeof(struct tcphdr) +
+- (sysctl_tcp_timestamps ? TCPOLEN_TSTAMP_ALIGNED : 0);
++ (sk->sk_net->sysctl_tcp_timestamps ? TCPOLEN_TSTAMP_ALIGNED : 0);
+
+ #ifdef CONFIG_TCP_MD5SIG
+ if (tp->af_specific->md5_lookup(sk, sk) != NULL)
+@@ -2238,7 +2238,7 @@
+ tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0),
+ &tp->rcv_wnd,
+ &tp->window_clamp,
+- sysctl_tcp_window_scaling,
++ sk->sk_net->sysctl_tcp_window_scaling,
+ &rcv_wscale);
+
+ tp->rx_opt.rcv_wscale = rcv_wscale;
+diff -Nurb linux-2.6.22-570/net/ipv4/tcp_probe.c linux-2.6.22-590/net/ipv4/tcp_probe.c
+--- linux-2.6.22-570/net/ipv4/tcp_probe.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/tcp_probe.c 2008-01-29 22:12:32.000000000 -0500
+@@ -172,7 +172,7 @@
+ if (IS_ERR(tcpw.fifo))
+ return PTR_ERR(tcpw.fifo);
+
+- if (!proc_net_fops_create(procname, S_IRUSR, &tcpprobe_fops))
++ if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &tcpprobe_fops))
+ goto err0;
+
+ ret = register_jprobe(&tcp_probe);
+@@ -182,7 +182,7 @@
+ pr_info("TCP watch registered (port=%d)\n", port);
+ return 0;
+ err1:
+- proc_net_remove(procname);
++ proc_net_remove(&init_net, procname);
+ err0:
+ kfifo_free(tcpw.fifo);
+ return ret;
+@@ -192,7 +192,7 @@
+ static __exit void tcpprobe_exit(void)
+ {
+ kfifo_free(tcpw.fifo);
+- proc_net_remove(procname);
++ proc_net_remove(&init_net, procname);
+ unregister_jprobe(&tcp_probe);
+
+ }
+diff -Nurb linux-2.6.22-570/net/ipv4/tunnel4.c linux-2.6.22-590/net/ipv4/tunnel4.c
+--- linux-2.6.22-570/net/ipv4/tunnel4.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/tunnel4.c 2008-01-29 22:12:32.000000000 -0500
+@@ -75,6 +75,10 @@
+ {
+ struct xfrm_tunnel *handler;
+
++ if (skb->dev->nd_net != &init_net) {
++ kfree_skb(skb);
++ return 0;
++ }
+ if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+ goto drop;
+
+@@ -113,6 +117,9 @@
+ {
+ struct xfrm_tunnel *handler;
+
++ if (skb->dev->nd_net != &init_net)
++ return;
++
+ for (handler = tunnel4_handlers; handler; handler = handler->next)
+ if (!handler->err_handler(skb, info))
+ break;
+diff -Nurb linux-2.6.22-570/net/ipv4/udp.c linux-2.6.22-590/net/ipv4/udp.c
+--- linux-2.6.22-570/net/ipv4/udp.c 2008-01-29 22:12:23.000000000 -0500
++++ linux-2.6.22-590/net/ipv4/udp.c 2008-01-29 22:12:32.000000000 -0500
+@@ -101,6 +101,7 @@
+ #include <net/route.h>
+ #include <net/checksum.h>
+ #include <net/xfrm.h>
++#include <net/net_namespace.h>
+ #include "udp_impl.h"
+
+ /*
+@@ -112,16 +113,17 @@
+ struct hlist_head udp_hash[UDP_HTABLE_SIZE];
+ DEFINE_RWLOCK(udp_hash_lock);
+
+-static int udp_port_rover;
+-
+-static inline int __udp_lib_lport_inuse(__u16 num, struct hlist_head udptable[])
++static inline int __udp_lib_lport_inuse(struct net *net, __u16 num, struct hlist_head udptable[])
+ {
+ struct sock *sk;
+ struct hlist_node *node;
+
+- sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)])
++ sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)]) {
++ if (sk->sk_net != net)
++ continue;
+ if (sk->sk_hash == num)
+ return 1;
++ }
+ return 0;
+ }
+
+@@ -148,9 +150,9 @@
+ if (snum == 0) {
+ int best_size_so_far, best, result, i;
+
+- if (*port_rover > sysctl_local_port_range[1] ||
+- *port_rover < sysctl_local_port_range[0])
+- *port_rover = sysctl_local_port_range[0];
++ if (*port_rover > sk->sk_net->sysctl_local_port_range[1] ||
++ *port_rover < sk->sk_net->sysctl_local_port_range[0])
++ *port_rover = sk->sk_net->sysctl_local_port_range[0];
+ best_size_so_far = 32767;
+ best = result = *port_rover;
+ for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) {
+@@ -158,9 +160,9 @@
+
+ head = &udptable[result & (UDP_HTABLE_SIZE - 1)];
+ if (hlist_empty(head)) {
+- if (result > sysctl_local_port_range[1])
+- result = sysctl_local_port_range[0] +
+- ((result - sysctl_local_port_range[0]) &
++ if (result > sk->sk_net->sysctl_local_port_range[1])
++ result = sk->sk_net->sysctl_local_port_range[0] +
++ ((result - sk->sk_net->sysctl_local_port_range[0]) &
+ (UDP_HTABLE_SIZE - 1));
+ goto gotit;
+ }
+@@ -177,11 +179,11 @@
+ result = best;
+ for (i = 0; i < (1 << 16) / UDP_HTABLE_SIZE;
+ i++, result += UDP_HTABLE_SIZE) {
+- if (result > sysctl_local_port_range[1])
+- result = sysctl_local_port_range[0]
+- + ((result - sysctl_local_port_range[0]) &
++ if (result > sk->sk_net->sysctl_local_port_range[1])
++ result = sk->sk_net->sysctl_local_port_range[0]
++ + ((result - sk->sk_net->sysctl_local_port_range[0]) &
+ (UDP_HTABLE_SIZE - 1));
+- if (! __udp_lib_lport_inuse(result, udptable))
++ if (! __udp_lib_lport_inuse(sk->sk_net, result, udptable))
+ break;
+ }
+ if (i >= (1 << 16) / UDP_HTABLE_SIZE)
+@@ -194,6 +196,7 @@
+ sk_for_each(sk2, node, head)
+ if (sk2->sk_hash == snum &&
+ sk2 != sk &&
++ sk->sk_net == sk2->sk_net &&
+ (!sk2->sk_reuse || !sk->sk_reuse) &&
+ (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
+ || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
+@@ -216,7 +219,7 @@
+ int udp_get_port(struct sock *sk, unsigned short snum,
+ int (*scmp)(const struct sock *, const struct sock *))
+ {
+- return __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, scmp);
++ return __udp_lib_get_port(sk, snum, udp_hash, &sk->sk_net->udp_port_rover, scmp);
+ }
+
+ extern int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2);
+@@ -229,7 +232,8 @@
+ /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
+ * harder than this. -DaveM
+ */
+-static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
++static struct sock *__udp4_lib_lookup(struct net *net,
++ __be32 saddr, __be16 sport,
+ __be32 daddr, __be16 dport,
+ int dif, struct hlist_head udptable[])
+ {
+@@ -243,6 +247,9 @@
+ sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
+ struct inet_sock *inet = inet_sk(sk);
+
++ if (sk->sk_net != net)
++ continue;
++
+ if (sk->sk_hash == hnum && !ipv6_only_sock(sk)) {
+ int score = (sk->sk_family == PF_INET ? 1 : 0);
+
+@@ -299,6 +306,9 @@
+ sk_for_each_from(s, node) {
+ struct inet_sock *inet = inet_sk(s);
+
++ if (s->sk_net != sk->sk_net)
++ continue;
++
+ if (s->sk_hash != hnum ||
+ (inet->daddr && inet->daddr != rmt_addr) ||
+ (inet->dport != rmt_port && inet->dport) ||
+@@ -328,6 +338,7 @@
+
+ void __udp4_lib_err(struct sk_buff *skb, u32 info, struct hlist_head udptable[])
+ {
++ struct net *net = skb->dev->nd_net;
+ struct inet_sock *inet;
+ struct iphdr *iph = (struct iphdr*)skb->data;
+ struct udphdr *uh = (struct udphdr*)(skb->data+(iph->ihl<<2));
+@@ -337,7 +348,7 @@
+ int harderr;
+ int err;
+
+- sk = __udp4_lib_lookup(iph->daddr, uh->dest, iph->saddr, uh->source,
++ sk = __udp4_lib_lookup(net, iph->daddr, uh->dest, iph->saddr, uh->source,
+ skb->dev->ifindex, udptable );
+ if (sk == NULL) {
+ ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
+@@ -623,7 +634,8 @@
+ rt = (struct rtable*)sk_dst_check(sk, 0);
+
+ if (rt == NULL) {
+- struct flowi fl = { .oif = ipc.oif,
++ struct flowi fl = { .fl_net = sk->sk_net,
++ .oif = ipc.oif,
+ .nl_u = { .ip4_u =
+ { .daddr = faddr,
+ .saddr = saddr,
+@@ -1288,6 +1300,7 @@
+ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
+ int proto)
+ {
++ struct net *net = skb->dev->nd_net;
+ struct sock *sk;
+ struct udphdr *uh = udp_hdr(skb);
+ unsigned short ulen;
+@@ -1322,7 +1335,7 @@
+ udp_ping_of_death(skb, uh, saddr);
+ #endif
+
+- sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest,
++ sk = __udp4_lib_lookup(net, saddr, uh->source, daddr, uh->dest,
+ skb->dev->ifindex, udptable );
+
+ if (sk != NULL) {
+@@ -1651,7 +1664,7 @@
+ sk = sk_next(sk);
+ try_again:
+ ;
+- } while (sk && (sk->sk_family != state->family ||
++ } while (sk && ((sk->sk_net != state->net) || sk->sk_family != state->family ||
+ !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
+
+ if (!sk && ++state->bucket < UDP_HTABLE_SIZE) {
+@@ -1717,6 +1730,7 @@
+
+ seq = file->private_data;
+ seq->private = s;
++ s->net = get_net(PROC_NET(inode));
+ out:
+ return rc;
+ out_kfree:
+@@ -1724,21 +1738,31 @@
+ goto out;
+ }
+
++static int udp_seq_release(struct inode *inode, struct file *file)
++{
++ struct seq_file *seq = file->private_data;
++ struct udp_iter_state *state = seq->private;
++ put_net(state->net);
++ return seq_release_private(inode, file);
++}
++
+ /* ------------------------------------------------------------------------ */
+-int udp_proc_register(struct udp_seq_afinfo *afinfo)
++int udp_proc_register(struct net *net, struct udp_seq_afinfo *afinfo)
+ {
+ struct proc_dir_entry *p;
+ int rc = 0;
+
+ if (!afinfo)
+ return -EINVAL;
++ if (net == &init_net) {
+ afinfo->seq_fops->owner = afinfo->owner;
+ afinfo->seq_fops->open = udp_seq_open;
+ afinfo->seq_fops->read = seq_read;
+ afinfo->seq_fops->llseek = seq_lseek;
+- afinfo->seq_fops->release = seq_release_private;
++ afinfo->seq_fops->release = udp_seq_release;
++ }
+
+- p = proc_net_fops_create(afinfo->name, S_IRUGO, afinfo->seq_fops);
++ p = proc_net_fops_create(net, afinfo->name, S_IRUGO, afinfo->seq_fops);
+ if (p)
+ p->data = afinfo;
+ else
+@@ -1746,11 +1770,12 @@
+ return rc;
+ }
+
+-void udp_proc_unregister(struct udp_seq_afinfo *afinfo)
++void udp_proc_unregister(struct net *net, struct udp_seq_afinfo *afinfo)
+ {
+ if (!afinfo)
+ return;
+- proc_net_remove(afinfo->name);
++ proc_net_remove(net, afinfo->name);
++ if (net == &init_net)
+ memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops));
+ }
+
+@@ -1803,14 +1828,30 @@
+ .seq_fops = &udp4_seq_fops,
+ };
+
++
++static int udp4_proc_net_init(struct net *net)
++{
++ return udp_proc_register(net, &udp4_seq_afinfo);
++}
++
++static void udp4_proc_net_exit(struct net *net)
++{
++ udp_proc_unregister(net, &udp4_seq_afinfo);
++}
++
++static struct pernet_operations udp4_proc_net_ops = {
++ .init = udp4_proc_net_init,
++ .exit = udp4_proc_net_exit,
++};
++
+ int __init udp4_proc_init(void)
+ {
+- return udp_proc_register(&udp4_seq_afinfo);
++ return register_pernet_subsys(&udp4_proc_net_ops);
+ }
+
+ void udp4_proc_exit(void)
+ {
+- udp_proc_unregister(&udp4_seq_afinfo);
++ unregister_pernet_subsys(&udp4_proc_net_ops);
+ }
+ #endif /* CONFIG_PROC_FS */
+
+diff -Nurb linux-2.6.22-570/net/ipv4/udplite.c linux-2.6.22-590/net/ipv4/udplite.c
+--- linux-2.6.22-570/net/ipv4/udplite.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/udplite.c 2008-01-29 22:12:32.000000000 -0500
+@@ -31,11 +31,18 @@
+
+ static int udplite_rcv(struct sk_buff *skb)
+ {
++ if (skb->dev->nd_net != &init_net) {
++ kfree_skb(skb);
++ return 0;
++ }
+ return __udp4_lib_rcv(skb, udplite_hash, IPPROTO_UDPLITE);
+ }
+
+ static void udplite_err(struct sk_buff *skb, u32 info)
+ {
++ if (skb->dev->nd_net != &init_net)
++ return;
++
+ return __udp4_lib_err(skb, info, udplite_hash);
+ }
+
+@@ -103,7 +110,7 @@
+ inet_register_protosw(&udplite4_protosw);
+
+ #ifdef CONFIG_PROC_FS
+- if (udp_proc_register(&udplite4_seq_afinfo)) /* udplite4_proc_init() */
++ if (udp_proc_register(&init_net, &udplite4_seq_afinfo)) /* udplite4_proc_init() */
+ printk(KERN_ERR "%s: Cannot register /proc!\n", __FUNCTION__);
+ #endif
+ return;
+diff -Nurb linux-2.6.22-570/net/ipv4/xfrm4_input.c linux-2.6.22-590/net/ipv4/xfrm4_input.c
+--- linux-2.6.22-570/net/ipv4/xfrm4_input.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/xfrm4_input.c 2008-01-29 22:12:32.000000000 -0500
+@@ -18,6 +18,10 @@
+
+ int xfrm4_rcv(struct sk_buff *skb)
+ {
++ if (skb->dev->nd_net != &init_net) {
++ kfree_skb(skb);
++ return 0;
++ }
+ return xfrm4_rcv_encap(skb, 0);
+ }
+
+diff -Nurb linux-2.6.22-570/net/ipv4/xfrm4_policy.c linux-2.6.22-590/net/ipv4/xfrm4_policy.c
+--- linux-2.6.22-570/net/ipv4/xfrm4_policy.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/xfrm4_policy.c 2008-01-29 22:12:32.000000000 -0500
+@@ -25,6 +25,7 @@
+ {
+ struct rtable *rt;
+ struct flowi fl_tunnel = {
++ .fl_net = &init_net,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = daddr->a4,
+@@ -73,6 +74,7 @@
+ struct rtable *rt0 = (struct rtable*)(*dst_p);
+ struct rtable *rt = rt0;
+ struct flowi fl_tunnel = {
++ .fl_net = &init_net,
+ .nl_u = {
+ .ip4_u = {
+ .saddr = fl->fl4_src,
+@@ -213,6 +215,7 @@
+ u8 *xprth = skb_network_header(skb) + iph->ihl * 4;
+
+ memset(fl, 0, sizeof(struct flowi));
++ fl->fl_net = &init_net;
+ if (!(iph->frag_off & htons(IP_MF | IP_OFFSET))) {
+ switch (iph->protocol) {
+ case IPPROTO_UDP:
+@@ -306,7 +309,7 @@
+
+ xdst = (struct xfrm_dst *)dst;
+ if (xdst->u.rt.idev->dev == dev) {
+- struct in_device *loopback_idev = in_dev_get(&loopback_dev);
++ struct in_device *loopback_idev = in_dev_get(&init_net.loopback_dev);
+ BUG_ON(!loopback_idev);
+
+ do {
+diff -Nurb linux-2.6.22-570/net/ipv4/xfrm4_state.c linux-2.6.22-590/net/ipv4/xfrm4_state.c
+--- linux-2.6.22-570/net/ipv4/xfrm4_state.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/xfrm4_state.c 2008-01-29 22:12:32.000000000 -0500
+@@ -16,7 +16,7 @@
+
+ static int xfrm4_init_flags(struct xfrm_state *x)
+ {
+- if (ipv4_config.no_pmtu_disc)
++ if (init_net.sysctl_ipv4_no_pmtu_disc)
+ x->props.flags |= XFRM_STATE_NOPMTUDISC;
+ return 0;
+ }
+diff -Nurb linux-2.6.22-570/net/ipv4/xfrm4_tunnel.c linux-2.6.22-590/net/ipv4/xfrm4_tunnel.c
+--- linux-2.6.22-570/net/ipv4/xfrm4_tunnel.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv4/xfrm4_tunnel.c 2008-01-29 22:12:32.000000000 -0500
+@@ -109,3 +109,4 @@
+ module_init(ipip_init);
+ module_exit(ipip_fini);
+ MODULE_LICENSE("GPL");
++MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_IPIP);
+diff -Nurb linux-2.6.22-570/net/ipv6/Kconfig linux-2.6.22-590/net/ipv6/Kconfig
+--- linux-2.6.22-570/net/ipv6/Kconfig 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/ipv6/Kconfig 2008-01-29 22:12:32.000000000 -0500
+@@ -109,7 +109,7 @@
+ If unsure, say Y.
+
+ config IPV6_MIP6
+- bool "IPv6: Mobility (EXPERIMENTAL)"
++ tristate "IPv6: Mobility (EXPERIMENTAL)"
+ depends on IPV6 && EXPERIMENTAL
+ select XFRM
+ ---help---
+diff -Nurb linux-2.6.22-570/net/ipv6/Makefile linux-2.6.22-590/net/ipv6/Makefile
+--- linux-2.6.22-570/net/ipv6/Makefile 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/Makefile 2008-01-29 22:12:32.000000000 -0500
+@@ -14,7 +14,6 @@
+ xfrm6_output.o
+ ipv6-$(CONFIG_NETFILTER) += netfilter.o
+ ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o
+-ipv6-$(CONFIG_IPV6_MIP6) += mip6.o
+ ipv6-$(CONFIG_PROC_FS) += proc.o
+
+ ipv6-objs += $(ipv6-y)
+@@ -28,6 +27,7 @@
+ obj-$(CONFIG_INET6_XFRM_MODE_TUNNEL) += xfrm6_mode_tunnel.o
+ obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o
+ obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o
++obj-$(CONFIG_IPV6_MIP6) += mip6.o
+ obj-$(CONFIG_NETFILTER) += netfilter/
+
+ obj-$(CONFIG_IPV6_SIT) += sit.o
+diff -Nurb linux-2.6.22-570/net/ipv6/addrconf.c linux-2.6.22-590/net/ipv6/addrconf.c
+--- linux-2.6.22-570/net/ipv6/addrconf.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/ipv6/addrconf.c 2008-01-29 22:12:32.000000000 -0500
+@@ -73,6 +73,7 @@
+ #include <net/tcp.h>
+ #include <net/ip.h>
+ #include <net/netlink.h>
++#include <net/net_namespace.h>
+ #include <net/pkt_sched.h>
+ #include <linux/if_tunnel.h>
+ #include <linux/rtnetlink.h>
+@@ -457,7 +458,7 @@
+ struct inet6_dev *idev;
+
+ read_lock(&dev_base_lock);
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ rcu_read_lock();
+ idev = __in6_dev_get(dev);
+ if (idev) {
+@@ -920,7 +921,7 @@
+ read_lock(&dev_base_lock);
+ rcu_read_lock();
+
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ struct inet6_dev *idev;
+ struct inet6_ifaddr *ifa;
+
+@@ -1047,7 +1048,7 @@
+ }
+
+ /* Rule 4: Prefer home address */
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ if (hiscore.rule < 4) {
+ if (ifa_result->flags & IFA_F_HOMEADDRESS)
+ hiscore.attrs |= IPV6_SADDR_SCORE_HOA;
+@@ -1882,7 +1883,7 @@
+ if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq)))
+ goto err_exit;
+
+- dev = __dev_get_by_index(ireq.ifr6_ifindex);
++ dev = __dev_get_by_index(&init_net, ireq.ifr6_ifindex);
+
+ err = -ENODEV;
+ if (dev == NULL)
+@@ -1913,7 +1914,7 @@
+
+ if (err == 0) {
+ err = -ENOBUFS;
+- if ((dev = __dev_get_by_name(p.name)) == NULL)
++ if ((dev = __dev_get_by_name(&init_net, p.name)) == NULL)
+ goto err_exit;
+ err = dev_open(dev);
+ }
+@@ -1943,7 +1944,7 @@
+ if (!valid_lft || prefered_lft > valid_lft)
+ return -EINVAL;
+
+- if ((dev = __dev_get_by_index(ifindex)) == NULL)
++ if ((dev = __dev_get_by_index(&init_net, ifindex)) == NULL)
+ return -ENODEV;
+
+ if ((idev = addrconf_add_dev(dev)) == NULL)
+@@ -1994,7 +1995,7 @@
+ struct inet6_dev *idev;
+ struct net_device *dev;
+
+- if ((dev = __dev_get_by_index(ifindex)) == NULL)
++ if ((dev = __dev_get_by_index(&init_net, ifindex)) == NULL)
+ return -ENODEV;
+
+ if ((idev = __in6_dev_get(dev)) == NULL)
+@@ -2089,7 +2090,7 @@
+ return;
+ }
+
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ struct in_device * in_dev = __in_dev_get_rtnl(dev);
+ if (in_dev && (dev->flags & IFF_UP)) {
+ struct in_ifaddr * ifa;
+@@ -2245,12 +2246,12 @@
+
+ /* first try to inherit the link-local address from the link device */
+ if (idev->dev->iflink &&
+- (link_dev = __dev_get_by_index(idev->dev->iflink))) {
++ (link_dev = __dev_get_by_index(&init_net, idev->dev->iflink))) {
+ if (!ipv6_inherit_linklocal(idev, link_dev))
+ return;
+ }
+ /* then try to inherit it from any device */
+- for_each_netdev(link_dev) {
++ for_each_netdev(&init_net, link_dev) {
+ if (!ipv6_inherit_linklocal(idev, link_dev))
+ return;
+ }
+@@ -2282,6 +2283,9 @@
+ struct inet6_dev *idev = __in6_dev_get(dev);
+ int run_pending = 0;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ switch(event) {
+ case NETDEV_REGISTER:
+ if (!idev && dev->mtu >= IPV6_MIN_MTU) {
+@@ -2419,7 +2423,7 @@
+
+ ASSERT_RTNL();
+
+- if (dev == &loopback_dev && how == 1)
++ if (dev == &init_net.loopback_dev && how == 1)
+ how = 0;
+
+ rt6_ifdown(dev);
+@@ -2850,18 +2854,18 @@
+
+ int __init if6_proc_init(void)
+ {
+- if (!proc_net_fops_create("if_inet6", S_IRUGO, &if6_fops))
++ if (!proc_net_fops_create(&init_net, "if_inet6", S_IRUGO, &if6_fops))
+ return -ENOMEM;
+ return 0;
+ }
+
+ void if6_proc_exit(void)
+ {
+- proc_net_remove("if_inet6");
++ proc_net_remove(&init_net, "if_inet6");
+ }
+ #endif /* CONFIG_PROC_FS */
+
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ /* Check if address is a home address configured on any interface. */
+ int ipv6_chk_home_addr(struct in6_addr *addr)
+ {
+@@ -3017,11 +3021,15 @@
+ static int
+ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct ifaddrmsg *ifm;
+ struct nlattr *tb[IFA_MAX+1];
+ struct in6_addr *pfx;
+ int err;
+
++ if (net != &init_net)
++ return -EINVAL;
++
+ err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
+ if (err < 0)
+ return err;
+@@ -3074,6 +3082,7 @@
+ static int
+ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct ifaddrmsg *ifm;
+ struct nlattr *tb[IFA_MAX+1];
+ struct in6_addr *pfx;
+@@ -3083,6 +3092,9 @@
+ u8 ifa_flags;
+ int err;
+
++ if (net != &init_net)
++ return -EINVAL;
++
+ err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
+ if (err < 0)
+ return err;
+@@ -3103,7 +3115,7 @@
+ valid_lft = INFINITY_LIFE_TIME;
+ }
+
+- dev = __dev_get_by_index(ifm->ifa_index);
++ dev = __dev_get_by_index(&init_net, ifm->ifa_index);
+ if (dev == NULL)
+ return -ENODEV;
+
+@@ -3292,7 +3304,7 @@
+ s_ip_idx = ip_idx = cb->args[1];
+
+ idx = 0;
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ if (idx < s_idx)
+ goto cont;
+ if (idx > s_idx)
+@@ -3367,26 +3379,42 @@
+
+ static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
+ {
++ struct net *net = skb->sk->sk_net;
+ enum addr_type_t type = UNICAST_ADDR;
++
++ if (net != &init_net)
++ return 0;
++
+ return inet6_dump_addr(skb, cb, type);
+ }
+
+ static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb)
+ {
++ struct net *net = skb->sk->sk_net;
+ enum addr_type_t type = MULTICAST_ADDR;
++
++ if (net != &init_net)
++ return 0;
++
+ return inet6_dump_addr(skb, cb, type);
+ }
+
+
+ static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb)
+ {
++ struct net *net = skb->sk->sk_net;
+ enum addr_type_t type = ANYCAST_ADDR;
++
++ if (net != &init_net)
++ return 0;
++
+ return inet6_dump_addr(skb, cb, type);
+ }
+
+ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
+ void *arg)
+ {
++ struct net *net = in_skb->sk->sk_net;
+ struct ifaddrmsg *ifm;
+ struct nlattr *tb[IFA_MAX+1];
+ struct in6_addr *addr = NULL;
+@@ -3395,6 +3423,9 @@
+ struct sk_buff *skb;
+ int err;
+
++ if (net != &init_net)
++ return -EINVAL;
++
+ err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
+ if (err < 0)
+ goto errout;
+@@ -3407,7 +3438,7 @@
+
+ ifm = nlmsg_data(nlh);
+ if (ifm->ifa_index)
+- dev = __dev_get_by_index(ifm->ifa_index);
++ dev = __dev_get_by_index(&init_net, ifm->ifa_index);
+
+ if ((ifa = ipv6_get_ifaddr(addr, dev, 1)) == NULL) {
+ err = -EADDRNOTAVAIL;
+@@ -3427,7 +3458,7 @@
+ kfree_skb(skb);
+ goto errout_ifa;
+ }
+- err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
++ err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
+ errout_ifa:
+ in6_ifa_put(ifa);
+ errout:
+@@ -3450,10 +3481,10 @@
+ kfree_skb(skb);
+ goto errout;
+ }
+- err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
++ err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
+ errout:
+ if (err < 0)
+- rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
++ rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err);
+ }
+
+ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
+@@ -3612,19 +3643,22 @@
+
+ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
+ {
++ struct net *net = skb->sk->sk_net;
+ int idx, err;
+ int s_idx = cb->args[0];
+ struct net_device *dev;
+ struct inet6_dev *idev;
+ struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL;
+
++ if (net != &init_net)
++ return 0;
+ /* FIXME: maybe disable ipv6 on non v6 guests?
+ if (skb->sk && skb->sk->sk_vx_info)
+ return skb->len; */
+
+ read_lock(&dev_base_lock);
+ idx = 0;
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ if (idx < s_idx)
+ goto cont;
+ if (!v6_dev_in_nx_info(dev, nxi))
+@@ -3661,10 +3695,10 @@
+ kfree_skb(skb);
+ goto errout;
+ }
+- err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
++ err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
+ errout:
+ if (err < 0)
+- rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
++ rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err);
+ }
+
+ static inline size_t inet6_prefix_nlmsg_size(void)
+@@ -3730,10 +3764,10 @@
+ kfree_skb(skb);
+ goto errout;
+ }
+- err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
++ err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
+ errout:
+ if (err < 0)
+- rtnl_set_sk_err(RTNLGRP_IPV6_PREFIX, err);
++ rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_PREFIX, err);
+ }
+
+ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
+@@ -4244,16 +4278,16 @@
+ * device and it being up should be removed.
+ */
+ rtnl_lock();
+- if (!ipv6_add_dev(&loopback_dev))
++ if (!ipv6_add_dev(&init_net.loopback_dev))
+ err = -ENOMEM;
+ rtnl_unlock();
+ if (err)
+ return err;
+
+- ip6_null_entry.rt6i_idev = in6_dev_get(&loopback_dev);
++ ip6_null_entry.rt6i_idev = in6_dev_get(&init_net.loopback_dev);
+ #ifdef CONFIG_IPV6_MULTIPLE_TABLES
+- ip6_prohibit_entry.rt6i_idev = in6_dev_get(&loopback_dev);
+- ip6_blk_hole_entry.rt6i_idev = in6_dev_get(&loopback_dev);
++ ip6_prohibit_entry.rt6i_idev = in6_dev_get(&init_net.loopback_dev);
++ ip6_blk_hole_entry.rt6i_idev = in6_dev_get(&init_net.loopback_dev);
+ #endif
+
+ register_netdevice_notifier(&ipv6_dev_notf);
+@@ -4304,12 +4338,12 @@
+ * clean dev list.
+ */
+
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ if ((idev = __in6_dev_get(dev)) == NULL)
+ continue;
+ addrconf_ifdown(dev, 1);
+ }
+- addrconf_ifdown(&loopback_dev, 2);
++ addrconf_ifdown(&init_net.loopback_dev, 2);
+
+ /*
+ * Check hash table.
+@@ -4335,6 +4369,6 @@
+ rtnl_unlock();
+
+ #ifdef CONFIG_PROC_FS
+- proc_net_remove("if_inet6");
++ proc_net_remove(&init_net, "if_inet6");
+ #endif
+ }
+diff -Nurb linux-2.6.22-570/net/ipv6/addrconf.c.orig linux-2.6.22-590/net/ipv6/addrconf.c.orig
+--- linux-2.6.22-570/net/ipv6/addrconf.c.orig 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/ipv6/addrconf.c.orig 1969-12-31 19:00:00.000000000 -0500
+@@ -1,4301 +0,0 @@
+-/*
+- * IPv6 Address [auto]configuration
+- * Linux INET6 implementation
+- *
+- * Authors:
+- * Pedro Roque <roque@di.fc.ul.pt>
+- * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
+- *
+- * $Id: addrconf.c,v 1.69 2001/10/31 21:55:54 davem Exp $
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- */
+-
+-/*
+- * Changes:
+- *
+- * Janos Farkas : delete timer on ifdown
+- * <chexum@bankinf.banki.hu>
+- * Andi Kleen : kill double kfree on module
+- * unload.
+- * Maciej W. Rozycki : FDDI support
+- * sekiya@USAGI : Don't send too many RS
+- * packets.
+- * yoshfuji@USAGI : Fixed interval between DAD
+- * packets.
+- * YOSHIFUJI Hideaki @USAGI : improved accuracy of
+- * address validation timer.
+- * YOSHIFUJI Hideaki @USAGI : Privacy Extensions (RFC3041)
+- * support.
+- * Yuji SEKIYA @USAGI : Don't assign a same IPv6
+- * address on a same interface.
+- * YOSHIFUJI Hideaki @USAGI : ARCnet support
+- * YOSHIFUJI Hideaki @USAGI : convert /proc/net/if_inet6 to
+- * seq_file.
+- * YOSHIFUJI Hideaki @USAGI : improved source address
+- * selection; consider scope,
+- * status etc.
+- */
+-
+-#include <linux/errno.h>
+-#include <linux/types.h>
+-#include <linux/socket.h>
+-#include <linux/sockios.h>
+-#include <linux/net.h>
+-#include <linux/in6.h>
+-#include <linux/netdevice.h>
+-#include <linux/if_addr.h>
+-#include <linux/if_arp.h>
+-#include <linux/if_arcnet.h>
+-#include <linux/if_infiniband.h>
+-#include <linux/route.h>
+-#include <linux/inetdevice.h>
+-#include <linux/init.h>
+-#ifdef CONFIG_SYSCTL
+-#include <linux/sysctl.h>
+-#endif
+-#include <linux/capability.h>
+-#include <linux/delay.h>
+-#include <linux/notifier.h>
+-#include <linux/string.h>
+-
+-#include <net/sock.h>
+-#include <net/snmp.h>
+-
+-#include <net/ipv6.h>
+-#include <net/protocol.h>
+-#include <net/ndisc.h>
+-#include <net/ip6_route.h>
+-#include <net/addrconf.h>
+-#include <net/tcp.h>
+-#include <net/ip.h>
+-#include <net/netlink.h>
+-#include <net/pkt_sched.h>
+-#include <linux/if_tunnel.h>
+-#include <linux/rtnetlink.h>
+-
+-#ifdef CONFIG_IPV6_PRIVACY
+-#include <linux/random.h>
+-#endif
+-
+-#include <asm/uaccess.h>
+-#include <asm/unaligned.h>
+-
+-#include <linux/proc_fs.h>
+-#include <linux/seq_file.h>
+-
+-/* Set to 3 to get tracing... */
+-#define ACONF_DEBUG 2
+-
+-#if ACONF_DEBUG >= 3
+-#define ADBG(x) printk x
+-#else
+-#define ADBG(x)
+-#endif
+-
+-#define INFINITY_LIFE_TIME 0xFFFFFFFF
+-#define TIME_DELTA(a,b) ((unsigned long)((long)(a) - (long)(b)))
+-
+-#ifdef CONFIG_SYSCTL
+-static void addrconf_sysctl_register(struct inet6_dev *idev, struct ipv6_devconf *p);
+-static void addrconf_sysctl_unregister(struct ipv6_devconf *p);
+-#endif
+-
+-#ifdef CONFIG_IPV6_PRIVACY
+-static int __ipv6_regen_rndid(struct inet6_dev *idev);
+-static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr);
+-static void ipv6_regen_rndid(unsigned long data);
+-
+-static int desync_factor = MAX_DESYNC_FACTOR * HZ;
+-#endif
+-
+-static int ipv6_count_addresses(struct inet6_dev *idev);
+-
+-/*
+- * Configured unicast address hash table
+- */
+-static struct inet6_ifaddr *inet6_addr_lst[IN6_ADDR_HSIZE];
+-static DEFINE_RWLOCK(addrconf_hash_lock);
+-
+-static void addrconf_verify(unsigned long);
+-
+-static DEFINE_TIMER(addr_chk_timer, addrconf_verify, 0, 0);
+-static DEFINE_SPINLOCK(addrconf_verify_lock);
+-
+-static void addrconf_join_anycast(struct inet6_ifaddr *ifp);
+-static void addrconf_leave_anycast(struct inet6_ifaddr *ifp);
+-
+-static int addrconf_ifdown(struct net_device *dev, int how);
+-
+-static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags);
+-static void addrconf_dad_timer(unsigned long data);
+-static void addrconf_dad_completed(struct inet6_ifaddr *ifp);
+-static void addrconf_dad_run(struct inet6_dev *idev);
+-static void addrconf_rs_timer(unsigned long data);
+-static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa);
+-static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa);
+-
+-static void inet6_prefix_notify(int event, struct inet6_dev *idev,
+- struct prefix_info *pinfo);
+-static int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev);
+-
+-static ATOMIC_NOTIFIER_HEAD(inet6addr_chain);
+-
+-struct ipv6_devconf ipv6_devconf __read_mostly = {
+- .forwarding = 0,
+- .hop_limit = IPV6_DEFAULT_HOPLIMIT,
+- .mtu6 = IPV6_MIN_MTU,
+- .accept_ra = 1,
+- .accept_redirects = 1,
+- .autoconf = 1,
+- .force_mld_version = 0,
+- .dad_transmits = 1,
+- .rtr_solicits = MAX_RTR_SOLICITATIONS,
+- .rtr_solicit_interval = RTR_SOLICITATION_INTERVAL,
+- .rtr_solicit_delay = MAX_RTR_SOLICITATION_DELAY,
+-#ifdef CONFIG_IPV6_PRIVACY
+- .use_tempaddr = 0,
+- .temp_valid_lft = TEMP_VALID_LIFETIME,
+- .temp_prefered_lft = TEMP_PREFERRED_LIFETIME,
+- .regen_max_retry = REGEN_MAX_RETRY,
+- .max_desync_factor = MAX_DESYNC_FACTOR,
+-#endif
+- .max_addresses = IPV6_MAX_ADDRESSES,
+- .accept_ra_defrtr = 1,
+- .accept_ra_pinfo = 1,
+-#ifdef CONFIG_IPV6_ROUTER_PREF
+- .accept_ra_rtr_pref = 1,
+- .rtr_probe_interval = 60 * HZ,
+-#ifdef CONFIG_IPV6_ROUTE_INFO
+- .accept_ra_rt_info_max_plen = 0,
+-#endif
+-#endif
+- .proxy_ndp = 0,
+- .accept_source_route = 0, /* we do not accept RH0 by default. */
+-};
+-
+-static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
+- .forwarding = 0,
+- .hop_limit = IPV6_DEFAULT_HOPLIMIT,
+- .mtu6 = IPV6_MIN_MTU,
+- .accept_ra = 1,
+- .accept_redirects = 1,
+- .autoconf = 1,
+- .dad_transmits = 1,
+- .rtr_solicits = MAX_RTR_SOLICITATIONS,
+- .rtr_solicit_interval = RTR_SOLICITATION_INTERVAL,
+- .rtr_solicit_delay = MAX_RTR_SOLICITATION_DELAY,
+-#ifdef CONFIG_IPV6_PRIVACY
+- .use_tempaddr = 0,
+- .temp_valid_lft = TEMP_VALID_LIFETIME,
+- .temp_prefered_lft = TEMP_PREFERRED_LIFETIME,
+- .regen_max_retry = REGEN_MAX_RETRY,
+- .max_desync_factor = MAX_DESYNC_FACTOR,
+-#endif
+- .max_addresses = IPV6_MAX_ADDRESSES,
+- .accept_ra_defrtr = 1,
+- .accept_ra_pinfo = 1,
+-#ifdef CONFIG_IPV6_ROUTER_PREF
+- .accept_ra_rtr_pref = 1,
+- .rtr_probe_interval = 60 * HZ,
+-#ifdef CONFIG_IPV6_ROUTE_INFO
+- .accept_ra_rt_info_max_plen = 0,
+-#endif
+-#endif
+- .proxy_ndp = 0,
+- .accept_source_route = 0, /* we do not accept RH0 by default. */
+-};
+-
+-/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
+-const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
+-const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
+-
+-/* Check if a valid qdisc is available */
+-static inline int addrconf_qdisc_ok(struct net_device *dev)
+-{
+- return (dev->qdisc != &noop_qdisc);
+-}
+-
+-static void addrconf_del_timer(struct inet6_ifaddr *ifp)
+-{
+- if (del_timer(&ifp->timer))
+- __in6_ifa_put(ifp);
+-}
+-
+-enum addrconf_timer_t
+-{
+- AC_NONE,
+- AC_DAD,
+- AC_RS,
+-};
+-
+-static void addrconf_mod_timer(struct inet6_ifaddr *ifp,
+- enum addrconf_timer_t what,
+- unsigned long when)
+-{
+- if (!del_timer(&ifp->timer))
+- in6_ifa_hold(ifp);
+-
+- switch (what) {
+- case AC_DAD:
+- ifp->timer.function = addrconf_dad_timer;
+- break;
+- case AC_RS:
+- ifp->timer.function = addrconf_rs_timer;
+- break;
+- default:;
+- }
+- ifp->timer.expires = jiffies + when;
+- add_timer(&ifp->timer);
+-}
+-
+-static int snmp6_alloc_dev(struct inet6_dev *idev)
+-{
+- int err = -ENOMEM;
+-
+- if (!idev || !idev->dev)
+- return -EINVAL;
+-
+- if (snmp_mib_init((void **)idev->stats.ipv6,
+- sizeof(struct ipstats_mib),
+- __alignof__(struct ipstats_mib)) < 0)
+- goto err_ip;
+- if (snmp_mib_init((void **)idev->stats.icmpv6,
+- sizeof(struct icmpv6_mib),
+- __alignof__(struct icmpv6_mib)) < 0)
+- goto err_icmp;
+-
+- return 0;
+-
+-err_icmp:
+- snmp_mib_free((void **)idev->stats.ipv6);
+-err_ip:
+- return err;
+-}
+-
+-static int snmp6_free_dev(struct inet6_dev *idev)
+-{
+- snmp_mib_free((void **)idev->stats.icmpv6);
+- snmp_mib_free((void **)idev->stats.ipv6);
+- return 0;
+-}
+-
+-/* Nobody refers to this device, we may destroy it. */
+-
+-static void in6_dev_finish_destroy_rcu(struct rcu_head *head)
+-{
+- struct inet6_dev *idev = container_of(head, struct inet6_dev, rcu);
+- kfree(idev);
+-}
+-
+-void in6_dev_finish_destroy(struct inet6_dev *idev)
+-{
+- struct net_device *dev = idev->dev;
+- BUG_TRAP(idev->addr_list==NULL);
+- BUG_TRAP(idev->mc_list==NULL);
+-#ifdef NET_REFCNT_DEBUG
+- printk(KERN_DEBUG "in6_dev_finish_destroy: %s\n", dev ? dev->name : "NIL");
+-#endif
+- dev_put(dev);
+- if (!idev->dead) {
+- printk("Freeing alive inet6 device %p\n", idev);
+- return;
+- }
+- snmp6_free_dev(idev);
+- call_rcu(&idev->rcu, in6_dev_finish_destroy_rcu);
+-}
+-
+-EXPORT_SYMBOL(in6_dev_finish_destroy);
+-
+-static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
+-{
+- struct inet6_dev *ndev;
+- struct in6_addr maddr;
+-
+- ASSERT_RTNL();
+-
+- if (dev->mtu < IPV6_MIN_MTU)
+- return NULL;
+-
+- ndev = kzalloc(sizeof(struct inet6_dev), GFP_KERNEL);
+-
+- if (ndev == NULL)
+- return NULL;
+-
+- rwlock_init(&ndev->lock);
+- ndev->dev = dev;
+- memcpy(&ndev->cnf, &ipv6_devconf_dflt, sizeof(ndev->cnf));
+- ndev->cnf.mtu6 = dev->mtu;
+- ndev->cnf.sysctl = NULL;
+- ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl);
+- if (ndev->nd_parms == NULL) {
+- kfree(ndev);
+- return NULL;
+- }
+- /* We refer to the device */
+- dev_hold(dev);
+-
+- if (snmp6_alloc_dev(ndev) < 0) {
+- ADBG((KERN_WARNING
+- "%s(): cannot allocate memory for statistics; dev=%s.\n",
+- __FUNCTION__, dev->name));
+- neigh_parms_release(&nd_tbl, ndev->nd_parms);
+- ndev->dead = 1;
+- in6_dev_finish_destroy(ndev);
+- return NULL;
+- }
+-
+- if (snmp6_register_dev(ndev) < 0) {
+- ADBG((KERN_WARNING
+- "%s(): cannot create /proc/net/dev_snmp6/%s\n",
+- __FUNCTION__, dev->name));
+- neigh_parms_release(&nd_tbl, ndev->nd_parms);
+- ndev->dead = 1;
+- in6_dev_finish_destroy(ndev);
+- return NULL;
+- }
+-
+- /* One reference from device. We must do this before
+- * we invoke __ipv6_regen_rndid().
+- */
+- in6_dev_hold(ndev);
+-
+-#ifdef CONFIG_IPV6_PRIVACY
+- init_timer(&ndev->regen_timer);
+- ndev->regen_timer.function = ipv6_regen_rndid;
+- ndev->regen_timer.data = (unsigned long) ndev;
+- if ((dev->flags&IFF_LOOPBACK) ||
+- dev->type == ARPHRD_TUNNEL ||
+-#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
+- dev->type == ARPHRD_SIT ||
+-#endif
+- dev->type == ARPHRD_NONE) {
+- printk(KERN_INFO
+- "%s: Disabled Privacy Extensions\n",
+- dev->name);
+- ndev->cnf.use_tempaddr = -1;
+- } else {
+- in6_dev_hold(ndev);
+- ipv6_regen_rndid((unsigned long) ndev);
+- }
+-#endif
+-
+- if (netif_running(dev) && addrconf_qdisc_ok(dev))
+- ndev->if_flags |= IF_READY;
+-
+- ipv6_mc_init_dev(ndev);
+- ndev->tstamp = jiffies;
+-#ifdef CONFIG_SYSCTL
+- neigh_sysctl_register(dev, ndev->nd_parms, NET_IPV6,
+- NET_IPV6_NEIGH, "ipv6",
+- &ndisc_ifinfo_sysctl_change,
+- NULL);
+- addrconf_sysctl_register(ndev, &ndev->cnf);
+-#endif
+- /* protected by rtnl_lock */
+- rcu_assign_pointer(dev->ip6_ptr, ndev);
+-
+- /* Join all-node multicast group */
+- ipv6_addr_all_nodes(&maddr);
+- ipv6_dev_mc_inc(dev, &maddr);
+-
+- return ndev;
+-}
+-
+-static struct inet6_dev * ipv6_find_idev(struct net_device *dev)
+-{
+- struct inet6_dev *idev;
+-
+- ASSERT_RTNL();
+-
+- if ((idev = __in6_dev_get(dev)) == NULL) {
+- if ((idev = ipv6_add_dev(dev)) == NULL)
+- return NULL;
+- }
+-
+- if (dev->flags&IFF_UP)
+- ipv6_mc_up(idev);
+- return idev;
+-}
+-
+-#ifdef CONFIG_SYSCTL
+-static void dev_forward_change(struct inet6_dev *idev)
+-{
+- struct net_device *dev;
+- struct inet6_ifaddr *ifa;
+- struct in6_addr addr;
+-
+- if (!idev)
+- return;
+- dev = idev->dev;
+- if (dev && (dev->flags & IFF_MULTICAST)) {
+- ipv6_addr_all_routers(&addr);
+-
+- if (idev->cnf.forwarding)
+- ipv6_dev_mc_inc(dev, &addr);
+- else
+- ipv6_dev_mc_dec(dev, &addr);
+- }
+- for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) {
+- if (ifa->flags&IFA_F_TENTATIVE)
+- continue;
+- if (idev->cnf.forwarding)
+- addrconf_join_anycast(ifa);
+- else
+- addrconf_leave_anycast(ifa);
+- }
+-}
+-
+-
+-static void addrconf_forward_change(void)
+-{
+- struct net_device *dev;
+- struct inet6_dev *idev;
+-
+- read_lock(&dev_base_lock);
+- for_each_netdev(dev) {
+- rcu_read_lock();
+- idev = __in6_dev_get(dev);
+- if (idev) {
+- int changed = (!idev->cnf.forwarding) ^ (!ipv6_devconf.forwarding);
+- idev->cnf.forwarding = ipv6_devconf.forwarding;
+- if (changed)
+- dev_forward_change(idev);
+- }
+- rcu_read_unlock();
+- }
+- read_unlock(&dev_base_lock);
+-}
+-#endif
+-
+-/* Nobody refers to this ifaddr, destroy it */
+-
+-void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)
+-{
+- BUG_TRAP(ifp->if_next==NULL);
+- BUG_TRAP(ifp->lst_next==NULL);
+-#ifdef NET_REFCNT_DEBUG
+- printk(KERN_DEBUG "inet6_ifa_finish_destroy\n");
+-#endif
+-
+- in6_dev_put(ifp->idev);
+-
+- if (del_timer(&ifp->timer))
+- printk("Timer is still running, when freeing ifa=%p\n", ifp);
+-
+- if (!ifp->dead) {
+- printk("Freeing alive inet6 address %p\n", ifp);
+- return;
+- }
+- dst_release(&ifp->rt->u.dst);
+-
+- kfree(ifp);
+-}
+-
+-static void
+-ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp)
+-{
+- struct inet6_ifaddr *ifa, **ifap;
+- int ifp_scope = ipv6_addr_src_scope(&ifp->addr);
+-
+- /*
+- * Each device address list is sorted in order of scope -
+- * global before linklocal.
+- */
+- for (ifap = &idev->addr_list; (ifa = *ifap) != NULL;
+- ifap = &ifa->if_next) {
+- if (ifp_scope >= ipv6_addr_src_scope(&ifa->addr))
+- break;
+- }
+-
+- ifp->if_next = *ifap;
+- *ifap = ifp;
+-}
+-
+-/* On success it returns ifp with increased reference count */
+-
+-static struct inet6_ifaddr *
+-ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
+- int scope, u32 flags)
+-{
+- struct inet6_ifaddr *ifa = NULL;
+- struct rt6_info *rt;
+- int hash;
+- int err = 0;
+-
+- rcu_read_lock_bh();
+- if (idev->dead) {
+- err = -ENODEV; /*XXX*/
+- goto out2;
+- }
+-
+- write_lock(&addrconf_hash_lock);
+-
+- /* Ignore adding duplicate addresses on an interface */
+- if (ipv6_chk_same_addr(addr, idev->dev)) {
+- ADBG(("ipv6_add_addr: already assigned\n"));
+- err = -EEXIST;
+- goto out;
+- }
+-
+- ifa = kzalloc(sizeof(struct inet6_ifaddr), GFP_ATOMIC);
+-
+- if (ifa == NULL) {
+- ADBG(("ipv6_add_addr: malloc failed\n"));
+- err = -ENOBUFS;
+- goto out;
+- }
+-
+- rt = addrconf_dst_alloc(idev, addr, 0);
+- if (IS_ERR(rt)) {
+- err = PTR_ERR(rt);
+- goto out;
+- }
+-
+- ipv6_addr_copy(&ifa->addr, addr);
+-
+- spin_lock_init(&ifa->lock);
+- init_timer(&ifa->timer);
+- ifa->timer.data = (unsigned long) ifa;
+- ifa->scope = scope;
+- ifa->prefix_len = pfxlen;
+- ifa->flags = flags | IFA_F_TENTATIVE;
+- ifa->cstamp = ifa->tstamp = jiffies;
+-
+- ifa->rt = rt;
+-
+- /*
+- * part one of RFC 4429, section 3.3
+- * We should not configure an address as
+- * optimistic if we do not yet know the link
+- * layer address of our nexhop router
+- */
+-
+- if (rt->rt6i_nexthop == NULL)
+- ifa->flags &= ~IFA_F_OPTIMISTIC;
+-
+- ifa->idev = idev;
+- in6_dev_hold(idev);
+- /* For caller */
+- in6_ifa_hold(ifa);
+-
+- /* Add to big hash table */
+- hash = ipv6_addr_hash(addr);
+-
+- ifa->lst_next = inet6_addr_lst[hash];
+- inet6_addr_lst[hash] = ifa;
+- in6_ifa_hold(ifa);
+- write_unlock(&addrconf_hash_lock);
+-
+- write_lock(&idev->lock);
+- /* Add to inet6_dev unicast addr list. */
+- ipv6_link_dev_addr(idev, ifa);
+-
+-#ifdef CONFIG_IPV6_PRIVACY
+- if (ifa->flags&IFA_F_TEMPORARY) {
+- ifa->tmp_next = idev->tempaddr_list;
+- idev->tempaddr_list = ifa;
+- in6_ifa_hold(ifa);
+- }
+-#endif
+-
+- in6_ifa_hold(ifa);
+- write_unlock(&idev->lock);
+-out2:
+- rcu_read_unlock_bh();
+-
+- if (likely(err == 0))
+- atomic_notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa);
+- else {
+- kfree(ifa);
+- ifa = ERR_PTR(err);
+- }
+-
+- return ifa;
+-out:
+- write_unlock(&addrconf_hash_lock);
+- goto out2;
+-}
+-
+-/* This function wants to get referenced ifp and releases it before return */
+-
+-static void ipv6_del_addr(struct inet6_ifaddr *ifp)
+-{
+- struct inet6_ifaddr *ifa, **ifap;
+- struct inet6_dev *idev = ifp->idev;
+- int hash;
+- int deleted = 0, onlink = 0;
+- unsigned long expires = jiffies;
+-
+- hash = ipv6_addr_hash(&ifp->addr);
+-
+- ifp->dead = 1;
+-
+- write_lock_bh(&addrconf_hash_lock);
+- for (ifap = &inet6_addr_lst[hash]; (ifa=*ifap) != NULL;
+- ifap = &ifa->lst_next) {
+- if (ifa == ifp) {
+- *ifap = ifa->lst_next;
+- __in6_ifa_put(ifp);
+- ifa->lst_next = NULL;
+- break;
+- }
+- }
+- write_unlock_bh(&addrconf_hash_lock);
+-
+- write_lock_bh(&idev->lock);
+-#ifdef CONFIG_IPV6_PRIVACY
+- if (ifp->flags&IFA_F_TEMPORARY) {
+- for (ifap = &idev->tempaddr_list; (ifa=*ifap) != NULL;
+- ifap = &ifa->tmp_next) {
+- if (ifa == ifp) {
+- *ifap = ifa->tmp_next;
+- if (ifp->ifpub) {
+- in6_ifa_put(ifp->ifpub);
+- ifp->ifpub = NULL;
+- }
+- __in6_ifa_put(ifp);
+- ifa->tmp_next = NULL;
+- break;
+- }
+- }
+- }
+-#endif
+-
+- for (ifap = &idev->addr_list; (ifa=*ifap) != NULL;) {
+- if (ifa == ifp) {
+- *ifap = ifa->if_next;
+- __in6_ifa_put(ifp);
+- ifa->if_next = NULL;
+- if (!(ifp->flags & IFA_F_PERMANENT) || onlink > 0)
+- break;
+- deleted = 1;
+- continue;
+- } else if (ifp->flags & IFA_F_PERMANENT) {
+- if (ipv6_prefix_equal(&ifa->addr, &ifp->addr,
+- ifp->prefix_len)) {
+- if (ifa->flags & IFA_F_PERMANENT) {
+- onlink = 1;
+- if (deleted)
+- break;
+- } else {
+- unsigned long lifetime;
+-
+- if (!onlink)
+- onlink = -1;
+-
+- spin_lock(&ifa->lock);
+- lifetime = min_t(unsigned long,
+- ifa->valid_lft, 0x7fffffffUL/HZ);
+- if (time_before(expires,
+- ifa->tstamp + lifetime * HZ))
+- expires = ifa->tstamp + lifetime * HZ;
+- spin_unlock(&ifa->lock);
+- }
+- }
+- }
+- ifap = &ifa->if_next;
+- }
+- write_unlock_bh(&idev->lock);
+-
+- ipv6_ifa_notify(RTM_DELADDR, ifp);
+-
+- atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifp);
+-
+- addrconf_del_timer(ifp);
+-
+- /*
+- * Purge or update corresponding prefix
+- *
+- * 1) we don't purge prefix here if address was not permanent.
+- * prefix is managed by its own lifetime.
+- * 2) if there're no addresses, delete prefix.
+- * 3) if there're still other permanent address(es),
+- * corresponding prefix is still permanent.
+- * 4) otherwise, update prefix lifetime to the
+- * longest valid lifetime among the corresponding
+- * addresses on the device.
+- * Note: subsequent RA will update lifetime.
+- *
+- * --yoshfuji
+- */
+- if ((ifp->flags & IFA_F_PERMANENT) && onlink < 1) {
+- struct in6_addr prefix;
+- struct rt6_info *rt;
+-
+- ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len);
+- rt = rt6_lookup(&prefix, NULL, ifp->idev->dev->ifindex, 1);
+-
+- if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
+- if (onlink == 0) {
+- ip6_del_rt(rt);
+- rt = NULL;
+- } else if (!(rt->rt6i_flags & RTF_EXPIRES)) {
+- rt->rt6i_expires = expires;
+- rt->rt6i_flags |= RTF_EXPIRES;
+- }
+- }
+- dst_release(&rt->u.dst);
+- }
+-
+- in6_ifa_put(ifp);
+-}
+-
+-#ifdef CONFIG_IPV6_PRIVACY
+-static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *ift)
+-{
+- struct inet6_dev *idev = ifp->idev;
+- struct in6_addr addr, *tmpaddr;
+- unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp;
+- int tmp_plen;
+- int ret = 0;
+- int max_addresses;
+- u32 addr_flags;
+-
+- write_lock(&idev->lock);
+- if (ift) {
+- spin_lock_bh(&ift->lock);
+- memcpy(&addr.s6_addr[8], &ift->addr.s6_addr[8], 8);
+- spin_unlock_bh(&ift->lock);
+- tmpaddr = &addr;
+- } else {
+- tmpaddr = NULL;
+- }
+-retry:
+- in6_dev_hold(idev);
+- if (idev->cnf.use_tempaddr <= 0) {
+- write_unlock(&idev->lock);
+- printk(KERN_INFO
+- "ipv6_create_tempaddr(): use_tempaddr is disabled.\n");
+- in6_dev_put(idev);
+- ret = -1;
+- goto out;
+- }
+- spin_lock_bh(&ifp->lock);
+- if (ifp->regen_count++ >= idev->cnf.regen_max_retry) {
+- idev->cnf.use_tempaddr = -1; /*XXX*/
+- spin_unlock_bh(&ifp->lock);
+- write_unlock(&idev->lock);
+- printk(KERN_WARNING
+- "ipv6_create_tempaddr(): regeneration time exceeded. disabled temporary address support.\n");
+- in6_dev_put(idev);
+- ret = -1;
+- goto out;
+- }
+- in6_ifa_hold(ifp);
+- memcpy(addr.s6_addr, ifp->addr.s6_addr, 8);
+- if (__ipv6_try_regen_rndid(idev, tmpaddr) < 0) {
+- spin_unlock_bh(&ifp->lock);
+- write_unlock(&idev->lock);
+- printk(KERN_WARNING
+- "ipv6_create_tempaddr(): regeneration of randomized interface id failed.\n");
+- in6_ifa_put(ifp);
+- in6_dev_put(idev);
+- ret = -1;
+- goto out;
+- }
+- memcpy(&addr.s6_addr[8], idev->rndid, 8);
+- tmp_valid_lft = min_t(__u32,
+- ifp->valid_lft,
+- idev->cnf.temp_valid_lft);
+- tmp_prefered_lft = min_t(__u32,
+- ifp->prefered_lft,
+- idev->cnf.temp_prefered_lft - desync_factor / HZ);
+- tmp_plen = ifp->prefix_len;
+- max_addresses = idev->cnf.max_addresses;
+- tmp_cstamp = ifp->cstamp;
+- tmp_tstamp = ifp->tstamp;
+- spin_unlock_bh(&ifp->lock);
+-
+- write_unlock(&idev->lock);
+-
+- addr_flags = IFA_F_TEMPORARY;
+- /* set in addrconf_prefix_rcv() */
+- if (ifp->flags & IFA_F_OPTIMISTIC)
+- addr_flags |= IFA_F_OPTIMISTIC;
+-
+- ift = !max_addresses ||
+- ipv6_count_addresses(idev) < max_addresses ?
+- ipv6_add_addr(idev, &addr, tmp_plen,
+- ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK,
+- addr_flags) : NULL;
+- if (!ift || IS_ERR(ift)) {
+- in6_ifa_put(ifp);
+- in6_dev_put(idev);
+- printk(KERN_INFO
+- "ipv6_create_tempaddr(): retry temporary address regeneration.\n");
+- tmpaddr = &addr;
+- write_lock(&idev->lock);
+- goto retry;
+- }
+-
+- spin_lock_bh(&ift->lock);
+- ift->ifpub = ifp;
+- ift->valid_lft = tmp_valid_lft;
+- ift->prefered_lft = tmp_prefered_lft;
+- ift->cstamp = tmp_cstamp;
+- ift->tstamp = tmp_tstamp;
+- spin_unlock_bh(&ift->lock);
+-
+- addrconf_dad_start(ift, 0);
+- in6_ifa_put(ift);
+- in6_dev_put(idev);
+-out:
+- return ret;
+-}
+-#endif
+-
+-/*
+- * Choose an appropriate source address (RFC3484)
+- */
+-struct ipv6_saddr_score {
+- int addr_type;
+- unsigned int attrs;
+- int matchlen;
+- int scope;
+- unsigned int rule;
+-};
+-
+-#define IPV6_SADDR_SCORE_LOCAL 0x0001
+-#define IPV6_SADDR_SCORE_PREFERRED 0x0004
+-#define IPV6_SADDR_SCORE_HOA 0x0008
+-#define IPV6_SADDR_SCORE_OIF 0x0010
+-#define IPV6_SADDR_SCORE_LABEL 0x0020
+-#define IPV6_SADDR_SCORE_PRIVACY 0x0040
+-
+-static inline int ipv6_saddr_preferred(int type)
+-{
+- if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4|
+- IPV6_ADDR_LOOPBACK|IPV6_ADDR_RESERVED))
+- return 1;
+- return 0;
+-}
+-
+-/* static matching label */
+-static inline int ipv6_saddr_label(const struct in6_addr *addr, int type)
+-{
+- /*
+- * prefix (longest match) label
+- * -----------------------------
+- * ::1/128 0
+- * ::/0 1
+- * 2002::/16 2
+- * ::/96 3
+- * ::ffff:0:0/96 4
+- * fc00::/7 5
+- * 2001::/32 6
+- */
+- if (type & IPV6_ADDR_LOOPBACK)
+- return 0;
+- else if (type & IPV6_ADDR_COMPATv4)
+- return 3;
+- else if (type & IPV6_ADDR_MAPPED)
+- return 4;
+- else if (addr->s6_addr32[0] == htonl(0x20010000))
+- return 6;
+- else if (addr->s6_addr16[0] == htons(0x2002))
+- return 2;
+- else if ((addr->s6_addr[0] & 0xfe) == 0xfc)
+- return 5;
+- return 1;
+-}
+-
+-int ipv6_dev_get_saddr(struct net_device *daddr_dev,
+- struct in6_addr *daddr, struct in6_addr *saddr)
+-{
+- struct ipv6_saddr_score hiscore;
+- struct inet6_ifaddr *ifa_result = NULL;
+- int daddr_type = __ipv6_addr_type(daddr);
+- int daddr_scope = __ipv6_addr_src_scope(daddr_type);
+- u32 daddr_label = ipv6_saddr_label(daddr, daddr_type);
+- struct net_device *dev;
+-
+- memset(&hiscore, 0, sizeof(hiscore));
+-
+- read_lock(&dev_base_lock);
+- rcu_read_lock();
+-
+- for_each_netdev(dev) {
+- struct inet6_dev *idev;
+- struct inet6_ifaddr *ifa;
+-
+- /* Rule 0: Candidate Source Address (section 4)
+- * - multicast and link-local destination address,
+- * the set of candidate source address MUST only
+- * include addresses assigned to interfaces
+- * belonging to the same link as the outgoing
+- * interface.
+- * (- For site-local destination addresses, the
+- * set of candidate source addresses MUST only
+- * include addresses assigned to interfaces
+- * belonging to the same site as the outgoing
+- * interface.)
+- */
+- if ((daddr_type & IPV6_ADDR_MULTICAST ||
+- daddr_scope <= IPV6_ADDR_SCOPE_LINKLOCAL) &&
+- daddr_dev && dev != daddr_dev)
+- continue;
+-
+- idev = __in6_dev_get(dev);
+- if (!idev)
+- continue;
+-
+- read_lock_bh(&idev->lock);
+- for (ifa = idev->addr_list; ifa; ifa = ifa->if_next) {
+- struct ipv6_saddr_score score;
+-
+- score.addr_type = __ipv6_addr_type(&ifa->addr);
+-
+- /* Rule 0:
+- * - Tentative Address (RFC2462 section 5.4)
+- * - A tentative address is not considered
+- * "assigned to an interface" in the traditional
+- * sense, unless it is also flagged as optimistic.
+- * - Candidate Source Address (section 4)
+- * - In any case, anycast addresses, multicast
+- * addresses, and the unspecified address MUST
+- * NOT be included in a candidate set.
+- */
+- if ((ifa->flags & IFA_F_TENTATIVE) &&
+- (!(ifa->flags & IFA_F_OPTIMISTIC)))
+- continue;
+- if (unlikely(score.addr_type == IPV6_ADDR_ANY ||
+- score.addr_type & IPV6_ADDR_MULTICAST)) {
+- LIMIT_NETDEBUG(KERN_DEBUG
+- "ADDRCONF: unspecified / multicast address"
+- "assigned as unicast address on %s",
+- dev->name);
+- continue;
+- }
+-
+- score.attrs = 0;
+- score.matchlen = 0;
+- score.scope = 0;
+- score.rule = 0;
+-
+- if (ifa_result == NULL) {
+- /* record it if the first available entry */
+- goto record_it;
+- }
+-
+- /* Rule 1: Prefer same address */
+- if (hiscore.rule < 1) {
+- if (ipv6_addr_equal(&ifa_result->addr, daddr))
+- hiscore.attrs |= IPV6_SADDR_SCORE_LOCAL;
+- hiscore.rule++;
+- }
+- if (ipv6_addr_equal(&ifa->addr, daddr)) {
+- score.attrs |= IPV6_SADDR_SCORE_LOCAL;
+- if (!(hiscore.attrs & IPV6_SADDR_SCORE_LOCAL)) {
+- score.rule = 1;
+- goto record_it;
+- }
+- } else {
+- if (hiscore.attrs & IPV6_SADDR_SCORE_LOCAL)
+- continue;
+- }
+-
+- /* Rule 2: Prefer appropriate scope */
+- if (hiscore.rule < 2) {
+- hiscore.scope = __ipv6_addr_src_scope(hiscore.addr_type);
+- hiscore.rule++;
+- }
+- score.scope = __ipv6_addr_src_scope(score.addr_type);
+- if (hiscore.scope < score.scope) {
+- if (hiscore.scope < daddr_scope) {
+- score.rule = 2;
+- goto record_it;
+- } else
+- continue;
+- } else if (score.scope < hiscore.scope) {
+- if (score.scope < daddr_scope)
+- break; /* addresses sorted by scope */
+- else {
+- score.rule = 2;
+- goto record_it;
+- }
+- }
+-
+- /* Rule 3: Avoid deprecated and optimistic addresses */
+- if (hiscore.rule < 3) {
+- if (ipv6_saddr_preferred(hiscore.addr_type) ||
+- (((ifa_result->flags &
+- (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)) == 0)))
+- hiscore.attrs |= IPV6_SADDR_SCORE_PREFERRED;
+- hiscore.rule++;
+- }
+- if (ipv6_saddr_preferred(score.addr_type) ||
+- (((ifa->flags &
+- (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)) == 0))) {
+- score.attrs |= IPV6_SADDR_SCORE_PREFERRED;
+- if (!(hiscore.attrs & IPV6_SADDR_SCORE_PREFERRED)) {
+- score.rule = 3;
+- goto record_it;
+- }
+- } else {
+- if (hiscore.attrs & IPV6_SADDR_SCORE_PREFERRED)
+- continue;
+- }
+-
+- /* Rule 4: Prefer home address */
+-#ifdef CONFIG_IPV6_MIP6
+- if (hiscore.rule < 4) {
+- if (ifa_result->flags & IFA_F_HOMEADDRESS)
+- hiscore.attrs |= IPV6_SADDR_SCORE_HOA;
+- hiscore.rule++;
+- }
+- if (ifa->flags & IFA_F_HOMEADDRESS) {
+- score.attrs |= IPV6_SADDR_SCORE_HOA;
+- if (!(ifa_result->flags & IFA_F_HOMEADDRESS)) {
+- score.rule = 4;
+- goto record_it;
+- }
+- } else {
+- if (hiscore.attrs & IPV6_SADDR_SCORE_HOA)
+- continue;
+- }
+-#else
+- if (hiscore.rule < 4)
+- hiscore.rule++;
+-#endif
+-
+- /* Rule 5: Prefer outgoing interface */
+- if (hiscore.rule < 5) {
+- if (daddr_dev == NULL ||
+- daddr_dev == ifa_result->idev->dev)
+- hiscore.attrs |= IPV6_SADDR_SCORE_OIF;
+- hiscore.rule++;
+- }
+- if (daddr_dev == NULL ||
+- daddr_dev == ifa->idev->dev) {
+- score.attrs |= IPV6_SADDR_SCORE_OIF;
+- if (!(hiscore.attrs & IPV6_SADDR_SCORE_OIF)) {
+- score.rule = 5;
+- goto record_it;
+- }
+- } else {
+- if (hiscore.attrs & IPV6_SADDR_SCORE_OIF)
+- continue;
+- }
+-
+- /* Rule 6: Prefer matching label */
+- if (hiscore.rule < 6) {
+- if (ipv6_saddr_label(&ifa_result->addr, hiscore.addr_type) == daddr_label)
+- hiscore.attrs |= IPV6_SADDR_SCORE_LABEL;
+- hiscore.rule++;
+- }
+- if (ipv6_saddr_label(&ifa->addr, score.addr_type) == daddr_label) {
+- score.attrs |= IPV6_SADDR_SCORE_LABEL;
+- if (!(hiscore.attrs & IPV6_SADDR_SCORE_LABEL)) {
+- score.rule = 6;
+- goto record_it;
+- }
+- } else {
+- if (hiscore.attrs & IPV6_SADDR_SCORE_LABEL)
+- continue;
+- }
+-
+-#ifdef CONFIG_IPV6_PRIVACY
+- /* Rule 7: Prefer public address
+- * Note: prefer temprary address if use_tempaddr >= 2
+- */
+- if (hiscore.rule < 7) {
+- if ((!(ifa_result->flags & IFA_F_TEMPORARY)) ^
+- (ifa_result->idev->cnf.use_tempaddr >= 2))
+- hiscore.attrs |= IPV6_SADDR_SCORE_PRIVACY;
+- hiscore.rule++;
+- }
+- if ((!(ifa->flags & IFA_F_TEMPORARY)) ^
+- (ifa->idev->cnf.use_tempaddr >= 2)) {
+- score.attrs |= IPV6_SADDR_SCORE_PRIVACY;
+- if (!(hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)) {
+- score.rule = 7;
+- goto record_it;
+- }
+- } else {
+- if (hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)
+- continue;
+- }
+-#else
+- if (hiscore.rule < 7)
+- hiscore.rule++;
+-#endif
+- /* Rule 8: Use longest matching prefix */
+- if (hiscore.rule < 8) {
+- hiscore.matchlen = ipv6_addr_diff(&ifa_result->addr, daddr);
+- hiscore.rule++;
+- }
+- score.matchlen = ipv6_addr_diff(&ifa->addr, daddr);
+- if (score.matchlen > hiscore.matchlen) {
+- score.rule = 8;
+- goto record_it;
+- }
+-#if 0
+- else if (score.matchlen < hiscore.matchlen)
+- continue;
+-#endif
+-
+- /* Final Rule: choose first available one */
+- continue;
+-record_it:
+- if (ifa_result)
+- in6_ifa_put(ifa_result);
+- in6_ifa_hold(ifa);
+- ifa_result = ifa;
+- hiscore = score;
+- }
+- read_unlock_bh(&idev->lock);
+- }
+- rcu_read_unlock();
+- read_unlock(&dev_base_lock);
+-
+- if (!ifa_result)
+- return -EADDRNOTAVAIL;
+-
+- ipv6_addr_copy(saddr, &ifa_result->addr);
+- in6_ifa_put(ifa_result);
+- return 0;
+-}
+-
+-
+-int ipv6_get_saddr(struct dst_entry *dst,
+- struct in6_addr *daddr, struct in6_addr *saddr)
+-{
+- return ipv6_dev_get_saddr(dst ? ip6_dst_idev(dst)->dev : NULL, daddr, saddr);
+-}
+-
+-EXPORT_SYMBOL(ipv6_get_saddr);
+-
+-int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
+- unsigned char banned_flags)
+-{
+- struct inet6_dev *idev;
+- int err = -EADDRNOTAVAIL;
+-
+- rcu_read_lock();
+- if ((idev = __in6_dev_get(dev)) != NULL) {
+- struct inet6_ifaddr *ifp;
+-
+- read_lock_bh(&idev->lock);
+- for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) {
+- if (ifp->scope == IFA_LINK && !(ifp->flags & banned_flags)) {
+- ipv6_addr_copy(addr, &ifp->addr);
+- err = 0;
+- break;
+- }
+- }
+- read_unlock_bh(&idev->lock);
+- }
+- rcu_read_unlock();
+- return err;
+-}
+-
+-static int ipv6_count_addresses(struct inet6_dev *idev)
+-{
+- int cnt = 0;
+- struct inet6_ifaddr *ifp;
+-
+- read_lock_bh(&idev->lock);
+- for (ifp=idev->addr_list; ifp; ifp=ifp->if_next)
+- cnt++;
+- read_unlock_bh(&idev->lock);
+- return cnt;
+-}
+-
+-int ipv6_chk_addr(struct in6_addr *addr, struct net_device *dev, int strict)
+-{
+- struct inet6_ifaddr * ifp;
+- u8 hash = ipv6_addr_hash(addr);
+-
+- read_lock_bh(&addrconf_hash_lock);
+- for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) {
+- if (ipv6_addr_equal(&ifp->addr, addr) &&
+- !(ifp->flags&IFA_F_TENTATIVE)) {
+- if (dev == NULL || ifp->idev->dev == dev ||
+- !(ifp->scope&(IFA_LINK|IFA_HOST) || strict))
+- break;
+- }
+- }
+- read_unlock_bh(&addrconf_hash_lock);
+- return ifp != NULL;
+-}
+-
+-EXPORT_SYMBOL(ipv6_chk_addr);
+-
+-static
+-int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev)
+-{
+- struct inet6_ifaddr * ifp;
+- u8 hash = ipv6_addr_hash(addr);
+-
+- for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) {
+- if (ipv6_addr_equal(&ifp->addr, addr)) {
+- if (dev == NULL || ifp->idev->dev == dev)
+- break;
+- }
+- }
+- return ifp != NULL;
+-}
+-
+-struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, struct net_device *dev, int strict)
+-{
+- struct inet6_ifaddr * ifp;
+- u8 hash = ipv6_addr_hash(addr);
+-
+- read_lock_bh(&addrconf_hash_lock);
+- for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) {
+- if (ipv6_addr_equal(&ifp->addr, addr)) {
+- if (dev == NULL || ifp->idev->dev == dev ||
+- !(ifp->scope&(IFA_LINK|IFA_HOST) || strict)) {
+- in6_ifa_hold(ifp);
+- break;
+- }
+- }
+- }
+- read_unlock_bh(&addrconf_hash_lock);
+-
+- return ifp;
+-}
+-
+-int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
+-{
+- const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr;
+- const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
+- __be32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr;
+- __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
+- int sk_ipv6only = ipv6_only_sock(sk);
+- int sk2_ipv6only = inet_v6_ipv6only(sk2);
+- int addr_type = ipv6_addr_type(sk_rcv_saddr6);
+- int addr_type2 = sk2_rcv_saddr6 ? ipv6_addr_type(sk2_rcv_saddr6) : IPV6_ADDR_MAPPED;
+-
+- if (!sk2_rcv_saddr && !sk_ipv6only)
+- return 1;
+-
+- if (addr_type2 == IPV6_ADDR_ANY &&
+- !(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED))
+- return 1;
+-
+- if (addr_type == IPV6_ADDR_ANY &&
+- !(sk_ipv6only && addr_type2 == IPV6_ADDR_MAPPED))
+- return 1;
+-
+- if (sk2_rcv_saddr6 &&
+- ipv6_addr_equal(sk_rcv_saddr6, sk2_rcv_saddr6))
+- return 1;
+-
+- if (addr_type == IPV6_ADDR_MAPPED &&
+- !sk2_ipv6only &&
+- (!sk2_rcv_saddr || !sk_rcv_saddr || sk_rcv_saddr == sk2_rcv_saddr))
+- return 1;
+-
+- return 0;
+-}
+-
+-/* Gets referenced address, destroys ifaddr */
+-
+-static void addrconf_dad_stop(struct inet6_ifaddr *ifp)
+-{
+- if (ifp->flags&IFA_F_PERMANENT) {
+- spin_lock_bh(&ifp->lock);
+- addrconf_del_timer(ifp);
+- ifp->flags |= IFA_F_TENTATIVE;
+- spin_unlock_bh(&ifp->lock);
+- in6_ifa_put(ifp);
+-#ifdef CONFIG_IPV6_PRIVACY
+- } else if (ifp->flags&IFA_F_TEMPORARY) {
+- struct inet6_ifaddr *ifpub;
+- spin_lock_bh(&ifp->lock);
+- ifpub = ifp->ifpub;
+- if (ifpub) {
+- in6_ifa_hold(ifpub);
+- spin_unlock_bh(&ifp->lock);
+- ipv6_create_tempaddr(ifpub, ifp);
+- in6_ifa_put(ifpub);
+- } else {
+- spin_unlock_bh(&ifp->lock);
+- }
+- ipv6_del_addr(ifp);
+-#endif
+- } else
+- ipv6_del_addr(ifp);
+-}
+-
+-void addrconf_dad_failure(struct inet6_ifaddr *ifp)
+-{
+- if (net_ratelimit())
+- printk(KERN_INFO "%s: duplicate address detected!\n", ifp->idev->dev->name);
+- addrconf_dad_stop(ifp);
+-}
+-
+-/* Join to solicited addr multicast group. */
+-
+-void addrconf_join_solict(struct net_device *dev, struct in6_addr *addr)
+-{
+- struct in6_addr maddr;
+-
+- if (dev->flags&(IFF_LOOPBACK|IFF_NOARP))
+- return;
+-
+- addrconf_addr_solict_mult(addr, &maddr);
+- ipv6_dev_mc_inc(dev, &maddr);
+-}
+-
+-void addrconf_leave_solict(struct inet6_dev *idev, struct in6_addr *addr)
+-{
+- struct in6_addr maddr;
+-
+- if (idev->dev->flags&(IFF_LOOPBACK|IFF_NOARP))
+- return;
+-
+- addrconf_addr_solict_mult(addr, &maddr);
+- __ipv6_dev_mc_dec(idev, &maddr);
+-}
+-
+-static void addrconf_join_anycast(struct inet6_ifaddr *ifp)
+-{
+- struct in6_addr addr;
+- ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
+- if (ipv6_addr_any(&addr))
+- return;
+- ipv6_dev_ac_inc(ifp->idev->dev, &addr);
+-}
+-
+-static void addrconf_leave_anycast(struct inet6_ifaddr *ifp)
+-{
+- struct in6_addr addr;
+- ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
+- if (ipv6_addr_any(&addr))
+- return;
+- __ipv6_dev_ac_dec(ifp->idev, &addr);
+-}
+-
+-static int addrconf_ifid_eui48(u8 *eui, struct net_device *dev)
+-{
+- if (dev->addr_len != ETH_ALEN)
+- return -1;
+- memcpy(eui, dev->dev_addr, 3);
+- memcpy(eui + 5, dev->dev_addr + 3, 3);
+-
+- /*
+- * The zSeries OSA network cards can be shared among various
+- * OS instances, but the OSA cards have only one MAC address.
+- * This leads to duplicate address conflicts in conjunction
+- * with IPv6 if more than one instance uses the same card.
+- *
+- * The driver for these cards can deliver a unique 16-bit
+- * identifier for each instance sharing the same card. It is
+- * placed instead of 0xFFFE in the interface identifier. The
+- * "u" bit of the interface identifier is not inverted in this
+- * case. Hence the resulting interface identifier has local
+- * scope according to RFC2373.
+- */
+- if (dev->dev_id) {
+- eui[3] = (dev->dev_id >> 8) & 0xFF;
+- eui[4] = dev->dev_id & 0xFF;
+- } else {
+- eui[3] = 0xFF;
+- eui[4] = 0xFE;
+- eui[0] ^= 2;
+- }
+- return 0;
+-}
+-
+-static int addrconf_ifid_arcnet(u8 *eui, struct net_device *dev)
+-{
+- /* XXX: inherit EUI-64 from other interface -- yoshfuji */
+- if (dev->addr_len != ARCNET_ALEN)
+- return -1;
+- memset(eui, 0, 7);
+- eui[7] = *(u8*)dev->dev_addr;
+- return 0;
+-}
+-
+-static int addrconf_ifid_infiniband(u8 *eui, struct net_device *dev)
+-{
+- if (dev->addr_len != INFINIBAND_ALEN)
+- return -1;
+- memcpy(eui, dev->dev_addr + 12, 8);
+- eui[0] |= 2;
+- return 0;
+-}
+-
+-static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
+-{
+- switch (dev->type) {
+- case ARPHRD_ETHER:
+- case ARPHRD_FDDI:
+- case ARPHRD_IEEE802_TR:
+- return addrconf_ifid_eui48(eui, dev);
+- case ARPHRD_ARCNET:
+- return addrconf_ifid_arcnet(eui, dev);
+- case ARPHRD_INFINIBAND:
+- return addrconf_ifid_infiniband(eui, dev);
+- }
+- return -1;
+-}
+-
+-static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev)
+-{
+- int err = -1;
+- struct inet6_ifaddr *ifp;
+-
+- read_lock_bh(&idev->lock);
+- for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) {
+- if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) {
+- memcpy(eui, ifp->addr.s6_addr+8, 8);
+- err = 0;
+- break;
+- }
+- }
+- read_unlock_bh(&idev->lock);
+- return err;
+-}
+-
+-#ifdef CONFIG_IPV6_PRIVACY
+-/* (re)generation of randomized interface identifier (RFC 3041 3.2, 3.5) */
+-static int __ipv6_regen_rndid(struct inet6_dev *idev)
+-{
+-regen:
+- get_random_bytes(idev->rndid, sizeof(idev->rndid));
+- idev->rndid[0] &= ~0x02;
+-
+- /*
+- * <draft-ietf-ipngwg-temp-addresses-v2-00.txt>:
+- * check if generated address is not inappropriate
+- *
+- * - Reserved subnet anycast (RFC 2526)
+- * 11111101 11....11 1xxxxxxx
+- * - ISATAP (draft-ietf-ngtrans-isatap-13.txt) 5.1
+- * 00-00-5E-FE-xx-xx-xx-xx
+- * - value 0
+- * - XXX: already assigned to an address on the device
+- */
+- if (idev->rndid[0] == 0xfd &&
+- (idev->rndid[1]&idev->rndid[2]&idev->rndid[3]&idev->rndid[4]&idev->rndid[5]&idev->rndid[6]) == 0xff &&
+- (idev->rndid[7]&0x80))
+- goto regen;
+- if ((idev->rndid[0]|idev->rndid[1]) == 0) {
+- if (idev->rndid[2] == 0x5e && idev->rndid[3] == 0xfe)
+- goto regen;
+- if ((idev->rndid[2]|idev->rndid[3]|idev->rndid[4]|idev->rndid[5]|idev->rndid[6]|idev->rndid[7]) == 0x00)
+- goto regen;
+- }
+-
+- return 0;
+-}
+-
+-static void ipv6_regen_rndid(unsigned long data)
+-{
+- struct inet6_dev *idev = (struct inet6_dev *) data;
+- unsigned long expires;
+-
+- rcu_read_lock_bh();
+- write_lock_bh(&idev->lock);
+-
+- if (idev->dead)
+- goto out;
+-
+- if (__ipv6_regen_rndid(idev) < 0)
+- goto out;
+-
+- expires = jiffies +
+- idev->cnf.temp_prefered_lft * HZ -
+- idev->cnf.regen_max_retry * idev->cnf.dad_transmits * idev->nd_parms->retrans_time - desync_factor;
+- if (time_before(expires, jiffies)) {
+- printk(KERN_WARNING
+- "ipv6_regen_rndid(): too short regeneration interval; timer disabled for %s.\n",
+- idev->dev->name);
+- goto out;
+- }
+-
+- if (!mod_timer(&idev->regen_timer, expires))
+- in6_dev_hold(idev);
+-
+-out:
+- write_unlock_bh(&idev->lock);
+- rcu_read_unlock_bh();
+- in6_dev_put(idev);
+-}
+-
+-static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr) {
+- int ret = 0;
+-
+- if (tmpaddr && memcmp(idev->rndid, &tmpaddr->s6_addr[8], 8) == 0)
+- ret = __ipv6_regen_rndid(idev);
+- return ret;
+-}
+-#endif
+-
+-/*
+- * Add prefix route.
+- */
+-
+-static void
+-addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
+- unsigned long expires, u32 flags)
+-{
+- struct fib6_config cfg = {
+- .fc_table = RT6_TABLE_PREFIX,
+- .fc_metric = IP6_RT_PRIO_ADDRCONF,
+- .fc_ifindex = dev->ifindex,
+- .fc_expires = expires,
+- .fc_dst_len = plen,
+- .fc_flags = RTF_UP | flags,
+- };
+-
+- ipv6_addr_copy(&cfg.fc_dst, pfx);
+-
+- /* Prevent useless cloning on PtP SIT.
+- This thing is done here expecting that the whole
+- class of non-broadcast devices need not cloning.
+- */
+-#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
+- if (dev->type == ARPHRD_SIT && (dev->flags & IFF_POINTOPOINT))
+- cfg.fc_flags |= RTF_NONEXTHOP;
+-#endif
+-
+- ip6_route_add(&cfg);
+-}
+-
+-/* Create "default" multicast route to the interface */
+-
+-static void addrconf_add_mroute(struct net_device *dev)
+-{
+- struct fib6_config cfg = {
+- .fc_table = RT6_TABLE_LOCAL,
+- .fc_metric = IP6_RT_PRIO_ADDRCONF,
+- .fc_ifindex = dev->ifindex,
+- .fc_dst_len = 8,
+- .fc_flags = RTF_UP,
+- };
+-
+- ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0);
+-
+- ip6_route_add(&cfg);
+-}
+-
+-#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
+-static void sit_route_add(struct net_device *dev)
+-{
+- struct fib6_config cfg = {
+- .fc_table = RT6_TABLE_MAIN,
+- .fc_metric = IP6_RT_PRIO_ADDRCONF,
+- .fc_ifindex = dev->ifindex,
+- .fc_dst_len = 96,
+- .fc_flags = RTF_UP | RTF_NONEXTHOP,
+- };
+-
+- /* prefix length - 96 bits "::d.d.d.d" */
+- ip6_route_add(&cfg);
+-}
+-#endif
+-
+-static void addrconf_add_lroute(struct net_device *dev)
+-{
+- struct in6_addr addr;
+-
+- ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0);
+- addrconf_prefix_route(&addr, 64, dev, 0, 0);
+-}
+-
+-static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
+-{
+- struct inet6_dev *idev;
+-
+- ASSERT_RTNL();
+-
+- if ((idev = ipv6_find_idev(dev)) == NULL)
+- return NULL;
+-
+- /* Add default multicast route */
+- addrconf_add_mroute(dev);
+-
+- /* Add link local route */
+- addrconf_add_lroute(dev);
+- return idev;
+-}
+-
+-void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
+-{
+- struct prefix_info *pinfo;
+- __u32 valid_lft;
+- __u32 prefered_lft;
+- int addr_type;
+- unsigned long rt_expires;
+- struct inet6_dev *in6_dev;
+-
+- pinfo = (struct prefix_info *) opt;
+-
+- if (len < sizeof(struct prefix_info)) {
+- ADBG(("addrconf: prefix option too short\n"));
+- return;
+- }
+-
+- /*
+- * Validation checks ([ADDRCONF], page 19)
+- */
+-
+- addr_type = ipv6_addr_type(&pinfo->prefix);
+-
+- if (addr_type & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL))
+- return;
+-
+- valid_lft = ntohl(pinfo->valid);
+- prefered_lft = ntohl(pinfo->prefered);
+-
+- if (prefered_lft > valid_lft) {
+- if (net_ratelimit())
+- printk(KERN_WARNING "addrconf: prefix option has invalid lifetime\n");
+- return;
+- }
+-
+- in6_dev = in6_dev_get(dev);
+-
+- if (in6_dev == NULL) {
+- if (net_ratelimit())
+- printk(KERN_DEBUG "addrconf: device %s not configured\n", dev->name);
+- return;
+- }
+-
+- /*
+- * Two things going on here:
+- * 1) Add routes for on-link prefixes
+- * 2) Configure prefixes with the auto flag set
+- */
+-
+- /* Avoid arithmetic overflow. Really, we could
+- save rt_expires in seconds, likely valid_lft,
+- but it would require division in fib gc, that it
+- not good.
+- */
+- if (valid_lft >= 0x7FFFFFFF/HZ)
+- rt_expires = 0x7FFFFFFF - (0x7FFFFFFF % HZ);
+- else
+- rt_expires = valid_lft * HZ;
+-
+- /*
+- * We convert this (in jiffies) to clock_t later.
+- * Avoid arithmetic overflow there as well.
+- * Overflow can happen only if HZ < USER_HZ.
+- */
+- if (HZ < USER_HZ && rt_expires > 0x7FFFFFFF / USER_HZ)
+- rt_expires = 0x7FFFFFFF / USER_HZ;
+-
+- if (pinfo->onlink) {
+- struct rt6_info *rt;
+- rt = rt6_lookup(&pinfo->prefix, NULL, dev->ifindex, 1);
+-
+- if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
+- if (rt->rt6i_flags&RTF_EXPIRES) {
+- if (valid_lft == 0) {
+- ip6_del_rt(rt);
+- rt = NULL;
+- } else {
+- rt->rt6i_expires = jiffies + rt_expires;
+- }
+- }
+- } else if (valid_lft) {
+- addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len,
+- dev, jiffies_to_clock_t(rt_expires), RTF_ADDRCONF|RTF_EXPIRES|RTF_PREFIX_RT);
+- }
+- if (rt)
+- dst_release(&rt->u.dst);
+- }
+-
+- /* Try to figure out our local address for this prefix */
+-
+- if (pinfo->autoconf && in6_dev->cnf.autoconf) {
+- struct inet6_ifaddr * ifp;
+- struct in6_addr addr;
+- int create = 0, update_lft = 0;
+-
+- if (pinfo->prefix_len == 64) {
+- memcpy(&addr, &pinfo->prefix, 8);
+- if (ipv6_generate_eui64(addr.s6_addr + 8, dev) &&
+- ipv6_inherit_eui64(addr.s6_addr + 8, in6_dev)) {
+- in6_dev_put(in6_dev);
+- return;
+- }
+- goto ok;
+- }
+- if (net_ratelimit())
+- printk(KERN_DEBUG "IPv6 addrconf: prefix with wrong length %d\n",
+- pinfo->prefix_len);
+- in6_dev_put(in6_dev);
+- return;
+-
+-ok:
+-
+- ifp = ipv6_get_ifaddr(&addr, dev, 1);
+-
+- if (ifp == NULL && valid_lft) {
+- int max_addresses = in6_dev->cnf.max_addresses;
+- u32 addr_flags = 0;
+-
+-#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
+- if (in6_dev->cnf.optimistic_dad &&
+- !ipv6_devconf.forwarding)
+- addr_flags = IFA_F_OPTIMISTIC;
+-#endif
+-
+- /* Do not allow to create too much of autoconfigured
+- * addresses; this would be too easy way to crash kernel.
+- */
+- if (!max_addresses ||
+- ipv6_count_addresses(in6_dev) < max_addresses)
+- ifp = ipv6_add_addr(in6_dev, &addr, pinfo->prefix_len,
+- addr_type&IPV6_ADDR_SCOPE_MASK,
+- addr_flags);
+-
+- if (!ifp || IS_ERR(ifp)) {
+- in6_dev_put(in6_dev);
+- return;
+- }
+-
+- update_lft = create = 1;
+- ifp->cstamp = jiffies;
+- addrconf_dad_start(ifp, RTF_ADDRCONF|RTF_PREFIX_RT);
+- }
+-
+- if (ifp) {
+- int flags;
+- unsigned long now;
+-#ifdef CONFIG_IPV6_PRIVACY
+- struct inet6_ifaddr *ift;
+-#endif
+- u32 stored_lft;
+-
+- /* update lifetime (RFC2462 5.5.3 e) */
+- spin_lock(&ifp->lock);
+- now = jiffies;
+- if (ifp->valid_lft > (now - ifp->tstamp) / HZ)
+- stored_lft = ifp->valid_lft - (now - ifp->tstamp) / HZ;
+- else
+- stored_lft = 0;
+- if (!update_lft && stored_lft) {
+- if (valid_lft > MIN_VALID_LIFETIME ||
+- valid_lft > stored_lft)
+- update_lft = 1;
+- else if (stored_lft <= MIN_VALID_LIFETIME) {
+- /* valid_lft <= stored_lft is always true */
+- /* XXX: IPsec */
+- update_lft = 0;
+- } else {
+- valid_lft = MIN_VALID_LIFETIME;
+- if (valid_lft < prefered_lft)
+- prefered_lft = valid_lft;
+- update_lft = 1;
+- }
+- }
+-
+- if (update_lft) {
+- ifp->valid_lft = valid_lft;
+- ifp->prefered_lft = prefered_lft;
+- ifp->tstamp = now;
+- flags = ifp->flags;
+- ifp->flags &= ~IFA_F_DEPRECATED;
+- spin_unlock(&ifp->lock);
+-
+- if (!(flags&IFA_F_TENTATIVE))
+- ipv6_ifa_notify(0, ifp);
+- } else
+- spin_unlock(&ifp->lock);
+-
+-#ifdef CONFIG_IPV6_PRIVACY
+- read_lock_bh(&in6_dev->lock);
+- /* update all temporary addresses in the list */
+- for (ift=in6_dev->tempaddr_list; ift; ift=ift->tmp_next) {
+- /*
+- * When adjusting the lifetimes of an existing
+- * temporary address, only lower the lifetimes.
+- * Implementations must not increase the
+- * lifetimes of an existing temporary address
+- * when processing a Prefix Information Option.
+- */
+- spin_lock(&ift->lock);
+- flags = ift->flags;
+- if (ift->valid_lft > valid_lft &&
+- ift->valid_lft - valid_lft > (jiffies - ift->tstamp) / HZ)
+- ift->valid_lft = valid_lft + (jiffies - ift->tstamp) / HZ;
+- if (ift->prefered_lft > prefered_lft &&
+- ift->prefered_lft - prefered_lft > (jiffies - ift->tstamp) / HZ)
+- ift->prefered_lft = prefered_lft + (jiffies - ift->tstamp) / HZ;
+- spin_unlock(&ift->lock);
+- if (!(flags&IFA_F_TENTATIVE))
+- ipv6_ifa_notify(0, ift);
+- }
+-
+- if (create && in6_dev->cnf.use_tempaddr > 0) {
+- /*
+- * When a new public address is created as described in [ADDRCONF],
+- * also create a new temporary address.
+- */
+- read_unlock_bh(&in6_dev->lock);
+- ipv6_create_tempaddr(ifp, NULL);
+- } else {
+- read_unlock_bh(&in6_dev->lock);
+- }
+-#endif
+- in6_ifa_put(ifp);
+- addrconf_verify(0);
+- }
+- }
+- inet6_prefix_notify(RTM_NEWPREFIX, in6_dev, pinfo);
+- in6_dev_put(in6_dev);
+-}
+-
+-/*
+- * Set destination address.
+- * Special case for SIT interfaces where we create a new "virtual"
+- * device.
+- */
+-int addrconf_set_dstaddr(void __user *arg)
+-{
+- struct in6_ifreq ireq;
+- struct net_device *dev;
+- int err = -EINVAL;
+-
+- rtnl_lock();
+-
+- err = -EFAULT;
+- if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq)))
+- goto err_exit;
+-
+- dev = __dev_get_by_index(ireq.ifr6_ifindex);
+-
+- err = -ENODEV;
+- if (dev == NULL)
+- goto err_exit;
+-
+-#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
+- if (dev->type == ARPHRD_SIT) {
+- struct ifreq ifr;
+- mm_segment_t oldfs;
+- struct ip_tunnel_parm p;
+-
+- err = -EADDRNOTAVAIL;
+- if (!(ipv6_addr_type(&ireq.ifr6_addr) & IPV6_ADDR_COMPATv4))
+- goto err_exit;
+-
+- memset(&p, 0, sizeof(p));
+- p.iph.daddr = ireq.ifr6_addr.s6_addr32[3];
+- p.iph.saddr = 0;
+- p.iph.version = 4;
+- p.iph.ihl = 5;
+- p.iph.protocol = IPPROTO_IPV6;
+- p.iph.ttl = 64;
+- ifr.ifr_ifru.ifru_data = (void __user *)&p;
+-
+- oldfs = get_fs(); set_fs(KERNEL_DS);
+- err = dev->do_ioctl(dev, &ifr, SIOCADDTUNNEL);
+- set_fs(oldfs);
+-
+- if (err == 0) {
+- err = -ENOBUFS;
+- if ((dev = __dev_get_by_name(p.name)) == NULL)
+- goto err_exit;
+- err = dev_open(dev);
+- }
+- }
+-#endif
+-
+-err_exit:
+- rtnl_unlock();
+- return err;
+-}
+-
+-/*
+- * Manual configuration of address on an interface
+- */
+-static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen,
+- __u8 ifa_flags, __u32 prefered_lft, __u32 valid_lft)
+-{
+- struct inet6_ifaddr *ifp;
+- struct inet6_dev *idev;
+- struct net_device *dev;
+- int scope;
+- u32 flags = RTF_EXPIRES;
+-
+- ASSERT_RTNL();
+-
+- /* check the lifetime */
+- if (!valid_lft || prefered_lft > valid_lft)
+- return -EINVAL;
+-
+- if ((dev = __dev_get_by_index(ifindex)) == NULL)
+- return -ENODEV;
+-
+- if ((idev = addrconf_add_dev(dev)) == NULL)
+- return -ENOBUFS;
+-
+- scope = ipv6_addr_scope(pfx);
+-
+- if (valid_lft == INFINITY_LIFE_TIME) {
+- ifa_flags |= IFA_F_PERMANENT;
+- flags = 0;
+- } else if (valid_lft >= 0x7FFFFFFF/HZ)
+- valid_lft = 0x7FFFFFFF/HZ;
+-
+- if (prefered_lft == 0)
+- ifa_flags |= IFA_F_DEPRECATED;
+- else if ((prefered_lft >= 0x7FFFFFFF/HZ) &&
+- (prefered_lft != INFINITY_LIFE_TIME))
+- prefered_lft = 0x7FFFFFFF/HZ;
+-
+- ifp = ipv6_add_addr(idev, pfx, plen, scope, ifa_flags);
+-
+- if (!IS_ERR(ifp)) {
+- spin_lock_bh(&ifp->lock);
+- ifp->valid_lft = valid_lft;
+- ifp->prefered_lft = prefered_lft;
+- ifp->tstamp = jiffies;
+- spin_unlock_bh(&ifp->lock);
+-
+- addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev,
+- jiffies_to_clock_t(valid_lft * HZ), flags);
+- /*
+- * Note that section 3.1 of RFC 4429 indicates
+- * that the Optimistic flag should not be set for
+- * manually configured addresses
+- */
+- addrconf_dad_start(ifp, 0);
+- in6_ifa_put(ifp);
+- addrconf_verify(0);
+- return 0;
+- }
+-
+- return PTR_ERR(ifp);
+-}
+-
+-static int inet6_addr_del(int ifindex, struct in6_addr *pfx, int plen)
+-{
+- struct inet6_ifaddr *ifp;
+- struct inet6_dev *idev;
+- struct net_device *dev;
+-
+- if ((dev = __dev_get_by_index(ifindex)) == NULL)
+- return -ENODEV;
+-
+- if ((idev = __in6_dev_get(dev)) == NULL)
+- return -ENXIO;
+-
+- read_lock_bh(&idev->lock);
+- for (ifp = idev->addr_list; ifp; ifp=ifp->if_next) {
+- if (ifp->prefix_len == plen &&
+- ipv6_addr_equal(pfx, &ifp->addr)) {
+- in6_ifa_hold(ifp);
+- read_unlock_bh(&idev->lock);
+-
+- ipv6_del_addr(ifp);
+-
+- /* If the last address is deleted administratively,
+- disable IPv6 on this interface.
+- */
+- if (idev->addr_list == NULL)
+- addrconf_ifdown(idev->dev, 1);
+- return 0;
+- }
+- }
+- read_unlock_bh(&idev->lock);
+- return -EADDRNOTAVAIL;
+-}
+-
+-
+-int addrconf_add_ifaddr(void __user *arg)
+-{
+- struct in6_ifreq ireq;
+- int err;
+-
+- if (!capable(CAP_NET_ADMIN))
+- return -EPERM;
+-
+- if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq)))
+- return -EFAULT;
+-
+- rtnl_lock();
+- err = inet6_addr_add(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen,
+- IFA_F_PERMANENT, INFINITY_LIFE_TIME, INFINITY_LIFE_TIME);
+- rtnl_unlock();
+- return err;
+-}
+-
+-int addrconf_del_ifaddr(void __user *arg)
+-{
+- struct in6_ifreq ireq;
+- int err;
+-
+- if (!capable(CAP_NET_ADMIN))
+- return -EPERM;
+-
+- if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq)))
+- return -EFAULT;
+-
+- rtnl_lock();
+- err = inet6_addr_del(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen);
+- rtnl_unlock();
+- return err;
+-}
+-
+-#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
+-static void sit_add_v4_addrs(struct inet6_dev *idev)
+-{
+- struct inet6_ifaddr * ifp;
+- struct in6_addr addr;
+- struct net_device *dev;
+- int scope;
+-
+- ASSERT_RTNL();
+-
+- memset(&addr, 0, sizeof(struct in6_addr));
+- memcpy(&addr.s6_addr32[3], idev->dev->dev_addr, 4);
+-
+- if (idev->dev->flags&IFF_POINTOPOINT) {
+- addr.s6_addr32[0] = htonl(0xfe800000);
+- scope = IFA_LINK;
+- } else {
+- scope = IPV6_ADDR_COMPATv4;
+- }
+-
+- if (addr.s6_addr32[3]) {
+- ifp = ipv6_add_addr(idev, &addr, 128, scope, IFA_F_PERMANENT);
+- if (!IS_ERR(ifp)) {
+- spin_lock_bh(&ifp->lock);
+- ifp->flags &= ~IFA_F_TENTATIVE;
+- spin_unlock_bh(&ifp->lock);
+- ipv6_ifa_notify(RTM_NEWADDR, ifp);
+- in6_ifa_put(ifp);
+- }
+- return;
+- }
+-
+- for_each_netdev(dev) {
+- struct in_device * in_dev = __in_dev_get_rtnl(dev);
+- if (in_dev && (dev->flags & IFF_UP)) {
+- struct in_ifaddr * ifa;
+-
+- int flag = scope;
+-
+- for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
+- int plen;
+-
+- addr.s6_addr32[3] = ifa->ifa_local;
+-
+- if (ifa->ifa_scope == RT_SCOPE_LINK)
+- continue;
+- if (ifa->ifa_scope >= RT_SCOPE_HOST) {
+- if (idev->dev->flags&IFF_POINTOPOINT)
+- continue;
+- flag |= IFA_HOST;
+- }
+- if (idev->dev->flags&IFF_POINTOPOINT)
+- plen = 64;
+- else
+- plen = 96;
+-
+- ifp = ipv6_add_addr(idev, &addr, plen, flag,
+- IFA_F_PERMANENT);
+- if (!IS_ERR(ifp)) {
+- spin_lock_bh(&ifp->lock);
+- ifp->flags &= ~IFA_F_TENTATIVE;
+- spin_unlock_bh(&ifp->lock);
+- ipv6_ifa_notify(RTM_NEWADDR, ifp);
+- in6_ifa_put(ifp);
+- }
+- }
+- }
+- }
+-}
+-#endif
+-
+-static void init_loopback(struct net_device *dev)
+-{
+- struct inet6_dev *idev;
+- struct inet6_ifaddr * ifp;
+-
+- /* ::1 */
+-
+- ASSERT_RTNL();
+-
+- if ((idev = ipv6_find_idev(dev)) == NULL) {
+- printk(KERN_DEBUG "init loopback: add_dev failed\n");
+- return;
+- }
+-
+- ifp = ipv6_add_addr(idev, &in6addr_loopback, 128, IFA_HOST, IFA_F_PERMANENT);
+- if (!IS_ERR(ifp)) {
+- spin_lock_bh(&ifp->lock);
+- ifp->flags &= ~IFA_F_TENTATIVE;
+- spin_unlock_bh(&ifp->lock);
+- ipv6_ifa_notify(RTM_NEWADDR, ifp);
+- in6_ifa_put(ifp);
+- }
+-}
+-
+-static void addrconf_add_linklocal(struct inet6_dev *idev, struct in6_addr *addr)
+-{
+- struct inet6_ifaddr * ifp;
+- u32 addr_flags = IFA_F_PERMANENT;
+-
+-#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
+- if (idev->cnf.optimistic_dad &&
+- !ipv6_devconf.forwarding)
+- addr_flags |= IFA_F_OPTIMISTIC;
+-#endif
+-
+-
+- ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, addr_flags);
+- if (!IS_ERR(ifp)) {
+- addrconf_prefix_route(&ifp->addr, ifp->prefix_len, idev->dev, 0, 0);
+- addrconf_dad_start(ifp, 0);
+- in6_ifa_put(ifp);
+- }
+-}
+-
+-static void addrconf_dev_config(struct net_device *dev)
+-{
+- struct in6_addr addr;
+- struct inet6_dev * idev;
+-
+- ASSERT_RTNL();
+-
+- if ((dev->type != ARPHRD_ETHER) &&
+- (dev->type != ARPHRD_FDDI) &&
+- (dev->type != ARPHRD_IEEE802_TR) &&
+- (dev->type != ARPHRD_ARCNET) &&
+- (dev->type != ARPHRD_INFINIBAND)) {
+- /* Alas, we support only Ethernet autoconfiguration. */
+- return;
+- }
+-
+- idev = addrconf_add_dev(dev);
+- if (idev == NULL)
+- return;
+-
+- memset(&addr, 0, sizeof(struct in6_addr));
+- addr.s6_addr32[0] = htonl(0xFE800000);
+-
+- if (ipv6_generate_eui64(addr.s6_addr + 8, dev) == 0)
+- addrconf_add_linklocal(idev, &addr);
+-}
+-
+-#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
+-static void addrconf_sit_config(struct net_device *dev)
+-{
+- struct inet6_dev *idev;
+-
+- ASSERT_RTNL();
+-
+- /*
+- * Configure the tunnel with one of our IPv4
+- * addresses... we should configure all of
+- * our v4 addrs in the tunnel
+- */
+-
+- if ((idev = ipv6_find_idev(dev)) == NULL) {
+- printk(KERN_DEBUG "init sit: add_dev failed\n");
+- return;
+- }
+-
+- sit_add_v4_addrs(idev);
+-
+- if (dev->flags&IFF_POINTOPOINT) {
+- addrconf_add_mroute(dev);
+- addrconf_add_lroute(dev);
+- } else
+- sit_route_add(dev);
+-}
+-#endif
+-
+-static inline int
+-ipv6_inherit_linklocal(struct inet6_dev *idev, struct net_device *link_dev)
+-{
+- struct in6_addr lladdr;
+-
+- if (!ipv6_get_lladdr(link_dev, &lladdr, IFA_F_TENTATIVE)) {
+- addrconf_add_linklocal(idev, &lladdr);
+- return 0;
+- }
+- return -1;
+-}
+-
+-static void ip6_tnl_add_linklocal(struct inet6_dev *idev)
+-{
+- struct net_device *link_dev;
+-
+- /* first try to inherit the link-local address from the link device */
+- if (idev->dev->iflink &&
+- (link_dev = __dev_get_by_index(idev->dev->iflink))) {
+- if (!ipv6_inherit_linklocal(idev, link_dev))
+- return;
+- }
+- /* then try to inherit it from any device */
+- for_each_netdev(link_dev) {
+- if (!ipv6_inherit_linklocal(idev, link_dev))
+- return;
+- }
+- printk(KERN_DEBUG "init ip6-ip6: add_linklocal failed\n");
+-}
+-
+-/*
+- * Autoconfigure tunnel with a link-local address so routing protocols,
+- * DHCPv6, MLD etc. can be run over the virtual link
+- */
+-
+-static void addrconf_ip6_tnl_config(struct net_device *dev)
+-{
+- struct inet6_dev *idev;
+-
+- ASSERT_RTNL();
+-
+- if ((idev = addrconf_add_dev(dev)) == NULL) {
+- printk(KERN_DEBUG "init ip6-ip6: add_dev failed\n");
+- return;
+- }
+- ip6_tnl_add_linklocal(idev);
+-}
+-
+-static int addrconf_notify(struct notifier_block *this, unsigned long event,
+- void * data)
+-{
+- struct net_device *dev = (struct net_device *) data;
+- struct inet6_dev *idev = __in6_dev_get(dev);
+- int run_pending = 0;
+-
+- switch(event) {
+- case NETDEV_REGISTER:
+- if (!idev && dev->mtu >= IPV6_MIN_MTU) {
+- idev = ipv6_add_dev(dev);
+- if (!idev)
+- printk(KERN_WARNING "IPv6: add_dev failed for %s\n",
+- dev->name);
+- }
+- break;
+- case NETDEV_UP:
+- case NETDEV_CHANGE:
+- if (event == NETDEV_UP) {
+- if (!addrconf_qdisc_ok(dev)) {
+- /* device is not ready yet. */
+- printk(KERN_INFO
+- "ADDRCONF(NETDEV_UP): %s: "
+- "link is not ready\n",
+- dev->name);
+- break;
+- }
+-
+- if (idev)
+- idev->if_flags |= IF_READY;
+- } else {
+- if (!addrconf_qdisc_ok(dev)) {
+- /* device is still not ready. */
+- break;
+- }
+-
+- if (idev) {
+- if (idev->if_flags & IF_READY) {
+- /* device is already configured. */
+- break;
+- }
+- idev->if_flags |= IF_READY;
+- }
+-
+- printk(KERN_INFO
+- "ADDRCONF(NETDEV_CHANGE): %s: "
+- "link becomes ready\n",
+- dev->name);
+-
+- run_pending = 1;
+- }
+-
+- switch(dev->type) {
+-#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
+- case ARPHRD_SIT:
+- addrconf_sit_config(dev);
+- break;
+-#endif
+- case ARPHRD_TUNNEL6:
+- addrconf_ip6_tnl_config(dev);
+- break;
+- case ARPHRD_LOOPBACK:
+- init_loopback(dev);
+- break;
+-
+- default:
+- addrconf_dev_config(dev);
+- break;
+- }
+- if (idev) {
+- if (run_pending)
+- addrconf_dad_run(idev);
+-
+- /* If the MTU changed during the interface down, when the
+- interface up, the changed MTU must be reflected in the
+- idev as well as routers.
+- */
+- if (idev->cnf.mtu6 != dev->mtu && dev->mtu >= IPV6_MIN_MTU) {
+- rt6_mtu_change(dev, dev->mtu);
+- idev->cnf.mtu6 = dev->mtu;
+- }
+- idev->tstamp = jiffies;
+- inet6_ifinfo_notify(RTM_NEWLINK, idev);
+- /* If the changed mtu during down is lower than IPV6_MIN_MTU
+- stop IPv6 on this interface.
+- */
+- if (dev->mtu < IPV6_MIN_MTU)
+- addrconf_ifdown(dev, event != NETDEV_DOWN);
+- }
+- break;
+-
+- case NETDEV_CHANGEMTU:
+- if ( idev && dev->mtu >= IPV6_MIN_MTU) {
+- rt6_mtu_change(dev, dev->mtu);
+- idev->cnf.mtu6 = dev->mtu;
+- break;
+- }
+-
+- /* MTU falled under IPV6_MIN_MTU. Stop IPv6 on this interface. */
+-
+- case NETDEV_DOWN:
+- case NETDEV_UNREGISTER:
+- /*
+- * Remove all addresses from this interface.
+- */
+- addrconf_ifdown(dev, event != NETDEV_DOWN);
+- break;
+-
+- case NETDEV_CHANGENAME:
+- if (idev) {
+- snmp6_unregister_dev(idev);
+-#ifdef CONFIG_SYSCTL
+- addrconf_sysctl_unregister(&idev->cnf);
+- neigh_sysctl_unregister(idev->nd_parms);
+- neigh_sysctl_register(dev, idev->nd_parms,
+- NET_IPV6, NET_IPV6_NEIGH, "ipv6",
+- &ndisc_ifinfo_sysctl_change,
+- NULL);
+- addrconf_sysctl_register(idev, &idev->cnf);
+-#endif
+- snmp6_register_dev(idev);
+- }
+- break;
+- }
+-
+- return NOTIFY_OK;
+-}
+-
+-/*
+- * addrconf module should be notified of a device going up
+- */
+-static struct notifier_block ipv6_dev_notf = {
+- .notifier_call = addrconf_notify,
+- .priority = 0
+-};
+-
+-static int addrconf_ifdown(struct net_device *dev, int how)
+-{
+- struct inet6_dev *idev;
+- struct inet6_ifaddr *ifa, **bifa;
+- int i;
+-
+- ASSERT_RTNL();
+-
+- if (dev == &loopback_dev && how == 1)
+- how = 0;
+-
+- rt6_ifdown(dev);
+- neigh_ifdown(&nd_tbl, dev);
+-
+- idev = __in6_dev_get(dev);
+- if (idev == NULL)
+- return -ENODEV;
+-
+- /* Step 1: remove reference to ipv6 device from parent device.
+- Do not dev_put!
+- */
+- if (how == 1) {
+- idev->dead = 1;
+-
+- /* protected by rtnl_lock */
+- rcu_assign_pointer(dev->ip6_ptr, NULL);
+-
+- /* Step 1.5: remove snmp6 entry */
+- snmp6_unregister_dev(idev);
+-
+- }
+-
+- /* Step 2: clear hash table */
+- for (i=0; i<IN6_ADDR_HSIZE; i++) {
+- bifa = &inet6_addr_lst[i];
+-
+- write_lock_bh(&addrconf_hash_lock);
+- while ((ifa = *bifa) != NULL) {
+- if (ifa->idev == idev) {
+- *bifa = ifa->lst_next;
+- ifa->lst_next = NULL;
+- addrconf_del_timer(ifa);
+- in6_ifa_put(ifa);
+- continue;
+- }
+- bifa = &ifa->lst_next;
+- }
+- write_unlock_bh(&addrconf_hash_lock);
+- }
+-
+- write_lock_bh(&idev->lock);
+-
+- /* Step 3: clear flags for stateless addrconf */
+- if (how != 1)
+- idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD|IF_READY);
+-
+- /* Step 4: clear address list */
+-#ifdef CONFIG_IPV6_PRIVACY
+- if (how == 1 && del_timer(&idev->regen_timer))
+- in6_dev_put(idev);
+-
+- /* clear tempaddr list */
+- while ((ifa = idev->tempaddr_list) != NULL) {
+- idev->tempaddr_list = ifa->tmp_next;
+- ifa->tmp_next = NULL;
+- ifa->dead = 1;
+- write_unlock_bh(&idev->lock);
+- spin_lock_bh(&ifa->lock);
+-
+- if (ifa->ifpub) {
+- in6_ifa_put(ifa->ifpub);
+- ifa->ifpub = NULL;
+- }
+- spin_unlock_bh(&ifa->lock);
+- in6_ifa_put(ifa);
+- write_lock_bh(&idev->lock);
+- }
+-#endif
+- while ((ifa = idev->addr_list) != NULL) {
+- idev->addr_list = ifa->if_next;
+- ifa->if_next = NULL;
+- ifa->dead = 1;
+- addrconf_del_timer(ifa);
+- write_unlock_bh(&idev->lock);
+-
+- __ipv6_ifa_notify(RTM_DELADDR, ifa);
+- atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa);
+- in6_ifa_put(ifa);
+-
+- write_lock_bh(&idev->lock);
+- }
+- write_unlock_bh(&idev->lock);
+-
+- /* Step 5: Discard multicast list */
+-
+- if (how == 1)
+- ipv6_mc_destroy_dev(idev);
+- else
+- ipv6_mc_down(idev);
+-
+- /* Step 5: netlink notification of this interface */
+- idev->tstamp = jiffies;
+- inet6_ifinfo_notify(RTM_DELLINK, idev);
+-
+- /* Shot the device (if unregistered) */
+-
+- if (how == 1) {
+-#ifdef CONFIG_SYSCTL
+- addrconf_sysctl_unregister(&idev->cnf);
+- neigh_sysctl_unregister(idev->nd_parms);
+-#endif
+- neigh_parms_release(&nd_tbl, idev->nd_parms);
+- neigh_ifdown(&nd_tbl, dev);
+- in6_dev_put(idev);
+- }
+- return 0;
+-}
+-
+-static void addrconf_rs_timer(unsigned long data)
+-{
+- struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data;
+-
+- if (ifp->idev->cnf.forwarding)
+- goto out;
+-
+- if (ifp->idev->if_flags & IF_RA_RCVD) {
+- /*
+- * Announcement received after solicitation
+- * was sent
+- */
+- goto out;
+- }
+-
+- spin_lock(&ifp->lock);
+- if (ifp->probes++ < ifp->idev->cnf.rtr_solicits) {
+- struct in6_addr all_routers;
+-
+- /* The wait after the last probe can be shorter */
+- addrconf_mod_timer(ifp, AC_RS,
+- (ifp->probes == ifp->idev->cnf.rtr_solicits) ?
+- ifp->idev->cnf.rtr_solicit_delay :
+- ifp->idev->cnf.rtr_solicit_interval);
+- spin_unlock(&ifp->lock);
+-
+- ipv6_addr_all_routers(&all_routers);
+-
+- ndisc_send_rs(ifp->idev->dev, &ifp->addr, &all_routers);
+- } else {
+- spin_unlock(&ifp->lock);
+- /*
+- * Note: we do not support deprecated "all on-link"
+- * assumption any longer.
+- */
+- printk(KERN_DEBUG "%s: no IPv6 routers present\n",
+- ifp->idev->dev->name);
+- }
+-
+-out:
+- in6_ifa_put(ifp);
+-}
+-
+-/*
+- * Duplicate Address Detection
+- */
+-static void addrconf_dad_kick(struct inet6_ifaddr *ifp)
+-{
+- unsigned long rand_num;
+- struct inet6_dev *idev = ifp->idev;
+-
+- if (ifp->flags & IFA_F_OPTIMISTIC)
+- rand_num = 0;
+- else
+- rand_num = net_random() % (idev->cnf.rtr_solicit_delay ? : 1);
+-
+- ifp->probes = idev->cnf.dad_transmits;
+- addrconf_mod_timer(ifp, AC_DAD, rand_num);
+-}
+-
+-static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
+-{
+- struct inet6_dev *idev = ifp->idev;
+- struct net_device *dev = idev->dev;
+-
+- addrconf_join_solict(dev, &ifp->addr);
+-
+- net_srandom(ifp->addr.s6_addr32[3]);
+-
+- read_lock_bh(&idev->lock);
+- if (ifp->dead)
+- goto out;
+- spin_lock_bh(&ifp->lock);
+-
+- if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
+- !(ifp->flags&IFA_F_TENTATIVE) ||
+- ifp->flags & IFA_F_NODAD) {
+- ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC);
+- spin_unlock_bh(&ifp->lock);
+- read_unlock_bh(&idev->lock);
+-
+- addrconf_dad_completed(ifp);
+- return;
+- }
+-
+- if (!(idev->if_flags & IF_READY)) {
+- spin_unlock_bh(&ifp->lock);
+- read_unlock_bh(&idev->lock);
+- /*
+- * If the defice is not ready:
+- * - keep it tentative if it is a permanent address.
+- * - otherwise, kill it.
+- */
+- in6_ifa_hold(ifp);
+- addrconf_dad_stop(ifp);
+- return;
+- }
+-
+- /*
+- * Optimistic nodes can start receiving
+- * Frames right away
+- */
+- if(ifp->flags & IFA_F_OPTIMISTIC)
+- ip6_ins_rt(ifp->rt);
+-
+- addrconf_dad_kick(ifp);
+- spin_unlock_bh(&ifp->lock);
+-out:
+- read_unlock_bh(&idev->lock);
+-}
+-
+-static void addrconf_dad_timer(unsigned long data)
+-{
+- struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data;
+- struct inet6_dev *idev = ifp->idev;
+- struct in6_addr unspec;
+- struct in6_addr mcaddr;
+-
+- read_lock_bh(&idev->lock);
+- if (idev->dead) {
+- read_unlock_bh(&idev->lock);
+- goto out;
+- }
+- spin_lock_bh(&ifp->lock);
+- if (ifp->probes == 0) {
+- /*
+- * DAD was successful
+- */
+-
+- ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC);
+- spin_unlock_bh(&ifp->lock);
+- read_unlock_bh(&idev->lock);
+-
+- addrconf_dad_completed(ifp);
+-
+- goto out;
+- }
+-
+- ifp->probes--;
+- addrconf_mod_timer(ifp, AC_DAD, ifp->idev->nd_parms->retrans_time);
+- spin_unlock_bh(&ifp->lock);
+- read_unlock_bh(&idev->lock);
+-
+- /* send a neighbour solicitation for our addr */
+- memset(&unspec, 0, sizeof(unspec));
+- addrconf_addr_solict_mult(&ifp->addr, &mcaddr);
+- ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &unspec);
+-out:
+- in6_ifa_put(ifp);
+-}
+-
+-static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
+-{
+- struct net_device * dev = ifp->idev->dev;
+-
+- /*
+- * Configure the address for reception. Now it is valid.
+- */
+-
+- ipv6_ifa_notify(RTM_NEWADDR, ifp);
+-
+- /* If added prefix is link local and forwarding is off,
+- start sending router solicitations.
+- */
+-
+- if (ifp->idev->cnf.forwarding == 0 &&
+- ifp->idev->cnf.rtr_solicits > 0 &&
+- (dev->flags&IFF_LOOPBACK) == 0 &&
+- (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
+- struct in6_addr all_routers;
+-
+- ipv6_addr_all_routers(&all_routers);
+-
+- /*
+- * If a host as already performed a random delay
+- * [...] as part of DAD [...] there is no need
+- * to delay again before sending the first RS
+- */
+- ndisc_send_rs(ifp->idev->dev, &ifp->addr, &all_routers);
+-
+- spin_lock_bh(&ifp->lock);
+- ifp->probes = 1;
+- ifp->idev->if_flags |= IF_RS_SENT;
+- addrconf_mod_timer(ifp, AC_RS, ifp->idev->cnf.rtr_solicit_interval);
+- spin_unlock_bh(&ifp->lock);
+- }
+-}
+-
+-static void addrconf_dad_run(struct inet6_dev *idev) {
+- struct inet6_ifaddr *ifp;
+-
+- read_lock_bh(&idev->lock);
+- for (ifp = idev->addr_list; ifp; ifp = ifp->if_next) {
+- spin_lock_bh(&ifp->lock);
+- if (!(ifp->flags & IFA_F_TENTATIVE)) {
+- spin_unlock_bh(&ifp->lock);
+- continue;
+- }
+- spin_unlock_bh(&ifp->lock);
+- addrconf_dad_kick(ifp);
+- }
+- read_unlock_bh(&idev->lock);
+-}
+-
+-#ifdef CONFIG_PROC_FS
+-struct if6_iter_state {
+- int bucket;
+-};
+-
+-static struct inet6_ifaddr *if6_get_first(struct seq_file *seq)
+-{
+- struct inet6_ifaddr *ifa = NULL;
+- struct if6_iter_state *state = seq->private;
+-
+- for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) {
+- ifa = inet6_addr_lst[state->bucket];
+- if (ifa)
+- break;
+- }
+- return ifa;
+-}
+-
+-static struct inet6_ifaddr *if6_get_next(struct seq_file *seq, struct inet6_ifaddr *ifa)
+-{
+- struct if6_iter_state *state = seq->private;
+-
+- ifa = ifa->lst_next;
+-try_again:
+- if (!ifa && ++state->bucket < IN6_ADDR_HSIZE) {
+- ifa = inet6_addr_lst[state->bucket];
+- goto try_again;
+- }
+- return ifa;
+-}
+-
+-static struct inet6_ifaddr *if6_get_idx(struct seq_file *seq, loff_t pos)
+-{
+- struct inet6_ifaddr *ifa = if6_get_first(seq);
+-
+- if (ifa)
+- while(pos && (ifa = if6_get_next(seq, ifa)) != NULL)
+- --pos;
+- return pos ? NULL : ifa;
+-}
+-
+-static void *if6_seq_start(struct seq_file *seq, loff_t *pos)
+-{
+- read_lock_bh(&addrconf_hash_lock);
+- return if6_get_idx(seq, *pos);
+-}
+-
+-static void *if6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+-{
+- struct inet6_ifaddr *ifa;
+-
+- ifa = if6_get_next(seq, v);
+- ++*pos;
+- return ifa;
+-}
+-
+-static void if6_seq_stop(struct seq_file *seq, void *v)
+-{
+- read_unlock_bh(&addrconf_hash_lock);
+-}
+-
+-static int if6_seq_show(struct seq_file *seq, void *v)
+-{
+- struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
+- seq_printf(seq,
+- NIP6_SEQFMT " %02x %02x %02x %02x %8s\n",
+- NIP6(ifp->addr),
+- ifp->idev->dev->ifindex,
+- ifp->prefix_len,
+- ifp->scope,
+- ifp->flags,
+- ifp->idev->dev->name);
+- return 0;
+-}
+-
+-static struct seq_operations if6_seq_ops = {
+- .start = if6_seq_start,
+- .next = if6_seq_next,
+- .show = if6_seq_show,
+- .stop = if6_seq_stop,
+-};
+-
+-static int if6_seq_open(struct inode *inode, struct file *file)
+-{
+- struct seq_file *seq;
+- int rc = -ENOMEM;
+- struct if6_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
+-
+- if (!s)
+- goto out;
+-
+- rc = seq_open(file, &if6_seq_ops);
+- if (rc)
+- goto out_kfree;
+-
+- seq = file->private_data;
+- seq->private = s;
+-out:
+- return rc;
+-out_kfree:
+- kfree(s);
+- goto out;
+-}
+-
+-static const struct file_operations if6_fops = {
+- .owner = THIS_MODULE,
+- .open = if6_seq_open,
+- .read = seq_read,
+- .llseek = seq_lseek,
+- .release = seq_release_private,
+-};
+-
+-int __init if6_proc_init(void)
+-{
+- if (!proc_net_fops_create("if_inet6", S_IRUGO, &if6_fops))
+- return -ENOMEM;
+- return 0;
+-}
+-
+-void if6_proc_exit(void)
+-{
+- proc_net_remove("if_inet6");
+-}
+-#endif /* CONFIG_PROC_FS */
+-
+-#ifdef CONFIG_IPV6_MIP6
+-/* Check if address is a home address configured on any interface. */
+-int ipv6_chk_home_addr(struct in6_addr *addr)
+-{
+- int ret = 0;
+- struct inet6_ifaddr * ifp;
+- u8 hash = ipv6_addr_hash(addr);
+- read_lock_bh(&addrconf_hash_lock);
+- for (ifp = inet6_addr_lst[hash]; ifp; ifp = ifp->lst_next) {
+- if (ipv6_addr_cmp(&ifp->addr, addr) == 0 &&
+- (ifp->flags & IFA_F_HOMEADDRESS)) {
+- ret = 1;
+- break;
+- }
+- }
+- read_unlock_bh(&addrconf_hash_lock);
+- return ret;
+-}
+-#endif
+-
+-/*
+- * Periodic address status verification
+- */
+-
+-static void addrconf_verify(unsigned long foo)
+-{
+- struct inet6_ifaddr *ifp;
+- unsigned long now, next;
+- int i;
+-
+- spin_lock_bh(&addrconf_verify_lock);
+- now = jiffies;
+- next = now + ADDR_CHECK_FREQUENCY;
+-
+- del_timer(&addr_chk_timer);
+-
+- for (i=0; i < IN6_ADDR_HSIZE; i++) {
+-
+-restart:
+- read_lock(&addrconf_hash_lock);
+- for (ifp=inet6_addr_lst[i]; ifp; ifp=ifp->lst_next) {
+- unsigned long age;
+-#ifdef CONFIG_IPV6_PRIVACY
+- unsigned long regen_advance;
+-#endif
+-
+- if (ifp->flags & IFA_F_PERMANENT)
+- continue;
+-
+- spin_lock(&ifp->lock);
+- age = (now - ifp->tstamp) / HZ;
+-
+-#ifdef CONFIG_IPV6_PRIVACY
+- regen_advance = ifp->idev->cnf.regen_max_retry *
+- ifp->idev->cnf.dad_transmits *
+- ifp->idev->nd_parms->retrans_time / HZ;
+-#endif
+-
+- if (ifp->valid_lft != INFINITY_LIFE_TIME &&
+- age >= ifp->valid_lft) {
+- spin_unlock(&ifp->lock);
+- in6_ifa_hold(ifp);
+- read_unlock(&addrconf_hash_lock);
+- ipv6_del_addr(ifp);
+- goto restart;
+- } else if (ifp->prefered_lft == INFINITY_LIFE_TIME) {
+- spin_unlock(&ifp->lock);
+- continue;
+- } else if (age >= ifp->prefered_lft) {
+- /* jiffies - ifp->tsamp > age >= ifp->prefered_lft */
+- int deprecate = 0;
+-
+- if (!(ifp->flags&IFA_F_DEPRECATED)) {
+- deprecate = 1;
+- ifp->flags |= IFA_F_DEPRECATED;
+- }
+-
+- if (time_before(ifp->tstamp + ifp->valid_lft * HZ, next))
+- next = ifp->tstamp + ifp->valid_lft * HZ;
+-
+- spin_unlock(&ifp->lock);
+-
+- if (deprecate) {
+- in6_ifa_hold(ifp);
+- read_unlock(&addrconf_hash_lock);
+-
+- ipv6_ifa_notify(0, ifp);
+- in6_ifa_put(ifp);
+- goto restart;
+- }
+-#ifdef CONFIG_IPV6_PRIVACY
+- } else if ((ifp->flags&IFA_F_TEMPORARY) &&
+- !(ifp->flags&IFA_F_TENTATIVE)) {
+- if (age >= ifp->prefered_lft - regen_advance) {
+- struct inet6_ifaddr *ifpub = ifp->ifpub;
+- if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next))
+- next = ifp->tstamp + ifp->prefered_lft * HZ;
+- if (!ifp->regen_count && ifpub) {
+- ifp->regen_count++;
+- in6_ifa_hold(ifp);
+- in6_ifa_hold(ifpub);
+- spin_unlock(&ifp->lock);
+- read_unlock(&addrconf_hash_lock);
+- spin_lock(&ifpub->lock);
+- ifpub->regen_count = 0;
+- spin_unlock(&ifpub->lock);
+- ipv6_create_tempaddr(ifpub, ifp);
+- in6_ifa_put(ifpub);
+- in6_ifa_put(ifp);
+- goto restart;
+- }
+- } else if (time_before(ifp->tstamp + ifp->prefered_lft * HZ - regen_advance * HZ, next))
+- next = ifp->tstamp + ifp->prefered_lft * HZ - regen_advance * HZ;
+- spin_unlock(&ifp->lock);
+-#endif
+- } else {
+- /* ifp->prefered_lft <= ifp->valid_lft */
+- if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next))
+- next = ifp->tstamp + ifp->prefered_lft * HZ;
+- spin_unlock(&ifp->lock);
+- }
+- }
+- read_unlock(&addrconf_hash_lock);
+- }
+-
+- addr_chk_timer.expires = time_before(next, jiffies + HZ) ? jiffies + HZ : next;
+- add_timer(&addr_chk_timer);
+- spin_unlock_bh(&addrconf_verify_lock);
+-}
+-
+-static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local)
+-{
+- struct in6_addr *pfx = NULL;
+-
+- if (addr)
+- pfx = nla_data(addr);
+-
+- if (local) {
+- if (pfx && nla_memcmp(local, pfx, sizeof(*pfx)))
+- pfx = NULL;
+- else
+- pfx = nla_data(local);
+- }
+-
+- return pfx;
+-}
+-
+-static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = {
+- [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) },
+- [IFA_LOCAL] = { .len = sizeof(struct in6_addr) },
+- [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) },
+-};
+-
+-static int
+-inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+-{
+- struct ifaddrmsg *ifm;
+- struct nlattr *tb[IFA_MAX+1];
+- struct in6_addr *pfx;
+- int err;
+-
+- err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
+- if (err < 0)
+- return err;
+-
+- ifm = nlmsg_data(nlh);
+- pfx = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL]);
+- if (pfx == NULL)
+- return -EINVAL;
+-
+- return inet6_addr_del(ifm->ifa_index, pfx, ifm->ifa_prefixlen);
+-}
+-
+-static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags,
+- u32 prefered_lft, u32 valid_lft)
+-{
+- u32 flags = RTF_EXPIRES;
+-
+- if (!valid_lft || (prefered_lft > valid_lft))
+- return -EINVAL;
+-
+- if (valid_lft == INFINITY_LIFE_TIME) {
+- ifa_flags |= IFA_F_PERMANENT;
+- flags = 0;
+- } else if (valid_lft >= 0x7FFFFFFF/HZ)
+- valid_lft = 0x7FFFFFFF/HZ;
+-
+- if (prefered_lft == 0)
+- ifa_flags |= IFA_F_DEPRECATED;
+- else if ((prefered_lft >= 0x7FFFFFFF/HZ) &&
+- (prefered_lft != INFINITY_LIFE_TIME))
+- prefered_lft = 0x7FFFFFFF/HZ;
+-
+- spin_lock_bh(&ifp->lock);
+- ifp->flags = (ifp->flags & ~(IFA_F_DEPRECATED | IFA_F_PERMANENT | IFA_F_NODAD | IFA_F_HOMEADDRESS)) | ifa_flags;
+- ifp->tstamp = jiffies;
+- ifp->valid_lft = valid_lft;
+- ifp->prefered_lft = prefered_lft;
+-
+- spin_unlock_bh(&ifp->lock);
+- if (!(ifp->flags&IFA_F_TENTATIVE))
+- ipv6_ifa_notify(0, ifp);
+-
+- addrconf_prefix_route(&ifp->addr, ifp->prefix_len, ifp->idev->dev,
+- jiffies_to_clock_t(valid_lft * HZ), flags);
+- addrconf_verify(0);
+-
+- return 0;
+-}
+-
+-static int
+-inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+-{
+- struct ifaddrmsg *ifm;
+- struct nlattr *tb[IFA_MAX+1];
+- struct in6_addr *pfx;
+- struct inet6_ifaddr *ifa;
+- struct net_device *dev;
+- u32 valid_lft = INFINITY_LIFE_TIME, preferred_lft = INFINITY_LIFE_TIME;
+- u8 ifa_flags;
+- int err;
+-
+- err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
+- if (err < 0)
+- return err;
+-
+- ifm = nlmsg_data(nlh);
+- pfx = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL]);
+- if (pfx == NULL)
+- return -EINVAL;
+-
+- if (tb[IFA_CACHEINFO]) {
+- struct ifa_cacheinfo *ci;
+-
+- ci = nla_data(tb[IFA_CACHEINFO]);
+- valid_lft = ci->ifa_valid;
+- preferred_lft = ci->ifa_prefered;
+- } else {
+- preferred_lft = INFINITY_LIFE_TIME;
+- valid_lft = INFINITY_LIFE_TIME;
+- }
+-
+- dev = __dev_get_by_index(ifm->ifa_index);
+- if (dev == NULL)
+- return -ENODEV;
+-
+- /* We ignore other flags so far. */
+- ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS);
+-
+- ifa = ipv6_get_ifaddr(pfx, dev, 1);
+- if (ifa == NULL) {
+- /*
+- * It would be best to check for !NLM_F_CREATE here but
+- * userspace alreay relies on not having to provide this.
+- */
+- return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen,
+- ifa_flags, preferred_lft, valid_lft);
+- }
+-
+- if (nlh->nlmsg_flags & NLM_F_EXCL ||
+- !(nlh->nlmsg_flags & NLM_F_REPLACE))
+- err = -EEXIST;
+- else
+- err = inet6_addr_modify(ifa, ifa_flags, preferred_lft, valid_lft);
+-
+- in6_ifa_put(ifa);
+-
+- return err;
+-}
+-
+-static void put_ifaddrmsg(struct nlmsghdr *nlh, u8 prefixlen, u8 flags,
+- u8 scope, int ifindex)
+-{
+- struct ifaddrmsg *ifm;
+-
+- ifm = nlmsg_data(nlh);
+- ifm->ifa_family = AF_INET6;
+- ifm->ifa_prefixlen = prefixlen;
+- ifm->ifa_flags = flags;
+- ifm->ifa_scope = scope;
+- ifm->ifa_index = ifindex;
+-}
+-
+-static int put_cacheinfo(struct sk_buff *skb, unsigned long cstamp,
+- unsigned long tstamp, u32 preferred, u32 valid)
+-{
+- struct ifa_cacheinfo ci;
+-
+- ci.cstamp = (u32)(TIME_DELTA(cstamp, INITIAL_JIFFIES) / HZ * 100
+- + TIME_DELTA(cstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
+- ci.tstamp = (u32)(TIME_DELTA(tstamp, INITIAL_JIFFIES) / HZ * 100
+- + TIME_DELTA(tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
+- ci.ifa_prefered = preferred;
+- ci.ifa_valid = valid;
+-
+- return nla_put(skb, IFA_CACHEINFO, sizeof(ci), &ci);
+-}
+-
+-static inline int rt_scope(int ifa_scope)
+-{
+- if (ifa_scope & IFA_HOST)
+- return RT_SCOPE_HOST;
+- else if (ifa_scope & IFA_LINK)
+- return RT_SCOPE_LINK;
+- else if (ifa_scope & IFA_SITE)
+- return RT_SCOPE_SITE;
+- else
+- return RT_SCOPE_UNIVERSE;
+-}
+-
+-static inline int inet6_ifaddr_msgsize(void)
+-{
+- return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
+- + nla_total_size(16) /* IFA_ADDRESS */
+- + nla_total_size(sizeof(struct ifa_cacheinfo));
+-}
+-
+-static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
+- u32 pid, u32 seq, int event, unsigned int flags)
+-{
+- struct nlmsghdr *nlh;
+- u32 preferred, valid;
+-
+- nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
+- if (nlh == NULL)
+- return -EMSGSIZE;
+-
+- put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope),
+- ifa->idev->dev->ifindex);
+-
+- if (!(ifa->flags&IFA_F_PERMANENT)) {
+- preferred = ifa->prefered_lft;
+- valid = ifa->valid_lft;
+- if (preferred != INFINITY_LIFE_TIME) {
+- long tval = (jiffies - ifa->tstamp)/HZ;
+- preferred -= tval;
+- if (valid != INFINITY_LIFE_TIME)
+- valid -= tval;
+- }
+- } else {
+- preferred = INFINITY_LIFE_TIME;
+- valid = INFINITY_LIFE_TIME;
+- }
+-
+- if (nla_put(skb, IFA_ADDRESS, 16, &ifa->addr) < 0 ||
+- put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0) {
+- nlmsg_cancel(skb, nlh);
+- return -EMSGSIZE;
+- }
+-
+- return nlmsg_end(skb, nlh);
+-}
+-
+-static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
+- u32 pid, u32 seq, int event, u16 flags)
+-{
+- struct nlmsghdr *nlh;
+- u8 scope = RT_SCOPE_UNIVERSE;
+- int ifindex = ifmca->idev->dev->ifindex;
+-
+- if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE)
+- scope = RT_SCOPE_SITE;
+-
+- nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
+- if (nlh == NULL)
+- return -EMSGSIZE;
+-
+- put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
+- if (nla_put(skb, IFA_MULTICAST, 16, &ifmca->mca_addr) < 0 ||
+- put_cacheinfo(skb, ifmca->mca_cstamp, ifmca->mca_tstamp,
+- INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
+- nlmsg_cancel(skb, nlh);
+- return -EMSGSIZE;
+- }
+-
+- return nlmsg_end(skb, nlh);
+-}
+-
+-static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
+- u32 pid, u32 seq, int event, unsigned int flags)
+-{
+- struct nlmsghdr *nlh;
+- u8 scope = RT_SCOPE_UNIVERSE;
+- int ifindex = ifaca->aca_idev->dev->ifindex;
+-
+- if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE)
+- scope = RT_SCOPE_SITE;
+-
+- nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
+- if (nlh == NULL)
+- return -EMSGSIZE;
+-
+- put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
+- if (nla_put(skb, IFA_ANYCAST, 16, &ifaca->aca_addr) < 0 ||
+- put_cacheinfo(skb, ifaca->aca_cstamp, ifaca->aca_tstamp,
+- INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
+- nlmsg_cancel(skb, nlh);
+- return -EMSGSIZE;
+- }
+-
+- return nlmsg_end(skb, nlh);
+-}
+-
+-enum addr_type_t
+-{
+- UNICAST_ADDR,
+- MULTICAST_ADDR,
+- ANYCAST_ADDR,
+-};
+-
+-static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
+- enum addr_type_t type)
+-{
+- int idx, ip_idx;
+- int s_idx, s_ip_idx;
+- int err = 1;
+- struct net_device *dev;
+- struct inet6_dev *idev = NULL;
+- struct inet6_ifaddr *ifa;
+- struct ifmcaddr6 *ifmca;
+- struct ifacaddr6 *ifaca;
+-
+- s_idx = cb->args[0];
+- s_ip_idx = ip_idx = cb->args[1];
+-
+- idx = 0;
+- for_each_netdev(dev) {
+- if (idx < s_idx)
+- goto cont;
+- if (idx > s_idx)
+- s_ip_idx = 0;
+- ip_idx = 0;
+- if ((idev = in6_dev_get(dev)) == NULL)
+- goto cont;
+- read_lock_bh(&idev->lock);
+- switch (type) {
+- case UNICAST_ADDR:
+- /* unicast address incl. temp addr */
+- for (ifa = idev->addr_list; ifa;
+- ifa = ifa->if_next, ip_idx++) {
+- if (ip_idx < s_ip_idx)
+- continue;
+- if ((err = inet6_fill_ifaddr(skb, ifa,
+- NETLINK_CB(cb->skb).pid,
+- cb->nlh->nlmsg_seq, RTM_NEWADDR,
+- NLM_F_MULTI)) <= 0)
+- goto done;
+- }
+- break;
+- case MULTICAST_ADDR:
+- /* multicast address */
+- for (ifmca = idev->mc_list; ifmca;
+- ifmca = ifmca->next, ip_idx++) {
+- if (ip_idx < s_ip_idx)
+- continue;
+- if ((err = inet6_fill_ifmcaddr(skb, ifmca,
+- NETLINK_CB(cb->skb).pid,
+- cb->nlh->nlmsg_seq, RTM_GETMULTICAST,
+- NLM_F_MULTI)) <= 0)
+- goto done;
+- }
+- break;
+- case ANYCAST_ADDR:
+- /* anycast address */
+- for (ifaca = idev->ac_list; ifaca;
+- ifaca = ifaca->aca_next, ip_idx++) {
+- if (ip_idx < s_ip_idx)
+- continue;
+- if ((err = inet6_fill_ifacaddr(skb, ifaca,
+- NETLINK_CB(cb->skb).pid,
+- cb->nlh->nlmsg_seq, RTM_GETANYCAST,
+- NLM_F_MULTI)) <= 0)
+- goto done;
+- }
+- break;
+- default:
+- break;
+- }
+- read_unlock_bh(&idev->lock);
+- in6_dev_put(idev);
+-cont:
+- idx++;
+- }
+-done:
+- if (err <= 0) {
+- read_unlock_bh(&idev->lock);
+- in6_dev_put(idev);
+- }
+- cb->args[0] = idx;
+- cb->args[1] = ip_idx;
+- return skb->len;
+-}
+-
+-static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
+-{
+- enum addr_type_t type = UNICAST_ADDR;
+- return inet6_dump_addr(skb, cb, type);
+-}
+-
+-static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb)
+-{
+- enum addr_type_t type = MULTICAST_ADDR;
+- return inet6_dump_addr(skb, cb, type);
+-}
+-
+-
+-static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb)
+-{
+- enum addr_type_t type = ANYCAST_ADDR;
+- return inet6_dump_addr(skb, cb, type);
+-}
+-
+-static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
+- void *arg)
+-{
+- struct ifaddrmsg *ifm;
+- struct nlattr *tb[IFA_MAX+1];
+- struct in6_addr *addr = NULL;
+- struct net_device *dev = NULL;
+- struct inet6_ifaddr *ifa;
+- struct sk_buff *skb;
+- int err;
+-
+- err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
+- if (err < 0)
+- goto errout;
+-
+- addr = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL]);
+- if (addr == NULL) {
+- err = -EINVAL;
+- goto errout;
+- }
+-
+- ifm = nlmsg_data(nlh);
+- if (ifm->ifa_index)
+- dev = __dev_get_by_index(ifm->ifa_index);
+-
+- if ((ifa = ipv6_get_ifaddr(addr, dev, 1)) == NULL) {
+- err = -EADDRNOTAVAIL;
+- goto errout;
+- }
+-
+- if ((skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_KERNEL)) == NULL) {
+- err = -ENOBUFS;
+- goto errout_ifa;
+- }
+-
+- err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid,
+- nlh->nlmsg_seq, RTM_NEWADDR, 0);
+- if (err < 0) {
+- /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
+- WARN_ON(err == -EMSGSIZE);
+- kfree_skb(skb);
+- goto errout_ifa;
+- }
+- err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
+-errout_ifa:
+- in6_ifa_put(ifa);
+-errout:
+- return err;
+-}
+-
+-static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
+-{
+- struct sk_buff *skb;
+- int err = -ENOBUFS;
+-
+- skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC);
+- if (skb == NULL)
+- goto errout;
+-
+- err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0);
+- if (err < 0) {
+- /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
+- WARN_ON(err == -EMSGSIZE);
+- kfree_skb(skb);
+- goto errout;
+- }
+- err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
+-errout:
+- if (err < 0)
+- rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
+-}
+-
+-static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
+- __s32 *array, int bytes)
+-{
+- BUG_ON(bytes < (DEVCONF_MAX * 4));
+-
+- memset(array, 0, bytes);
+- array[DEVCONF_FORWARDING] = cnf->forwarding;
+- array[DEVCONF_HOPLIMIT] = cnf->hop_limit;
+- array[DEVCONF_MTU6] = cnf->mtu6;
+- array[DEVCONF_ACCEPT_RA] = cnf->accept_ra;
+- array[DEVCONF_ACCEPT_REDIRECTS] = cnf->accept_redirects;
+- array[DEVCONF_AUTOCONF] = cnf->autoconf;
+- array[DEVCONF_DAD_TRANSMITS] = cnf->dad_transmits;
+- array[DEVCONF_RTR_SOLICITS] = cnf->rtr_solicits;
+- array[DEVCONF_RTR_SOLICIT_INTERVAL] = cnf->rtr_solicit_interval;
+- array[DEVCONF_RTR_SOLICIT_DELAY] = cnf->rtr_solicit_delay;
+- array[DEVCONF_FORCE_MLD_VERSION] = cnf->force_mld_version;
+-#ifdef CONFIG_IPV6_PRIVACY
+- array[DEVCONF_USE_TEMPADDR] = cnf->use_tempaddr;
+- array[DEVCONF_TEMP_VALID_LFT] = cnf->temp_valid_lft;
+- array[DEVCONF_TEMP_PREFERED_LFT] = cnf->temp_prefered_lft;
+- array[DEVCONF_REGEN_MAX_RETRY] = cnf->regen_max_retry;
+- array[DEVCONF_MAX_DESYNC_FACTOR] = cnf->max_desync_factor;
+-#endif
+- array[DEVCONF_MAX_ADDRESSES] = cnf->max_addresses;
+- array[DEVCONF_ACCEPT_RA_DEFRTR] = cnf->accept_ra_defrtr;
+- array[DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo;
+-#ifdef CONFIG_IPV6_ROUTER_PREF
+- array[DEVCONF_ACCEPT_RA_RTR_PREF] = cnf->accept_ra_rtr_pref;
+- array[DEVCONF_RTR_PROBE_INTERVAL] = cnf->rtr_probe_interval;
+-#ifdef CONFIG_IPV6_ROUTE_INFO
+- array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen;
+-#endif
+-#endif
+- array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp;
+- array[DEVCONF_ACCEPT_SOURCE_ROUTE] = cnf->accept_source_route;
+-#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
+- array[DEVCONF_OPTIMISTIC_DAD] = cnf->optimistic_dad;
+-#endif
+-}
+-
+-static inline size_t inet6_if_nlmsg_size(void)
+-{
+- return NLMSG_ALIGN(sizeof(struct ifinfomsg))
+- + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
+- + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
+- + nla_total_size(4) /* IFLA_MTU */
+- + nla_total_size(4) /* IFLA_LINK */
+- + nla_total_size( /* IFLA_PROTINFO */
+- nla_total_size(4) /* IFLA_INET6_FLAGS */
+- + nla_total_size(sizeof(struct ifla_cacheinfo))
+- + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */
+- + nla_total_size(IPSTATS_MIB_MAX * 8) /* IFLA_INET6_STATS */
+- + nla_total_size(ICMP6_MIB_MAX * 8) /* IFLA_INET6_ICMP6STATS */
+- );
+-}
+-
+-static inline void __snmp6_fill_stats(u64 *stats, void **mib, int items,
+- int bytes)
+-{
+- int i;
+- int pad = bytes - sizeof(u64) * items;
+- BUG_ON(pad < 0);
+-
+- /* Use put_unaligned() because stats may not be aligned for u64. */
+- put_unaligned(items, &stats[0]);
+- for (i = 1; i < items; i++)
+- put_unaligned(snmp_fold_field(mib, i), &stats[i]);
+-
+- memset(&stats[items], 0, pad);
+-}
+-
+-static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
+- int bytes)
+-{
+- switch(attrtype) {
+- case IFLA_INET6_STATS:
+- __snmp6_fill_stats(stats, (void **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes);
+- break;
+- case IFLA_INET6_ICMP6STATS:
+- __snmp6_fill_stats(stats, (void **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes);
+- break;
+- }
+-}
+-
+-static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
+- u32 pid, u32 seq, int event, unsigned int flags)
+-{
+- struct net_device *dev = idev->dev;
+- struct nlattr *nla;
+- struct ifinfomsg *hdr;
+- struct nlmsghdr *nlh;
+- void *protoinfo;
+- struct ifla_cacheinfo ci;
+-
+- nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags);
+- if (nlh == NULL)
+- return -EMSGSIZE;
+-
+- hdr = nlmsg_data(nlh);
+- hdr->ifi_family = AF_INET6;
+- hdr->__ifi_pad = 0;
+- hdr->ifi_type = dev->type;
+- hdr->ifi_index = dev->ifindex;
+- hdr->ifi_flags = dev_get_flags(dev);
+- hdr->ifi_change = 0;
+-
+- NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name);
+-
+- if (dev->addr_len)
+- NLA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr);
+-
+- NLA_PUT_U32(skb, IFLA_MTU, dev->mtu);
+- if (dev->ifindex != dev->iflink)
+- NLA_PUT_U32(skb, IFLA_LINK, dev->iflink);
+-
+- protoinfo = nla_nest_start(skb, IFLA_PROTINFO);
+- if (protoinfo == NULL)
+- goto nla_put_failure;
+-
+- NLA_PUT_U32(skb, IFLA_INET6_FLAGS, idev->if_flags);
+-
+- ci.max_reasm_len = IPV6_MAXPLEN;
+- ci.tstamp = (__u32)(TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) / HZ * 100
+- + TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
+- ci.reachable_time = idev->nd_parms->reachable_time;
+- ci.retrans_time = idev->nd_parms->retrans_time;
+- NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci);
+-
+- nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32));
+- if (nla == NULL)
+- goto nla_put_failure;
+- ipv6_store_devconf(&idev->cnf, nla_data(nla), nla_len(nla));
+-
+- /* XXX - MC not implemented */
+-
+- nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64));
+- if (nla == NULL)
+- goto nla_put_failure;
+- snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla));
+-
+- nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS, ICMP6_MIB_MAX * sizeof(u64));
+- if (nla == NULL)
+- goto nla_put_failure;
+- snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla));
+-
+- nla_nest_end(skb, protoinfo);
+- return nlmsg_end(skb, nlh);
+-
+-nla_put_failure:
+- nlmsg_cancel(skb, nlh);
+- return -EMSGSIZE;
+-}
+-
+-static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
+-{
+- int idx, err;
+- int s_idx = cb->args[0];
+- struct net_device *dev;
+- struct inet6_dev *idev;
+-
+- read_lock(&dev_base_lock);
+- idx = 0;
+- for_each_netdev(dev) {
+- if (idx < s_idx)
+- goto cont;
+- if ((idev = in6_dev_get(dev)) == NULL)
+- goto cont;
+- err = inet6_fill_ifinfo(skb, idev, NETLINK_CB(cb->skb).pid,
+- cb->nlh->nlmsg_seq, RTM_NEWLINK, NLM_F_MULTI);
+- in6_dev_put(idev);
+- if (err <= 0)
+- break;
+-cont:
+- idx++;
+- }
+- read_unlock(&dev_base_lock);
+- cb->args[0] = idx;
+-
+- return skb->len;
+-}
+-
+-void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
+-{
+- struct sk_buff *skb;
+- int err = -ENOBUFS;
+-
+- skb = nlmsg_new(inet6_if_nlmsg_size(), GFP_ATOMIC);
+- if (skb == NULL)
+- goto errout;
+-
+- err = inet6_fill_ifinfo(skb, idev, 0, 0, event, 0);
+- if (err < 0) {
+- /* -EMSGSIZE implies BUG in inet6_if_nlmsg_size() */
+- WARN_ON(err == -EMSGSIZE);
+- kfree_skb(skb);
+- goto errout;
+- }
+- err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
+-errout:
+- if (err < 0)
+- rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
+-}
+-
+-static inline size_t inet6_prefix_nlmsg_size(void)
+-{
+- return NLMSG_ALIGN(sizeof(struct prefixmsg))
+- + nla_total_size(sizeof(struct in6_addr))
+- + nla_total_size(sizeof(struct prefix_cacheinfo));
+-}
+-
+-static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
+- struct prefix_info *pinfo, u32 pid, u32 seq,
+- int event, unsigned int flags)
+-{
+- struct prefixmsg *pmsg;
+- struct nlmsghdr *nlh;
+- struct prefix_cacheinfo ci;
+-
+- nlh = nlmsg_put(skb, pid, seq, event, sizeof(*pmsg), flags);
+- if (nlh == NULL)
+- return -EMSGSIZE;
+-
+- pmsg = nlmsg_data(nlh);
+- pmsg->prefix_family = AF_INET6;
+- pmsg->prefix_pad1 = 0;
+- pmsg->prefix_pad2 = 0;
+- pmsg->prefix_ifindex = idev->dev->ifindex;
+- pmsg->prefix_len = pinfo->prefix_len;
+- pmsg->prefix_type = pinfo->type;
+- pmsg->prefix_pad3 = 0;
+- pmsg->prefix_flags = 0;
+- if (pinfo->onlink)
+- pmsg->prefix_flags |= IF_PREFIX_ONLINK;
+- if (pinfo->autoconf)
+- pmsg->prefix_flags |= IF_PREFIX_AUTOCONF;
+-
+- NLA_PUT(skb, PREFIX_ADDRESS, sizeof(pinfo->prefix), &pinfo->prefix);
+-
+- ci.preferred_time = ntohl(pinfo->prefered);
+- ci.valid_time = ntohl(pinfo->valid);
+- NLA_PUT(skb, PREFIX_CACHEINFO, sizeof(ci), &ci);
+-
+- return nlmsg_end(skb, nlh);
+-
+-nla_put_failure:
+- nlmsg_cancel(skb, nlh);
+- return -EMSGSIZE;
+-}
+-
+-static void inet6_prefix_notify(int event, struct inet6_dev *idev,
+- struct prefix_info *pinfo)
+-{
+- struct sk_buff *skb;
+- int err = -ENOBUFS;
+-
+- skb = nlmsg_new(inet6_prefix_nlmsg_size(), GFP_ATOMIC);
+- if (skb == NULL)
+- goto errout;
+-
+- err = inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0);
+- if (err < 0) {
+- /* -EMSGSIZE implies BUG in inet6_prefix_nlmsg_size() */
+- WARN_ON(err == -EMSGSIZE);
+- kfree_skb(skb);
+- goto errout;
+- }
+- err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
+-errout:
+- if (err < 0)
+- rtnl_set_sk_err(RTNLGRP_IPV6_PREFIX, err);
+-}
+-
+-static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
+-{
+- inet6_ifa_notify(event ? : RTM_NEWADDR, ifp);
+-
+- switch (event) {
+- case RTM_NEWADDR:
+- /*
+- * If the address was optimistic
+- * we inserted the route at the start of
+- * our DAD process, so we don't need
+- * to do it again
+- */
+- if (!(ifp->rt->rt6i_node))
+- ip6_ins_rt(ifp->rt);
+- if (ifp->idev->cnf.forwarding)
+- addrconf_join_anycast(ifp);
+- break;
+- case RTM_DELADDR:
+- if (ifp->idev->cnf.forwarding)
+- addrconf_leave_anycast(ifp);
+- addrconf_leave_solict(ifp->idev, &ifp->addr);
+- dst_hold(&ifp->rt->u.dst);
+- if (ip6_del_rt(ifp->rt))
+- dst_free(&ifp->rt->u.dst);
+- break;
+- }
+-}
+-
+-static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
+-{
+- rcu_read_lock_bh();
+- if (likely(ifp->idev->dead == 0))
+- __ipv6_ifa_notify(event, ifp);
+- rcu_read_unlock_bh();
+-}
+-
+-#ifdef CONFIG_SYSCTL
+-
+-static
+-int addrconf_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
+- void __user *buffer, size_t *lenp, loff_t *ppos)
+-{
+- int *valp = ctl->data;
+- int val = *valp;
+- int ret;
+-
+- ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
+-
+- if (write && valp != &ipv6_devconf_dflt.forwarding) {
+- if (valp != &ipv6_devconf.forwarding) {
+- if ((!*valp) ^ (!val)) {
+- struct inet6_dev *idev = (struct inet6_dev *)ctl->extra1;
+- if (idev == NULL)
+- return ret;
+- dev_forward_change(idev);
+- }
+- } else {
+- ipv6_devconf_dflt.forwarding = ipv6_devconf.forwarding;
+- addrconf_forward_change();
+- }
+- if (*valp)
+- rt6_purge_dflt_routers();
+- }
+-
+- return ret;
+-}
+-
+-static int addrconf_sysctl_forward_strategy(ctl_table *table,
+- int __user *name, int nlen,
+- void __user *oldval,
+- size_t __user *oldlenp,
+- void __user *newval, size_t newlen)
+-{
+- int *valp = table->data;
+- int new;
+-
+- if (!newval || !newlen)
+- return 0;
+- if (newlen != sizeof(int))
+- return -EINVAL;
+- if (get_user(new, (int __user *)newval))
+- return -EFAULT;
+- if (new == *valp)
+- return 0;
+- if (oldval && oldlenp) {
+- size_t len;
+- if (get_user(len, oldlenp))
+- return -EFAULT;
+- if (len) {
+- if (len > table->maxlen)
+- len = table->maxlen;
+- if (copy_to_user(oldval, valp, len))
+- return -EFAULT;
+- if (put_user(len, oldlenp))
+- return -EFAULT;
+- }
+- }
+-
+- if (valp != &ipv6_devconf_dflt.forwarding) {
+- if (valp != &ipv6_devconf.forwarding) {
+- struct inet6_dev *idev = (struct inet6_dev *)table->extra1;
+- int changed;
+- if (unlikely(idev == NULL))
+- return -ENODEV;
+- changed = (!*valp) ^ (!new);
+- *valp = new;
+- if (changed)
+- dev_forward_change(idev);
+- } else {
+- *valp = new;
+- addrconf_forward_change();
+- }
+-
+- if (*valp)
+- rt6_purge_dflt_routers();
+- } else
+- *valp = new;
+-
+- return 1;
+-}
+-
+-static struct addrconf_sysctl_table
+-{
+- struct ctl_table_header *sysctl_header;
+- ctl_table addrconf_vars[__NET_IPV6_MAX];
+- ctl_table addrconf_dev[2];
+- ctl_table addrconf_conf_dir[2];
+- ctl_table addrconf_proto_dir[2];
+- ctl_table addrconf_root_dir[2];
+-} addrconf_sysctl __read_mostly = {
+- .sysctl_header = NULL,
+- .addrconf_vars = {
+- {
+- .ctl_name = NET_IPV6_FORWARDING,
+- .procname = "forwarding",
+- .data = &ipv6_devconf.forwarding,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &addrconf_sysctl_forward,
+- .strategy = &addrconf_sysctl_forward_strategy,
+- },
+- {
+- .ctl_name = NET_IPV6_HOP_LIMIT,
+- .procname = "hop_limit",
+- .data = &ipv6_devconf.hop_limit,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = proc_dointvec,
+- },
+- {
+- .ctl_name = NET_IPV6_MTU,
+- .procname = "mtu",
+- .data = &ipv6_devconf.mtu6,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+- },
+- {
+- .ctl_name = NET_IPV6_ACCEPT_RA,
+- .procname = "accept_ra",
+- .data = &ipv6_devconf.accept_ra,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+- },
+- {
+- .ctl_name = NET_IPV6_ACCEPT_REDIRECTS,
+- .procname = "accept_redirects",
+- .data = &ipv6_devconf.accept_redirects,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+- },
+- {
+- .ctl_name = NET_IPV6_AUTOCONF,
+- .procname = "autoconf",
+- .data = &ipv6_devconf.autoconf,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+- },
+- {
+- .ctl_name = NET_IPV6_DAD_TRANSMITS,
+- .procname = "dad_transmits",
+- .data = &ipv6_devconf.dad_transmits,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+- },
+- {
+- .ctl_name = NET_IPV6_RTR_SOLICITS,
+- .procname = "router_solicitations",
+- .data = &ipv6_devconf.rtr_solicits,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+- },
+- {
+- .ctl_name = NET_IPV6_RTR_SOLICIT_INTERVAL,
+- .procname = "router_solicitation_interval",
+- .data = &ipv6_devconf.rtr_solicit_interval,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec_jiffies,
+- .strategy = &sysctl_jiffies,
+- },
+- {
+- .ctl_name = NET_IPV6_RTR_SOLICIT_DELAY,
+- .procname = "router_solicitation_delay",
+- .data = &ipv6_devconf.rtr_solicit_delay,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec_jiffies,
+- .strategy = &sysctl_jiffies,
+- },
+- {
+- .ctl_name = NET_IPV6_FORCE_MLD_VERSION,
+- .procname = "force_mld_version",
+- .data = &ipv6_devconf.force_mld_version,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+- },
+-#ifdef CONFIG_IPV6_PRIVACY
+- {
+- .ctl_name = NET_IPV6_USE_TEMPADDR,
+- .procname = "use_tempaddr",
+- .data = &ipv6_devconf.use_tempaddr,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+- },
+- {
+- .ctl_name = NET_IPV6_TEMP_VALID_LFT,
+- .procname = "temp_valid_lft",
+- .data = &ipv6_devconf.temp_valid_lft,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+- },
+- {
+- .ctl_name = NET_IPV6_TEMP_PREFERED_LFT,
+- .procname = "temp_prefered_lft",
+- .data = &ipv6_devconf.temp_prefered_lft,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+- },
+- {
+- .ctl_name = NET_IPV6_REGEN_MAX_RETRY,
+- .procname = "regen_max_retry",
+- .data = &ipv6_devconf.regen_max_retry,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+- },
+- {
+- .ctl_name = NET_IPV6_MAX_DESYNC_FACTOR,
+- .procname = "max_desync_factor",
+- .data = &ipv6_devconf.max_desync_factor,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+- },
+-#endif
+- {
+- .ctl_name = NET_IPV6_MAX_ADDRESSES,
+- .procname = "max_addresses",
+- .data = &ipv6_devconf.max_addresses,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+- },
+- {
+- .ctl_name = NET_IPV6_ACCEPT_RA_DEFRTR,
+- .procname = "accept_ra_defrtr",
+- .data = &ipv6_devconf.accept_ra_defrtr,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+- },
+- {
+- .ctl_name = NET_IPV6_ACCEPT_RA_PINFO,
+- .procname = "accept_ra_pinfo",
+- .data = &ipv6_devconf.accept_ra_pinfo,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+- },
+-#ifdef CONFIG_IPV6_ROUTER_PREF
+- {
+- .ctl_name = NET_IPV6_ACCEPT_RA_RTR_PREF,
+- .procname = "accept_ra_rtr_pref",
+- .data = &ipv6_devconf.accept_ra_rtr_pref,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+- },
+- {
+- .ctl_name = NET_IPV6_RTR_PROBE_INTERVAL,
+- .procname = "router_probe_interval",
+- .data = &ipv6_devconf.rtr_probe_interval,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec_jiffies,
+- .strategy = &sysctl_jiffies,
+- },
+-#ifdef CONFIG_IPV6_ROUTE_INFO
+- {
+- .ctl_name = NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN,
+- .procname = "accept_ra_rt_info_max_plen",
+- .data = &ipv6_devconf.accept_ra_rt_info_max_plen,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+- },
+-#endif
+-#endif
+- {
+- .ctl_name = NET_IPV6_PROXY_NDP,
+- .procname = "proxy_ndp",
+- .data = &ipv6_devconf.proxy_ndp,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+- },
+- {
+- .ctl_name = NET_IPV6_ACCEPT_SOURCE_ROUTE,
+- .procname = "accept_source_route",
+- .data = &ipv6_devconf.accept_source_route,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+- },
+-#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
+- {
+- .ctl_name = CTL_UNNUMBERED,
+- .procname = "optimistic_dad",
+- .data = &ipv6_devconf.optimistic_dad,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = &proc_dointvec,
+-
+- },
+-#endif
+- {
+- .ctl_name = 0, /* sentinel */
+- }
+- },
+- .addrconf_dev = {
+- {
+- .ctl_name = NET_PROTO_CONF_ALL,
+- .procname = "all",
+- .mode = 0555,
+- .child = addrconf_sysctl.addrconf_vars,
+- },
+- {
+- .ctl_name = 0, /* sentinel */
+- }
+- },
+- .addrconf_conf_dir = {
+- {
+- .ctl_name = NET_IPV6_CONF,
+- .procname = "conf",
+- .mode = 0555,
+- .child = addrconf_sysctl.addrconf_dev,
+- },
+- {
+- .ctl_name = 0, /* sentinel */
+- }
+- },
+- .addrconf_proto_dir = {
+- {
+- .ctl_name = NET_IPV6,
+- .procname = "ipv6",
+- .mode = 0555,
+- .child = addrconf_sysctl.addrconf_conf_dir,
+- },
+- {
+- .ctl_name = 0, /* sentinel */
+- }
+- },
+- .addrconf_root_dir = {
+- {
+- .ctl_name = CTL_NET,
+- .procname = "net",
+- .mode = 0555,
+- .child = addrconf_sysctl.addrconf_proto_dir,
+- },
+- {
+- .ctl_name = 0, /* sentinel */
+- }
+- },
+-};
+-
+-static void addrconf_sysctl_register(struct inet6_dev *idev, struct ipv6_devconf *p)
+-{
+- int i;
+- struct net_device *dev = idev ? idev->dev : NULL;
+- struct addrconf_sysctl_table *t;
+- char *dev_name = NULL;
+-
+- t = kmemdup(&addrconf_sysctl, sizeof(*t), GFP_KERNEL);
+- if (t == NULL)
+- return;
+- for (i=0; t->addrconf_vars[i].data; i++) {
+- t->addrconf_vars[i].data += (char*)p - (char*)&ipv6_devconf;
+- t->addrconf_vars[i].extra1 = idev; /* embedded; no ref */
+- }
+- if (dev) {
+- dev_name = dev->name;
+- t->addrconf_dev[0].ctl_name = dev->ifindex;
+- } else {
+- dev_name = "default";
+- t->addrconf_dev[0].ctl_name = NET_PROTO_CONF_DEFAULT;
+- }
+-
+- /*
+- * Make a copy of dev_name, because '.procname' is regarded as const
+- * by sysctl and we wouldn't want anyone to change it under our feet
+- * (see SIOCSIFNAME).
+- */
+- dev_name = kstrdup(dev_name, GFP_KERNEL);
+- if (!dev_name)
+- goto free;
+-
+- t->addrconf_dev[0].procname = dev_name;
+-
+- t->addrconf_dev[0].child = t->addrconf_vars;
+- t->addrconf_conf_dir[0].child = t->addrconf_dev;
+- t->addrconf_proto_dir[0].child = t->addrconf_conf_dir;
+- t->addrconf_root_dir[0].child = t->addrconf_proto_dir;
+-
+- t->sysctl_header = register_sysctl_table(t->addrconf_root_dir);
+- if (t->sysctl_header == NULL)
+- goto free_procname;
+- else
+- p->sysctl = t;
+- return;
+-
+- /* error path */
+- free_procname:
+- kfree(dev_name);
+- free:
+- kfree(t);
+-
+- return;
+-}
+-
+-static void addrconf_sysctl_unregister(struct ipv6_devconf *p)
+-{
+- if (p->sysctl) {
+- struct addrconf_sysctl_table *t = p->sysctl;
+- p->sysctl = NULL;
+- unregister_sysctl_table(t->sysctl_header);
+- kfree(t->addrconf_dev[0].procname);
+- kfree(t);
+- }
+-}
+-
+-
+-#endif
+-
+-/*
+- * Device notifier
+- */
+-
+-int register_inet6addr_notifier(struct notifier_block *nb)
+-{
+- return atomic_notifier_chain_register(&inet6addr_chain, nb);
+-}
+-
+-EXPORT_SYMBOL(register_inet6addr_notifier);
+-
+-int unregister_inet6addr_notifier(struct notifier_block *nb)
+-{
+- return atomic_notifier_chain_unregister(&inet6addr_chain,nb);
+-}
+-
+-EXPORT_SYMBOL(unregister_inet6addr_notifier);
+-
+-/*
+- * Init / cleanup code
+- */
+-
+-int __init addrconf_init(void)
+-{
+- int err = 0;
+-
+- /* The addrconf netdev notifier requires that loopback_dev
+- * has it's ipv6 private information allocated and setup
+- * before it can bring up and give link-local addresses
+- * to other devices which are up.
+- *
+- * Unfortunately, loopback_dev is not necessarily the first
+- * entry in the global dev_base list of net devices. In fact,
+- * it is likely to be the very last entry on that list.
+- * So this causes the notifier registry below to try and
+- * give link-local addresses to all devices besides loopback_dev
+- * first, then loopback_dev, which cases all the non-loopback_dev
+- * devices to fail to get a link-local address.
+- *
+- * So, as a temporary fix, allocate the ipv6 structure for
+- * loopback_dev first by hand.
+- * Longer term, all of the dependencies ipv6 has upon the loopback
+- * device and it being up should be removed.
+- */
+- rtnl_lock();
+- if (!ipv6_add_dev(&loopback_dev))
+- err = -ENOMEM;
+- rtnl_unlock();
+- if (err)
+- return err;
+-
+- ip6_null_entry.rt6i_idev = in6_dev_get(&loopback_dev);
+-#ifdef CONFIG_IPV6_MULTIPLE_TABLES
+- ip6_prohibit_entry.rt6i_idev = in6_dev_get(&loopback_dev);
+- ip6_blk_hole_entry.rt6i_idev = in6_dev_get(&loopback_dev);
+-#endif
+-
+- register_netdevice_notifier(&ipv6_dev_notf);
+-
+- addrconf_verify(0);
+-
+- err = __rtnl_register(PF_INET6, RTM_GETLINK, NULL, inet6_dump_ifinfo);
+- if (err < 0)
+- goto errout;
+-
+- /* Only the first call to __rtnl_register can fail */
+- __rtnl_register(PF_INET6, RTM_NEWADDR, inet6_rtm_newaddr, NULL);
+- __rtnl_register(PF_INET6, RTM_DELADDR, inet6_rtm_deladdr, NULL);
+- __rtnl_register(PF_INET6, RTM_GETADDR, inet6_rtm_getaddr, inet6_dump_ifaddr);
+- __rtnl_register(PF_INET6, RTM_GETMULTICAST, NULL, inet6_dump_ifmcaddr);
+- __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, inet6_dump_ifacaddr);
+-
+-#ifdef CONFIG_SYSCTL
+- addrconf_sysctl.sysctl_header =
+- register_sysctl_table(addrconf_sysctl.addrconf_root_dir);
+- addrconf_sysctl_register(NULL, &ipv6_devconf_dflt);
+-#endif
+-
+- return 0;
+-errout:
+- unregister_netdevice_notifier(&ipv6_dev_notf);
+-
+- return err;
+-}
+-
+-void __exit addrconf_cleanup(void)
+-{
+- struct net_device *dev;
+- struct inet6_dev *idev;
+- struct inet6_ifaddr *ifa;
+- int i;
+-
+- unregister_netdevice_notifier(&ipv6_dev_notf);
+-
+-#ifdef CONFIG_SYSCTL
+- addrconf_sysctl_unregister(&ipv6_devconf_dflt);
+- addrconf_sysctl_unregister(&ipv6_devconf);
+-#endif
+-
+- rtnl_lock();
+-
+- /*
+- * clean dev list.
+- */
+-
+- for_each_netdev(dev) {
+- if ((idev = __in6_dev_get(dev)) == NULL)
+- continue;
+- addrconf_ifdown(dev, 1);
+- }
+- addrconf_ifdown(&loopback_dev, 2);
+-
+- /*
+- * Check hash table.
+- */
+-
+- write_lock_bh(&addrconf_hash_lock);
+- for (i=0; i < IN6_ADDR_HSIZE; i++) {
+- for (ifa=inet6_addr_lst[i]; ifa; ) {
+- struct inet6_ifaddr *bifa;
+-
+- bifa = ifa;
+- ifa = ifa->lst_next;
+- printk(KERN_DEBUG "bug: IPv6 address leakage detected: ifa=%p\n", bifa);
+- /* Do not free it; something is wrong.
+- Now we can investigate it with debugger.
+- */
+- }
+- }
+- write_unlock_bh(&addrconf_hash_lock);
+-
+- del_timer(&addr_chk_timer);
+-
+- rtnl_unlock();
+-
+-#ifdef CONFIG_PROC_FS
+- proc_net_remove("if_inet6");
+-#endif
+-}
+diff -Nurb linux-2.6.22-570/net/ipv6/af_inet6.c linux-2.6.22-590/net/ipv6/af_inet6.c
+--- linux-2.6.22-570/net/ipv6/af_inet6.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/ipv6/af_inet6.c 2008-01-29 22:12:32.000000000 -0500
+@@ -59,9 +59,6 @@
+ #ifdef CONFIG_IPV6_TUNNEL
+ #include <net/ip6_tunnel.h>
+ #endif
+-#ifdef CONFIG_IPV6_MIP6
+-#include <net/mip6.h>
+-#endif
+
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
+@@ -85,7 +82,7 @@
+ return (struct ipv6_pinfo *)(((u8 *)sk) + offset);
+ }
+
+-static int inet6_create(struct socket *sock, int protocol)
++static int inet6_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct inet_sock *inet;
+ struct ipv6_pinfo *np;
+@@ -98,6 +95,9 @@
+ int try_loading_module = 0;
+ int err;
+
++ if (net != &init_net)
++ return -EAFNOSUPPORT;
++
+ if (sock->type != SOCK_RAW &&
+ sock->type != SOCK_DGRAM &&
+ !inet_ehash_secret)
+@@ -166,7 +166,7 @@
+ BUG_TRAP(answer_prot->slab != NULL);
+
+ err = -ENOBUFS;
+- sk = sk_alloc(PF_INET6, GFP_KERNEL, answer_prot, 1);
++ sk = sk_alloc(net, PF_INET6, GFP_KERNEL, answer_prot, 1);
+ if (sk == NULL)
+ goto out;
+
+@@ -209,7 +209,7 @@
+ inet->mc_index = 0;
+ inet->mc_list = NULL;
+
+- if (ipv4_config.no_pmtu_disc)
++ if (init_net.sysctl_ipv4_no_pmtu_disc)
+ inet->pmtudisc = IP_PMTUDISC_DONT;
+ else
+ inet->pmtudisc = IP_PMTUDISC_WANT;
+@@ -290,7 +290,7 @@
+ /* Check if the address belongs to the host. */
+ if (addr_type == IPV6_ADDR_MAPPED) {
+ v4addr = addr->sin6_addr.s6_addr32[3];
+- if (inet_addr_type(v4addr) != RTN_LOCAL) {
++ if (inet_addr_type(&init_net, v4addr) != RTN_LOCAL) {
+ err = -EADDRNOTAVAIL;
+ goto out;
+ }
+@@ -316,7 +316,7 @@
+ err = -EINVAL;
+ goto out;
+ }
+- dev = dev_get_by_index(sk->sk_bound_dev_if);
++ dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if);
+ if (!dev) {
+ err = -ENODEV;
+ goto out;
+@@ -675,6 +675,7 @@
+ struct flowi fl;
+
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ fl.proto = sk->sk_protocol;
+ ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+ ipv6_addr_copy(&fl.fl6_src, &np->saddr);
+@@ -876,9 +877,6 @@
+ ipv6_frag_init();
+ ipv6_nodata_init();
+ ipv6_destopt_init();
+-#ifdef CONFIG_IPV6_MIP6
+- mip6_init();
+-#endif
+
+ /* Init v6 transport protocols. */
+ udpv6_init();
+@@ -944,9 +942,7 @@
+
+ /* Cleanup code parts. */
+ ipv6_packet_cleanup();
+-#ifdef CONFIG_IPV6_MIP6
+- mip6_fini();
+-#endif
++
+ addrconf_cleanup();
+ ip6_flowlabel_cleanup();
+ ip6_route_cleanup();
+diff -Nurb linux-2.6.22-570/net/ipv6/ah6.c linux-2.6.22-590/net/ipv6/ah6.c
+--- linux-2.6.22-570/net/ipv6/ah6.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/ah6.c 2008-01-29 22:12:32.000000000 -0500
+@@ -74,7 +74,7 @@
+ return 0;
+ }
+
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ /**
+ * ipv6_rearrange_destopt - rearrange IPv6 destination options header
+ * @iph: IPv6 header
+@@ -132,6 +132,8 @@
+ bad:
+ return;
+ }
++#else
++static void ipv6_rearrange_destopt(struct ipv6hdr *iph, struct ipv6_opt_hdr *destopt) {}
+ #endif
+
+ /**
+@@ -189,10 +191,8 @@
+ while (exthdr.raw < end) {
+ switch (nexthdr) {
+ case NEXTHDR_DEST:
+-#ifdef CONFIG_IPV6_MIP6
+ if (dir == XFRM_POLICY_OUT)
+ ipv6_rearrange_destopt(iph, exthdr.opth);
+-#endif
+ case NEXTHDR_HOP:
+ if (!zero_out_mutable_opts(exthdr.opth)) {
+ LIMIT_NETDEBUG(
+@@ -228,7 +228,7 @@
+ u8 nexthdr;
+ char tmp_base[8];
+ struct {
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ struct in6_addr saddr;
+ #endif
+ struct in6_addr daddr;
+@@ -255,7 +255,7 @@
+ err = -ENOMEM;
+ goto error;
+ }
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ memcpy(tmp_ext, &top_iph->saddr, extlen);
+ #else
+ memcpy(tmp_ext, &top_iph->daddr, extlen);
+@@ -294,7 +294,7 @@
+
+ memcpy(top_iph, tmp_base, sizeof(tmp_base));
+ if (tmp_ext) {
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ memcpy(&top_iph->saddr, tmp_ext, extlen);
+ #else
+ memcpy(&top_iph->daddr, tmp_ext, extlen);
+@@ -554,3 +554,4 @@
+ module_exit(ah6_fini);
+
+ MODULE_LICENSE("GPL");
++MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_AH);
+diff -Nurb linux-2.6.22-570/net/ipv6/anycast.c linux-2.6.22-590/net/ipv6/anycast.c
+--- linux-2.6.22-570/net/ipv6/anycast.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/ipv6/anycast.c 2008-01-29 22:12:32.000000000 -0500
+@@ -32,6 +32,7 @@
+
+ #include <net/sock.h>
+ #include <net/snmp.h>
++#include <net/net_namespace.h>
+
+ #include <net/ipv6.h>
+ #include <net/protocol.h>
+@@ -112,10 +113,10 @@
+ } else {
+ /* router, no matching interface: just pick one */
+
+- dev = dev_get_by_flags(IFF_UP, IFF_UP|IFF_LOOPBACK);
++ dev = dev_get_by_flags(&init_net, IFF_UP, IFF_UP|IFF_LOOPBACK);
+ }
+ } else
+- dev = dev_get_by_index(ifindex);
++ dev = dev_get_by_index(&init_net, ifindex);
+
+ if (dev == NULL) {
+ err = -ENODEV;
+@@ -196,7 +197,7 @@
+
+ write_unlock_bh(&ipv6_sk_ac_lock);
+
+- dev = dev_get_by_index(pac->acl_ifindex);
++ dev = dev_get_by_index(&init_net, pac->acl_ifindex);
+ if (dev) {
+ ipv6_dev_ac_dec(dev, &pac->acl_addr);
+ dev_put(dev);
+@@ -224,7 +225,7 @@
+ if (pac->acl_ifindex != prev_index) {
+ if (dev)
+ dev_put(dev);
+- dev = dev_get_by_index(pac->acl_ifindex);
++ dev = dev_get_by_index(&init_net, pac->acl_ifindex);
+ prev_index = pac->acl_ifindex;
+ }
+ if (dev)
+@@ -429,7 +430,7 @@
+ if (dev)
+ return ipv6_chk_acast_dev(dev, addr);
+ read_lock(&dev_base_lock);
+- for_each_netdev(dev)
++ for_each_netdev(&init_net, dev)
+ if (ipv6_chk_acast_dev(dev, addr)) {
+ found = 1;
+ break;
+@@ -453,7 +454,7 @@
+ struct ac6_iter_state *state = ac6_seq_private(seq);
+
+ state->idev = NULL;
+- for_each_netdev(state->dev) {
++ for_each_netdev(&init_net, state->dev) {
+ struct inet6_dev *idev;
+ idev = in6_dev_get(state->dev);
+ if (!idev)
+@@ -579,7 +580,7 @@
+
+ int __init ac6_proc_init(void)
+ {
+- if (!proc_net_fops_create("anycast6", S_IRUGO, &ac6_seq_fops))
++ if (!proc_net_fops_create(&init_net, "anycast6", S_IRUGO, &ac6_seq_fops))
+ return -ENOMEM;
+
+ return 0;
+@@ -587,7 +588,7 @@
+
+ void ac6_proc_exit(void)
+ {
+- proc_net_remove("anycast6");
++ proc_net_remove(&init_net, "anycast6");
+ }
+ #endif
+
+diff -Nurb linux-2.6.22-570/net/ipv6/datagram.c linux-2.6.22-590/net/ipv6/datagram.c
+--- linux-2.6.22-570/net/ipv6/datagram.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/datagram.c 2008-01-29 22:12:32.000000000 -0500
+@@ -60,6 +60,7 @@
+ return -EAFNOSUPPORT;
+
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ if (np->sndflow) {
+ fl.fl6_flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK;
+ if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
+@@ -544,7 +545,7 @@
+ if (!src_info->ipi6_ifindex)
+ return -EINVAL;
+ else {
+- dev = dev_get_by_index(src_info->ipi6_ifindex);
++ dev = dev_get_by_index(&init_net, src_info->ipi6_ifindex);
+ if (!dev)
+ return -ENODEV;
+ }
+@@ -658,7 +659,7 @@
+
+ switch (rthdr->type) {
+ case IPV6_SRCRT_TYPE_0:
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ case IPV6_SRCRT_TYPE_2:
+ #endif
+ break;
+diff -Nurb linux-2.6.22-570/net/ipv6/esp6.c linux-2.6.22-590/net/ipv6/esp6.c
+--- linux-2.6.22-570/net/ipv6/esp6.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/esp6.c 2008-01-29 22:12:32.000000000 -0500
+@@ -421,3 +421,4 @@
+ module_exit(esp6_fini);
+
+ MODULE_LICENSE("GPL");
++MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_ESP);
+diff -Nurb linux-2.6.22-570/net/ipv6/exthdrs.c linux-2.6.22-590/net/ipv6/exthdrs.c
+--- linux-2.6.22-570/net/ipv6/exthdrs.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/exthdrs.c 2008-01-29 22:12:32.000000000 -0500
+@@ -42,7 +42,7 @@
+ #include <net/ndisc.h>
+ #include <net/ip6_route.h>
+ #include <net/addrconf.h>
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ #include <net/xfrm.h>
+ #endif
+
+@@ -90,6 +90,7 @@
+ bad:
+ return -1;
+ }
++EXPORT_SYMBOL_GPL(ipv6_find_tlv);
+
+ /*
+ * Parsing tlv encoded headers.
+@@ -196,7 +197,7 @@
+ Destination options header.
+ *****************************/
+
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
+ {
+ struct sk_buff *skb = *skbp;
+@@ -270,7 +271,7 @@
+ #endif
+
+ static struct tlvtype_proc tlvprocdestopt_lst[] = {
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ {
+ .type = IPV6_TLV_HAO,
+ .func = ipv6_dest_hao,
+@@ -283,7 +284,7 @@
+ {
+ struct sk_buff *skb = *skbp;
+ struct inet6_skb_parm *opt = IP6CB(skb);
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ __u16 dstbuf;
+ #endif
+ struct dst_entry *dst;
+@@ -298,7 +299,7 @@
+ }
+
+ opt->lastopt = opt->dst1 = skb_network_header_len(skb);
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ dstbuf = opt->dst1;
+ #endif
+
+@@ -308,7 +309,7 @@
+ skb = *skbp;
+ skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3;
+ opt = IP6CB(skb);
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ opt->nhoff = dstbuf;
+ #else
+ opt->nhoff = opt->dst1;
+@@ -427,7 +428,7 @@
+ looped_back:
+ if (hdr->segments_left == 0) {
+ switch (hdr->type) {
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ case IPV6_SRCRT_TYPE_2:
+ /* Silently discard type 2 header unless it was
+ * processed by own
+@@ -463,7 +464,7 @@
+ return -1;
+ }
+ break;
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ case IPV6_SRCRT_TYPE_2:
+ /* Silently discard invalid RTH type 2 */
+ if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
+@@ -520,7 +521,7 @@
+ addr += i - 1;
+
+ switch (hdr->type) {
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ case IPV6_SRCRT_TYPE_2:
+ if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
+ (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
+diff -Nurb linux-2.6.22-570/net/ipv6/fib6_rules.c linux-2.6.22-590/net/ipv6/fib6_rules.c
+--- linux-2.6.22-570/net/ipv6/fib6_rules.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/ipv6/fib6_rules.c 2008-01-29 22:12:32.000000000 -0500
+@@ -244,7 +244,7 @@
+ return -ENOBUFS;
+ }
+
+-static u32 fib6_rule_default_pref(void)
++static u32 fib6_rule_default_pref(struct fib_rules_ops *ops)
+ {
+ return 0x3FFF;
+ }
+@@ -277,10 +277,10 @@
+ list_add_tail(&local_rule.common.list, &fib6_rules);
+ list_add_tail(&main_rule.common.list, &fib6_rules);
+
+- fib_rules_register(&fib6_rules_ops);
++ fib_rules_register(&init_net, &fib6_rules_ops);
+ }
+
+ void fib6_rules_cleanup(void)
+ {
+- fib_rules_unregister(&fib6_rules_ops);
++ fib_rules_unregister(&init_net, &fib6_rules_ops);
+ }
+diff -Nurb linux-2.6.22-570/net/ipv6/icmp.c linux-2.6.22-590/net/ipv6/icmp.c
+--- linux-2.6.22-570/net/ipv6/icmp.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/ipv6/icmp.c 2008-01-29 22:12:32.000000000 -0500
+@@ -272,7 +272,7 @@
+ return 0;
+ }
+
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ static void mip6_addr_swap(struct sk_buff *skb)
+ {
+ struct ipv6hdr *iph = ipv6_hdr(skb);
+@@ -377,6 +377,7 @@
+ mip6_addr_swap(skb);
+
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ fl.proto = IPPROTO_ICMPV6;
+ ipv6_addr_copy(&fl.fl6_dst, &hdr->saddr);
+ if (saddr)
+@@ -495,6 +496,7 @@
+ tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY;
+
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ fl.proto = IPPROTO_ICMPV6;
+ ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr);
+ if (saddr)
+diff -Nurb linux-2.6.22-570/net/ipv6/inet6_connection_sock.c linux-2.6.22-590/net/ipv6/inet6_connection_sock.c
+--- linux-2.6.22-570/net/ipv6/inet6_connection_sock.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/inet6_connection_sock.c 2008-01-29 22:12:32.000000000 -0500
+@@ -149,6 +149,7 @@
+ struct in6_addr *final_p = NULL, final;
+
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ fl.proto = sk->sk_protocol;
+ ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+ ipv6_addr_copy(&fl.fl6_src, &np->saddr);
+diff -Nurb linux-2.6.22-570/net/ipv6/inet6_hashtables.c linux-2.6.22-590/net/ipv6/inet6_hashtables.c
+--- linux-2.6.22-570/net/ipv6/inet6_hashtables.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/ipv6/inet6_hashtables.c 2008-01-29 22:12:32.000000000 -0500
+@@ -61,7 +61,7 @@
+ const __be16 sport,
+ const struct in6_addr *daddr,
+ const u16 hnum,
+- const int dif)
++ const int dif, struct net *net)
+ {
+ struct sock *sk;
+ const struct hlist_node *node;
+@@ -105,7 +105,7 @@
+
+ struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
+ const struct in6_addr *daddr,
+- const unsigned short hnum, const int dif)
++ const unsigned short hnum, const int dif, struct net *net)
+ {
+ struct sock *sk;
+ const struct hlist_node *node;
+@@ -113,7 +113,7 @@
+ int score, hiscore = 0;
+
+ read_lock(&hashinfo->lhash_lock);
+- sk_for_each(sk, node, &hashinfo->listening_hash[inet_lhashfn(hnum)]) {
++ sk_for_each(sk, node, &hashinfo->listening_hash[inet_lhashfn(net, hnum)]) {
+ if (inet_sk(sk)->num == hnum && sk->sk_family == PF_INET6) {
+ const struct ipv6_pinfo *np = inet6_sk(sk);
+
+@@ -152,12 +152,12 @@
+ struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
+ const struct in6_addr *saddr, const __be16 sport,
+ const struct in6_addr *daddr, const __be16 dport,
+- const int dif)
++ const int dif, struct net *net)
+ {
+ struct sock *sk;
+
+ local_bh_disable();
+- sk = __inet6_lookup(hashinfo, saddr, sport, daddr, ntohs(dport), dif);
++ sk = __inet6_lookup(hashinfo, saddr, sport, daddr, ntohs(dport), dif, net);
+ local_bh_enable();
+
+ return sk;
+@@ -251,6 +251,7 @@
+ int inet6_hash_connect(struct inet_timewait_death_row *death_row,
+ struct sock *sk)
+ {
++ struct net *net = sk->sk_net;
+ struct inet_hashinfo *hinfo = death_row->hashinfo;
+ const unsigned short snum = inet_sk(sk)->num;
+ struct inet_bind_hashbucket *head;
+@@ -258,8 +259,8 @@
+ int ret;
+
+ if (snum == 0) {
+- const int low = sysctl_local_port_range[0];
+- const int high = sysctl_local_port_range[1];
++ const int low = sk->sk_net->sysctl_local_port_range[0];
++ const int high = sk->sk_net->sysctl_local_port_range[1];
+ const int range = high - low;
+ int i, port;
+ static u32 hint;
+@@ -270,7 +271,7 @@
+ local_bh_disable();
+ for (i = 1; i <= range; i++) {
+ port = low + (i + offset) % range;
+- head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)];
++ head = &hinfo->bhash[inet_bhashfn(net, port, hinfo->bhash_size)];
+ spin_lock(&head->lock);
+
+ /* Does not bother with rcv_saddr checks,
+@@ -278,7 +279,7 @@
+ * unique enough.
+ */
+ inet_bind_bucket_for_each(tb, node, &head->chain) {
+- if (tb->port == port) {
++ if ((tb->port == port) && (tb->net == net)) {
+ BUG_TRAP(!hlist_empty(&tb->owners));
+ if (tb->fastreuse >= 0)
+ goto next_port;
+@@ -291,7 +292,7 @@
+ }
+
+ tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
+- head, port);
++ head, net, port);
+ if (!tb) {
+ spin_unlock(&head->lock);
+ break;
+@@ -326,7 +327,7 @@
+ goto out;
+ }
+
+- head = &hinfo->bhash[inet_bhashfn(snum, hinfo->bhash_size)];
++ head = &hinfo->bhash[inet_bhashfn(net, snum, hinfo->bhash_size)];
+ tb = inet_csk(sk)->icsk_bind_hash;
+ spin_lock_bh(&head->lock);
+
+diff -Nurb linux-2.6.22-570/net/ipv6/ip6_fib.c linux-2.6.22-590/net/ipv6/ip6_fib.c
+--- linux-2.6.22-570/net/ipv6/ip6_fib.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/ip6_fib.c 2008-01-29 22:12:32.000000000 -0500
+@@ -361,6 +361,7 @@
+
+ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
+ {
++ struct net *net = skb->sk->sk_net;
+ unsigned int h, s_h;
+ unsigned int e = 0, s_e;
+ struct rt6_rtnl_dump_arg arg;
+@@ -369,6 +370,9 @@
+ struct hlist_node *node;
+ int res = 0;
+
++ if (net != &init_net)
++ return 0;
++
+ s_h = cb->args[0];
+ s_e = cb->args[1];
+
+@@ -1311,6 +1315,11 @@
+
+ static int fib6_clean_node(struct fib6_walker_t *w)
+ {
++ struct nl_info info = {
++ .nlh = NULL,
++ .pid = 0,
++ .net = &init_net,
++ };
+ int res;
+ struct rt6_info *rt;
+ struct fib6_cleaner_t *c = (struct fib6_cleaner_t*)w;
+@@ -1319,7 +1328,7 @@
+ res = c->func(rt, c->arg);
+ if (res < 0) {
+ w->leaf = rt;
+- res = fib6_del(rt, NULL);
++ res = fib6_del(rt, &info);
+ if (res) {
+ #if RT6_DEBUG >= 2
+ printk(KERN_DEBUG "fib6_clean_node: del failed: rt=%p@%p err=%d\n", rt, rt->rt6i_node, res);
+diff -Nurb linux-2.6.22-570/net/ipv6/ip6_flowlabel.c linux-2.6.22-590/net/ipv6/ip6_flowlabel.c
+--- linux-2.6.22-570/net/ipv6/ip6_flowlabel.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/ip6_flowlabel.c 2008-01-29 22:12:32.000000000 -0500
+@@ -22,6 +22,7 @@
+ #include <linux/seq_file.h>
+
+ #include <net/sock.h>
++#include <net/net_namespace.h>
+
+ #include <net/ipv6.h>
+ #include <net/ndisc.h>
+@@ -309,6 +310,7 @@
+
+ msg.msg_controllen = olen;
+ msg.msg_control = (void*)(fl->opt+1);
++ flowi.fl_net = &init_net;
+ flowi.oif = 0;
+
+ err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk, &junk);
+@@ -690,7 +692,7 @@
+ void ip6_flowlabel_init(void)
+ {
+ #ifdef CONFIG_PROC_FS
+- proc_net_fops_create("ip6_flowlabel", S_IRUGO, &ip6fl_seq_fops);
++ proc_net_fops_create(&init_net, "ip6_flowlabel", S_IRUGO, &ip6fl_seq_fops);
+ #endif
+ }
+
+@@ -698,6 +700,6 @@
+ {
+ del_timer(&ip6_fl_gc_timer);
+ #ifdef CONFIG_PROC_FS
+- proc_net_remove("ip6_flowlabel");
++ proc_net_remove(&init_net, "ip6_flowlabel");
+ #endif
+ }
+diff -Nurb linux-2.6.22-570/net/ipv6/ip6_input.c linux-2.6.22-590/net/ipv6/ip6_input.c
+--- linux-2.6.22-570/net/ipv6/ip6_input.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/ip6_input.c 2008-01-29 22:12:32.000000000 -0500
+@@ -61,6 +61,11 @@
+ u32 pkt_len;
+ struct inet6_dev *idev;
+
++ if (dev->nd_net != &init_net) {
++ kfree_skb(skb);
++ return 0;
++ }
++
+ if (skb->pkt_type == PACKET_OTHERHOST) {
+ kfree_skb(skb);
+ return 0;
+diff -Nurb linux-2.6.22-570/net/ipv6/ip6_output.c linux-2.6.22-590/net/ipv6/ip6_output.c
+--- linux-2.6.22-570/net/ipv6/ip6_output.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/ipv6/ip6_output.c 2008-01-29 22:12:32.000000000 -0500
+@@ -423,7 +423,7 @@
+
+ /* XXX: idev->cnf.proxy_ndp? */
+ if (ipv6_devconf.proxy_ndp &&
+- pneigh_lookup(&nd_tbl, &hdr->daddr, skb->dev, 0)) {
++ pneigh_lookup(&nd_tbl, &init_net, &hdr->daddr, skb->dev, 0)) {
+ int proxied = ip6_forward_proxy_check(skb);
+ if (proxied > 0)
+ return ip6_input(skb);
+@@ -543,7 +543,7 @@
+ found_rhdr = 1;
+ break;
+ case NEXTHDR_DEST:
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0)
+ break;
+ #endif
+diff -Nurb linux-2.6.22-570/net/ipv6/ip6_tunnel.c linux-2.6.22-590/net/ipv6/ip6_tunnel.c
+--- linux-2.6.22-570/net/ipv6/ip6_tunnel.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/ipv6/ip6_tunnel.c 2008-01-29 22:12:32.000000000 -0500
+@@ -235,7 +235,7 @@
+ int i;
+ for (i = 1; i < IP6_TNL_MAX; i++) {
+ sprintf(name, "ip6tnl%d", i);
+- if (__dev_get_by_name(name) == NULL)
++ if (__dev_get_by_name(&init_net, name) == NULL)
+ break;
+ }
+ if (i == IP6_TNL_MAX)
+@@ -651,7 +651,7 @@
+ struct net_device *ldev = NULL;
+
+ if (p->link)
+- ldev = dev_get_by_index(p->link);
++ ldev = dev_get_by_index(&init_net, p->link);
+
+ if ((ipv6_addr_is_multicast(&p->laddr) ||
+ likely(ipv6_chk_addr(&p->laddr, ldev, 0))) &&
+@@ -787,7 +787,7 @@
+ struct net_device *ldev = NULL;
+
+ if (p->link)
+- ldev = dev_get_by_index(p->link);
++ ldev = dev_get_by_index(&init_net, p->link);
+
+ if (unlikely(!ipv6_chk_addr(&p->laddr, ldev, 0)))
+ printk(KERN_WARNING
+diff -Nurb linux-2.6.22-570/net/ipv6/ipcomp6.c linux-2.6.22-590/net/ipv6/ipcomp6.c
+--- linux-2.6.22-570/net/ipv6/ipcomp6.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/ipv6/ipcomp6.c 2008-01-29 22:12:32.000000000 -0500
+@@ -501,4 +501,4 @@
+ MODULE_DESCRIPTION("IP Payload Compression Protocol (IPComp) for IPv6 - RFC3173");
+ MODULE_AUTHOR("Mitsuru KANDA <mk@linux-ipv6.org>");
+
+-
++MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_COMP);
+diff -Nurb linux-2.6.22-570/net/ipv6/ipv6_sockglue.c linux-2.6.22-590/net/ipv6/ipv6_sockglue.c
+--- linux-2.6.22-570/net/ipv6/ipv6_sockglue.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/ipv6/ipv6_sockglue.c 2008-01-29 22:12:32.000000000 -0500
+@@ -123,7 +123,7 @@
+ struct ipv6hdr *ipv6h;
+ struct inet6_protocol *ops;
+
+- if (!(features & NETIF_F_HW_CSUM))
++ if (!(features & NETIF_F_V6_CSUM))
+ features &= ~NETIF_F_SG;
+
+ if (unlikely(skb_shinfo(skb)->gso_type &
+@@ -417,7 +417,7 @@
+ struct ipv6_rt_hdr *rthdr = opt->srcrt;
+ switch (rthdr->type) {
+ case IPV6_SRCRT_TYPE_0:
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ case IPV6_SRCRT_TYPE_2:
+ #endif
+ break;
+@@ -463,6 +463,7 @@
+ struct flowi fl;
+ int junk;
+
++ fl.fl_net = &init_net;
+ fl.fl6_flowlabel = 0;
+ fl.oif = sk->sk_bound_dev_if;
+
+@@ -547,7 +548,7 @@
+ if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != val)
+ goto e_inval;
+
+- if (__dev_get_by_index(val) == NULL) {
++ if (__dev_get_by_index(&init_net, val) == NULL) {
+ retv = -ENODEV;
+ break;
+ }
+diff -Nurb linux-2.6.22-570/net/ipv6/mcast.c linux-2.6.22-590/net/ipv6/mcast.c
+--- linux-2.6.22-570/net/ipv6/mcast.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/mcast.c 2008-01-29 22:12:32.000000000 -0500
+@@ -51,6 +51,7 @@
+
+ #include <net/sock.h>
+ #include <net/snmp.h>
++#include <net/net_namespace.h>
+
+ #include <net/ipv6.h>
+ #include <net/protocol.h>
+@@ -214,7 +215,7 @@
+ dst_release(&rt->u.dst);
+ }
+ } else
+- dev = dev_get_by_index(ifindex);
++ dev = dev_get_by_index(&init_net, ifindex);
+
+ if (dev == NULL) {
+ sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
+@@ -265,7 +266,7 @@
+ *lnk = mc_lst->next;
+ write_unlock_bh(&ipv6_sk_mc_lock);
+
+- if ((dev = dev_get_by_index(mc_lst->ifindex)) != NULL) {
++ if ((dev = dev_get_by_index(&init_net, mc_lst->ifindex)) != NULL) {
+ struct inet6_dev *idev = in6_dev_get(dev);
+
+ (void) ip6_mc_leave_src(sk, mc_lst, idev);
+@@ -300,7 +301,7 @@
+ dst_release(&rt->u.dst);
+ }
+ } else
+- dev = dev_get_by_index(ifindex);
++ dev = dev_get_by_index(&init_net, ifindex);
+
+ if (!dev)
+ return NULL;
+@@ -331,7 +332,7 @@
+ np->ipv6_mc_list = mc_lst->next;
+ write_unlock_bh(&ipv6_sk_mc_lock);
+
+- dev = dev_get_by_index(mc_lst->ifindex);
++ dev = dev_get_by_index(&init_net, mc_lst->ifindex);
+ if (dev) {
+ struct inet6_dev *idev = in6_dev_get(dev);
+
+@@ -2332,7 +2333,7 @@
+ struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
+
+ state->idev = NULL;
+- for_each_netdev(state->dev) {
++ for_each_netdev(&init_net, state->dev) {
+ struct inet6_dev *idev;
+ idev = in6_dev_get(state->dev);
+ if (!idev)
+@@ -2476,7 +2477,7 @@
+
+ state->idev = NULL;
+ state->im = NULL;
+- for_each_netdev(state->dev) {
++ for_each_netdev(&init_net, state->dev) {
+ struct inet6_dev *idev;
+ idev = in6_dev_get(state->dev);
+ if (unlikely(idev == NULL))
+@@ -2658,8 +2659,8 @@
+ np->hop_limit = 1;
+
+ #ifdef CONFIG_PROC_FS
+- proc_net_fops_create("igmp6", S_IRUGO, &igmp6_mc_seq_fops);
+- proc_net_fops_create("mcfilter6", S_IRUGO, &igmp6_mcf_seq_fops);
++ proc_net_fops_create(&init_net, "igmp6", S_IRUGO, &igmp6_mc_seq_fops);
++ proc_net_fops_create(&init_net, "mcfilter6", S_IRUGO, &igmp6_mcf_seq_fops);
+ #endif
+
+ return 0;
+@@ -2671,7 +2672,7 @@
+ igmp6_socket = NULL; /* for safety */
+
+ #ifdef CONFIG_PROC_FS
+- proc_net_remove("mcfilter6");
+- proc_net_remove("igmp6");
++ proc_net_remove(&init_net, "mcfilter6");
++ proc_net_remove(&init_net, "igmp6");
+ #endif
+ }
+diff -Nurb linux-2.6.22-570/net/ipv6/mip6.c linux-2.6.22-590/net/ipv6/mip6.c
+--- linux-2.6.22-570/net/ipv6/mip6.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/mip6.c 2008-01-29 22:12:32.000000000 -0500
+@@ -30,6 +30,7 @@
+ #include <net/sock.h>
+ #include <net/ipv6.h>
+ #include <net/ip6_checksum.h>
++#include <net/rawv6.h>
+ #include <net/xfrm.h>
+ #include <net/mip6.h>
+
+@@ -86,7 +87,7 @@
+ return len;
+ }
+
+-int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
++static int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
+ {
+ struct ip6_mh *mh;
+
+@@ -471,7 +472,7 @@
+ .remote_addr = mip6_xfrm_addr,
+ };
+
+-int __init mip6_init(void)
++static int __init mip6_init(void)
+ {
+ printk(KERN_INFO "Mobile IPv6\n");
+
+@@ -483,18 +484,35 @@
+ printk(KERN_INFO "%s: can't add xfrm type(rthdr)\n", __FUNCTION__);
+ goto mip6_rthdr_xfrm_fail;
+ }
++ if (rawv6_mh_filter_register(mip6_mh_filter) < 0) {
++ printk(KERN_INFO "%s: can't add rawv6 mh filter\n", __FUNCTION__);
++ goto mip6_rawv6_mh_fail;
++ }
++
++
+ return 0;
+
++ mip6_rawv6_mh_fail:
++ xfrm_unregister_type(&mip6_rthdr_type, AF_INET6);
+ mip6_rthdr_xfrm_fail:
+ xfrm_unregister_type(&mip6_destopt_type, AF_INET6);
+ mip6_destopt_xfrm_fail:
+ return -EAGAIN;
+ }
+
+-void __exit mip6_fini(void)
++static void __exit mip6_fini(void)
+ {
++ if (rawv6_mh_filter_unregister(mip6_mh_filter) < 0)
++ printk(KERN_INFO "%s: can't remove rawv6 mh filter\n", __FUNCTION__);
+ if (xfrm_unregister_type(&mip6_rthdr_type, AF_INET6) < 0)
+ printk(KERN_INFO "%s: can't remove xfrm type(rthdr)\n", __FUNCTION__);
+ if (xfrm_unregister_type(&mip6_destopt_type, AF_INET6) < 0)
+ printk(KERN_INFO "%s: can't remove xfrm type(destopt)\n", __FUNCTION__);
+ }
++
++module_init(mip6_init);
++module_exit(mip6_fini);
++
++MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_DSTOPTS);
+MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_ROUTING);
+diff -Nurb linux-2.6.22-570/net/ipv6/ndisc.c linux-2.6.22-590/net/ipv6/ndisc.c
+--- linux-2.6.22-570/net/ipv6/ndisc.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/ipv6/ndisc.c 2008-01-29 22:12:32.000000000 -0500
+@@ -418,6 +418,7 @@
+ int oif)
+ {
+ memset(fl, 0, sizeof(*fl));
++ fl->fl_net = &init_net;
+ ipv6_addr_copy(&fl->fl6_src, saddr);
+ ipv6_addr_copy(&fl->fl6_dst, daddr);
+ fl->proto = IPPROTO_ICMPV6;
+@@ -760,7 +761,7 @@
+ if (ipv6_chk_acast_addr(dev, &msg->target) ||
+ (idev->cnf.forwarding &&
+ (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) &&
+- (pneigh = pneigh_lookup(&nd_tbl,
++ (pneigh = pneigh_lookup(&nd_tbl, &init_net,
+ &msg->target, dev, 0)) != NULL)) {
+ if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
+ skb->pkt_type != PACKET_HOST &&
+@@ -901,7 +902,7 @@
+ */
+ if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
+ ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp &&
+- pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) {
++ pneigh_lookup(&nd_tbl, &init_net, &msg->target, dev, 0)) {
+ /* XXX: idev->cnf.prixy_ndp */
+ goto out;
+ }
+@@ -1525,6 +1526,9 @@
+ {
+ struct net_device *dev = ptr;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ switch (event) {
+ case NETDEV_CHANGEADDR:
+ neigh_changeaddr(&nd_tbl, dev);
+diff -Nurb linux-2.6.22-570/net/ipv6/netfilter/ip6_queue.c linux-2.6.22-590/net/ipv6/netfilter/ip6_queue.c
+--- linux-2.6.22-570/net/ipv6/netfilter/ip6_queue.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/netfilter/ip6_queue.c 2008-01-29 22:12:32.000000000 -0500
+@@ -24,6 +24,7 @@
+ #include <linux/sysctl.h>
+ #include <linux/proc_fs.h>
+ #include <linux/mutex.h>
++#include <net/net_namespace.h>
+ #include <net/sock.h>
+ #include <net/ipv6.h>
+ #include <net/ip6_route.h>
+@@ -546,6 +547,9 @@
+ {
+ struct net_device *dev = ptr;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ /* Drop any packets associated with the downed device */
+ if (event == NETDEV_DOWN)
+ ipq_dev_drop(dev->ifindex);
+@@ -565,7 +569,7 @@
+ if (event == NETLINK_URELEASE &&
+ n->protocol == NETLINK_IP6_FW && n->pid) {
+ write_lock_bh(&queue_lock);
+- if (n->pid == peer_pid)
++ if ((n->net == &init_net) && (n->pid == peer_pid))
+ __ipq_reset();
+ write_unlock_bh(&queue_lock);
+ }
+@@ -657,14 +661,14 @@
+ struct proc_dir_entry *proc;
+
+ netlink_register_notifier(&ipq_nl_notifier);
+- ipqnl = netlink_kernel_create(NETLINK_IP6_FW, 0, ipq_rcv_sk, NULL,
+- THIS_MODULE);
++ ipqnl = netlink_kernel_create(&init_net, NETLINK_IP6_FW, 0, ipq_rcv_sk,
++ NULL, THIS_MODULE);
+ if (ipqnl == NULL) {
+ printk(KERN_ERR "ip6_queue: failed to create netlink socket\n");
+ goto cleanup_netlink_notifier;
+ }
+
+- proc = proc_net_create(IPQ_PROC_FS_NAME, 0, ipq_get_info);
++ proc = proc_net_create(&init_net, IPQ_PROC_FS_NAME, 0, ipq_get_info);
+ if (proc)
+ proc->owner = THIS_MODULE;
+ else {
+@@ -685,7 +689,7 @@
+ cleanup_sysctl:
+ unregister_sysctl_table(ipq_sysctl_header);
+ unregister_netdevice_notifier(&ipq_dev_notifier);
+- proc_net_remove(IPQ_PROC_FS_NAME);
++ proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
+
+ cleanup_ipqnl:
+ sock_release(ipqnl->sk_socket);
+@@ -705,7 +709,7 @@
+
+ unregister_sysctl_table(ipq_sysctl_header);
+ unregister_netdevice_notifier(&ipq_dev_notifier);
+- proc_net_remove(IPQ_PROC_FS_NAME);
++ proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
+
+ sock_release(ipqnl->sk_socket);
+ mutex_lock(&ipqnl_mutex);
+diff -Nurb linux-2.6.22-570/net/ipv6/netfilter/ip6_tables.c linux-2.6.22-590/net/ipv6/netfilter/ip6_tables.c
+--- linux-2.6.22-570/net/ipv6/netfilter/ip6_tables.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/netfilter/ip6_tables.c 2008-01-29 22:12:32.000000000 -0500
+@@ -906,7 +906,7 @@
+ int ret;
+ struct xt_table *t;
+
+- t = xt_find_table_lock(AF_INET6, entries->name);
++ t = xt_find_table_lock(&init_net, AF_INET6, entries->name);
+ if (t && !IS_ERR(t)) {
+ struct xt_table_info *private = t->private;
+ duprintf("t->private->number = %u\n", private->number);
+@@ -972,7 +972,7 @@
+
+ duprintf("ip_tables: Translated table\n");
+
+- t = try_then_request_module(xt_find_table_lock(AF_INET6, tmp.name),
++ t = try_then_request_module(xt_find_table_lock(&init_net, AF_INET6, tmp.name),
+ "ip6table_%s", tmp.name);
+ if (!t || IS_ERR(t)) {
+ ret = t ? PTR_ERR(t) : -ENOENT;
+@@ -1073,7 +1073,7 @@
+ goto free;
+ }
+
+- t = xt_find_table_lock(AF_INET6, tmp.name);
++ t = xt_find_table_lock(&init_net, AF_INET6, tmp.name);
+ if (!t || IS_ERR(t)) {
+ ret = t ? PTR_ERR(t) : -ENOENT;
+ goto free;
+@@ -1109,6 +1109,9 @@
+ {
+ int ret;
+
++ if (sk->sk_net != &init_net)
++ return -ENOPROTOOPT;
++
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+@@ -1134,6 +1137,9 @@
+ {
+ int ret;
+
++ if (sk->sk_net != &init_net)
++ return -ENOPROTOOPT;
++
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+@@ -1155,7 +1161,7 @@
+ }
+ name[IP6T_TABLE_MAXNAMELEN-1] = '\0';
+
+- t = try_then_request_module(xt_find_table_lock(AF_INET6, name),
++ t = try_then_request_module(xt_find_table_lock(&init_net, AF_INET6, name),
+ "ip6table_%s", name);
+ if (t && !IS_ERR(t)) {
+ struct ip6t_getinfo info;
+@@ -1259,7 +1265,7 @@
+ return ret;
+ }
+
+- ret = xt_register_table(table, &bootstrap, newinfo);
++ ret = xt_register_table(&init_net, table, &bootstrap, newinfo);
+ if (ret != 0) {
+ xt_free_table_info(newinfo);
+ return ret;
+diff -Nurb linux-2.6.22-570/net/ipv6/netfilter/ip6t_REJECT.c linux-2.6.22-590/net/ipv6/netfilter/ip6t_REJECT.c
+--- linux-2.6.22-570/net/ipv6/netfilter/ip6t_REJECT.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/netfilter/ip6t_REJECT.c 2008-01-29 22:12:32.000000000 -0500
+@@ -92,6 +92,7 @@
+ }
+
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ fl.proto = IPPROTO_TCP;
+ ipv6_addr_copy(&fl.fl6_src, &oip6h->daddr);
+ ipv6_addr_copy(&fl.fl6_dst, &oip6h->saddr);
+@@ -172,7 +173,7 @@
+ send_unreach(struct sk_buff *skb_in, unsigned char code, unsigned int hooknum)
+ {
+ if (hooknum == NF_IP6_LOCAL_OUT && skb_in->dev == NULL)
+- skb_in->dev = &loopback_dev;
++ skb_in->dev = &init_net.loopback_dev;
+
+ icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL);
+ }
+diff -Nurb linux-2.6.22-570/net/ipv6/netfilter/ip6table_filter.c linux-2.6.22-590/net/ipv6/netfilter/ip6table_filter.c
+--- linux-2.6.22-570/net/ipv6/netfilter/ip6table_filter.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/netfilter/ip6table_filter.c 2008-01-29 22:12:32.000000000 -0500
+@@ -65,6 +65,10 @@
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ return ip6t_do_table(pskb, hook, in, out, &packet_filter);
+ }
+
+@@ -75,6 +79,10 @@
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ #if 0
+ /* root is playing with raw sockets. */
+ if ((*pskb)->len < sizeof(struct iphdr)
+diff -Nurb linux-2.6.22-570/net/ipv6/netfilter/ip6table_mangle.c linux-2.6.22-590/net/ipv6/netfilter/ip6table_mangle.c
+--- linux-2.6.22-570/net/ipv6/netfilter/ip6table_mangle.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/netfilter/ip6table_mangle.c 2008-01-29 22:12:32.000000000 -0500
+@@ -79,6 +79,10 @@
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ return ip6t_do_table(pskb, hook, in, out, &packet_mangler);
+ }
+
+@@ -95,6 +99,10 @@
+ u_int8_t hop_limit;
+ u_int32_t flowlabel, mark;
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ #if 0
+ /* root is playing with raw sockets. */
+ if ((*pskb)->len < sizeof(struct iphdr)
+diff -Nurb linux-2.6.22-570/net/ipv6/netfilter/ip6table_raw.c linux-2.6.22-590/net/ipv6/netfilter/ip6table_raw.c
+--- linux-2.6.22-570/net/ipv6/netfilter/ip6table_raw.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/netfilter/ip6table_raw.c 2008-01-29 22:12:32.000000000 -0500
+@@ -57,6 +57,10 @@
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ return ip6t_do_table(pskb, hook, in, out, &packet_raw);
+ }
+
+diff -Nurb linux-2.6.22-570/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c linux-2.6.22-590/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+--- linux-2.6.22-570/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c 2008-01-29 22:12:32.000000000 -0500
+@@ -167,6 +167,10 @@
+ unsigned char pnum = ipv6_hdr(*pskb)->nexthdr;
+
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ /* This is where we call the helper: as the packet goes out. */
+ ct = nf_ct_get(*pskb, &ctinfo);
+ if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)
+@@ -203,6 +207,10 @@
+ {
+ struct sk_buff *reasm;
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ /* Previously seen (loopback)? */
+ if ((*pskb)->nfct)
+ return NF_ACCEPT;
+@@ -231,6 +239,10 @@
+ {
+ struct sk_buff *reasm = (*pskb)->nfct_reasm;
+
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ /* This packet is fragmented and has reassembled packet. */
+ if (reasm) {
+ /* Reassembled packet isn't parsed yet ? */
+@@ -256,6 +268,10 @@
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ /* root is playing with raw sockets. */
+ if ((*pskb)->len < sizeof(struct ipv6hdr)) {
+ if (net_ratelimit())
+diff -Nurb linux-2.6.22-570/net/ipv6/netfilter.c linux-2.6.22-590/net/ipv6/netfilter.c
+--- linux-2.6.22-570/net/ipv6/netfilter.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/netfilter.c 2008-01-29 22:12:32.000000000 -0500
+@@ -14,6 +14,7 @@
+ struct ipv6hdr *iph = ipv6_hdr(skb);
+ struct dst_entry *dst;
+ struct flowi fl = {
++ .fl_net = &init_net,
+ .oif = skb->sk ? skb->sk->sk_bound_dev_if : 0,
+ .mark = skb->mark,
+ .nl_u =
+diff -Nurb linux-2.6.22-570/net/ipv6/proc.c linux-2.6.22-590/net/ipv6/proc.c
+--- linux-2.6.22-570/net/ipv6/proc.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/proc.c 2008-01-29 22:12:32.000000000 -0500
+@@ -28,6 +28,7 @@
+ #include <net/tcp.h>
+ #include <net/transp_v6.h>
+ #include <net/ipv6.h>
++#include <net/net_namespace.h>
+
+ static struct proc_dir_entry *proc_net_devsnmp6;
+
+@@ -231,22 +232,22 @@
+ {
+ int rc = 0;
+
+- if (!proc_net_fops_create("snmp6", S_IRUGO, &snmp6_seq_fops))
++ if (!proc_net_fops_create(&init_net, "snmp6", S_IRUGO, &snmp6_seq_fops))
+ goto proc_snmp6_fail;
+
+- proc_net_devsnmp6 = proc_mkdir("dev_snmp6", proc_net);
++ proc_net_devsnmp6 = proc_mkdir("dev_snmp6", init_net.proc_net);
+ if (!proc_net_devsnmp6)
+ goto proc_dev_snmp6_fail;
+
+- if (!proc_net_fops_create("sockstat6", S_IRUGO, &sockstat6_seq_fops))
++ if (!proc_net_fops_create(&init_net, "sockstat6", S_IRUGO, &sockstat6_seq_fops))
+ goto proc_sockstat6_fail;
+ out:
+ return rc;
+
+ proc_sockstat6_fail:
+- proc_net_remove("dev_snmp6");
++ proc_net_remove(&init_net, "dev_snmp6");
+ proc_dev_snmp6_fail:
+- proc_net_remove("snmp6");
++ proc_net_remove(&init_net, "snmp6");
+ proc_snmp6_fail:
+ rc = -ENOMEM;
+ goto out;
+@@ -254,8 +255,8 @@
+
+ void ipv6_misc_proc_exit(void)
+ {
+- proc_net_remove("sockstat6");
+- proc_net_remove("dev_snmp6");
+- proc_net_remove("snmp6");
++ proc_net_remove(&init_net, "sockstat6");
++ proc_net_remove(&init_net, "dev_snmp6");
++ proc_net_remove(&init_net, "snmp6");
+ }
+
diff -Nurb linux-2.6.22-570/net/ipv6/raw.c linux-2.6.22-590/net/ipv6/raw.c
---- linux-2.6.22-570/net/ipv6/raw.c 2008-03-15 10:34:20.000000000 -0400
-+++ linux-2.6.22-590/net/ipv6/raw.c 2008-03-15 10:35:47.000000000 -0400
-@@ -49,7 +49,7 @@
+--- linux-2.6.22-570/net/ipv6/raw.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/ipv6/raw.c 2008-01-29 22:12:32.000000000 -0500
+@@ -49,7 +49,8 @@
#include <net/udp.h>
#include <net/inet_common.h>
#include <net/tcp_states.h>
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- #include <net/mip6.h>
- #endif
+-#ifdef CONFIG_IPV6_MIP6
++#include <net/net_namespace.h>
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ #include <net/mip6.h>
+ #endif
+
+@@ -137,6 +138,28 @@
+ return 0;
+ }
+
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
++static int (*mh_filter)(struct sock *sock, struct sk_buff *skb);
++
++int rawv6_mh_filter_register(int (*filter)(struct sock *sock,
++ struct sk_buff *skb))
++{
++ rcu_assign_pointer(mh_filter, filter);
++ return 0;
++}
++EXPORT_SYMBOL(rawv6_mh_filter_register);
++
++int rawv6_mh_filter_unregister(int (*filter)(struct sock *sock,
++ struct sk_buff *skb))
++{
++ rcu_assign_pointer(mh_filter, NULL);
++ synchronize_rcu();
++ return 0;
++}
++EXPORT_SYMBOL(rawv6_mh_filter_unregister);
++
++#endif
++
+ /*
+ * demultiplex raw sockets.
+ * (should consider queueing the skb in the sock receive_queue
+@@ -178,16 +201,22 @@
+ case IPPROTO_ICMPV6:
+ filtered = icmpv6_filter(sk, skb);
+ break;
+-#ifdef CONFIG_IPV6_MIP6
++
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ case IPPROTO_MH:
++ {
+ /* XXX: To validate MH only once for each packet,
+ * this is placed here. It should be after checking
+ * xfrm policy, however it doesn't. The checking xfrm
+ * policy is placed in rawv6_rcv() because it is
+ * required for each socket.
+ */
+- filtered = mip6_mh_filter(sk, skb);
++ int (*filter)(struct sock *sock, struct sk_buff *skb);
++
++ filter = rcu_dereference(mh_filter);
++ filtered = filter ? filter(sk, skb) : 0;
+ break;
++ }
+ #endif
+ default:
+ filtered = 0;
+@@ -254,7 +283,7 @@
+ if (!sk->sk_bound_dev_if)
+ goto out;
+
+- dev = dev_get_by_index(sk->sk_bound_dev_if);
++ dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if);
+ if (!dev) {
+ err = -ENODEV;
+ goto out;
+@@ -611,9 +640,7 @@
+ struct iovec *iov;
+ u8 __user *type = NULL;
+ u8 __user *code = NULL;
+-#ifdef CONFIG_IPV6_MIP6
+ u8 len = 0;
+-#endif
+ int probed = 0;
+ int i;
+
+@@ -646,7 +673,6 @@
+ probed = 1;
+ }
+ break;
+-#ifdef CONFIG_IPV6_MIP6
+ case IPPROTO_MH:
+ if (iov->iov_base && iov->iov_len < 1)
+ break;
+@@ -660,7 +686,6 @@
+ len += iov->iov_len;
+
+ break;
+-#endif
+ default:
+ probed = 1;
+ break;
+@@ -704,6 +729,7 @@
+ * Get and verify the address.
+ */
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+
+ if (sin6) {
+ if (addr_len < SIN6_LEN_RFC2133)
+@@ -1291,13 +1317,13 @@
+
+ int __init raw6_proc_init(void)
+ {
+- if (!proc_net_fops_create("raw6", S_IRUGO, &raw6_seq_fops))
++ if (!proc_net_fops_create(&init_net, "raw6", S_IRUGO, &raw6_seq_fops))
+ return -ENOMEM;
+ return 0;
+ }
+
+ void raw6_proc_exit(void)
+ {
+- proc_net_remove("raw6");
++ proc_net_remove(&init_net, "raw6");
+ }
+ #endif /* CONFIG_PROC_FS */
+diff -Nurb linux-2.6.22-570/net/ipv6/reassembly.c linux-2.6.22-590/net/ipv6/reassembly.c
+--- linux-2.6.22-570/net/ipv6/reassembly.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/reassembly.c 2008-01-29 22:12:32.000000000 -0500
+@@ -301,7 +301,7 @@
+
+ fq_kill(fq);
+
+- dev = dev_get_by_index(fq->iif);
++ dev = dev_get_by_index(&init_net, fq->iif);
+ if (!dev)
+ goto out;
+
+diff -Nurb linux-2.6.22-570/net/ipv6/route.c linux-2.6.22-590/net/ipv6/route.c
+--- linux-2.6.22-570/net/ipv6/route.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/ipv6/route.c 2008-01-29 22:12:32.000000000 -0500
+@@ -56,6 +56,7 @@
+ #include <net/xfrm.h>
+ #include <net/netevent.h>
+ #include <net/netlink.h>
++#include <net/net_namespace.h>
+
+ #include <asm/uaccess.h>
+
+@@ -137,7 +138,7 @@
+ .dst = {
+ .__refcnt = ATOMIC_INIT(1),
+ .__use = 1,
+- .dev = &loopback_dev,
++ .dev = NULL,
+ .obsolete = -1,
+ .error = -ENETUNREACH,
+ .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
+@@ -163,7 +164,7 @@
+ .dst = {
+ .__refcnt = ATOMIC_INIT(1),
+ .__use = 1,
+- .dev = &loopback_dev,
++ .dev = NULL,
+ .obsolete = -1,
+ .error = -EACCES,
+ .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
+@@ -183,7 +184,7 @@
+ .dst = {
+ .__refcnt = ATOMIC_INIT(1),
+ .__use = 1,
+- .dev = &loopback_dev,
++ .dev = NULL,
+ .obsolete = -1,
+ .error = -EINVAL,
+ .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
+@@ -223,8 +224,8 @@
+ struct rt6_info *rt = (struct rt6_info *)dst;
+ struct inet6_dev *idev = rt->rt6i_idev;
+
+- if (dev != &loopback_dev && idev != NULL && idev->dev == dev) {
+- struct inet6_dev *loopback_idev = in6_dev_get(&loopback_dev);
++ if (dev != &init_net.loopback_dev && idev != NULL && idev->dev == dev) {
++ struct inet6_dev *loopback_idev = in6_dev_get(&init_net.loopback_dev);
+ if (loopback_idev != NULL) {
+ rt->rt6i_idev = loopback_idev;
+ in6_dev_put(idev);
+@@ -564,6 +565,7 @@
+ int oif, int strict)
+ {
+ struct flowi fl = {
++ .fl_net = &init_net,
+ .oif = oif,
+ .nl_u = {
+ .ip6_u = {
+@@ -611,7 +613,12 @@
+
+ int ip6_ins_rt(struct rt6_info *rt)
+ {
+- return __ip6_ins_rt(rt, NULL);
++ struct nl_info info = {
++ .nlh = NULL,
++ .pid = 0,
++ .net = &init_net,
++ };
++ return __ip6_ins_rt(rt, &info);
+ }
+
+ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *daddr,
+@@ -742,6 +749,7 @@
+ struct ipv6hdr *iph = ipv6_hdr(skb);
+ int flags = RT6_LOOKUP_F_HAS_SADDR;
+ struct flowi fl = {
++ .fl_net = &init_net,
+ .iif = skb->dev->ifindex,
+ .nl_u = {
+ .ip6_u = {
+@@ -1129,7 +1137,7 @@
+ #endif
+ if (cfg->fc_ifindex) {
+ err = -ENODEV;
+- dev = dev_get_by_index(cfg->fc_ifindex);
++ dev = dev_get_by_index(&init_net, cfg->fc_ifindex);
+ if (!dev)
+ goto out;
+ idev = in6_dev_get(dev);
+@@ -1187,12 +1195,12 @@
+ if ((cfg->fc_flags & RTF_REJECT) ||
+ (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) {
+ /* hold loopback dev/idev if we haven't done so. */
+- if (dev != &loopback_dev) {
++ if (dev != &init_net.loopback_dev) {
+ if (dev) {
+ dev_put(dev);
+ in6_dev_put(idev);
+ }
+- dev = &loopback_dev;
++ dev = &init_net.loopback_dev;
+ dev_hold(dev);
+ idev = in6_dev_get(dev);
+ if (!idev) {
+@@ -1333,7 +1341,12 @@
+
+ int ip6_del_rt(struct rt6_info *rt)
+ {
+- return __ip6_del_rt(rt, NULL);
++ struct nl_info info = {
++ .nlh = NULL,
++ .pid = 0,
++ .net = &init_net,
++ };
++ return __ip6_del_rt(rt, &info);
+ }
+
+ static int ip6_route_del(struct fib6_config *cfg)
+@@ -1444,6 +1457,7 @@
+ int flags = RT6_LOOKUP_F_HAS_SADDR;
+ struct ip6rd_flowi rdfl = {
+ .fl = {
++ .fl_net = &init_net,
+ .oif = dev->ifindex,
+ .nl_u = {
+ .ip6_u = {
+@@ -1896,13 +1910,13 @@
+ if (rt == NULL)
+ return ERR_PTR(-ENOMEM);
+
+- dev_hold(&loopback_dev);
++ dev_hold(&init_net.loopback_dev);
+ in6_dev_hold(idev);
+
+ rt->u.dst.flags = DST_HOST;
+ rt->u.dst.input = ip6_input;
+ rt->u.dst.output = ip6_output;
+- rt->rt6i_dev = &loopback_dev;
++ rt->rt6i_dev = &init_net.loopback_dev;
+ rt->rt6i_idev = idev;
+ rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev);
+ rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst));
+@@ -2033,6 +2047,7 @@
+
+ cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
+ cfg->fc_nlinfo.nlh = nlh;
++ cfg->fc_nlinfo.net = skb->sk->sk_net;
+
+ if (tb[RTA_GATEWAY]) {
+ nla_memcpy(&cfg->fc_gateway, tb[RTA_GATEWAY], 16);
+@@ -2078,9 +2093,13 @@
+
+ static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct fib6_config cfg;
+ int err;
+
++ if (net != &init_net)
++ return -EINVAL;
++
+ err = rtm_to_fib6_config(skb, nlh, &cfg);
+ if (err < 0)
+ return err;
+@@ -2090,9 +2109,13 @@
+
+ static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct fib6_config cfg;
+ int err;
+
++ if (net != &init_net)
++ return -EINVAL;
++
+ err = rtm_to_fib6_config(skb, nlh, &cfg);
+ if (err < 0)
+ return err;
+@@ -2227,6 +2250,7 @@
+
+ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
+ {
++ struct net *net = in_skb->sk->sk_net;
+ struct nlattr *tb[RTA_MAX+1];
+ struct rt6_info *rt;
+ struct sk_buff *skb;
+@@ -2234,12 +2258,16 @@
+ struct flowi fl;
+ int err, iif = 0;
+
++ if (net != &init_net)
++ return -EINVAL;
++
+ err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
+ if (err < 0)
+ goto errout;
+
+ err = -EINVAL;
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+
+ if (tb[RTA_SRC]) {
+ if (nla_len(tb[RTA_SRC]) < sizeof(struct in6_addr))
+@@ -2263,7 +2291,7 @@
+
+ if (iif) {
+ struct net_device *dev;
+- dev = __dev_get_by_index(iif);
++ dev = __dev_get_by_index(&init_net, iif);
+ if (!dev) {
+ err = -ENODEV;
+ goto errout;
+@@ -2293,7 +2321,7 @@
+ goto errout;
+ }
+
+- err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
++ err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
+ errout:
+ return err;
+ }
+@@ -2301,17 +2329,10 @@
+ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
+ {
+ struct sk_buff *skb;
+- u32 pid = 0, seq = 0;
+- struct nlmsghdr *nlh = NULL;
++ u32 pid = info->pid, seq = info->nlh ? info->nlh->nlmsg_seq : 0;
++ struct nlmsghdr *nlh = info->nlh;
+ int err = -ENOBUFS;
+
+- if (info) {
+- pid = info->pid;
+- nlh = info->nlh;
+- if (nlh)
+- seq = nlh->nlmsg_seq;
+- }
+-
+ skb = nlmsg_new(rt6_nlmsg_size(), gfp_any());
+ if (skb == NULL)
+ goto errout;
+@@ -2323,10 +2344,10 @@
+ kfree_skb(skb);
+ goto errout;
+ }
+- err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any());
++ err = rtnl_notify(skb, &init_net, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any());
+ errout:
+ if (err < 0)
+- rtnl_set_sk_err(RTNLGRP_IPV6_ROUTE, err);
++ rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_ROUTE, err);
+ }
+
+ /*
+@@ -2558,13 +2579,19 @@
+ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
+ ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops.kmem_cachep;
+
++ /* Perform the initialization we can't perform at compile time */
++ ip6_null_entry.u.dst.dev = &init_net.loopback_dev;
++#ifdef CONFIG_IPV6_MULTIPLE_TABLES
++ ip6_prohibit_entry.u.dst.dev = &init_net.loopback_dev;
++ ip6_blk_hole_entry.u.dst.dev = &init_net.loopback_dev;
++#endif
+ fib6_init();
+ #ifdef CONFIG_PROC_FS
+- p = proc_net_create("ipv6_route", 0, rt6_proc_info);
++ p = proc_net_create(&init_net, "ipv6_route", 0, rt6_proc_info);
+ if (p)
+ p->owner = THIS_MODULE;
+
+- proc_net_fops_create("rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
++ proc_net_fops_create(&init_net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
+ #endif
+ #ifdef CONFIG_XFRM
+ xfrm6_init();
+@@ -2584,8 +2611,8 @@
+ fib6_rules_cleanup();
+ #endif
+ #ifdef CONFIG_PROC_FS
+- proc_net_remove("ipv6_route");
+- proc_net_remove("rt6_stats");
++ proc_net_remove(&init_net, "ipv6_route");
++ proc_net_remove(&init_net, "rt6_stats");
+ #endif
+ #ifdef CONFIG_XFRM
+ xfrm6_fini();
+diff -Nurb linux-2.6.22-570/net/ipv6/sit.c linux-2.6.22-590/net/ipv6/sit.c
+--- linux-2.6.22-570/net/ipv6/sit.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/sit.c 2008-01-29 22:12:32.000000000 -0500
+@@ -167,7 +167,7 @@
+ int i;
+ for (i=1; i<100; i++) {
+ sprintf(name, "sit%d", i);
+- if (__dev_get_by_name(name) == NULL)
++ if (__dev_get_by_name(&init_net, name) == NULL)
+ break;
+ }
+ if (i==100)
+@@ -283,6 +283,9 @@
+ struct sk_buff *skb2;
+ struct rt6_info *rt6i;
+
++ if (skb->dev->nd_net != &init_net)
++ return;
++
+ if (len < hlen + sizeof(struct ipv6hdr))
+ return;
+ iph6 = (struct ipv6hdr*)(dp + hlen);
+@@ -369,6 +372,10 @@
+ struct iphdr *iph;
+ struct ip_tunnel *tunnel;
+
++ if (skb->dev->nd_net != &init_net) {
++ kfree_skb(skb);
++ return 0;
++ }
+ if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
+ goto out;
+
+@@ -474,7 +481,8 @@
+ }
+
+ {
+- struct flowi fl = { .nl_u = { .ip4_u =
++ struct flowi fl = { .fl_net = &init_net,
++ .nl_u = { .ip4_u =
+ { .daddr = dst,
+ .saddr = tiph->saddr,
+ .tos = RT_TOS(tos) } },
+@@ -745,7 +753,8 @@
+ memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
+
+ if (iph->daddr) {
+- struct flowi fl = { .nl_u = { .ip4_u =
++ struct flowi fl = { .fl_net = &init_net,
++ .nl_u = { .ip4_u =
+ { .daddr = iph->daddr,
+ .saddr = iph->saddr,
+ .tos = RT_TOS(iph->tos) } },
+@@ -760,7 +769,7 @@
+ }
+
+ if (!tdev && tunnel->parms.link)
+- tdev = __dev_get_by_index(tunnel->parms.link);
++ tdev = __dev_get_by_index(&init_net, tunnel->parms.link);
+
+ if (tdev) {
+ dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
+diff -Nurb linux-2.6.22-570/net/ipv6/tcp_ipv6.c linux-2.6.22-590/net/ipv6/tcp_ipv6.c
+--- linux-2.6.22-570/net/ipv6/tcp_ipv6.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/ipv6/tcp_ipv6.c 2008-01-29 22:12:32.000000000 -0500
+@@ -143,6 +143,7 @@
+ return(-EAFNOSUPPORT);
+
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+
+ if (np->sndflow) {
+ fl.fl6_flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK;
+@@ -330,6 +331,7 @@
+ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+ int type, int code, int offset, __be32 info)
+ {
++ struct net *net = skb->dev->nd_net;
+ struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
+ const struct tcphdr *th = (struct tcphdr *)(skb->data+offset);
+ struct ipv6_pinfo *np;
+@@ -339,7 +341,7 @@
+ __u32 seq;
+
+ sk = inet6_lookup(&tcp_hashinfo, &hdr->daddr, th->dest, &hdr->saddr,
+- th->source, skb->dev->ifindex);
++ th->source, skb->dev->ifindex, net);
+
+ if (sk == NULL) {
+ ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
+@@ -388,6 +390,7 @@
+ for now.
+ */
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ fl.proto = IPPROTO_TCP;
+ ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+ ipv6_addr_copy(&fl.fl6_src, &np->saddr);
+@@ -481,6 +484,7 @@
+ int err = -1;
+
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ fl.proto = IPPROTO_TCP;
+ ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr);
+ ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);
+@@ -1066,6 +1070,7 @@
+ buff->csum = csum_partial((char *)t1, sizeof(*t1), 0);
+
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr);
+ ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr);
+
+@@ -1167,6 +1172,7 @@
+ buff->csum = csum_partial((char *)t1, tot_len, 0);
+
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr);
+ ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr);
+
+@@ -1224,7 +1230,8 @@
+
+ nsk = __inet6_lookup_established(&tcp_hashinfo, &ipv6_hdr(skb)->saddr,
+ th->source, &ipv6_hdr(skb)->daddr,
+- ntohs(th->dest), inet6_iif(skb));
++ ntohs(th->dest), inet6_iif(skb),
++ sk->sk_net);
+
+ if (nsk) {
+ if (nsk->sk_state != TCP_TIME_WAIT) {
+@@ -1414,6 +1421,7 @@
+ struct flowi fl;
+
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ fl.proto = IPPROTO_TCP;
+ ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr);
+ if (opt && opt->srcrt) {
+@@ -1700,6 +1708,7 @@
+ static int tcp_v6_rcv(struct sk_buff **pskb)
+ {
+ struct sk_buff *skb = *pskb;
++ struct net *net = skb->dev->nd_net;
+ struct tcphdr *th;
+ struct sock *sk;
+ int ret;
+@@ -1736,7 +1745,7 @@
+
+ sk = __inet6_lookup(&tcp_hashinfo, &ipv6_hdr(skb)->saddr, th->source,
+ &ipv6_hdr(skb)->daddr, ntohs(th->dest),
+- inet6_iif(skb));
++ inet6_iif(skb), net);
+
+ if (!sk)
+ goto no_tcp_socket;
+@@ -1816,7 +1825,8 @@
+
+ sk2 = inet6_lookup_listener(&tcp_hashinfo,
+ &ipv6_hdr(skb)->daddr,
+- ntohs(th->dest), inet6_iif(skb));
++ ntohs(th->dest), inet6_iif(skb),
++ net);
+ if (sk2 != NULL) {
+ struct inet_timewait_sock *tw = inet_twsk(sk);
+ inet_twsk_deschedule(tw, &tcp_death_row);
+@@ -2121,12 +2131,12 @@
+
+ int __init tcp6_proc_init(void)
+ {
+- return tcp_proc_register(&tcp6_seq_afinfo);
++ return tcp_proc_register(&init_net, &tcp6_seq_afinfo);
+ }
+
+ void tcp6_proc_exit(void)
+ {
+- tcp_proc_unregister(&tcp6_seq_afinfo);
++ tcp_proc_unregister(&init_net, &tcp6_seq_afinfo);
+ }
+ #endif
+
+diff -Nurb linux-2.6.22-570/net/ipv6/udp.c linux-2.6.22-590/net/ipv6/udp.c
+--- linux-2.6.22-570/net/ipv6/udp.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/ipv6/udp.c 2008-01-29 22:12:32.000000000 -0500
+@@ -657,6 +657,7 @@
+ ulen += sizeof(struct udphdr);
+
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+
+ if (sin6) {
+ if (sin6->sin6_port == 0)
+@@ -967,11 +968,11 @@
+
+ int __init udp6_proc_init(void)
+ {
+- return udp_proc_register(&udp6_seq_afinfo);
++ return udp_proc_register(&init_net, &udp6_seq_afinfo);
+ }
+
+ void udp6_proc_exit(void) {
+- udp_proc_unregister(&udp6_seq_afinfo);
++ udp_proc_unregister(&init_net, &udp6_seq_afinfo);
+ }
+ #endif /* CONFIG_PROC_FS */
+
+diff -Nurb linux-2.6.22-570/net/ipv6/udplite.c linux-2.6.22-590/net/ipv6/udplite.c
+--- linux-2.6.22-570/net/ipv6/udplite.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/udplite.c 2008-01-29 22:12:32.000000000 -0500
+@@ -95,11 +95,11 @@
+
+ int __init udplite6_proc_init(void)
+ {
+- return udp_proc_register(&udplite6_seq_afinfo);
++ return udp_proc_register(&init_net, &udplite6_seq_afinfo);
+ }
+
+ void udplite6_proc_exit(void)
+ {
+- udp_proc_unregister(&udplite6_seq_afinfo);
++ udp_proc_unregister(&init_net, &udplite6_seq_afinfo);
+ }
+ #endif
+diff -Nurb linux-2.6.22-570/net/ipv6/xfrm6_policy.c linux-2.6.22-590/net/ipv6/xfrm6_policy.c
+--- linux-2.6.22-570/net/ipv6/xfrm6_policy.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/ipv6/xfrm6_policy.c 2008-01-29 22:12:32.000000000 -0500
+@@ -18,7 +18,7 @@
+ #include <net/ip.h>
+ #include <net/ipv6.h>
+ #include <net/ip6_route.h>
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ #include <net/mip6.h>
+ #endif
+
+@@ -40,6 +40,7 @@
+ {
+ struct rt6_info *rt;
+ struct flowi fl_tunnel = {
++ .fl_net = &init_net,
+ .nl_u = {
+ .ip6_u = {
+ .daddr = *(struct in6_addr *)&daddr->a6,
+@@ -132,6 +133,7 @@
+ struct rt6_info *rt0 = (struct rt6_info*)(*dst_p);
+ struct rt6_info *rt = rt0;
+ struct flowi fl_tunnel = {
++ .fl_net = &init_net,
+ .nl_u = {
+ .ip6_u = {
+ .saddr = fl->fl6_src,
+@@ -278,6 +280,7 @@
+ u8 nexthdr = nh[IP6CB(skb)->nhoff];
+
+ memset(fl, 0, sizeof(struct flowi));
++ fl->fl_net = &init_net;
+ ipv6_addr_copy(&fl->fl6_dst, &hdr->daddr);
+ ipv6_addr_copy(&fl->fl6_src, &hdr->saddr);
+
+@@ -318,7 +321,7 @@
+ fl->proto = nexthdr;
+ return;
+
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ case IPPROTO_MH:
+ if (pskb_may_pull(skb, nh + offset + 3 - skb->data)) {
+ struct ip6_mh *mh;
+@@ -375,7 +378,7 @@
+
+ xdst = (struct xfrm_dst *)dst;
+ if (xdst->u.rt6.rt6i_idev->dev == dev) {
+- struct inet6_dev *loopback_idev = in6_dev_get(&loopback_dev);
++ struct inet6_dev *loopback_idev = in6_dev_get(&init_net.loopback_dev);
+ BUG_ON(!loopback_idev);
+
+ do {
+diff -Nurb linux-2.6.22-570/net/ipv6/xfrm6_state.c linux-2.6.22-590/net/ipv6/xfrm6_state.c
+--- linux-2.6.22-570/net/ipv6/xfrm6_state.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/xfrm6_state.c 2008-01-29 22:12:32.000000000 -0500
+@@ -65,7 +65,7 @@
+ goto end;
+
+ /* Rule 2: select MIPv6 RO or inbound trigger */
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ for (i = 0; i < n; i++) {
+ if (src[i] &&
+ (src[i]->props.mode == XFRM_MODE_ROUTEOPTIMIZATION ||
+@@ -130,7 +130,7 @@
+ goto end;
+
+ /* Rule 2: select MIPv6 RO or inbound trigger */
+-#ifdef CONFIG_IPV6_MIP6
++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+ for (i = 0; i < n; i++) {
+ if (src[i] &&
+ (src[i]->mode == XFRM_MODE_ROUTEOPTIMIZATION ||
+diff -Nurb linux-2.6.22-570/net/ipv6/xfrm6_tunnel.c linux-2.6.22-590/net/ipv6/xfrm6_tunnel.c
+--- linux-2.6.22-570/net/ipv6/xfrm6_tunnel.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipv6/xfrm6_tunnel.c 2008-01-29 22:12:32.000000000 -0500
+@@ -379,3 +379,4 @@
+ module_init(xfrm6_tunnel_init);
+ module_exit(xfrm6_tunnel_fini);
+ MODULE_LICENSE("GPL");
++MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_IPV6);
+diff -Nurb linux-2.6.22-570/net/ipx/af_ipx.c linux-2.6.22-590/net/ipx/af_ipx.c
+--- linux-2.6.22-570/net/ipx/af_ipx.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipx/af_ipx.c 2008-01-29 22:12:32.000000000 -0500
+@@ -347,6 +347,9 @@
+ struct net_device *dev = ptr;
+ struct ipx_interface *i, *tmp;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ if (event != NETDEV_DOWN && event != NETDEV_UP)
+ goto out;
+
+@@ -986,7 +989,7 @@
+ if (intrfc)
+ ipxitf_put(intrfc);
+
+- dev = dev_get_by_name(idef->ipx_device);
++ dev = dev_get_by_name(&init_net, idef->ipx_device);
+ rc = -ENODEV;
+ if (!dev)
+ goto out;
+@@ -1094,7 +1097,7 @@
+ if (!dlink_type)
+ goto out;
+
+- dev = __dev_get_by_name(idef->ipx_device);
++ dev = __dev_get_by_name(&init_net, idef->ipx_device);
+ rc = -ENODEV;
+ if (!dev)
+ goto out;
+@@ -1189,7 +1192,7 @@
+ if (copy_from_user(&ifr, arg, sizeof(ifr)))
+ break;
+ sipx = (struct sockaddr_ipx *)&ifr.ifr_addr;
+- dev = __dev_get_by_name(ifr.ifr_name);
++ dev = __dev_get_by_name(&init_net, ifr.ifr_name);
+ rc = -ENODEV;
+ if (!dev)
+ break;
+@@ -1360,11 +1363,14 @@
+ .obj_size = sizeof(struct ipx_sock),
+ };
+
+-static int ipx_create(struct socket *sock, int protocol)
++static int ipx_create(struct net *net, struct socket *sock, int protocol)
+ {
+ int rc = -ESOCKTNOSUPPORT;
+ struct sock *sk;
+
++ if (net != &init_net)
++ return -EAFNOSUPPORT;
++
+ /*
+ * SPX support is not anymore in the kernel sources. If you want to
+ * ressurrect it, completing it and making it understand shared skbs,
+@@ -1375,7 +1381,7 @@
+ goto out;
+
+ rc = -ENOMEM;
+- sk = sk_alloc(PF_IPX, GFP_KERNEL, &ipx_proto, 1);
++ sk = sk_alloc(net, PF_IPX, GFP_KERNEL, &ipx_proto, 1);
+ if (!sk)
+ goto out;
+ #ifdef IPX_REFCNT_DEBUG
+@@ -1644,6 +1650,9 @@
+ u16 ipx_pktsize;
+ int rc = 0;
+
++ if (dev->nd_net != &init_net)
++ goto drop;
++
+ /* Not ours */
+ if (skb->pkt_type == PACKET_OTHERHOST)
+ goto drop;
+diff -Nurb linux-2.6.22-570/net/ipx/ipx_proc.c linux-2.6.22-590/net/ipx/ipx_proc.c
+--- linux-2.6.22-570/net/ipx/ipx_proc.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/ipx/ipx_proc.c 2008-01-29 22:12:32.000000000 -0500
+@@ -9,6 +9,7 @@
+ #include <linux/proc_fs.h>
+ #include <linux/spinlock.h>
+ #include <linux/seq_file.h>
++#include <net/net_namespace.h>
+ #include <net/tcp_states.h>
+ #include <net/ipx.h>
+
+@@ -353,7 +354,7 @@
+ struct proc_dir_entry *p;
+ int rc = -ENOMEM;
+
+- ipx_proc_dir = proc_mkdir("ipx", proc_net);
++ ipx_proc_dir = proc_mkdir("ipx", init_net.proc_net);
+
+ if (!ipx_proc_dir)
+ goto out;
+@@ -381,7 +382,7 @@
+ out_route:
+ remove_proc_entry("interface", ipx_proc_dir);
+ out_interface:
+- remove_proc_entry("ipx", proc_net);
++ remove_proc_entry("ipx", init_net.proc_net);
+ goto out;
+ }
+
+@@ -390,7 +391,7 @@
+ remove_proc_entry("interface", ipx_proc_dir);
+ remove_proc_entry("route", ipx_proc_dir);
+ remove_proc_entry("socket", ipx_proc_dir);
+- remove_proc_entry("ipx", proc_net);
++ remove_proc_entry("ipx", init_net.proc_net);
+ }
+
+ #else /* CONFIG_PROC_FS */
+diff -Nurb linux-2.6.22-570/net/irda/af_irda.c linux-2.6.22-590/net/irda/af_irda.c
+--- linux-2.6.22-570/net/irda/af_irda.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/irda/af_irda.c 2008-01-29 22:12:32.000000000 -0500
+@@ -60,7 +60,7 @@
+
+ #include <net/irda/af_irda.h>
+
+-static int irda_create(struct socket *sock, int protocol);
++static int irda_create(struct net *net, struct socket *sock, int protocol);
+
+ static const struct proto_ops irda_stream_ops;
+ static const struct proto_ops irda_seqpacket_ops;
+@@ -831,7 +831,7 @@
+
+ IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
+
+- err = irda_create(newsock, sk->sk_protocol);
++ err = irda_create(sk->sk_net, newsock, sk->sk_protocol);
+ if (err)
+ return err;
+
+@@ -1057,13 +1057,16 @@
+ * Create IrDA socket
+ *
+ */
+-static int irda_create(struct socket *sock, int protocol)
++static int irda_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct sock *sk;
+ struct irda_sock *self;
+
+ IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
+
++ if (net != &init_net)
++ return -EAFNOSUPPORT;
++
+ /* Check for valid socket type */
+ switch (sock->type) {
+ case SOCK_STREAM: /* For TTP connections with SAR disabled */
+@@ -1075,7 +1078,7 @@
+ }
+
+ /* Allocate networking socket */
+- sk = sk_alloc(PF_IRDA, GFP_ATOMIC, &irda_proto, 1);
++ sk = sk_alloc(net, PF_IRDA, GFP_ATOMIC, &irda_proto, 1);
+ if (sk == NULL)
+ return -ENOMEM;
+
+diff -Nurb linux-2.6.22-570/net/irda/irias_object.c linux-2.6.22-590/net/irda/irias_object.c
+--- linux-2.6.22-570/net/irda/irias_object.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/irda/irias_object.c 2008-01-29 22:12:32.000000000 -0500
+@@ -36,39 +36,6 @@
+ */
+ struct ias_value irias_missing = { IAS_MISSING, 0, 0, 0, {0}};
+
+-/*
+- * Function strndup (str, max)
+- *
+- * My own kernel version of strndup!
+- *
+- * Faster, check boundary... Jean II
+- */
+-static char *strndup(char *str, size_t max)
+-{
+- char *new_str;
+- int len;
+-
+- /* Check string */
+- if (str == NULL)
+- return NULL;
+- /* Check length, truncate */
+- len = strlen(str);
+- if(len > max)
+- len = max;
+-
+- /* Allocate new string */
+- new_str = kmalloc(len + 1, GFP_ATOMIC);
+- if (new_str == NULL) {
+- IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
+- return NULL;
+- }
+-
+- /* Copy and truncate */
+- memcpy(new_str, str, len);
+- new_str[len] = '\0';
+-
+- return new_str;
+-}
+
+ /*
+ * Function ias_new_object (name, id)
+@@ -90,7 +57,7 @@
+ }
+
+ obj->magic = IAS_OBJECT_MAGIC;
+- obj->name = strndup(name, IAS_MAX_CLASSNAME);
++ obj->name = kstrndup(name, IAS_MAX_CLASSNAME, GFP_ATOMIC);
+ if (!obj->name) {
+ IRDA_WARNING("%s(), Unable to allocate name!\n",
+ __FUNCTION__);
+@@ -360,7 +327,7 @@
+ }
+
+ attrib->magic = IAS_ATTRIB_MAGIC;
+- attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
++ attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME, GFP_ATOMIC);
+
+ /* Insert value */
+ attrib->value = irias_new_integer_value(value);
+@@ -404,7 +371,7 @@
+ }
+
+ attrib->magic = IAS_ATTRIB_MAGIC;
+- attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
++ attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME, GFP_ATOMIC);
+
+ attrib->value = irias_new_octseq_value( octets, len);
+ if (!attrib->name || !attrib->value) {
+@@ -446,7 +413,7 @@
+ }
+
+ attrib->magic = IAS_ATTRIB_MAGIC;
+- attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
++ attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME, GFP_ATOMIC);
+
+ attrib->value = irias_new_string_value(value);
+ if (!attrib->name || !attrib->value) {
+@@ -506,7 +473,7 @@
+
+ value->type = IAS_STRING;
+ value->charset = CS_ASCII;
+- value->t.string = strndup(string, IAS_MAX_STRING);
++ value->t.string = kstrndup(string, IAS_MAX_STRING, GFP_ATOMIC);
+ if (!value->t.string) {
+ IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
+ kfree(value);
+diff -Nurb linux-2.6.22-570/net/irda/irlap_frame.c linux-2.6.22-590/net/irda/irlap_frame.c
+--- linux-2.6.22-570/net/irda/irlap_frame.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/irda/irlap_frame.c 2008-01-29 22:12:32.000000000 -0500
+@@ -1319,6 +1319,9 @@
+ int command;
+ __u8 control;
+
++ if (dev->nd_net != &init_net)
++ goto out;
++
+ /* FIXME: should we get our own field? */
+ self = (struct irlap_cb *) dev->atalk_ptr;
+
+diff -Nurb linux-2.6.22-570/net/irda/irproc.c linux-2.6.22-590/net/irda/irproc.c
+--- linux-2.6.22-570/net/irda/irproc.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/irda/irproc.c 2008-01-29 22:12:32.000000000 -0500
+@@ -28,6 +28,7 @@
+ #include <linux/seq_file.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
++#include <net/net_namespace.h>
+
+ #include <net/irda/irda.h>
+ #include <net/irda/irlap.h>
+@@ -66,7 +67,7 @@
+ int i;
+ struct proc_dir_entry *d;
+
+- proc_irda = proc_mkdir("irda", proc_net);
++ proc_irda = proc_mkdir("irda", init_net.proc_net);
+ if (proc_irda == NULL)
+ return;
+ proc_irda->owner = THIS_MODULE;
+@@ -92,7 +93,7 @@
+ for (i=0; i<ARRAY_SIZE(irda_dirs); i++)
+ remove_proc_entry(irda_dirs[i].name, proc_irda);
+
+- remove_proc_entry("irda", proc_net);
++ remove_proc_entry("irda", init_net.proc_net);
+ proc_irda = NULL;
+ }
+ }
+diff -Nurb linux-2.6.22-570/net/key/af_key.c linux-2.6.22-590/net/key/af_key.c
+--- linux-2.6.22-570/net/key/af_key.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/key/af_key.c 2008-01-29 22:12:32.000000000 -0500
+@@ -28,6 +28,7 @@
+ #include <linux/init.h>
+ #include <net/xfrm.h>
+ #include <linux/audit.h>
++#include <net/net_namespace.h>
+
+ #include <net/sock.h>
+
+@@ -136,11 +137,14 @@
+ .obj_size = sizeof(struct pfkey_sock),
+ };
+
+-static int pfkey_create(struct socket *sock, int protocol)
++static int pfkey_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct sock *sk;
+ int err;
+
++ if (net != &init_net)
++ return -EAFNOSUPPORT;
++
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ if (sock->type != SOCK_RAW)
+@@ -149,7 +153,7 @@
+ return -EPROTONOSUPPORT;
+
+ err = -ENOMEM;
+- sk = sk_alloc(PF_KEY, GFP_KERNEL, &key_proto, 1);
++ sk = sk_alloc(net, PF_KEY, GFP_KERNEL, &key_proto, 1);
+ if (sk == NULL)
+ goto out;
+
+@@ -3781,7 +3785,7 @@
+ static void __exit ipsec_pfkey_exit(void)
+ {
+ xfrm_unregister_km(&pfkeyv2_mgr);
+- remove_proc_entry("net/pfkey", NULL);
++ remove_proc_entry("pfkey", init_net.proc_net);
+ sock_unregister(PF_KEY);
+ proto_unregister(&key_proto);
+ }
+@@ -3798,7 +3802,7 @@
+ goto out_unregister_key_proto;
+ #ifdef CONFIG_PROC_FS
+ err = -ENOMEM;
+- if (create_proc_read_entry("net/pfkey", 0, NULL, pfkey_read_proc, NULL) == NULL)
++ if (create_proc_read_entry("pfkey", 0, init_net.proc_net, pfkey_read_proc, NULL) == NULL)
+ goto out_sock_unregister;
+ #endif
+ err = xfrm_register_km(&pfkeyv2_mgr);
+diff -Nurb linux-2.6.22-570/net/llc/af_llc.c linux-2.6.22-590/net/llc/af_llc.c
+--- linux-2.6.22-570/net/llc/af_llc.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/llc/af_llc.c 2008-01-29 22:12:32.000000000 -0500
+@@ -150,14 +150,17 @@
+ * socket type we have available.
+ * Returns 0 upon success, negative upon failure.
+ */
+-static int llc_ui_create(struct socket *sock, int protocol)
++static int llc_ui_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct sock *sk;
+ int rc = -ESOCKTNOSUPPORT;
+
++ if (net != &init_net)
++ return -EAFNOSUPPORT;
++
+ if (likely(sock->type == SOCK_DGRAM || sock->type == SOCK_STREAM)) {
+ rc = -ENOMEM;
+- sk = llc_sk_alloc(PF_LLC, GFP_KERNEL, &llc_proto);
++ sk = llc_sk_alloc(net, PF_LLC, GFP_KERNEL, &llc_proto);
+ if (sk) {
+ rc = 0;
+ llc_ui_sk_init(sock, sk);
+@@ -249,7 +252,7 @@
+ if (!sock_flag(sk, SOCK_ZAPPED))
+ goto out;
+ rc = -ENODEV;
+- llc->dev = dev_getfirstbyhwtype(addr->sllc_arphrd);
++ llc->dev = dev_getfirstbyhwtype(&init_net, addr->sllc_arphrd);
+ if (!llc->dev)
+ goto out;
+ rc = -EUSERS;
+@@ -300,7 +303,7 @@
+ goto out;
+ rc = -ENODEV;
+ rtnl_lock();
+- llc->dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_mac);
++ llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd, addr->sllc_mac);
+ rtnl_unlock();
+ if (!llc->dev)
+ goto out;
+diff -Nurb linux-2.6.22-570/net/llc/llc_conn.c linux-2.6.22-590/net/llc/llc_conn.c
+--- linux-2.6.22-570/net/llc/llc_conn.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/llc/llc_conn.c 2008-01-29 22:12:32.000000000 -0500
+@@ -700,7 +700,7 @@
+ struct llc_addr *saddr,
+ struct llc_addr *daddr)
+ {
+- struct sock *newsk = llc_sk_alloc(sk->sk_family, GFP_ATOMIC,
++ struct sock *newsk = llc_sk_alloc(sk->sk_net, sk->sk_family, GFP_ATOMIC,
+ sk->sk_prot);
+ struct llc_sock *newllc, *llc = llc_sk(sk);
+
+@@ -867,9 +867,9 @@
+ * Allocates a LLC sock and initializes it. Returns the new LLC sock
+ * or %NULL if there's no memory available for one
+ */
+-struct sock *llc_sk_alloc(int family, gfp_t priority, struct proto *prot)
++struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority, struct proto *prot)
+ {
+- struct sock *sk = sk_alloc(family, priority, prot, 1);
++ struct sock *sk = sk_alloc(net, family, priority, prot, 1);
+
+ if (!sk)
+ goto out;
+diff -Nurb linux-2.6.22-570/net/llc/llc_core.c linux-2.6.22-590/net/llc/llc_core.c
+--- linux-2.6.22-570/net/llc/llc_core.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/llc/llc_core.c 2008-01-29 22:12:32.000000000 -0500
+@@ -19,6 +19,7 @@
+ #include <linux/slab.h>
+ #include <linux/string.h>
+ #include <linux/init.h>
++#include <net/net_namespace.h>
+ #include <net/llc.h>
+
+ LIST_HEAD(llc_sap_list);
+@@ -162,7 +163,8 @@
+ {
+ struct net_device *dev;
+
+- dev = first_net_device();
++ /* XXX sapan
++ dev = first_net_device(&init_net);
+ if (dev != NULL)
+ dev = next_net_device(dev);
+
+@@ -172,6 +174,7 @@
+ memset(llc_station_mac_sa, 0, ETH_ALEN);
+ dev_add_pack(&llc_packet_type);
+ dev_add_pack(&llc_tr_packet_type);
++ */
+ return 0;
+ }
+
+diff -Nurb linux-2.6.22-570/net/llc/llc_input.c linux-2.6.22-590/net/llc/llc_input.c
+--- linux-2.6.22-570/net/llc/llc_input.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/llc/llc_input.c 2008-01-29 22:12:32.000000000 -0500
+@@ -12,6 +12,7 @@
+ * See the GNU General Public License for more details.
+ */
+ #include <linux/netdevice.h>
++#include <net/net_namespace.h>
+ #include <net/llc.h>
+ #include <net/llc_pdu.h>
+ #include <net/llc_sap.h>
+@@ -145,6 +146,9 @@
+ int (*rcv)(struct sk_buff *, struct net_device *,
+ struct packet_type *, struct net_device *);
+
++ if (dev->nd_net != &init_net)
++ goto drop;
++
+ /*
+ * When the interface is in promisc. mode, drop all the crap that it
+ * receives, do not try to analyse it.
+diff -Nurb linux-2.6.22-570/net/llc/llc_proc.c linux-2.6.22-590/net/llc/llc_proc.c
+--- linux-2.6.22-570/net/llc/llc_proc.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/llc/llc_proc.c 2008-01-29 22:12:32.000000000 -0500
+@@ -18,6 +18,7 @@
+ #include <linux/errno.h>
+ #include <linux/seq_file.h>
+ #include <net/sock.h>
++#include <net/net_namespace.h>
+ #include <net/llc.h>
+ #include <net/llc_c_ac.h>
+ #include <net/llc_c_ev.h>
+@@ -231,7 +232,7 @@
+ int rc = -ENOMEM;
+ struct proc_dir_entry *p;
+
+- llc_proc_dir = proc_mkdir("llc", proc_net);
++ llc_proc_dir = proc_mkdir("llc", init_net.proc_net);
+ if (!llc_proc_dir)
+ goto out;
+ llc_proc_dir->owner = THIS_MODULE;
+@@ -254,7 +255,7 @@
+ out_core:
+ remove_proc_entry("socket", llc_proc_dir);
+ out_socket:
+- remove_proc_entry("llc", proc_net);
++ remove_proc_entry("llc", init_net.proc_net);
+ goto out;
+ }
+
+@@ -262,5 +263,5 @@
+ {
+ remove_proc_entry("socket", llc_proc_dir);
+ remove_proc_entry("core", llc_proc_dir);
+- remove_proc_entry("llc", proc_net);
++ remove_proc_entry("llc", init_net.proc_net);
+ }
+diff -Nurb linux-2.6.22-570/net/mac80211/ieee80211_ioctl.c linux-2.6.22-590/net/mac80211/ieee80211_ioctl.c
+--- linux-2.6.22-570/net/mac80211/ieee80211_ioctl.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/mac80211/ieee80211_ioctl.c 2008-01-29 22:12:32.000000000 -0500
+@@ -838,6 +838,29 @@
+ }
+
+
++static int ieee80211_ioctl_giwrate(struct net_device *dev,
++ struct iw_request_info *info,
++ struct iw_param *rate, char *extra)
++{
++ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
++ struct sta_info *sta;
++ struct ieee80211_sub_if_data *sdata;
++
++ sdata = IEEE80211_DEV_TO_SUB_IF(dev);
++ if (sdata->type == IEEE80211_IF_TYPE_STA)
++ sta = sta_info_get(local, sdata->u.sta.bssid);
++ else
++ return -EOPNOTSUPP;
++ if (!sta)
++ return -ENODEV;
++ if (sta->txrate < local->oper_hw_mode->num_rates)
++ rate->value = local->oper_hw_mode->rates[sta->txrate].rate * 100000;
++ else
++ rate->value = 0;
++ sta_info_put(sta);
++ return 0;
++}
++
+ static int ieee80211_ioctl_siwrts(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
+@@ -1779,7 +1802,7 @@
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* SIOCSIWRATE */
+- (iw_handler) NULL, /* SIOCGIWRATE */
++ (iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */
+ (iw_handler) ieee80211_ioctl_siwrts, /* SIOCSIWRTS */
+ (iw_handler) ieee80211_ioctl_giwrts, /* SIOCGIWRTS */
+ (iw_handler) ieee80211_ioctl_siwfrag, /* SIOCSIWFRAG */
+diff -Nurb linux-2.6.22-570/net/netfilter/core.c linux-2.6.22-590/net/netfilter/core.c
+--- linux-2.6.22-570/net/netfilter/core.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/netfilter/core.c 2008-01-29 22:12:32.000000000 -0500
+@@ -20,6 +20,7 @@
+ #include <linux/proc_fs.h>
+ #include <linux/mutex.h>
+ #include <net/sock.h>
++#include <net/net_namespace.h>
+
+ #include "nf_internals.h"
+
+@@ -203,7 +204,9 @@
+ return 0;
+
+ /* Not exclusive use of packet? Must copy. */
+- if (skb_shared(*pskb) || skb_cloned(*pskb))
++ if (skb_cloned(*pskb) && !skb_clone_writable(*pskb, writable_len))
++ goto copy_skb;
++ if (skb_shared(*pskb))
+ goto copy_skb;
+
+ return pskb_may_pull(*pskb, writable_len);
+@@ -278,8 +281,28 @@
+ #endif /* CONFIG_NF_CONNTRACK */
+
+ #ifdef CONFIG_PROC_FS
+-struct proc_dir_entry *proc_net_netfilter;
+-EXPORT_SYMBOL(proc_net_netfilter);
++static int netfilter_proc_init(struct net * net)
++{
++ int error = -ENOMEM;
++ net->proc_net_netfilter = proc_mkdir("netfilter", net->proc_net);
++
++ if (net->proc_net_netfilter) {
++ net->proc_net_netfilter->data = net;
++ error = 0;
++ }
++ return error;
++}
++
++static void netfilter_proc_exit(struct net *net)
++{
++ remove_proc_entry("netfilter", net->proc_net);
++}
++
++static struct pernet_operations netfilter_proc_ops = {
++ .init = netfilter_proc_init,
++ .exit = netfilter_proc_exit,
++};
++
+ #endif
+
+ void __init netfilter_init(void)
+@@ -291,8 +314,7 @@
+ }
+
+ #ifdef CONFIG_PROC_FS
+- proc_net_netfilter = proc_mkdir("netfilter", proc_net);
+- if (!proc_net_netfilter)
++ if (register_pernet_subsys(&netfilter_proc_ops) < 0)
+ panic("cannot create netfilter proc entry");
+ #endif
+
+diff -Nurb linux-2.6.22-570/net/netfilter/nf_conntrack_h323_main.c linux-2.6.22-590/net/netfilter/nf_conntrack_h323_main.c
+--- linux-2.6.22-570/net/netfilter/nf_conntrack_h323_main.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/netfilter/nf_conntrack_h323_main.c 2008-01-29 22:12:32.000000000 -0500
+@@ -724,6 +724,8 @@
+
+ memset(&fl1, 0, sizeof(fl1));
+ memset(&fl2, 0, sizeof(fl2));
++ fl1.fl_net = &init_net;
++ fl2.fl_net = &init_net;
+
+ switch (family) {
+ case AF_INET: {
+diff -Nurb linux-2.6.22-570/net/netfilter/nf_conntrack_standalone.c linux-2.6.22-590/net/netfilter/nf_conntrack_standalone.c
+--- linux-2.6.22-570/net/netfilter/nf_conntrack_standalone.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/netfilter/nf_conntrack_standalone.c 2008-01-29 22:12:32.000000000 -0500
+@@ -14,6 +14,7 @@
+ #include <linux/seq_file.h>
+ #include <linux/percpu.h>
+ #include <linux/netdevice.h>
++#include <net/net_namespace.h>
+ #ifdef CONFIG_SYSCTL
+ #include <linux/sysctl.h>
+ #endif
+@@ -419,14 +420,14 @@
+ return ret;
+
+ #ifdef CONFIG_PROC_FS
+- proc = proc_net_fops_create("nf_conntrack", 0440, &ct_file_ops);
++ proc = proc_net_fops_create(&init_net, "nf_conntrack", 0440, &ct_file_ops);
+ if (!proc) goto cleanup_init;
+
+- proc_exp = proc_net_fops_create("nf_conntrack_expect", 0440,
++ proc_exp = proc_net_fops_create(&init_net, "nf_conntrack_expect", 0440,
+ &exp_file_ops);
+ if (!proc_exp) goto cleanup_proc;
+
+- proc_stat = create_proc_entry("nf_conntrack", S_IRUGO, proc_net_stat);
++ proc_stat = create_proc_entry("nf_conntrack", S_IRUGO, init_net.proc_net_stat);
+ if (!proc_stat)
+ goto cleanup_proc_exp;
+
+@@ -447,11 +448,11 @@
+ cleanup_proc_stat:
+ #endif
+ #ifdef CONFIG_PROC_FS
+- remove_proc_entry("nf_conntrack", proc_net_stat);
++ remove_proc_entry("nf_conntrack", init_net.proc_net_stat);
+ cleanup_proc_exp:
+- proc_net_remove("nf_conntrack_expect");
++ proc_net_remove(&init_net, "nf_conntrack_expect");
+ cleanup_proc:
+- proc_net_remove("nf_conntrack");
++ proc_net_remove(&init_net, "nf_conntrack");
+ cleanup_init:
+ #endif /* CNFIG_PROC_FS */
+ nf_conntrack_cleanup();
+@@ -464,9 +465,9 @@
+ unregister_sysctl_table(nf_ct_sysctl_header);
+ #endif
+ #ifdef CONFIG_PROC_FS
+- remove_proc_entry("nf_conntrack", proc_net_stat);
+- proc_net_remove("nf_conntrack_expect");
+- proc_net_remove("nf_conntrack");
++ remove_proc_entry("nf_conntrack", init_net.proc_net_stat);
++ proc_net_remove(&init_net, "nf_conntrack_expect");
++ proc_net_remove(&init_net, "nf_conntrack");
+ #endif /* CNFIG_PROC_FS */
+ nf_conntrack_cleanup();
+ }
+diff -Nurb linux-2.6.22-570/net/netfilter/nf_log.c linux-2.6.22-590/net/netfilter/nf_log.c
+--- linux-2.6.22-570/net/netfilter/nf_log.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/netfilter/nf_log.c 2008-01-29 22:12:32.000000000 -0500
+@@ -168,7 +168,8 @@
+ #ifdef CONFIG_PROC_FS
+ struct proc_dir_entry *pde;
+
+- pde = create_proc_entry("nf_log", S_IRUGO, proc_net_netfilter);
++ pde = create_proc_entry("nf_log", S_IRUGO,
++ init_net.proc_net_netfilter);
+ if (!pde)
+ return -1;
+
+diff -Nurb linux-2.6.22-570/net/netfilter/nf_queue.c linux-2.6.22-590/net/netfilter/nf_queue.c
+--- linux-2.6.22-570/net/netfilter/nf_queue.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/netfilter/nf_queue.c 2008-01-29 22:12:32.000000000 -0500
+@@ -346,7 +346,7 @@
+ #ifdef CONFIG_PROC_FS
+ struct proc_dir_entry *pde;
+
+- pde = create_proc_entry("nf_queue", S_IRUGO, proc_net_netfilter);
++ pde = create_proc_entry("nf_queue", S_IRUGO, init_net.proc_net_netfilter);
+ if (!pde)
+ return -1;
+ pde->proc_fops = &nfqueue_file_ops;
+diff -Nurb linux-2.6.22-570/net/netfilter/nfnetlink.c linux-2.6.22-590/net/netfilter/nfnetlink.c
+--- linux-2.6.22-570/net/netfilter/nfnetlink.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/netfilter/nfnetlink.c 2008-01-29 22:12:32.000000000 -0500
+@@ -264,7 +264,7 @@
+ {
+ printk("Netfilter messages via NETLINK v%s.\n", nfversion);
+
+- nfnl = netlink_kernel_create(NETLINK_NETFILTER, NFNLGRP_MAX,
++ nfnl = netlink_kernel_create(&init_net, NETLINK_NETFILTER, NFNLGRP_MAX,
+ nfnetlink_rcv, NULL, THIS_MODULE);
+ if (!nfnl) {
+ printk(KERN_ERR "cannot initialize nfnetlink!\n");
+diff -Nurb linux-2.6.22-570/net/netfilter/nfnetlink_log.c linux-2.6.22-590/net/netfilter/nfnetlink_log.c
+--- linux-2.6.22-570/net/netfilter/nfnetlink_log.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/netfilter/nfnetlink_log.c 2008-01-29 22:12:32.000000000 -0500
+@@ -705,7 +705,8 @@
+
+ hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) {
+ UDEBUG("node = %p\n", inst);
+- if (n->pid == inst->peer_pid)
++ if ((n->net == &init_net) &&
++ (n->pid == inst->peer_pid))
+ __instance_destroy(inst);
+ }
+ }
+@@ -1023,7 +1024,7 @@
+
+ #ifdef CONFIG_PROC_FS
+ proc_nful = create_proc_entry("nfnetlink_log", 0440,
+- proc_net_netfilter);
++ init_net.proc_net_netfilter);
+ if (!proc_nful)
+ goto cleanup_subsys;
+ proc_nful->proc_fops = &nful_file_ops;
+@@ -1043,7 +1044,7 @@
+ {
+ nf_log_unregister(&nfulnl_logger);
+ #ifdef CONFIG_PROC_FS
+- remove_proc_entry("nfnetlink_log", proc_net_netfilter);
++ remove_proc_entry("nfnetlink_log", init_net.proc_net_netfilter);
+ #endif
+ nfnetlink_subsys_unregister(&nfulnl_subsys);
+ netlink_unregister_notifier(&nfulnl_rtnl_notifier);
+diff -Nurb linux-2.6.22-570/net/netfilter/nfnetlink_queue.c linux-2.6.22-590/net/netfilter/nfnetlink_queue.c
+--- linux-2.6.22-570/net/netfilter/nfnetlink_queue.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/netfilter/nfnetlink_queue.c 2008-01-29 22:12:32.000000000 -0500
+@@ -734,6 +734,9 @@
+ {
+ struct net_device *dev = ptr;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ /* Drop any packets associated with the downed device */
+ if (event == NETDEV_DOWN)
+ nfqnl_dev_drop(dev->ifindex);
+@@ -762,7 +765,8 @@
+ struct hlist_head *head = &instance_table[i];
+
+ hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) {
+- if (n->pid == inst->peer_pid)
++ if ((n->net == &init_net) &&
++ (n->pid == inst->peer_pid))
+ __instance_destroy(inst);
+ }
+ }
+@@ -1106,7 +1110,7 @@
+
+ #ifdef CONFIG_PROC_FS
+ proc_nfqueue = create_proc_entry("nfnetlink_queue", 0440,
+- proc_net_netfilter);
++ init_net.proc_net_netfilter);
+ if (!proc_nfqueue)
+ goto cleanup_subsys;
+ proc_nfqueue->proc_fops = &nfqnl_file_ops;
+@@ -1129,7 +1133,7 @@
+ nf_unregister_queue_handlers(&nfqh);
+ unregister_netdevice_notifier(&nfqnl_dev_notifier);
+ #ifdef CONFIG_PROC_FS
+- remove_proc_entry("nfnetlink_queue", proc_net_netfilter);
++ remove_proc_entry("nfnetlink_queue", init_net.proc_net_netfilter);
+ #endif
+ nfnetlink_subsys_unregister(&nfqnl_subsys);
+ netlink_unregister_notifier(&nfqnl_rtnl_notifier);
+diff -Nurb linux-2.6.22-570/net/netfilter/x_tables.c linux-2.6.22-590/net/netfilter/x_tables.c
+--- linux-2.6.22-570/net/netfilter/x_tables.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/netfilter/x_tables.c 2008-01-29 22:12:32.000000000 -0500
+@@ -22,6 +22,7 @@
+ #include <linux/vmalloc.h>
+ #include <linux/mutex.h>
+ #include <linux/mm.h>
++#include <net/net_namespace.h>
+
+ #include <linux/netfilter/x_tables.h>
+ #include <linux/netfilter_arp.h>
+@@ -37,11 +38,16 @@
+ struct mutex mutex;
+ struct list_head match;
+ struct list_head target;
+- struct list_head tables;
+ struct mutex compat_mutex;
+ };
+
+-static struct xt_af *xt;
++
++struct xt_af_pernet {
++ struct list_head tables;
++};
++
++static struct xt_af * xt;
++
+
+ #ifdef DEBUG_IP_FIREWALL_USER
+ #define duprintf(format, args...) printk(format , ## args)
+@@ -286,9 +292,9 @@
+ return 1;
+ }
+ if (target == 1)
+- have_rev = target_revfn(af, name, revision, &best);
++ have_rev = target_revfn( af, name, revision, &best);
+ else
+- have_rev = match_revfn(af, name, revision, &best);
++ have_rev = match_revfn( af, name, revision, &best);
+ mutex_unlock(&xt[af].mutex);
+
+ /* Nothing at all? Return 0 to try loading module. */
+@@ -533,14 +539,14 @@
+ EXPORT_SYMBOL(xt_free_table_info);
+
+ /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */
+-struct xt_table *xt_find_table_lock(int af, const char *name)
++struct xt_table *xt_find_table_lock(struct net *net, int af, const char *name)
+ {
+ struct xt_table *t;
+
+ if (mutex_lock_interruptible(&xt[af].mutex) != 0)
+ return ERR_PTR(-EINTR);
+
+- list_for_each_entry(t, &xt[af].tables, list)
++ list_for_each_entry(t, &net->xtn[af].tables, list)
+ if (strcmp(t->name, name) == 0 && try_module_get(t->me))
+ return t;
+ mutex_unlock(&xt[af].mutex);
+@@ -596,7 +602,7 @@
+ }
+ EXPORT_SYMBOL_GPL(xt_replace_table);
+
+-int xt_register_table(struct xt_table *table,
++int xt_register_table(struct net *net, struct xt_table *table,
+ struct xt_table_info *bootstrap,
+ struct xt_table_info *newinfo)
+ {
+@@ -609,7 +615,7 @@
+ return ret;
+
+ /* Don't autoload: we'd eat our tail... */
+- list_for_each_entry(t, &xt[table->af].tables, list) {
++ list_for_each_entry(t, &net->xtn[table->af].tables, list) {
+ if (strcmp(t->name, table->name) == 0) {
+ ret = -EEXIST;
+ goto unlock;
+@@ -628,7 +634,7 @@
+ /* save number of initial entries */
+ private->initial_entries = private->number;
+
+- list_add(&table->list, &xt[table->af].tables);
++ list_add(&table->list, &net->xtn[table->af].tables);
+
+ ret = 0;
+ unlock:
+@@ -666,7 +672,7 @@
+ return pos ? NULL : head;
+ }
+
+-static struct list_head *type2list(u_int16_t af, u_int16_t type)
++static struct list_head *type2list(struct net *net, u_int16_t af, u_int16_t type)
+ {
+ struct list_head *list;
+
+@@ -678,7 +684,7 @@
+ list = &xt[af].match;
+ break;
+ case TABLE:
+- list = &xt[af].tables;
++ list = &net->xtn[af].tables;
+ break;
+ default:
+ list = NULL;
+@@ -691,6 +697,7 @@
+ static void *xt_tgt_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+ struct proc_dir_entry *pde = (struct proc_dir_entry *) seq->private;
++ struct net *net = PDE_NET(pde);
+ u_int16_t af = (unsigned long)pde->data & 0xffff;
+ u_int16_t type = (unsigned long)pde->data >> 16;
+ struct list_head *list;
+@@ -698,7 +705,7 @@
+ if (af >= NPROTO)
+ return NULL;
+
+- list = type2list(af, type);
++ list = type2list(net, af, type);
+ if (!list)
+ return NULL;
+
+@@ -711,6 +718,7 @@
+ static void *xt_tgt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+ struct proc_dir_entry *pde = seq->private;
++ struct net *net = PDE_NET(pde);
+ u_int16_t af = (unsigned long)pde->data & 0xffff;
+ u_int16_t type = (unsigned long)pde->data >> 16;
+ struct list_head *list;
+@@ -718,7 +726,7 @@
+ if (af >= NPROTO)
+ return NULL;
+
+- list = type2list(af, type);
++ list = type2list(net, af, type);
+ if (!list)
+ return NULL;
+
+@@ -759,6 +767,7 @@
+ if (!ret) {
+ struct seq_file *seq = file->private_data;
+ struct proc_dir_entry *pde = PDE(inode);
++ get_net(PROC_NET(inode));
+
+ seq->private = pde;
+ }
+@@ -766,12 +775,18 @@
+ return ret;
+ }
+
++static int xt_tgt_release(struct inode *inode, struct file *file)
++{
++ put_net(PROC_NET(inode));
++ return seq_release(inode, file);
++}
++
+ static const struct file_operations xt_file_ops = {
+ .owner = THIS_MODULE,
+ .open = xt_tgt_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+- .release = seq_release,
++ .release = xt_tgt_release,
+ };
+
+ #define FORMAT_TABLES "_tables_names"
+@@ -794,7 +809,7 @@
+ #ifdef CONFIG_PROC_FS
+ strlcpy(buf, xt_prefix[af], sizeof(buf));
+ strlcat(buf, FORMAT_TABLES, sizeof(buf));
+- proc = proc_net_fops_create(buf, 0440, &xt_file_ops);
++ proc = proc_net_fops_create(&init_net, buf, 0440, &xt_file_ops);
+ if (!proc)
+ goto out;
+ proc->data = (void *) ((unsigned long) af | (TABLE << 16));
+@@ -802,14 +817,14 @@
+
+ strlcpy(buf, xt_prefix[af], sizeof(buf));
+ strlcat(buf, FORMAT_MATCHES, sizeof(buf));
+- proc = proc_net_fops_create(buf, 0440, &xt_file_ops);
++ proc = proc_net_fops_create(&init_net, buf, 0440, &xt_file_ops);
+ if (!proc)
+ goto out_remove_tables;
+ proc->data = (void *) ((unsigned long) af | (MATCH << 16));
+
+ strlcpy(buf, xt_prefix[af], sizeof(buf));
+ strlcat(buf, FORMAT_TARGETS, sizeof(buf));
+- proc = proc_net_fops_create(buf, 0440, &xt_file_ops);
++ proc = proc_net_fops_create(&init_net, buf, 0440, &xt_file_ops);
+ if (!proc)
+ goto out_remove_matches;
+ proc->data = (void *) ((unsigned long) af | (TARGET << 16));
+@@ -821,12 +836,12 @@
+ out_remove_matches:
+ strlcpy(buf, xt_prefix[af], sizeof(buf));
+ strlcat(buf, FORMAT_MATCHES, sizeof(buf));
+- proc_net_remove(buf);
++ proc_net_remove(&init_net, buf);
+
+ out_remove_tables:
+ strlcpy(buf, xt_prefix[af], sizeof(buf));
+ strlcat(buf, FORMAT_TABLES, sizeof(buf));
+- proc_net_remove(buf);
++ proc_net_remove(&init_net, buf);
+ out:
+ return -1;
+ #endif
+@@ -840,19 +855,42 @@
+
+ strlcpy(buf, xt_prefix[af], sizeof(buf));
+ strlcat(buf, FORMAT_TABLES, sizeof(buf));
+- proc_net_remove(buf);
++ proc_net_remove(&init_net, buf);
+
+ strlcpy(buf, xt_prefix[af], sizeof(buf));
+ strlcat(buf, FORMAT_TARGETS, sizeof(buf));
+- proc_net_remove(buf);
++ proc_net_remove(&init_net, buf);
+
+ strlcpy(buf, xt_prefix[af], sizeof(buf));
+ strlcat(buf, FORMAT_MATCHES, sizeof(buf));
+- proc_net_remove(buf);
++ proc_net_remove(&init_net, buf);
+ #endif /*CONFIG_PROC_FS*/
+ }
+ EXPORT_SYMBOL_GPL(xt_proto_fini);
+
++static int xt_net_init(struct net *net)
++{
++ int i;
++
++ net->xtn = kmalloc(sizeof(struct xt_af_pernet) * NPROTO, GFP_KERNEL);
++ if (!net->xtn)
++ return -ENOMEM;
++
++ for (i = 0; i < NPROTO; i++) {
++ INIT_LIST_HEAD(&net->xtn[i].tables);
++ }
++ return 0;
++}
++
++static void xt_net_exit(struct net *net)
++{
++ kfree(net->xtn);
++}
++
++static struct pernet_operations xt_net_ops = {
++ .init = xt_net_init,
++ .exit = xt_net_exit,
++};
+
+ static int __init xt_init(void)
+ {
+@@ -869,13 +907,13 @@
+ #endif
+ INIT_LIST_HEAD(&xt[i].target);
+ INIT_LIST_HEAD(&xt[i].match);
+- INIT_LIST_HEAD(&xt[i].tables);
+ }
+- return 0;
++ return register_pernet_subsys(&xt_net_ops);
+ }
+
+ static void __exit xt_fini(void)
+ {
++ unregister_pernet_subsys(&xt_net_ops);
+ kfree(xt);
+ }
+
+diff -Nurb linux-2.6.22-570/net/netfilter/xt_MARK.c linux-2.6.22-590/net/netfilter/xt_MARK.c
+--- linux-2.6.22-570/net/netfilter/xt_MARK.c 2008-01-29 22:12:24.000000000 -0500
++++ linux-2.6.22-590/net/netfilter/xt_MARK.c 2008-01-29 22:12:32.000000000 -0500
+@@ -131,7 +131,7 @@
+ if ((*pskb)->sk)
+ connection_sk = (*pskb)->sk;
+ else {
+- connection_sk = inet_lookup(&tcp_hashinfo, src_ip, src_port, ip, port, dif);
++ connection_sk = inet_lookup(&tcp_hashinfo, src_ip, src_port, ip, port, dif,(*pskb)->sk->sk_net);
+ }
+
+ if (connection_sk) {
+diff -Nurb linux-2.6.22-570/net/netfilter/xt_hashlimit.c linux-2.6.22-590/net/netfilter/xt_hashlimit.c
+--- linux-2.6.22-570/net/netfilter/xt_hashlimit.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/netfilter/xt_hashlimit.c 2008-01-29 22:12:32.000000000 -0500
+@@ -21,6 +21,7 @@
+ #include <linux/in.h>
+ #include <linux/ip.h>
+ #include <linux/ipv6.h>
++#include <net/net_namespace.h>
+
+ #include <linux/netfilter/x_tables.h>
+ #include <linux/netfilter_ipv4/ip_tables.h>
+@@ -736,13 +737,13 @@
+ printk(KERN_ERR "xt_hashlimit: unable to create slab cache\n");
+ goto err2;
+ }
+- hashlimit_procdir4 = proc_mkdir("ipt_hashlimit", proc_net);
++ hashlimit_procdir4 = proc_mkdir("ipt_hashlimit", init_net.proc_net);
+ if (!hashlimit_procdir4) {
+ printk(KERN_ERR "xt_hashlimit: unable to create proc dir "
+ "entry\n");
+ goto err3;
+ }
+- hashlimit_procdir6 = proc_mkdir("ip6t_hashlimit", proc_net);
++ hashlimit_procdir6 = proc_mkdir("ip6t_hashlimit", init_net.proc_net);
+ if (!hashlimit_procdir6) {
+ printk(KERN_ERR "xt_hashlimit: unable to create proc dir "
+ "entry\n");
+@@ -750,7 +751,7 @@
+ }
+ return 0;
+ err4:
+- remove_proc_entry("ipt_hashlimit", proc_net);
++ remove_proc_entry("ipt_hashlimit", init_net.proc_net);
+ err3:
+ kmem_cache_destroy(hashlimit_cachep);
+ err2:
+@@ -762,8 +763,8 @@
+
+ static void __exit xt_hashlimit_fini(void)
+ {
+- remove_proc_entry("ipt_hashlimit", proc_net);
+- remove_proc_entry("ip6t_hashlimit", proc_net);
++ remove_proc_entry("ipt_hashlimit", init_net.proc_net);
++ remove_proc_entry("ip6t_hashlimit", init_net.proc_net);
+ kmem_cache_destroy(hashlimit_cachep);
+ xt_unregister_matches(xt_hashlimit, ARRAY_SIZE(xt_hashlimit));
+ }
+diff -Nurb linux-2.6.22-570/net/netlink/af_netlink.c linux-2.6.22-590/net/netlink/af_netlink.c
+--- linux-2.6.22-570/net/netlink/af_netlink.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/netlink/af_netlink.c 2008-01-29 22:12:32.000000000 -0500
+@@ -63,6 +63,7 @@
+ #include <net/sock.h>
+ #include <net/scm.h>
+ #include <net/netlink.h>
++#include <net/net_namespace.h>
+
+ #define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8)
+
+@@ -212,7 +213,7 @@
+ wake_up(&nl_table_wait);
+ }
+
+-static __inline__ struct sock *netlink_lookup(int protocol, u32 pid)
++static __inline__ struct sock *netlink_lookup(struct net *net, int protocol, u32 pid)
+ {
+ struct nl_pid_hash *hash = &nl_table[protocol].hash;
+ struct hlist_head *head;
+@@ -222,7 +223,7 @@
+ read_lock(&nl_table_lock);
+ head = nl_pid_hashfn(hash, pid);
+ sk_for_each(sk, node, head) {
+- if (nlk_sk(sk)->pid == pid) {
++ if ((sk->sk_net == net) && (nlk_sk(sk)->pid == pid)) {
+ sock_hold(sk);
+ goto found;
+ }
+@@ -327,7 +328,7 @@
+ * makes sure updates are visible before bind or setsockopt return. */
+ }
+
+-static int netlink_insert(struct sock *sk, u32 pid)
++static int netlink_insert(struct sock *sk, struct net *net, u32 pid)
+ {
+ struct nl_pid_hash *hash = &nl_table[sk->sk_protocol].hash;
+ struct hlist_head *head;
+@@ -340,7 +341,7 @@
+ head = nl_pid_hashfn(hash, pid);
+ len = 0;
+ sk_for_each(osk, node, head) {
+- if (nlk_sk(osk)->pid == pid)
++ if ((osk->sk_net == net) && (nlk_sk(osk)->pid == pid))
+ break;
+ len++;
+ }
+@@ -383,15 +384,15 @@
+ .obj_size = sizeof(struct netlink_sock),
+ };
+
+-static int __netlink_create(struct socket *sock, struct mutex *cb_mutex,
+- int protocol)
++static int __netlink_create(struct net *net, struct socket *sock,
++ struct mutex *cb_mutex, int protocol)
+ {
+ struct sock *sk;
+ struct netlink_sock *nlk;
+
+ sock->ops = &netlink_ops;
+
+- sk = sk_alloc(PF_NETLINK, GFP_KERNEL, &netlink_proto, 1);
++ sk = sk_alloc(net, PF_NETLINK, GFP_KERNEL, &netlink_proto, 1);
+ if (!sk)
+ return -ENOMEM;
+
+@@ -411,7 +412,7 @@
+ return 0;
+ }
+
+-static int netlink_create(struct socket *sock, int protocol)
++static int netlink_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct module *module = NULL;
+ struct mutex *cb_mutex;
+@@ -440,7 +441,7 @@
+ cb_mutex = nl_table[protocol].cb_mutex;
+ netlink_unlock_table();
+
+- if ((err = __netlink_create(sock, cb_mutex, protocol)) < 0)
++ if ((err = __netlink_create(net, sock, cb_mutex, protocol)) < 0)
+ goto out_module;
+
+ nlk = nlk_sk(sock->sk);
+@@ -477,6 +478,7 @@
+
+ if (nlk->pid && !nlk->subscriptions) {
+ struct netlink_notify n = {
++ .net = sk->sk_net,
+ .protocol = sk->sk_protocol,
+ .pid = nlk->pid,
+ };
+@@ -505,6 +507,7 @@
+ static int netlink_autobind(struct socket *sock)
+ {
+ struct sock *sk = sock->sk;
++ struct net *net = sk->sk_net;
+ struct nl_pid_hash *hash = &nl_table[sk->sk_protocol].hash;
+ struct hlist_head *head;
+ struct sock *osk;
+@@ -518,6 +521,8 @@
+ netlink_table_grab();
+ head = nl_pid_hashfn(hash, pid);
+ sk_for_each(osk, node, head) {
++ if ((osk->sk_net != net))
++ continue;
+ if (nlk_sk(osk)->pid == pid) {
+ /* Bind collision, search negative pid values. */
+ pid = rover--;
+@@ -529,7 +534,7 @@
+ }
+ netlink_table_ungrab();
+
+- err = netlink_insert(sk, pid);
++ err = netlink_insert(sk, net, pid);
+ if (err == -EADDRINUSE)
+ goto retry;
+
+@@ -583,6 +588,7 @@
+ static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
+ {
+ struct sock *sk = sock->sk;
++ struct net *net = sk->sk_net;
+ struct netlink_sock *nlk = nlk_sk(sk);
+ struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
+ int err;
+@@ -606,7 +612,7 @@
+ return -EINVAL;
+ } else {
+ err = nladdr->nl_pid ?
+- netlink_insert(sk, nladdr->nl_pid) :
++ netlink_insert(sk, net, nladdr->nl_pid) :
+ netlink_autobind(sock);
+ if (err)
+ return err;
+@@ -690,10 +696,12 @@
+ static struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid)
+ {
+ int protocol = ssk->sk_protocol;
++ struct net *net;
+ struct sock *sock;
+ struct netlink_sock *nlk;
+
+- sock = netlink_lookup(protocol, pid);
++ net = ssk->sk_net;
++ sock = netlink_lookup(net, protocol, pid);
+ if (!sock)
+ return ERR_PTR(-ECONNREFUSED);
+
+@@ -866,6 +874,7 @@
+
+ struct netlink_broadcast_data {
+ struct sock *exclude_sk;
++ struct net *net;
+ u32 pid;
+ u32 group;
+ int failure;
+@@ -888,6 +897,9 @@
+ !test_bit(p->group - 1, nlk->groups))
+ goto out;
+
++ if ((sk->sk_net != p->net))
++ goto out;
++
+ if (p->failure) {
+ netlink_overrun(sk);
+ goto out;
+@@ -926,6 +938,7 @@
+ int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid,
+ u32 group, gfp_t allocation)
+ {
++ struct net *net = ssk->sk_net;
+ struct netlink_broadcast_data info;
+ struct hlist_node *node;
+ struct sock *sk;
+@@ -933,6 +946,7 @@
+ skb = netlink_trim(skb, allocation);
+
+ info.exclude_sk = ssk;
++ info.net = net;
+ info.pid = pid;
+ info.group = group;
+ info.failure = 0;
+@@ -981,6 +995,9 @@
+ if (sk == p->exclude_sk)
+ goto out;
+
++ if (sk->sk_net != p->exclude_sk->sk_net)
++ goto out;
++
+ if (nlk->pid == p->pid || p->group - 1 >= nlk->ngroups ||
+ !test_bit(p->group - 1, nlk->groups))
+ goto out;
+@@ -1276,7 +1293,7 @@
+ */
+
+ struct sock *
+-netlink_kernel_create(int unit, unsigned int groups,
++netlink_kernel_create(struct net *net, int unit, unsigned int groups,
+ void (*input)(struct sock *sk, int len),
+ struct mutex *cb_mutex, struct module *module)
+ {
+@@ -1293,7 +1310,7 @@
+ if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
+ return NULL;
+
+- if (__netlink_create(sock, cb_mutex, unit) < 0)
++ if (__netlink_create(net, sock, cb_mutex, unit) < 0)
+ goto out_sock_release;
+
+ if (groups < 32)
+@@ -1308,18 +1325,20 @@
+ if (input)
+ nlk_sk(sk)->data_ready = input;
+
+- if (netlink_insert(sk, 0))
++ if (netlink_insert(sk, net, 0))
+ goto out_sock_release;
+
+ nlk = nlk_sk(sk);
+ nlk->flags |= NETLINK_KERNEL_SOCKET;
+
+ netlink_table_grab();
++ if (!nl_table[unit].registered) {
+ nl_table[unit].groups = groups;
+ nl_table[unit].listeners = listeners;
+ nl_table[unit].cb_mutex = cb_mutex;
+ nl_table[unit].module = module;
+ nl_table[unit].registered = 1;
++ }
+ netlink_table_ungrab();
+
+ return sk;
+@@ -1420,7 +1439,7 @@
+ atomic_inc(&skb->users);
+ cb->skb = skb;
+
+- sk = netlink_lookup(ssk->sk_protocol, NETLINK_CB(skb).pid);
++ sk = netlink_lookup(ssk->sk_net, ssk->sk_protocol, NETLINK_CB(skb).pid);
+ if (sk == NULL) {
+ netlink_destroy_callback(cb);
+ return -ECONNREFUSED;
+@@ -1462,7 +1481,8 @@
+ if (!skb) {
+ struct sock *sk;
+
+- sk = netlink_lookup(in_skb->sk->sk_protocol,
++ sk = netlink_lookup(in_skb->sk->sk_net,
++ in_skb->sk->sk_protocol,
+ NETLINK_CB(in_skb).pid);
+ if (sk) {
+ sk->sk_err = ENOBUFS;
+@@ -1613,6 +1633,7 @@
+
+ #ifdef CONFIG_PROC_FS
+ struct nl_seq_iter {
++ struct net *net;
+ int link;
+ int hash_idx;
+ };
+@@ -1630,6 +1651,8 @@
+
+ for (j = 0; j <= hash->mask; j++) {
+ sk_for_each(s, node, &hash->table[j]) {
++ if (iter->net != s->sk_net)
++ continue;
+ if (off == pos) {
+ iter->link = i;
+ iter->hash_idx = j;
+@@ -1659,11 +1682,14 @@
+ if (v == SEQ_START_TOKEN)
+ return netlink_seq_socket_idx(seq, 0);
+
+- s = sk_next(v);
++ iter = seq->private;
++ s = v;
++ do {
++ s = sk_next(s);
++ } while (s && (iter->net != s->sk_net));
+ if (s)
+ return s;
+
+- iter = seq->private;
+ i = iter->link;
+ j = iter->hash_idx + 1;
+
+@@ -1672,6 +1698,8 @@
+
+ for (; j <= hash->mask; j++) {
+ s = sk_head(&hash->table[j]);
++ while (s && (iter->net != s->sk_net))
++ s = sk_next(s);
+ if (s) {
+ iter->link = i;
+ iter->hash_idx = j;
+@@ -1742,15 +1770,24 @@
+
+ seq = file->private_data;
+ seq->private = iter;
++ iter->net = get_net(PROC_NET(inode));
+ return 0;
+ }
+
++static int netlink_seq_release(struct inode *inode, struct file *file)
++{
++ struct seq_file *seq = file->private_data;
++ struct nl_seq_iter *iter = seq->private;
++ put_net(iter->net);
++ return seq_release_private(inode, file);
++}
++
+ static const struct file_operations netlink_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = netlink_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+- .release = seq_release_private,
++ .release = netlink_seq_release,
+ };
+
+ #endif
+@@ -1792,6 +1829,27 @@
+ .owner = THIS_MODULE, /* for consistency 8) */
+ };
+
++static int netlink_net_init(struct net *net)
++{
++#ifdef CONFIG_PROC_FS
++ if (!proc_net_fops_create(net, "netlink", 0, &netlink_seq_fops))
++ return -ENOMEM;
++#endif
++ return 0;
++}
++
++static void netlink_net_exit(struct net *net)
++{
++#ifdef CONFIG_PROC_FS
++ proc_net_remove(net, "netlink");
++#endif
++}
++
++static struct pernet_operations netlink_net_ops = {
++ .init = netlink_net_init,
++ .exit = netlink_net_exit,
++};
++
+ static int __init netlink_proto_init(void)
+ {
+ struct sk_buff *dummy_skb;
+@@ -1837,9 +1895,7 @@
+ }
+
+ sock_register(&netlink_family_ops);
+-#ifdef CONFIG_PROC_FS
+- proc_net_fops_create("netlink", 0, &netlink_seq_fops);
+-#endif
++ register_pernet_subsys(&netlink_net_ops);
+ /* The netlink device handler may be needed early. */
+ rtnetlink_init();
+ out:
+diff -Nurb linux-2.6.22-570/net/netlink/attr.c linux-2.6.22-590/net/netlink/attr.c
+--- linux-2.6.22-570/net/netlink/attr.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/netlink/attr.c 2008-01-29 22:12:32.000000000 -0500
+@@ -72,6 +72,17 @@
+ return -ERANGE;
+ break;
+
++ case NLA_NESTED_COMPAT:
++ if (attrlen < pt->len)
++ return -ERANGE;
++ if (attrlen < NLA_ALIGN(pt->len))
++ break;
++ if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN)
++ return -ERANGE;
++ nla = nla_data(nla) + NLA_ALIGN(pt->len);
++ if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN + nla_len(nla))
++ return -ERANGE;
++ break;
+ default:
+ if (pt->len)
+ minlen = pt->len;
+diff -Nurb linux-2.6.22-570/net/netlink/genetlink.c linux-2.6.22-590/net/netlink/genetlink.c
+--- linux-2.6.22-570/net/netlink/genetlink.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/netlink/genetlink.c 2008-01-29 22:12:32.000000000 -0500
+@@ -557,8 +557,9 @@
+ goto errout_register;
+
+ netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV);
+- genl_sock = netlink_kernel_create(NETLINK_GENERIC, GENL_MAX_ID,
+- genl_rcv, NULL, THIS_MODULE);
++ genl_sock = netlink_kernel_create(&init_net, NETLINK_GENERIC,
++ GENL_MAX_ID, genl_rcv, NULL,
++ THIS_MODULE);
+ if (genl_sock == NULL)
+ panic("GENL: Cannot initialize generic netlink\n");
+
+diff -Nurb linux-2.6.22-570/net/netrom/af_netrom.c linux-2.6.22-590/net/netrom/af_netrom.c
+--- linux-2.6.22-570/net/netrom/af_netrom.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/netrom/af_netrom.c 2008-01-29 22:12:32.000000000 -0500
+@@ -41,6 +41,7 @@
+ #include <net/ip.h>
+ #include <net/tcp_states.h>
+ #include <net/arp.h>
++#include <net/net_namespace.h>
+ #include <linux/init.h>
-@@ -137,6 +137,28 @@
- return 0;
+ static int nr_ndevs = 4;
+@@ -105,6 +106,9 @@
+ {
+ struct net_device *dev = (struct net_device *)ptr;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ if (event != NETDEV_DOWN)
+ return NOTIFY_DONE;
+
+@@ -408,15 +412,18 @@
+ .obj_size = sizeof(struct nr_sock),
+ };
+
+-static int nr_create(struct socket *sock, int protocol)
++static int nr_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct sock *sk;
+ struct nr_sock *nr;
+
++ if (net != &init_net)
++ return -EAFNOSUPPORT;
++
+ if (sock->type != SOCK_SEQPACKET || protocol != 0)
+ return -ESOCKTNOSUPPORT;
+
+- if ((sk = sk_alloc(PF_NETROM, GFP_ATOMIC, &nr_proto, 1)) == NULL)
++ if ((sk = sk_alloc(net, PF_NETROM, GFP_ATOMIC, &nr_proto, 1)) == NULL)
+ return -ENOMEM;
+
+ nr = nr_sk(sk);
+@@ -458,7 +465,7 @@
+ if (osk->sk_type != SOCK_SEQPACKET)
+ return NULL;
+
+- if ((sk = sk_alloc(PF_NETROM, GFP_ATOMIC, osk->sk_prot, 1)) == NULL)
++ if ((sk = sk_alloc(osk->sk_net, PF_NETROM, GFP_ATOMIC, osk->sk_prot, 1)) == NULL)
+ return NULL;
+
+ nr = nr_sk(sk);
+@@ -1447,9 +1454,9 @@
+
+ nr_loopback_init();
+
+- proc_net_fops_create("nr", S_IRUGO, &nr_info_fops);
+- proc_net_fops_create("nr_neigh", S_IRUGO, &nr_neigh_fops);
+- proc_net_fops_create("nr_nodes", S_IRUGO, &nr_nodes_fops);
++ proc_net_fops_create(&init_net, "nr", S_IRUGO, &nr_info_fops);
++ proc_net_fops_create(&init_net, "nr_neigh", S_IRUGO, &nr_neigh_fops);
++ proc_net_fops_create(&init_net, "nr_nodes", S_IRUGO, &nr_nodes_fops);
+ out:
+ return rc;
+ fail:
+@@ -1477,9 +1484,9 @@
+ {
+ int i;
+
+- proc_net_remove("nr");
+- proc_net_remove("nr_neigh");
+- proc_net_remove("nr_nodes");
++ proc_net_remove(&init_net, "nr");
++ proc_net_remove(&init_net, "nr_neigh");
++ proc_net_remove(&init_net, "nr_nodes");
+ nr_loopback_clear();
+
+ nr_rt_free();
+diff -Nurb linux-2.6.22-570/net/netrom/nr_route.c linux-2.6.22-590/net/netrom/nr_route.c
+--- linux-2.6.22-570/net/netrom/nr_route.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/netrom/nr_route.c 2008-01-29 22:12:32.000000000 -0500
+@@ -580,7 +580,7 @@
+ {
+ struct net_device *dev;
+
+- if ((dev = dev_get_by_name(devname)) == NULL)
++ if ((dev = dev_get_by_name(&init_net, devname)) == NULL)
+ return NULL;
+
+ if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25)
+@@ -598,7 +598,7 @@
+ struct net_device *dev, *first = NULL;
+
+ read_lock(&dev_base_lock);
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM)
+ if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
+ first = dev;
+@@ -618,7 +618,7 @@
+ struct net_device *dev;
+
+ read_lock(&dev_base_lock);
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM && ax25cmp(addr, (ax25_address *)dev->dev_addr) == 0) {
+ dev_hold(dev);
+ goto out;
+diff -Nurb linux-2.6.22-570/net/packet/af_packet.c linux-2.6.22-590/net/packet/af_packet.c
+--- linux-2.6.22-570/net/packet/af_packet.c 2008-01-29 22:12:24.000000000 -0500
++++ linux-2.6.22-590/net/packet/af_packet.c 2008-01-29 22:12:32.000000000 -0500
+@@ -65,6 +65,7 @@
+ #include <net/protocol.h>
+ #include <linux/skbuff.h>
+ #include <net/sock.h>
++#include <net/net_namespace.h>
+ #include <linux/errno.h>
+ #include <linux/timer.h>
+ #include <asm/system.h>
+@@ -135,10 +136,6 @@
+ packet classifier depends on it.
+ */
+
+-/* List of all packet sockets. */
+-static HLIST_HEAD(packet_sklist);
+-static DEFINE_RWLOCK(packet_sklist_lock);
+-
+ static atomic_t packet_socks_nr;
+
+
+@@ -273,6 +270,9 @@
+ if (skb->pkt_type == PACKET_LOOPBACK)
+ goto out;
+
++ if (dev->nd_net != sk->sk_net)
++ goto out;
++
+ if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
+ goto oom;
+
+@@ -344,7 +344,7 @@
+ */
+
+ saddr->spkt_device[13] = 0;
+- dev = dev_get_by_name(saddr->spkt_device);
++ dev = dev_get_by_name(sk->sk_net, saddr->spkt_device);
+ err = -ENODEV;
+ if (dev == NULL)
+ goto out_unlock;
+@@ -462,6 +462,9 @@
+ sk = pt->af_packet_priv;
+ po = pkt_sk(sk);
+
++ if (dev->nd_net != sk->sk_net)
++ goto drop;
++
+ skb->dev = dev;
+
+ if (dev->hard_header) {
+@@ -578,6 +581,9 @@
+ sk = pt->af_packet_priv;
+ po = pkt_sk(sk);
+
++ if (dev->nd_net != sk->sk_net)
++ goto drop;
++
+ if (dev->hard_header) {
+ if (sk->sk_type != SOCK_DGRAM)
+ skb_push(skb, skb->data - skb_mac_header(skb));
+@@ -738,7 +744,7 @@
+ }
+
+
+- dev = dev_get_by_index(ifindex);
++ dev = dev_get_by_index(sk->sk_net, ifindex);
+ err = -ENXIO;
+ if (dev == NULL)
+ goto out_unlock;
+@@ -811,15 +817,17 @@
+ {
+ struct sock *sk = sock->sk;
+ struct packet_sock *po;
++ struct net *net;
+
+ if (!sk)
+ return 0;
+
++ net = sk->sk_net;
+ po = pkt_sk(sk);
+
+- write_lock_bh(&packet_sklist_lock);
++ write_lock_bh(&net->packet_sklist_lock);
+ sk_del_node_init(sk);
+- write_unlock_bh(&packet_sklist_lock);
++ write_unlock_bh(&net->packet_sklist_lock);
+
+ /*
+ * Unhook packet receive handler.
+@@ -933,7 +941,7 @@
+ return -EINVAL;
+ strlcpy(name,uaddr->sa_data,sizeof(name));
+
+- dev = dev_get_by_name(name);
++ dev = dev_get_by_name(sk->sk_net, name);
+ if (dev) {
+ err = packet_do_bind(sk, dev, pkt_sk(sk)->num);
+ dev_put(dev);
+@@ -960,7 +968,7 @@
+
+ if (sll->sll_ifindex) {
+ err = -ENODEV;
+- dev = dev_get_by_index(sll->sll_ifindex);
++ dev = dev_get_by_index(sk->sk_net, sll->sll_ifindex);
+ if (dev == NULL)
+ goto out;
+ }
+@@ -982,7 +990,7 @@
+ * Create a packet of type SOCK_PACKET.
+ */
+
+-static int packet_create(struct socket *sock, int protocol)
++static int packet_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct sock *sk;
+ struct packet_sock *po;
+@@ -998,7 +1006,7 @@
+ sock->state = SS_UNCONNECTED;
+
+ err = -ENOBUFS;
+- sk = sk_alloc(PF_PACKET, GFP_KERNEL, &packet_proto, 1);
++ sk = sk_alloc(net, PF_PACKET, GFP_KERNEL, &packet_proto, 1);
+ if (sk == NULL)
+ goto out;
+
+@@ -1034,9 +1042,9 @@
+ po->running = 1;
+ }
+
+- write_lock_bh(&packet_sklist_lock);
+- sk_add_node(sk, &packet_sklist);
+- write_unlock_bh(&packet_sklist_lock);
++ write_lock_bh(&net->packet_sklist_lock);
++ sk_add_node(sk, &net->packet_sklist);
++ write_unlock_bh(&net->packet_sklist_lock);
+ return(0);
+ out:
+ return err;
+@@ -1154,7 +1162,7 @@
+ return -EOPNOTSUPP;
+
+ uaddr->sa_family = AF_PACKET;
+- dev = dev_get_by_index(pkt_sk(sk)->ifindex);
++ dev = dev_get_by_index(sk->sk_net, pkt_sk(sk)->ifindex);
+ if (dev) {
+ strlcpy(uaddr->sa_data, dev->name, 15);
+ dev_put(dev);
+@@ -1179,7 +1187,7 @@
+ sll->sll_family = AF_PACKET;
+ sll->sll_ifindex = po->ifindex;
+ sll->sll_protocol = po->num;
+- dev = dev_get_by_index(po->ifindex);
++ dev = dev_get_by_index(sk->sk_net, po->ifindex);
+ if (dev) {
+ sll->sll_hatype = dev->type;
+ sll->sll_halen = dev->addr_len;
+@@ -1231,7 +1239,7 @@
+ rtnl_lock();
+
+ err = -ENODEV;
+- dev = __dev_get_by_index(mreq->mr_ifindex);
++ dev = __dev_get_by_index(sk->sk_net, mreq->mr_ifindex);
+ if (!dev)
+ goto done;
+
+@@ -1285,7 +1293,7 @@
+ if (--ml->count == 0) {
+ struct net_device *dev;
+ *mlp = ml->next;
+- dev = dev_get_by_index(ml->ifindex);
++ dev = dev_get_by_index(sk->sk_net, ml->ifindex);
+ if (dev) {
+ packet_dev_mc(dev, ml, -1);
+ dev_put(dev);
+@@ -1313,7 +1321,7 @@
+ struct net_device *dev;
+
+ po->mclist = ml->next;
+- if ((dev = dev_get_by_index(ml->ifindex)) != NULL) {
++ if ((dev = dev_get_by_index(sk->sk_net, ml->ifindex)) != NULL) {
+ packet_dev_mc(dev, ml, -1);
+ dev_put(dev);
+ }
+@@ -1469,9 +1477,10 @@
+ struct sock *sk;
+ struct hlist_node *node;
+ struct net_device *dev = data;
++ struct net *net = dev->nd_net;
+
+- read_lock(&packet_sklist_lock);
+- sk_for_each(sk, node, &packet_sklist) {
++ read_lock(&net->packet_sklist_lock);
++ sk_for_each(sk, node, &net->packet_sklist) {
+ struct packet_sock *po = pkt_sk(sk);
+
+ switch (msg) {
+@@ -1510,7 +1519,7 @@
+ break;
+ }
+ }
+- read_unlock(&packet_sklist_lock);
++ read_unlock(&net->packet_sklist_lock);
+ return NOTIFY_DONE;
}
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
-+static int (*mh_filter)(struct sock *sock, struct sk_buff *skb);
+@@ -1878,12 +1887,12 @@
+ };
+
+ #ifdef CONFIG_PROC_FS
+-static inline struct sock *packet_seq_idx(loff_t off)
++static inline struct sock *packet_seq_idx(struct net *net, loff_t off)
+ {
+ struct sock *s;
+ struct hlist_node *node;
+
+- sk_for_each(s, node, &packet_sklist) {
++ sk_for_each(s, node, &net->packet_sklist) {
+ if (!off--)
+ return s;
+ }
+@@ -1892,21 +1901,24 @@
+
+ static void *packet_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+- read_lock(&packet_sklist_lock);
+- return *pos ? packet_seq_idx(*pos - 1) : SEQ_START_TOKEN;
++ struct net *net = seq->private;
++ read_lock(&net->packet_sklist_lock);
++ return *pos ? packet_seq_idx(net, *pos - 1) : SEQ_START_TOKEN;
+ }
+
+ static void *packet_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
++ struct net *net = seq->private;
+ ++*pos;
+ return (v == SEQ_START_TOKEN)
+- ? sk_head(&packet_sklist)
++ ? sk_head(&net->packet_sklist)
+ : sk_next((struct sock*)v) ;
+ }
+
+ static void packet_seq_stop(struct seq_file *seq, void *v)
+ {
+- read_unlock(&packet_sklist_lock);
++ struct net *net = seq->private;
++ read_unlock(&net->packet_sklist_lock);
+ }
+
+ static int packet_seq_show(struct seq_file *seq, void *v)
+@@ -1942,7 +1954,22 @@
+
+ static int packet_seq_open(struct inode *inode, struct file *file)
+ {
+- return seq_open(file, &packet_seq_ops);
++ struct seq_file *seq;
++ int res;
++ res = seq_open(file, &packet_seq_ops);
++ if (!res) {
++ seq = file->private_data;
++ seq->private = get_net(PROC_NET(inode));
++ }
++ return res;
++}
+
-+int rawv6_mh_filter_register(int (*filter)(struct sock *sock,
-+ struct sk_buff *skb))
++static int packet_seq_release(struct inode *inode, struct file *file)
+{
-+ rcu_assign_pointer(mh_filter, filter);
++ struct seq_file *seq= file->private_data;
++ struct net *net = seq->private;
++ put_net(net);
++ return seq_release(inode, file);
+ }
+
+ static const struct file_operations packet_seq_fops = {
+@@ -1950,15 +1977,37 @@
+ .open = packet_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+- .release = seq_release,
++ .release = packet_seq_release,
+ };
+
+ #endif
+
++static int packet_net_init(struct net *net)
++{
++ rwlock_init(&net->packet_sklist_lock);
++ INIT_HLIST_HEAD(&net->packet_sklist);
++
++ if (!proc_net_fops_create(net, "packet", 0, &packet_seq_fops))
++ return -ENOMEM;
++
+ return 0;
+}
-+EXPORT_SYMBOL(rawv6_mh_filter_register);
+
-+int rawv6_mh_filter_unregister(int (*filter)(struct sock *sock,
-+ struct sk_buff *skb))
++static void packet_net_exit(struct net *net)
+{
-+ rcu_assign_pointer(mh_filter, NULL);
-+ synchronize_rcu();
-+ return 0;
++ proc_net_remove(net, "packet");
+}
-+EXPORT_SYMBOL(rawv6_mh_filter_unregister);
+
-+#endif
++static struct pernet_operations packet_net_ops = {
++ .init = packet_net_init,
++ .exit = packet_net_exit,
++};
++
++
+ static void __exit packet_exit(void)
+ {
+- proc_net_remove("packet");
+ unregister_netdevice_notifier(&packet_netdev_notifier);
++ unregister_pernet_subsys(&packet_net_ops);
+ sock_unregister(PF_PACKET);
+ proto_unregister(&packet_proto);
+ }
+@@ -1971,8 +2020,8 @@
+ goto out;
+
+ sock_register(&packet_family_ops);
++ register_pernet_subsys(&packet_net_ops);
+ register_netdevice_notifier(&packet_netdev_notifier);
+- proc_net_fops_create("packet", 0, &packet_seq_fops);
+ out:
+ return rc;
+ }
+diff -Nurb linux-2.6.22-570/net/rose/af_rose.c linux-2.6.22-590/net/rose/af_rose.c
+--- linux-2.6.22-570/net/rose/af_rose.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/rose/af_rose.c 2008-01-29 22:12:32.000000000 -0500
+@@ -45,6 +45,7 @@
+ #include <net/tcp_states.h>
+ #include <net/ip.h>
+ #include <net/arp.h>
++#include <net/net_namespace.h>
+
+ static int rose_ndevs = 10;
+
+@@ -196,6 +197,9 @@
+ {
+ struct net_device *dev = (struct net_device *)ptr;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
+
+ if (event != NETDEV_DOWN)
+ return NOTIFY_DONE;
+
+@@ -498,15 +502,18 @@
+ .obj_size = sizeof(struct rose_sock),
+ };
+
+-static int rose_create(struct socket *sock, int protocol)
++static int rose_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct sock *sk;
+ struct rose_sock *rose;
+
++ if (net != &init_net)
++ return -EAFNOSUPPORT;
++
+ if (sock->type != SOCK_SEQPACKET || protocol != 0)
+ return -ESOCKTNOSUPPORT;
+
+- if ((sk = sk_alloc(PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL)
++ if ((sk = sk_alloc(net, PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL)
+ return -ENOMEM;
+
+ rose = rose_sk(sk);
+@@ -544,7 +551,7 @@
+ if (osk->sk_type != SOCK_SEQPACKET)
+ return NULL;
+
+- if ((sk = sk_alloc(PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL)
++ if ((sk = sk_alloc(osk->sk_net, PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL)
+ return NULL;
+
+ rose = rose_sk(sk);
+@@ -1576,10 +1583,10 @@
+
+ rose_add_loopback_neigh();
+
+- proc_net_fops_create("rose", S_IRUGO, &rose_info_fops);
+- proc_net_fops_create("rose_neigh", S_IRUGO, &rose_neigh_fops);
+- proc_net_fops_create("rose_nodes", S_IRUGO, &rose_nodes_fops);
+- proc_net_fops_create("rose_routes", S_IRUGO, &rose_routes_fops);
++ proc_net_fops_create(&init_net, "rose", S_IRUGO, &rose_info_fops);
++ proc_net_fops_create(&init_net, "rose_neigh", S_IRUGO, &rose_neigh_fops);
++ proc_net_fops_create(&init_net, "rose_nodes", S_IRUGO, &rose_nodes_fops);
++ proc_net_fops_create(&init_net, "rose_routes", S_IRUGO, &rose_routes_fops);
+ out:
+ return rc;
+ fail:
+@@ -1606,10 +1613,10 @@
+ {
+ int i;
+
+- proc_net_remove("rose");
+- proc_net_remove("rose_neigh");
+- proc_net_remove("rose_nodes");
+- proc_net_remove("rose_routes");
++ proc_net_remove(&init_net, "rose");
++ proc_net_remove(&init_net, "rose_neigh");
++ proc_net_remove(&init_net, "rose_nodes");
++ proc_net_remove(&init_net, "rose_routes");
+ rose_loopback_clear();
+
+ rose_rt_free();
+diff -Nurb linux-2.6.22-570/net/rose/rose_route.c linux-2.6.22-590/net/rose/rose_route.c
+--- linux-2.6.22-570/net/rose/rose_route.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/rose/rose_route.c 2008-01-29 22:12:32.000000000 -0500
+@@ -583,7 +583,7 @@
+ {
+ struct net_device *dev;
+
+- if ((dev = dev_get_by_name(devname)) == NULL)
++ if ((dev = dev_get_by_name(&init_net, devname)) == NULL)
+ return NULL;
+
+ if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25)
+@@ -601,7 +601,7 @@
+ struct net_device *dev, *first = NULL;
+
+ read_lock(&dev_base_lock);
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE)
+ if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
+ first = dev;
+@@ -619,7 +619,7 @@
+ struct net_device *dev;
+
+ read_lock(&dev_base_lock);
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0) {
+ dev_hold(dev);
+ goto out;
+@@ -636,7 +636,7 @@
+ struct net_device *dev;
+
+ read_lock(&dev_base_lock);
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0)
+ goto out;
+ }
+diff -Nurb linux-2.6.22-570/net/rxrpc/af_rxrpc.c linux-2.6.22-590/net/rxrpc/af_rxrpc.c
+--- linux-2.6.22-570/net/rxrpc/af_rxrpc.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/rxrpc/af_rxrpc.c 2008-01-29 22:12:32.000000000 -0500
+@@ -14,6 +14,7 @@
+ #include <linux/skbuff.h>
+ #include <linux/poll.h>
+ #include <linux/proc_fs.h>
++#include <net/net_namespace.h>
+ #include <net/sock.h>
+ #include <net/af_rxrpc.h>
+ #include "ar-internal.h"
+@@ -605,13 +606,16 @@
/*
- * demultiplex raw sockets.
- * (should consider queueing the skb in the sock receive_queue
-@@ -178,16 +200,22 @@
- case IPPROTO_ICMPV6:
- filtered = icmpv6_filter(sk, skb);
- break;
--#ifdef CONFIG_IPV6_MIP6
+ * create an RxRPC socket
+ */
+-static int rxrpc_create(struct socket *sock, int protocol)
++static int rxrpc_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct rxrpc_sock *rx;
+ struct sock *sk;
+
+ _enter("%p,%d", sock, protocol);
+
++ if (net != &init_net)
++ return -EAFNOSUPPORT;
+
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- case IPPROTO_MH:
-+ {
- /* XXX: To validate MH only once for each packet,
- * this is placed here. It should be after checking
- * xfrm policy, however it doesn't. The checking xfrm
- * policy is placed in rawv6_rcv() because it is
- * required for each socket.
- */
-- filtered = mip6_mh_filter(sk, skb);
-+ int (*filter)(struct sock *sock, struct sk_buff *skb);
+ /* we support transport protocol UDP only */
+ if (protocol != PF_INET)
+ return -EPROTONOSUPPORT;
+@@ -622,7 +626,7 @@
+ sock->ops = &rxrpc_rpc_ops;
+ sock->state = SS_UNCONNECTED;
+
+- sk = sk_alloc(PF_RXRPC, GFP_KERNEL, &rxrpc_proto, 1);
++ sk = sk_alloc(net, PF_RXRPC, GFP_KERNEL, &rxrpc_proto, 1);
+ if (!sk)
+ return -ENOMEM;
+
+@@ -829,8 +833,8 @@
+ }
+
+ #ifdef CONFIG_PROC_FS
+- proc_net_fops_create("rxrpc_calls", 0, &rxrpc_call_seq_fops);
+- proc_net_fops_create("rxrpc_conns", 0, &rxrpc_connection_seq_fops);
++ proc_net_fops_create(&init_net, "rxrpc_calls", 0, &rxrpc_call_seq_fops);
++ proc_net_fops_create(&init_net, "rxrpc_conns", 0, &rxrpc_connection_seq_fops);
+ #endif
+ return 0;
+
+@@ -868,8 +872,8 @@
+
+ _debug("flush scheduled work");
+ flush_workqueue(rxrpc_workqueue);
+- proc_net_remove("rxrpc_conns");
+- proc_net_remove("rxrpc_calls");
++ proc_net_remove(&init_net, "rxrpc_conns");
++ proc_net_remove(&init_net, "rxrpc_calls");
+ destroy_workqueue(rxrpc_workqueue);
+ kmem_cache_destroy(rxrpc_call_jar);
+ _leave("");
+diff -Nurb linux-2.6.22-570/net/sched/act_api.c linux-2.6.22-590/net/sched/act_api.c
+--- linux-2.6.22-570/net/sched/act_api.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/sched/act_api.c 2008-01-29 22:12:32.000000000 -0500
+@@ -27,6 +27,7 @@
+ #include <linux/skbuff.h>
+ #include <linux/init.h>
+ #include <linux/kmod.h>
++#include <net/net_namespace.h>
+ #include <net/sock.h>
+ #include <net/sch_generic.h>
+ #include <net/act_api.h>
+@@ -675,7 +676,7 @@
+ return -EINVAL;
+ }
+
+- return rtnl_unicast(skb, pid);
++ return rtnl_unicast(skb, &init_net, pid);
+ }
+
+ static struct tc_action *
+@@ -796,7 +797,7 @@
+ nlh->nlmsg_flags |= NLM_F_ROOT;
+ module_put(a->ops->owner);
+ kfree(a);
+- err = rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
++ err = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
+ if (err > 0)
+ return 0;
+
+@@ -859,7 +860,7 @@
+
+ /* now do the delete */
+ tcf_action_destroy(head, 0);
+- ret = rtnetlink_send(skb, pid, RTNLGRP_TC,
++ ret = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC,
+ n->nlmsg_flags&NLM_F_ECHO);
+ if (ret > 0)
+ return 0;
+@@ -903,7 +904,7 @@
+ nlh->nlmsg_len = skb_tail_pointer(skb) - b;
+ NETLINK_CB(skb).dst_group = RTNLGRP_TC;
+
+- err = rtnetlink_send(skb, pid, RTNLGRP_TC, flags&NLM_F_ECHO);
++ err = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, flags&NLM_F_ECHO);
+ if (err > 0)
+ err = 0;
+ return err;
+@@ -941,10 +942,14 @@
+
+ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct rtattr **tca = arg;
+ u32 pid = skb ? NETLINK_CB(skb).pid : 0;
+ int ret = 0, ovr = 0;
+
++ if (net != &init_net)
++ return -EINVAL;
+
-+ filter = rcu_dereference(mh_filter);
-+ filtered = filter ? filter(sk, skb) : 0;
+ if (tca[TCA_ACT_TAB-1] == NULL) {
+ printk("tc_ctl_action: received NO action attribs\n");
+ return -EINVAL;
+@@ -1014,6 +1019,7 @@
+ static int
+ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct nlmsghdr *nlh;
+ unsigned char *b = skb_tail_pointer(skb);
+ struct rtattr *x;
+@@ -1023,6 +1029,9 @@
+ struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh);
+ struct rtattr *kind = find_dump_kind(cb->nlh);
+
++ if (net != &init_net)
++ return 0;
++
+ if (kind == NULL) {
+ printk("tc_dump_action: action bad kind\n");
+ return 0;
+diff -Nurb linux-2.6.22-570/net/sched/act_mirred.c linux-2.6.22-590/net/sched/act_mirred.c
+--- linux-2.6.22-570/net/sched/act_mirred.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/sched/act_mirred.c 2008-01-29 22:12:32.000000000 -0500
+@@ -85,7 +85,7 @@
+ parm = RTA_DATA(tb[TCA_MIRRED_PARMS-1]);
+
+ if (parm->ifindex) {
+- dev = __dev_get_by_index(parm->ifindex);
++ dev = __dev_get_by_index(&init_net, parm->ifindex);
+ if (dev == NULL)
+ return -ENODEV;
+ switch (dev->type) {
+diff -Nurb linux-2.6.22-570/net/sched/cls_api.c linux-2.6.22-590/net/sched/cls_api.c
+--- linux-2.6.22-570/net/sched/cls_api.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/sched/cls_api.c 2008-01-29 22:12:32.000000000 -0500
+@@ -129,6 +129,7 @@
+
+ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct rtattr **tca;
+ struct tcmsg *t;
+ u32 protocol;
+@@ -145,6 +146,9 @@
+ unsigned long fh;
+ int err;
+
++ if (net != &init_net)
++ return -EINVAL;
++
+ replay:
+ tca = arg;
+ t = NLMSG_DATA(n);
+@@ -164,7 +168,7 @@
+ /* Find head of filter chain. */
+
+ /* Find link */
+- if ((dev = __dev_get_by_index(t->tcm_ifindex)) == NULL)
++ if ((dev = __dev_get_by_index(&init_net, t->tcm_ifindex)) == NULL)
+ return -ENODEV;
+
+ /* Find qdisc */
+@@ -365,7 +369,7 @@
+ return -EINVAL;
+ }
+
+- return rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
++ return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
+ }
+
+ struct tcf_dump_args
+@@ -385,6 +389,7 @@
+
+ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
+ {
++ struct net *net = skb->sk->sk_net;
+ int t;
+ int s_t;
+ struct net_device *dev;
+@@ -395,9 +400,12 @@
+ struct Qdisc_class_ops *cops;
+ struct tcf_dump_args arg;
+
++ if (net != &init_net)
++ return 0;
++
+ if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm)))
+ return skb->len;
+- if ((dev = dev_get_by_index(tcm->tcm_ifindex)) == NULL)
++ if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
+ return skb->len;
+
+ if (!tcm->tcm_parent)
+diff -Nurb linux-2.6.22-570/net/sched/em_meta.c linux-2.6.22-590/net/sched/em_meta.c
+--- linux-2.6.22-570/net/sched/em_meta.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/sched/em_meta.c 2008-01-29 22:12:32.000000000 -0500
+@@ -291,7 +291,7 @@
+ } else {
+ struct net_device *dev;
+
+- dev = dev_get_by_index(skb->sk->sk_bound_dev_if);
++ dev = dev_get_by_index(&init_net, skb->sk->sk_bound_dev_if);
+ *err = var_dev(dev, dst);
+ if (dev)
+ dev_put(dev);
+diff -Nurb linux-2.6.22-570/net/sched/sch_api.c linux-2.6.22-590/net/sched/sch_api.c
+--- linux-2.6.22-570/net/sched/sch_api.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/sched/sch_api.c 2008-01-29 22:12:32.000000000 -0500
+@@ -35,6 +35,7 @@
+ #include <linux/bitops.h>
+ #include <linux/hrtimer.h>
+
++#include <net/net_namespace.h>
+ #include <net/netlink.h>
+ #include <net/sock.h>
+ #include <net/pkt_sched.h>
+@@ -609,6 +610,7 @@
+
+ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct tcmsg *tcm = NLMSG_DATA(n);
+ struct rtattr **tca = arg;
+ struct net_device *dev;
+@@ -617,7 +619,10 @@
+ struct Qdisc *p = NULL;
+ int err;
+
+- if ((dev = __dev_get_by_index(tcm->tcm_ifindex)) == NULL)
++ if (net != &init_net)
++ return -EINVAL;
++
++ if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
+ return -ENODEV;
+
+ if (clid) {
+@@ -670,6 +675,7 @@
+
+ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct tcmsg *tcm;
+ struct rtattr **tca;
+ struct net_device *dev;
+@@ -677,6 +683,9 @@
+ struct Qdisc *q, *p;
+ int err;
+
++ if (net != &init_net)
++ return -EINVAL;
++
+ replay:
+ /* Reinit, just in case something touches this. */
+ tcm = NLMSG_DATA(n);
+@@ -684,7 +693,7 @@
+ clid = tcm->tcm_parent;
+ q = p = NULL;
+
+- if ((dev = __dev_get_by_index(tcm->tcm_ifindex)) == NULL)
++ if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
+ return -ENODEV;
+
+ if (clid) {
+@@ -873,7 +882,7 @@
+ }
+
+ if (skb->len)
+- return rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
++ return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
+
+ err_out:
+ kfree_skb(skb);
+@@ -882,16 +891,20 @@
+
+ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
+ {
++ struct net *net = skb->sk->sk_net;
+ int idx, q_idx;
+ int s_idx, s_q_idx;
+ struct net_device *dev;
+ struct Qdisc *q;
+
++ if (net != &init_net)
++ return 0;
++
+ s_idx = cb->args[0];
+ s_q_idx = q_idx = cb->args[1];
+ read_lock(&dev_base_lock);
+ idx = 0;
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ if (idx < s_idx)
+ goto cont;
+ if (idx > s_idx)
+@@ -930,6 +943,7 @@
+
+ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct tcmsg *tcm = NLMSG_DATA(n);
+ struct rtattr **tca = arg;
+ struct net_device *dev;
+@@ -942,7 +956,10 @@
+ u32 qid = TC_H_MAJ(clid);
+ int err;
+
+- if ((dev = __dev_get_by_index(tcm->tcm_ifindex)) == NULL)
++ if (net != &init_net)
++ return -EINVAL;
++
++ if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
+ return -ENODEV;
+
+ /*
+@@ -1096,7 +1113,7 @@
+ return -EINVAL;
+ }
+
+- return rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
++ return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
+ }
+
+ struct qdisc_dump_args
+@@ -1116,6 +1133,7 @@
+
+ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
+ {
++ struct net *net = skb->sk->sk_net;
+ int t;
+ int s_t;
+ struct net_device *dev;
+@@ -1123,9 +1141,12 @@
+ struct tcmsg *tcm = (struct tcmsg*)NLMSG_DATA(cb->nlh);
+ struct qdisc_dump_args arg;
+
++ if (net != &init_net)
++ return 0;
++
+ if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm)))
+ return 0;
+- if ((dev = dev_get_by_index(tcm->tcm_ifindex)) == NULL)
++ if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
+ return 0;
+
+ s_t = cb->args[0];
+@@ -1252,7 +1273,7 @@
+ {
+ register_qdisc(&pfifo_qdisc_ops);
+ register_qdisc(&bfifo_qdisc_ops);
+- proc_net_fops_create("psched", 0, &psched_fops);
++ proc_net_fops_create(&init_net, "psched", 0, &psched_fops);
+
+ rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL);
+ rtnl_register(PF_UNSPEC, RTM_DELQDISC, tc_get_qdisc, NULL);
+diff -Nurb linux-2.6.22-570/net/sched/sch_generic.c linux-2.6.22-590/net/sched/sch_generic.c
+--- linux-2.6.22-570/net/sched/sch_generic.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/sched/sch_generic.c 2008-01-29 22:12:32.000000000 -0500
+@@ -59,122 +59,143 @@
+ spin_unlock_bh(&dev->queue_lock);
+ }
+
+-/*
+- dev->queue_lock serializes queue accesses for this device
+- AND dev->qdisc pointer itself.
++static inline int qdisc_qlen(struct Qdisc *q)
++{
++ return q->q.qlen;
++}
+
+- netif_tx_lock serializes accesses to device driver.
++static inline int dev_requeue_skb(struct sk_buff *skb, struct net_device *dev,
++ struct Qdisc *q)
++{
++ if (unlikely(skb->next))
++ dev->gso_skb = skb;
++ else
++ q->ops->requeue(skb, q);
+
+- dev->queue_lock and netif_tx_lock are mutually exclusive,
+- if one is grabbed, another must be free.
+- */
++ netif_schedule(dev);
++ return 0;
++}
+
++static inline struct sk_buff *dev_dequeue_skb(struct net_device *dev,
++ struct Qdisc *q)
++{
++ struct sk_buff *skb;
+
+-/* Kick device.
++ if ((skb = dev->gso_skb))
++ dev->gso_skb = NULL;
++ else
++ skb = q->dequeue(q);
+
+- Returns: 0 - queue is empty or throttled.
+- >0 - queue is not empty.
++ return skb;
++}
+
+- NOTE: Called under dev->queue_lock with locally disabled BH.
+-*/
++static inline int handle_dev_cpu_collision(struct sk_buff *skb,
++ struct net_device *dev,
++ struct Qdisc *q)
++{
++ int ret;
+
++ if (unlikely(dev->xmit_lock_owner == smp_processor_id())) {
++ /*
++ * Same CPU holding the lock. It may be a transient
++ * configuration error, when hard_start_xmit() recurses. We
++ * detect it by checking xmit owner and drop the packet when
++ * deadloop is detected. Return OK to try the next skb.
++ */
++ kfree_skb(skb);
++ if (net_ratelimit())
++ printk(KERN_WARNING "Dead loop on netdevice %s, "
++ "fix it urgently!\n", dev->name);
++ ret = qdisc_qlen(q);
++ } else {
++ /*
++ * Another cpu is holding lock, requeue & delay xmits for
++ * some time.
++ */
++ __get_cpu_var(netdev_rx_stat).cpu_collision++;
++ ret = dev_requeue_skb(skb, dev, q);
++ }
++
++ return ret;
++}
++
++/*
++ * NOTE: Called under dev->queue_lock with locally disabled BH.
++ *
++ * __LINK_STATE_QDISC_RUNNING guarantees only one CPU can process this
++ * device at a time. dev->queue_lock serializes queue accesses for
++ * this device AND dev->qdisc pointer itself.
++ *
++ * netif_tx_lock serializes accesses to device driver.
++ *
++ * dev->queue_lock and netif_tx_lock are mutually exclusive,
++ * if one is grabbed, another must be free.
++ *
++ * Note, that this procedure can be called by a watchdog timer
++ *
++ * Returns to the caller:
++ * 0 - queue is empty or throttled.
++ * >0 - queue is not empty.
++ *
++ */
+ static inline int qdisc_restart(struct net_device *dev)
+ {
+ struct Qdisc *q = dev->qdisc;
+ struct sk_buff *skb;
++ unsigned lockless;
++ int ret;
+
+ /* Dequeue packet */
+- if (((skb = dev->gso_skb)) || ((skb = q->dequeue(q)))) {
+- unsigned nolock = (dev->features & NETIF_F_LLTX);
+-
+- dev->gso_skb = NULL;
++ if (unlikely((skb = dev_dequeue_skb(dev, q)) == NULL))
++ return 0;
+
+ /*
+- * When the driver has LLTX set it does its own locking
+- * in start_xmit. No need to add additional overhead by
+- * locking again. These checks are worth it because
+- * even uncongested locks can be quite expensive.
+- * The driver can do trylock like here too, in case
+- * of lock congestion it should return -1 and the packet
+- * will be requeued.
+- */
+- if (!nolock) {
+- if (!netif_tx_trylock(dev)) {
+- collision:
+- /* So, someone grabbed the driver. */
+-
+- /* It may be transient configuration error,
+- when hard_start_xmit() recurses. We detect
+- it by checking xmit owner and drop the
+- packet when deadloop is detected.
++ * When the driver has LLTX set, it does its own locking in
++ * start_xmit. These checks are worth it because even uncongested
++ * locks can be quite expensive. The driver can do a trylock, as
++ * is being done here; in case of lock contention it should return
++ * NETDEV_TX_LOCKED and the packet will be requeued.
+ */
+- if (dev->xmit_lock_owner == smp_processor_id()) {
+- kfree_skb(skb);
+- if (net_ratelimit())
+- printk(KERN_DEBUG "Dead loop on netdevice %s, fix it urgently!\n", dev->name);
+- goto out;
+- }
+- __get_cpu_var(netdev_rx_stat).cpu_collision++;
+- goto requeue;
+- }
++ lockless = (dev->features & NETIF_F_LLTX);
++
++ if (!lockless && !netif_tx_trylock(dev)) {
++ /* Another CPU grabbed the driver tx lock */
++ return handle_dev_cpu_collision(skb, dev, q);
+ }
+
+- {
+ /* And release queue */
+ spin_unlock(&dev->queue_lock);
+
+- if (!netif_queue_stopped(dev)) {
+- int ret;
+-
+ ret = dev_hard_start_xmit(skb, dev);
+- if (ret == NETDEV_TX_OK) {
+- if (!nolock) {
+- netif_tx_unlock(dev);
+- }
+- spin_lock(&dev->queue_lock);
+- q = dev->qdisc;
+- goto out;
+- }
+- if (ret == NETDEV_TX_LOCKED && nolock) {
+- spin_lock(&dev->queue_lock);
+- q = dev->qdisc;
+- goto collision;
+- }
+- }
+
+- /* NETDEV_TX_BUSY - we need to requeue */
+- /* Release the driver */
+- if (!nolock) {
++ if (!lockless)
+ netif_tx_unlock(dev);
+- }
++
+ spin_lock(&dev->queue_lock);
+ q = dev->qdisc;
+- }
+
+- /* Device kicked us out :(
+- This is possible in three cases:
++ switch (ret) {
++ case NETDEV_TX_OK:
++ /* Driver sent out skb successfully */
++ ret = qdisc_qlen(q);
++ break;
+
+- 0. driver is locked
+- 1. fastroute is enabled
+- 2. device cannot determine busy state
+- before start of transmission (f.e. dialout)
+- 3. device is buggy (ppp)
+- */
++ case NETDEV_TX_LOCKED:
++ /* Driver try lock failed */
++ ret = handle_dev_cpu_collision(skb, dev, q);
++ break;
+
+-requeue:
+- if (unlikely(q == &noop_qdisc))
+- kfree_skb(skb);
+- else if (skb->next)
+- dev->gso_skb = skb;
+- else
+- q->ops->requeue(skb, q);
+- netif_schedule(dev);
++ default:
++ /* Driver returned NETDEV_TX_BUSY - requeue skb */
++ if (unlikely (ret != NETDEV_TX_BUSY && net_ratelimit()))
++ printk(KERN_WARNING "BUG %s code %d qlen %d\n",
++ dev->name, ret, q->q.qlen);
++
++ ret = dev_requeue_skb(skb, dev, q);
++ break;
+ }
+- return 0;
+
+-out:
+- BUG_ON((int) q->q.qlen < 0);
+- return q->q.qlen;
++ return ret;
+ }
+
+ void __qdisc_run(struct net_device *dev)
+diff -Nurb linux-2.6.22-570/net/sched/sch_ingress.c linux-2.6.22-590/net/sched/sch_ingress.c
+--- linux-2.6.22-570/net/sched/sch_ingress.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/sched/sch_ingress.c 2008-01-29 22:12:32.000000000 -0500
+@@ -243,6 +243,10 @@
+ struct net_device *dev = skb->dev;
+ int fwres=NF_ACCEPT;
+
++ /* Only filter packets in the initial network namespace */
++ if ((indev?indev:outdev)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ DPRINTK("ing_hook: skb %s dev=%s len=%u\n",
+ skb->sk ? "(owned)" : "(unowned)",
+ skb->dev ? (*pskb)->dev->name : "(no dev)",
+diff -Nurb linux-2.6.22-570/net/sctp/input.c linux-2.6.22-590/net/sctp/input.c
+--- linux-2.6.22-570/net/sctp/input.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/sctp/input.c 2008-01-29 22:12:32.000000000 -0500
+@@ -126,6 +126,10 @@
+ int family;
+ struct sctp_af *af;
+
++ if (skb->dev->nd_net != &init_net) {
++ kfree_skb(skb);
++ return 0;
++ }
+ if (skb->pkt_type!=PACKET_HOST)
+ goto discard_it;
+
+@@ -509,6 +513,9 @@
+ sk_buff_data_t saveip, savesctp;
+ int err;
+
++ if (skb->dev->nd_net != &init_net)
++ return;
++
+ if (skb->len < ihlen + 8) {
+ ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
+ return;
+diff -Nurb linux-2.6.22-570/net/sctp/ipv6.c linux-2.6.22-590/net/sctp/ipv6.c
+--- linux-2.6.22-570/net/sctp/ipv6.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/sctp/ipv6.c 2008-01-29 22:12:32.000000000 -0500
+@@ -189,6 +189,7 @@
+
+ memset(&fl, 0, sizeof(fl));
+
++ fl.fl_net = &init_net;
+ fl.proto = sk->sk_protocol;
+
+ /* Fill in the dest address from the route entry passed with the skb
+@@ -230,6 +231,7 @@
+ struct flowi fl;
+
+ memset(&fl, 0, sizeof(fl));
++ fl.fl_net = &init_net;
+ ipv6_addr_copy(&fl.fl6_dst, &daddr->v6.sin6_addr);
+ if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
+ fl.oif = daddr->v6.sin6_scope_id;
+@@ -619,7 +621,7 @@
+ struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
+ struct sctp6_sock *newsctp6sk;
+
+- newsk = sk_alloc(PF_INET6, GFP_KERNEL, sk->sk_prot, 1);
++ newsk = sk_alloc(sk->sk_net, PF_INET6, GFP_KERNEL, sk->sk_prot, 1);
+ if (!newsk)
+ goto out;
+
+@@ -664,7 +666,7 @@
+ newinet->mc_index = 0;
+ newinet->mc_list = NULL;
+
+- if (ipv4_config.no_pmtu_disc)
++ if (init_net.sysctl_ipv4_no_pmtu_disc)
+ newinet->pmtudisc = IP_PMTUDISC_DONT;
+ else
+ newinet->pmtudisc = IP_PMTUDISC_WANT;
+@@ -841,7 +843,7 @@
+ if (type & IPV6_ADDR_LINKLOCAL) {
+ if (!addr->v6.sin6_scope_id)
+ return 0;
+- dev = dev_get_by_index(addr->v6.sin6_scope_id);
++ dev = dev_get_by_index(&init_net, addr->v6.sin6_scope_id);
+ if (!dev)
+ return 0;
+ if (!ipv6_chk_addr(&addr->v6.sin6_addr, dev, 0)) {
+@@ -872,7 +874,7 @@
+ if (type & IPV6_ADDR_LINKLOCAL) {
+ if (!addr->v6.sin6_scope_id)
+ return 0;
+- dev = dev_get_by_index(addr->v6.sin6_scope_id);
++ dev = dev_get_by_index(&init_net, addr->v6.sin6_scope_id);
+ if (!dev)
+ return 0;
+ if (!ipv6_chk_addr(&addr->v6.sin6_addr, dev, 0)) {
+diff -Nurb linux-2.6.22-570/net/sctp/protocol.c linux-2.6.22-590/net/sctp/protocol.c
+--- linux-2.6.22-570/net/sctp/protocol.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/sctp/protocol.c 2008-01-29 22:12:32.000000000 -0500
+@@ -59,6 +59,7 @@
+ #include <net/addrconf.h>
+ #include <net/inet_common.h>
+ #include <net/inet_ecn.h>
++#include <net/net_namespace.h>
+
+ /* Global data structures. */
+ struct sctp_globals sctp_globals __read_mostly;
+@@ -93,7 +94,7 @@
+ {
+ if (!proc_net_sctp) {
+ struct proc_dir_entry *ent;
+- ent = proc_mkdir("net/sctp", NULL);
++ ent = proc_mkdir("sctp", init_net.proc_net);
+ if (ent) {
+ ent->owner = THIS_MODULE;
+ proc_net_sctp = ent;
+@@ -126,7 +127,7 @@
+
+ if (proc_net_sctp) {
+ proc_net_sctp = NULL;
+- remove_proc_entry("net/sctp", NULL);
++ remove_proc_entry("sctp", init_net.proc_net);
+ }
+ }
+
+@@ -170,7 +171,7 @@
+ struct sctp_af *af;
+
+ read_lock(&dev_base_lock);
+- for_each_netdev(dev) {
++ for_each_netdev(&init_net, dev) {
+ __list_for_each(pos, &sctp_address_families) {
+ af = list_entry(pos, struct sctp_af, list);
+ af->copy_addrlist(&sctp_local_addr_list, dev);
+@@ -354,13 +355,13 @@
+ /* Should this be available for binding? */
+ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
+ {
+- int ret = inet_addr_type(addr->v4.sin_addr.s_addr);
++ int ret = inet_addr_type(&init_net, addr->v4.sin_addr.s_addr);
+
+
+ if (addr->v4.sin_addr.s_addr != INADDR_ANY &&
+ ret != RTN_LOCAL &&
+ !sp->inet.freebind &&
+- !sysctl_ip_nonlocal_bind)
++ !init_net.sysctl_ip_nonlocal_bind)
+ return 0;
+
+ return 1;
+@@ -423,6 +424,7 @@
+ union sctp_addr dst_saddr;
+
+ memset(&fl, 0x0, sizeof(struct flowi));
++ fl.fl_net = &init_net;
+ fl.fl4_dst = daddr->v4.sin_addr.s_addr;
+ fl.proto = IPPROTO_SCTP;
+ if (asoc) {
+@@ -539,7 +541,7 @@
+ {
+ struct inet_sock *inet = inet_sk(sk);
+ struct inet_sock *newinet;
+- struct sock *newsk = sk_alloc(PF_INET, GFP_KERNEL, sk->sk_prot, 1);
++ struct sock *newsk = sk_alloc(sk->sk_net, PF_INET, GFP_KERNEL, sk->sk_prot, 1);
+
+ if (!newsk)
+ goto out;
+@@ -1122,7 +1124,7 @@
+ }
+
+ spin_lock_init(&sctp_port_alloc_lock);
+- sctp_port_rover = sysctl_local_port_range[0] - 1;
++ sctp_port_rover = init_net.sysctl_local_port_range[0] - 1;
+
+ printk(KERN_INFO "SCTP: Hash tables configured "
+ "(established %d bind %d)\n",
+diff -Nurb linux-2.6.22-570/net/sctp/socket.c linux-2.6.22-590/net/sctp/socket.c
+--- linux-2.6.22-570/net/sctp/socket.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/sctp/socket.c 2008-01-29 22:12:32.000000000 -0500
+@@ -5021,8 +5021,8 @@
+ * already in the hash table; if not, we use that; if
+ * it is, we try next.
+ */
+- int low = sysctl_local_port_range[0];
+- int high = sysctl_local_port_range[1];
++ int low = sk->sk_net->sysctl_local_port_range[0];
++ int high = sk->sk_net->sysctl_local_port_range[1];
+ int remaining = (high - low) + 1;
+ int rover;
+ int index;
+diff -Nurb linux-2.6.22-570/net/socket.c linux-2.6.22-590/net/socket.c
+--- linux-2.6.22-570/net/socket.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/socket.c 2008-01-29 22:12:32.000000000 -0500
+@@ -84,6 +84,7 @@
+ #include <linux/kmod.h>
+ #include <linux/audit.h>
+ #include <linux/wireless.h>
++#include <linux/nsproxy.h>
+
+ #include <asm/uaccess.h>
+ #include <asm/unistd.h>
+@@ -821,9 +822,9 @@
+ */
+
+ static DEFINE_MUTEX(br_ioctl_mutex);
+-static int (*br_ioctl_hook) (unsigned int cmd, void __user *arg) = NULL;
++static int (*br_ioctl_hook) (struct net *, unsigned int cmd, void __user *arg) = NULL;
+
+-void brioctl_set(int (*hook) (unsigned int, void __user *))
++void brioctl_set(int (*hook) (struct net *, unsigned int, void __user *))
+ {
+ mutex_lock(&br_ioctl_mutex);
+ br_ioctl_hook = hook;
+@@ -833,9 +834,9 @@
+ EXPORT_SYMBOL(brioctl_set);
+
+ static DEFINE_MUTEX(vlan_ioctl_mutex);
+-static int (*vlan_ioctl_hook) (void __user *arg);
++static int (*vlan_ioctl_hook) (struct net *, void __user *arg);
+
+-void vlan_ioctl_set(int (*hook) (void __user *))
++void vlan_ioctl_set(int (*hook) (struct net *, void __user *))
+ {
+ mutex_lock(&vlan_ioctl_mutex);
+ vlan_ioctl_hook = hook;
+@@ -864,16 +865,20 @@
+ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
+ {
+ struct socket *sock;
++ struct sock *sk;
+ void __user *argp = (void __user *)arg;
+ int pid, err;
++ struct net *net;
+
+ sock = file->private_data;
++ sk = sock->sk;
++ net = sk->sk_net;
+ if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
+- err = dev_ioctl(cmd, argp);
++ err = dev_ioctl(net, cmd, argp);
+ } else
+ #ifdef CONFIG_WIRELESS_EXT
+ if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
+- err = dev_ioctl(cmd, argp);
++ err = dev_ioctl(net, cmd, argp);
+ } else
+ #endif /* CONFIG_WIRELESS_EXT */
+ switch (cmd) {
+@@ -899,7 +904,7 @@
+
+ mutex_lock(&br_ioctl_mutex);
+ if (br_ioctl_hook)
+- err = br_ioctl_hook(cmd, argp);
++ err = br_ioctl_hook(net, cmd, argp);
+ mutex_unlock(&br_ioctl_mutex);
break;
-+ }
+ case SIOCGIFVLAN:
+@@ -910,7 +915,7 @@
+
+ mutex_lock(&vlan_ioctl_mutex);
+ if (vlan_ioctl_hook)
+- err = vlan_ioctl_hook(argp);
++ err = vlan_ioctl_hook(net, argp);
+ mutex_unlock(&vlan_ioctl_mutex);
+ break;
+ case SIOCADDDLCI:
+@@ -933,7 +938,7 @@
+ * to the NIC driver.
+ */
+ if (err == -ENOIOCTLCMD)
+- err = dev_ioctl(cmd, argp);
++ err = dev_ioctl(net, cmd, argp);
+ break;
+ }
+ return err;
+@@ -1102,7 +1107,7 @@
+ return 0;
+ }
+
+-static int __sock_create(int family, int type, int protocol,
++static int __sock_create(struct net *net, int family, int type, int protocol,
+ struct socket **res, int kern)
+ {
+ int err;
+@@ -1185,7 +1190,7 @@
+ /* Now protected by module ref count */
+ rcu_read_unlock();
+
+- err = pf->create(sock, protocol);
++ err = pf->create(net, sock, protocol);
+ if (err < 0)
+ goto out_module_put;
+
+@@ -1224,12 +1229,12 @@
+
+ int sock_create(int family, int type, int protocol, struct socket **res)
+ {
+- return __sock_create(family, type, protocol, res, 0);
++ return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);
+ }
+
+ int sock_create_kern(int family, int type, int protocol, struct socket **res)
+ {
+- return __sock_create(family, type, protocol, res, 1);
++ return __sock_create(&init_net, family, type, protocol, res, 1);
+ }
+
+ asmlinkage long sys_socket(int family, int type, int protocol)
+@@ -1389,8 +1394,6 @@
+ * ready for listening.
+ */
+
+-int sysctl_somaxconn __read_mostly = SOMAXCONN;
+-
+ asmlinkage long sys_listen(int fd, int backlog)
+ {
+ struct socket *sock;
+@@ -1398,8 +1401,9 @@
+
+ sock = sockfd_lookup_light(fd, &err, &fput_needed);
+ if (sock) {
+- if ((unsigned)backlog > sysctl_somaxconn)
+- backlog = sysctl_somaxconn;
++ struct net *net = sock->sk->sk_net;
++ if ((unsigned)backlog > net->sysctl_somaxconn)
++ backlog = net->sysctl_somaxconn;
+
+ err = security_socket_listen(sock, backlog);
+ if (!err)
+@@ -2189,6 +2193,16 @@
+ printk(KERN_INFO "NET: Unregistered protocol family %d\n", family);
+ }
+
++static int sock_pernet_init(struct net *net)
++{
++ net->sysctl_somaxconn = SOMAXCONN;
++ return 0;
++}
++
++static struct pernet_operations sock_net_ops = {
++ .init = sock_pernet_init,
++};
++
+ static int __init sock_init(void)
+ {
+ /*
+@@ -2217,6 +2231,8 @@
+ netfilter_init();
#endif
- default:
- filtered = 0;
-@@ -611,9 +639,7 @@
- struct iovec *iov;
- u8 __user *type = NULL;
- u8 __user *code = NULL;
--#ifdef CONFIG_IPV6_MIP6
- u8 len = 0;
--#endif
- int probed = 0;
- int i;
-@@ -646,7 +672,6 @@
- probed = 1;
- }
- break;
--#ifdef CONFIG_IPV6_MIP6
- case IPPROTO_MH:
- if (iov->iov_base && iov->iov_len < 1)
- break;
-@@ -660,7 +685,6 @@
- len += iov->iov_len;
++ register_pernet_subsys(&sock_net_ops);
++
+ return 0;
+ }
- break;
+diff -Nurb linux-2.6.22-570/net/socket.c.orig linux-2.6.22-590/net/socket.c.orig
+--- linux-2.6.22-570/net/socket.c.orig 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/socket.c.orig 1969-12-31 19:00:00.000000000 -0500
+@@ -1,2344 +0,0 @@
+-/*
+- * NET An implementation of the SOCKET network access protocol.
+- *
+- * Version: @(#)socket.c 1.1.93 18/02/95
+- *
+- * Authors: Orest Zborowski, <obz@Kodak.COM>
+- * Ross Biro
+- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+- *
+- * Fixes:
+- * Anonymous : NOTSOCK/BADF cleanup. Error fix in
+- * shutdown()
+- * Alan Cox : verify_area() fixes
+- * Alan Cox : Removed DDI
+- * Jonathan Kamens : SOCK_DGRAM reconnect bug
+- * Alan Cox : Moved a load of checks to the very
+- * top level.
+- * Alan Cox : Move address structures to/from user
+- * mode above the protocol layers.
+- * Rob Janssen : Allow 0 length sends.
+- * Alan Cox : Asynchronous I/O support (cribbed from the
+- * tty drivers).
+- * Niibe Yutaka : Asynchronous I/O for writes (4.4BSD style)
+- * Jeff Uphoff : Made max number of sockets command-line
+- * configurable.
+- * Matti Aarnio : Made the number of sockets dynamic,
+- * to be allocated when needed, and mr.
+- * Uphoff's max is used as max to be
+- * allowed to allocate.
+- * Linus : Argh. removed all the socket allocation
+- * altogether: it's in the inode now.
+- * Alan Cox : Made sock_alloc()/sock_release() public
+- * for NetROM and future kernel nfsd type
+- * stuff.
+- * Alan Cox : sendmsg/recvmsg basics.
+- * Tom Dyas : Export net symbols.
+- * Marcin Dalecki : Fixed problems with CONFIG_NET="n".
+- * Alan Cox : Added thread locking to sys_* calls
+- * for sockets. May have errors at the
+- * moment.
+- * Kevin Buhr : Fixed the dumb errors in the above.
+- * Andi Kleen : Some small cleanups, optimizations,
+- * and fixed a copy_from_user() bug.
+- * Tigran Aivazian : sys_send(args) calls sys_sendto(args, NULL, 0)
+- * Tigran Aivazian : Made listen(2) backlog sanity checks
+- * protocol-independent
+- *
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- *
+- *
+- * This module is effectively the top level interface to the BSD socket
+- * paradigm.
+- *
+- * Based upon Swansea University Computer Society NET3.039
+- */
+-
+-#include <linux/mm.h>
+-#include <linux/socket.h>
+-#include <linux/file.h>
+-#include <linux/net.h>
+-#include <linux/interrupt.h>
+-#include <linux/rcupdate.h>
+-#include <linux/netdevice.h>
+-#include <linux/proc_fs.h>
+-#include <linux/seq_file.h>
+-#include <linux/mutex.h>
+-#include <linux/wanrouter.h>
+-#include <linux/if_bridge.h>
+-#include <linux/if_frad.h>
+-#include <linux/if_vlan.h>
+-#include <linux/init.h>
+-#include <linux/poll.h>
+-#include <linux/cache.h>
+-#include <linux/module.h>
+-#include <linux/highmem.h>
+-#include <linux/mount.h>
+-#include <linux/security.h>
+-#include <linux/syscalls.h>
+-#include <linux/compat.h>
+-#include <linux/kmod.h>
+-#include <linux/audit.h>
+-#include <linux/wireless.h>
+-
+-#include <asm/uaccess.h>
+-#include <asm/unistd.h>
+-
+-#include <net/compat.h>
+-
+-#include <net/sock.h>
+-#include <linux/netfilter.h>
+-
+-static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
+-static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
+- unsigned long nr_segs, loff_t pos);
+-static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov,
+- unsigned long nr_segs, loff_t pos);
+-static int sock_mmap(struct file *file, struct vm_area_struct *vma);
+-
+-static int sock_close(struct inode *inode, struct file *file);
+-static unsigned int sock_poll(struct file *file,
+- struct poll_table_struct *wait);
+-static long sock_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+-#ifdef CONFIG_COMPAT
+-static long compat_sock_ioctl(struct file *file,
+- unsigned int cmd, unsigned long arg);
+-#endif
+-static int sock_fasync(int fd, struct file *filp, int on);
+-static ssize_t sock_sendpage(struct file *file, struct page *page,
+- int offset, size_t size, loff_t *ppos, int more);
+-
+-/*
+- * Socket files have a set of 'special' operations as well as the generic file ones. These don't appear
+- * in the operation structures but are done directly via the socketcall() multiplexor.
+- */
+-
+-static const struct file_operations socket_file_ops = {
+- .owner = THIS_MODULE,
+- .llseek = no_llseek,
+- .aio_read = sock_aio_read,
+- .aio_write = sock_aio_write,
+- .poll = sock_poll,
+- .unlocked_ioctl = sock_ioctl,
+-#ifdef CONFIG_COMPAT
+- .compat_ioctl = compat_sock_ioctl,
+-#endif
+- .mmap = sock_mmap,
+- .open = sock_no_open, /* special open code to disallow open via /proc */
+- .release = sock_close,
+- .fasync = sock_fasync,
+- .sendpage = sock_sendpage,
+- .splice_write = generic_splice_sendpage,
+-};
+-
+-/*
+- * The protocol list. Each protocol is registered in here.
+- */
+-
+-static DEFINE_SPINLOCK(net_family_lock);
+-static const struct net_proto_family *net_families[NPROTO] __read_mostly;
+-
+-/*
+- * Statistics counters of the socket lists
+- */
+-
+-static DEFINE_PER_CPU(int, sockets_in_use) = 0;
+-
+-/*
+- * Support routines.
+- * Move socket addresses back and forth across the kernel/user
+- * divide and look after the messy bits.
+- */
+-
+-#define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
+- 16 for IP, 16 for IPX,
+- 24 for IPv6,
+- about 80 for AX.25
+- must be at least one bigger than
+- the AF_UNIX size (see net/unix/af_unix.c
+- :unix_mkname()).
+- */
+-
+-/**
+- * move_addr_to_kernel - copy a socket address into kernel space
+- * @uaddr: Address in user space
+- * @kaddr: Address in kernel space
+- * @ulen: Length in user space
+- *
+- * The address is copied into kernel space. If the provided address is
+- * too long an error code of -EINVAL is returned. If the copy gives
+- * invalid addresses -EFAULT is returned. On a success 0 is returned.
+- */
+-
+-int move_addr_to_kernel(void __user *uaddr, int ulen, void *kaddr)
+-{
+- if (ulen < 0 || ulen > MAX_SOCK_ADDR)
+- return -EINVAL;
+- if (ulen == 0)
+- return 0;
+- if (copy_from_user(kaddr, uaddr, ulen))
+- return -EFAULT;
+- return audit_sockaddr(ulen, kaddr);
+-}
+-
+-/**
+- * move_addr_to_user - copy an address to user space
+- * @kaddr: kernel space address
+- * @klen: length of address in kernel
+- * @uaddr: user space address
+- * @ulen: pointer to user length field
+- *
+- * The value pointed to by ulen on entry is the buffer length available.
+- * This is overwritten with the buffer space used. -EINVAL is returned
+- * if an overlong buffer is specified or a negative buffer size. -EFAULT
+- * is returned if either the buffer or the length field are not
+- * accessible.
+- * After copying the data up to the limit the user specifies, the true
+- * length of the data is written over the length limit the user
+- * specified. Zero is returned for a success.
+- */
+-
+-int move_addr_to_user(void *kaddr, int klen, void __user *uaddr,
+- int __user *ulen)
+-{
+- int err;
+- int len;
+-
+- err = get_user(len, ulen);
+- if (err)
+- return err;
+- if (len > klen)
+- len = klen;
+- if (len < 0 || len > MAX_SOCK_ADDR)
+- return -EINVAL;
+- if (len) {
+- if (audit_sockaddr(klen, kaddr))
+- return -ENOMEM;
+- if (copy_to_user(uaddr, kaddr, len))
+- return -EFAULT;
+- }
+- /*
+- * "fromlen shall refer to the value before truncation.."
+- * 1003.1g
+- */
+- return __put_user(klen, ulen);
+-}
+-
+-#define SOCKFS_MAGIC 0x534F434B
+-
+-static struct kmem_cache *sock_inode_cachep __read_mostly;
+-
+-static struct inode *sock_alloc_inode(struct super_block *sb)
+-{
+- struct socket_alloc *ei;
+-
+- ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL);
+- if (!ei)
+- return NULL;
+- init_waitqueue_head(&ei->socket.wait);
+-
+- ei->socket.fasync_list = NULL;
+- ei->socket.state = SS_UNCONNECTED;
+- ei->socket.flags = 0;
+- ei->socket.ops = NULL;
+- ei->socket.sk = NULL;
+- ei->socket.file = NULL;
+-
+- return &ei->vfs_inode;
+-}
+-
+-static void sock_destroy_inode(struct inode *inode)
+-{
+- kmem_cache_free(sock_inode_cachep,
+- container_of(inode, struct socket_alloc, vfs_inode));
+-}
+-
+-static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
+-{
+- struct socket_alloc *ei = (struct socket_alloc *)foo;
+-
+- inode_init_once(&ei->vfs_inode);
+-}
+-
+-static int init_inodecache(void)
+-{
+- sock_inode_cachep = kmem_cache_create("sock_inode_cache",
+- sizeof(struct socket_alloc),
+- 0,
+- (SLAB_HWCACHE_ALIGN |
+- SLAB_RECLAIM_ACCOUNT |
+- SLAB_MEM_SPREAD),
+- init_once,
+- NULL);
+- if (sock_inode_cachep == NULL)
+- return -ENOMEM;
+- return 0;
+-}
+-
+-static struct super_operations sockfs_ops = {
+- .alloc_inode = sock_alloc_inode,
+- .destroy_inode =sock_destroy_inode,
+- .statfs = simple_statfs,
+-};
+-
+-static int sockfs_get_sb(struct file_system_type *fs_type,
+- int flags, const char *dev_name, void *data,
+- struct vfsmount *mnt)
+-{
+- return get_sb_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC,
+- mnt);
+-}
+-
+-static struct vfsmount *sock_mnt __read_mostly;
+-
+-static struct file_system_type sock_fs_type = {
+- .name = "sockfs",
+- .get_sb = sockfs_get_sb,
+- .kill_sb = kill_anon_super,
+-};
+-
+-static int sockfs_delete_dentry(struct dentry *dentry)
+-{
+- /*
+- * At creation time, we pretended this dentry was hashed
+- * (by clearing DCACHE_UNHASHED bit in d_flags)
+- * At delete time, we restore the truth : not hashed.
+- * (so that dput() can proceed correctly)
+- */
+- dentry->d_flags |= DCACHE_UNHASHED;
+- return 0;
+-}
+-
+-/*
+- * sockfs_dname() is called from d_path().
+- */
+-static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen)
+-{
+- return dynamic_dname(dentry, buffer, buflen, "socket:[%lu]",
+- dentry->d_inode->i_ino);
+-}
+-
+-static struct dentry_operations sockfs_dentry_operations = {
+- .d_delete = sockfs_delete_dentry,
+- .d_dname = sockfs_dname,
+-};
+-
+-/*
+- * Obtains the first available file descriptor and sets it up for use.
+- *
+- * These functions create file structures and maps them to fd space
+- * of the current process. On success it returns file descriptor
+- * and file struct implicitly stored in sock->file.
+- * Note that another thread may close file descriptor before we return
+- * from this function. We use the fact that now we do not refer
+- * to socket after mapping. If one day we will need it, this
+- * function will increment ref. count on file by 1.
+- *
+- * In any case returned fd MAY BE not valid!
+- * This race condition is unavoidable
+- * with shared fd spaces, we cannot solve it inside kernel,
+- * but we take care of internal coherence yet.
+- */
+-
+-static int sock_alloc_fd(struct file **filep)
+-{
+- int fd;
+-
+- fd = get_unused_fd();
+- if (likely(fd >= 0)) {
+- struct file *file = get_empty_filp();
+-
+- *filep = file;
+- if (unlikely(!file)) {
+- put_unused_fd(fd);
+- return -ENFILE;
+- }
+- } else
+- *filep = NULL;
+- return fd;
+-}
+-
+-static int sock_attach_fd(struct socket *sock, struct file *file)
+-{
+- struct qstr name = { .name = "" };
+-
+- file->f_path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name);
+- if (unlikely(!file->f_path.dentry))
+- return -ENOMEM;
+-
+- file->f_path.dentry->d_op = &sockfs_dentry_operations;
+- /*
+- * We dont want to push this dentry into global dentry hash table.
+- * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED
+- * This permits a working /proc/$pid/fd/XXX on sockets
+- */
+- file->f_path.dentry->d_flags &= ~DCACHE_UNHASHED;
+- d_instantiate(file->f_path.dentry, SOCK_INODE(sock));
+- file->f_path.mnt = mntget(sock_mnt);
+- file->f_mapping = file->f_path.dentry->d_inode->i_mapping;
+-
+- sock->file = file;
+- file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops;
+- file->f_mode = FMODE_READ | FMODE_WRITE;
+- file->f_flags = O_RDWR;
+- file->f_pos = 0;
+- file->private_data = sock;
+-
+- return 0;
+-}
+-
+-int sock_map_fd(struct socket *sock)
+-{
+- struct file *newfile;
+- int fd = sock_alloc_fd(&newfile);
+-
+- if (likely(fd >= 0)) {
+- int err = sock_attach_fd(sock, newfile);
+-
+- if (unlikely(err < 0)) {
+- put_filp(newfile);
+- put_unused_fd(fd);
+- return err;
+- }
+- fd_install(fd, newfile);
+- }
+- return fd;
+-}
+-
+-static struct socket *sock_from_file(struct file *file, int *err)
+-{
+- if (file->f_op == &socket_file_ops)
+- return file->private_data; /* set in sock_map_fd */
+-
+- *err = -ENOTSOCK;
+- return NULL;
+-}
+-
+-/**
+- * sockfd_lookup - Go from a file number to its socket slot
+- * @fd: file handle
+- * @err: pointer to an error code return
+- *
+- * The file handle passed in is locked and the socket it is bound
+- * too is returned. If an error occurs the err pointer is overwritten
+- * with a negative errno code and NULL is returned. The function checks
+- * for both invalid handles and passing a handle which is not a socket.
+- *
+- * On a success the socket object pointer is returned.
+- */
+-
+-struct socket *sockfd_lookup(int fd, int *err)
+-{
+- struct file *file;
+- struct socket *sock;
+-
+- file = fget(fd);
+- if (!file) {
+- *err = -EBADF;
+- return NULL;
+- }
+-
+- sock = sock_from_file(file, err);
+- if (!sock)
+- fput(file);
+- return sock;
+-}
+-
+-static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
+-{
+- struct file *file;
+- struct socket *sock;
+-
+- *err = -EBADF;
+- file = fget_light(fd, fput_needed);
+- if (file) {
+- sock = sock_from_file(file, err);
+- if (sock)
+- return sock;
+- fput_light(file, *fput_needed);
+- }
+- return NULL;
+-}
+-
+-/**
+- * sock_alloc - allocate a socket
+- *
+- * Allocate a new inode and socket object. The two are bound together
+- * and initialised. The socket is then returned. If we are out of inodes
+- * NULL is returned.
+- */
+-
+-static struct socket *sock_alloc(void)
+-{
+- struct inode *inode;
+- struct socket *sock;
+-
+- inode = new_inode(sock_mnt->mnt_sb);
+- if (!inode)
+- return NULL;
+-
+- sock = SOCKET_I(inode);
+-
+- inode->i_mode = S_IFSOCK | S_IRWXUGO;
+- inode->i_uid = current->fsuid;
+- inode->i_gid = current->fsgid;
+-
+- get_cpu_var(sockets_in_use)++;
+- put_cpu_var(sockets_in_use);
+- return sock;
+-}
+-
+-/*
+- * In theory you can't get an open on this inode, but /proc provides
+- * a back door. Remember to keep it shut otherwise you'll let the
+- * creepy crawlies in.
+- */
+-
+-static int sock_no_open(struct inode *irrelevant, struct file *dontcare)
+-{
+- return -ENXIO;
+-}
+-
+-const struct file_operations bad_sock_fops = {
+- .owner = THIS_MODULE,
+- .open = sock_no_open,
+-};
+-
+-/**
+- * sock_release - close a socket
+- * @sock: socket to close
+- *
+- * The socket is released from the protocol stack if it has a release
+- * callback, and the inode is then released if the socket is bound to
+- * an inode not a file.
+- */
+-
+-void sock_release(struct socket *sock)
+-{
+- if (sock->ops) {
+- struct module *owner = sock->ops->owner;
+-
+- sock->ops->release(sock);
+- sock->ops = NULL;
+- module_put(owner);
+- }
+-
+- if (sock->fasync_list)
+- printk(KERN_ERR "sock_release: fasync list not empty!\n");
+-
+- get_cpu_var(sockets_in_use)--;
+- put_cpu_var(sockets_in_use);
+- if (!sock->file) {
+- iput(SOCK_INODE(sock));
+- return;
+- }
+- sock->file = NULL;
+-}
+-
+-static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock,
+- struct msghdr *msg, size_t size)
+-{
+- struct sock_iocb *si = kiocb_to_siocb(iocb);
+- int err;
+-
+- si->sock = sock;
+- si->scm = NULL;
+- si->msg = msg;
+- si->size = size;
+-
+- err = security_socket_sendmsg(sock, msg, size);
+- if (err)
+- return err;
+-
+- return sock->ops->sendmsg(iocb, sock, msg, size);
+-}
+-
+-int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
+-{
+- struct kiocb iocb;
+- struct sock_iocb siocb;
+- int ret;
+-
+- init_sync_kiocb(&iocb, NULL);
+- iocb.private = &siocb;
+- ret = __sock_sendmsg(&iocb, sock, msg, size);
+- if (-EIOCBQUEUED == ret)
+- ret = wait_on_sync_kiocb(&iocb);
+- return ret;
+-}
+-
+-int kernel_sendmsg(struct socket *sock, struct msghdr *msg,
+- struct kvec *vec, size_t num, size_t size)
+-{
+- mm_segment_t oldfs = get_fs();
+- int result;
+-
+- set_fs(KERNEL_DS);
+- /*
+- * the following is safe, since for compiler definitions of kvec and
+- * iovec are identical, yielding the same in-core layout and alignment
+- */
+- msg->msg_iov = (struct iovec *)vec;
+- msg->msg_iovlen = num;
+- result = sock_sendmsg(sock, msg, size);
+- set_fs(oldfs);
+- return result;
+-}
+-
+-/*
+- * called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP)
+- */
+-void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
+- struct sk_buff *skb)
+-{
+- ktime_t kt = skb->tstamp;
+-
+- if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) {
+- struct timeval tv;
+- /* Race occurred between timestamp enabling and packet
+- receiving. Fill in the current time for now. */
+- if (kt.tv64 == 0)
+- kt = ktime_get_real();
+- skb->tstamp = kt;
+- tv = ktime_to_timeval(kt);
+- put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMP, sizeof(tv), &tv);
+- } else {
+- struct timespec ts;
+- /* Race occurred between timestamp enabling and packet
+- receiving. Fill in the current time for now. */
+- if (kt.tv64 == 0)
+- kt = ktime_get_real();
+- skb->tstamp = kt;
+- ts = ktime_to_timespec(kt);
+- put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS, sizeof(ts), &ts);
+- }
+-}
+-
+-EXPORT_SYMBOL_GPL(__sock_recv_timestamp);
+-
+-static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock,
+- struct msghdr *msg, size_t size, int flags)
+-{
+- int err;
+- struct sock_iocb *si = kiocb_to_siocb(iocb);
+-
+- si->sock = sock;
+- si->scm = NULL;
+- si->msg = msg;
+- si->size = size;
+- si->flags = flags;
+-
+- err = security_socket_recvmsg(sock, msg, size, flags);
+- if (err)
+- return err;
+-
+- return sock->ops->recvmsg(iocb, sock, msg, size, flags);
+-}
+-
+-int sock_recvmsg(struct socket *sock, struct msghdr *msg,
+- size_t size, int flags)
+-{
+- struct kiocb iocb;
+- struct sock_iocb siocb;
+- int ret;
+-
+- init_sync_kiocb(&iocb, NULL);
+- iocb.private = &siocb;
+- ret = __sock_recvmsg(&iocb, sock, msg, size, flags);
+- if (-EIOCBQUEUED == ret)
+- ret = wait_on_sync_kiocb(&iocb);
+- return ret;
+-}
+-
+-int kernel_recvmsg(struct socket *sock, struct msghdr *msg,
+- struct kvec *vec, size_t num, size_t size, int flags)
+-{
+- mm_segment_t oldfs = get_fs();
+- int result;
+-
+- set_fs(KERNEL_DS);
+- /*
+- * the following is safe, since for compiler definitions of kvec and
+- * iovec are identical, yielding the same in-core layout and alignment
+- */
+- msg->msg_iov = (struct iovec *)vec, msg->msg_iovlen = num;
+- result = sock_recvmsg(sock, msg, size, flags);
+- set_fs(oldfs);
+- return result;
+-}
+-
+-static void sock_aio_dtor(struct kiocb *iocb)
+-{
+- kfree(iocb->private);
+-}
+-
+-static ssize_t sock_sendpage(struct file *file, struct page *page,
+- int offset, size_t size, loff_t *ppos, int more)
+-{
+- struct socket *sock;
+- int flags;
+-
+- sock = file->private_data;
+-
+- flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
+- if (more)
+- flags |= MSG_MORE;
+-
+- return sock->ops->sendpage(sock, page, offset, size, flags);
+-}
+-
+-static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb,
+- struct sock_iocb *siocb)
+-{
+- if (!is_sync_kiocb(iocb)) {
+- siocb = kmalloc(sizeof(*siocb), GFP_KERNEL);
+- if (!siocb)
+- return NULL;
+- iocb->ki_dtor = sock_aio_dtor;
+- }
+-
+- siocb->kiocb = iocb;
+- iocb->private = siocb;
+- return siocb;
+-}
+-
+-static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb,
+- struct file *file, const struct iovec *iov,
+- unsigned long nr_segs)
+-{
+- struct socket *sock = file->private_data;
+- size_t size = 0;
+- int i;
+-
+- for (i = 0; i < nr_segs; i++)
+- size += iov[i].iov_len;
+-
+- msg->msg_name = NULL;
+- msg->msg_namelen = 0;
+- msg->msg_control = NULL;
+- msg->msg_controllen = 0;
+- msg->msg_iov = (struct iovec *)iov;
+- msg->msg_iovlen = nr_segs;
+- msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
+-
+- return __sock_recvmsg(iocb, sock, msg, size, msg->msg_flags);
+-}
+-
+-static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
+- unsigned long nr_segs, loff_t pos)
+-{
+- struct sock_iocb siocb, *x;
+-
+- if (pos != 0)
+- return -ESPIPE;
+-
+- if (iocb->ki_left == 0) /* Match SYS5 behaviour */
+- return 0;
+-
+-
+- x = alloc_sock_iocb(iocb, &siocb);
+- if (!x)
+- return -ENOMEM;
+- return do_sock_read(&x->async_msg, iocb, iocb->ki_filp, iov, nr_segs);
+-}
+-
+-static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb,
+- struct file *file, const struct iovec *iov,
+- unsigned long nr_segs)
+-{
+- struct socket *sock = file->private_data;
+- size_t size = 0;
+- int i;
+-
+- for (i = 0; i < nr_segs; i++)
+- size += iov[i].iov_len;
+-
+- msg->msg_name = NULL;
+- msg->msg_namelen = 0;
+- msg->msg_control = NULL;
+- msg->msg_controllen = 0;
+- msg->msg_iov = (struct iovec *)iov;
+- msg->msg_iovlen = nr_segs;
+- msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
+- if (sock->type == SOCK_SEQPACKET)
+- msg->msg_flags |= MSG_EOR;
+-
+- return __sock_sendmsg(iocb, sock, msg, size);
+-}
+-
+-static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov,
+- unsigned long nr_segs, loff_t pos)
+-{
+- struct sock_iocb siocb, *x;
+-
+- if (pos != 0)
+- return -ESPIPE;
+-
+- x = alloc_sock_iocb(iocb, &siocb);
+- if (!x)
+- return -ENOMEM;
+-
+- return do_sock_write(&x->async_msg, iocb, iocb->ki_filp, iov, nr_segs);
+-}
+-
+-/*
+- * Atomic setting of ioctl hooks to avoid race
+- * with module unload.
+- */
+-
+-static DEFINE_MUTEX(br_ioctl_mutex);
+-static int (*br_ioctl_hook) (unsigned int cmd, void __user *arg) = NULL;
+-
+-void brioctl_set(int (*hook) (unsigned int, void __user *))
+-{
+- mutex_lock(&br_ioctl_mutex);
+- br_ioctl_hook = hook;
+- mutex_unlock(&br_ioctl_mutex);
+-}
+-
+-EXPORT_SYMBOL(brioctl_set);
+-
+-static DEFINE_MUTEX(vlan_ioctl_mutex);
+-static int (*vlan_ioctl_hook) (void __user *arg);
+-
+-void vlan_ioctl_set(int (*hook) (void __user *))
+-{
+- mutex_lock(&vlan_ioctl_mutex);
+- vlan_ioctl_hook = hook;
+- mutex_unlock(&vlan_ioctl_mutex);
+-}
+-
+-EXPORT_SYMBOL(vlan_ioctl_set);
+-
+-static DEFINE_MUTEX(dlci_ioctl_mutex);
+-static int (*dlci_ioctl_hook) (unsigned int, void __user *);
+-
+-void dlci_ioctl_set(int (*hook) (unsigned int, void __user *))
+-{
+- mutex_lock(&dlci_ioctl_mutex);
+- dlci_ioctl_hook = hook;
+- mutex_unlock(&dlci_ioctl_mutex);
+-}
+-
+-EXPORT_SYMBOL(dlci_ioctl_set);
+-
+-/*
+- * With an ioctl, arg may well be a user mode pointer, but we don't know
+- * what to do with it - that's up to the protocol still.
+- */
+-
+-static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
+-{
+- struct socket *sock;
+- void __user *argp = (void __user *)arg;
+- int pid, err;
+-
+- sock = file->private_data;
+- if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
+- err = dev_ioctl(cmd, argp);
+- } else
+-#ifdef CONFIG_WIRELESS_EXT
+- if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
+- err = dev_ioctl(cmd, argp);
+- } else
+-#endif /* CONFIG_WIRELESS_EXT */
+- switch (cmd) {
+- case FIOSETOWN:
+- case SIOCSPGRP:
+- err = -EFAULT;
+- if (get_user(pid, (int __user *)argp))
+- break;
+- err = f_setown(sock->file, pid, 1);
+- break;
+- case FIOGETOWN:
+- case SIOCGPGRP:
+- err = put_user(f_getown(sock->file),
+- (int __user *)argp);
+- break;
+- case SIOCGIFBR:
+- case SIOCSIFBR:
+- case SIOCBRADDBR:
+- case SIOCBRDELBR:
+- err = -ENOPKG;
+- if (!br_ioctl_hook)
+- request_module("bridge");
+-
+- mutex_lock(&br_ioctl_mutex);
+- if (br_ioctl_hook)
+- err = br_ioctl_hook(cmd, argp);
+- mutex_unlock(&br_ioctl_mutex);
+- break;
+- case SIOCGIFVLAN:
+- case SIOCSIFVLAN:
+- err = -ENOPKG;
+- if (!vlan_ioctl_hook)
+- request_module("8021q");
+-
+- mutex_lock(&vlan_ioctl_mutex);
+- if (vlan_ioctl_hook)
+- err = vlan_ioctl_hook(argp);
+- mutex_unlock(&vlan_ioctl_mutex);
+- break;
+- case SIOCADDDLCI:
+- case SIOCDELDLCI:
+- err = -ENOPKG;
+- if (!dlci_ioctl_hook)
+- request_module("dlci");
+-
+- if (dlci_ioctl_hook) {
+- mutex_lock(&dlci_ioctl_mutex);
+- err = dlci_ioctl_hook(cmd, argp);
+- mutex_unlock(&dlci_ioctl_mutex);
+- }
+- break;
+- default:
+- err = sock->ops->ioctl(sock, cmd, arg);
+-
+- /*
+- * If this ioctl is unknown try to hand it down
+- * to the NIC driver.
+- */
+- if (err == -ENOIOCTLCMD)
+- err = dev_ioctl(cmd, argp);
+- break;
+- }
+- return err;
+-}
+-
+-int sock_create_lite(int family, int type, int protocol, struct socket **res)
+-{
+- int err;
+- struct socket *sock = NULL;
+-
+- err = security_socket_create(family, type, protocol, 1);
+- if (err)
+- goto out;
+-
+- sock = sock_alloc();
+- if (!sock) {
+- err = -ENOMEM;
+- goto out;
+- }
+-
+- sock->type = type;
+- err = security_socket_post_create(sock, family, type, protocol, 1);
+- if (err)
+- goto out_release;
+-
+-out:
+- *res = sock;
+- return err;
+-out_release:
+- sock_release(sock);
+- sock = NULL;
+- goto out;
+-}
+-
+-/* No kernel lock held - perfect */
+-static unsigned int sock_poll(struct file *file, poll_table *wait)
+-{
+- struct socket *sock;
+-
+- /*
+- * We can't return errors to poll, so it's either yes or no.
+- */
+- sock = file->private_data;
+- return sock->ops->poll(file, sock, wait);
+-}
+-
+-static int sock_mmap(struct file *file, struct vm_area_struct *vma)
+-{
+- struct socket *sock = file->private_data;
+-
+- return sock->ops->mmap(file, sock, vma);
+-}
+-
+-static int sock_close(struct inode *inode, struct file *filp)
+-{
+- /*
+- * It was possible the inode is NULL we were
+- * closing an unfinished socket.
+- */
+-
+- if (!inode) {
+- printk(KERN_DEBUG "sock_close: NULL inode\n");
+- return 0;
+- }
+- sock_fasync(-1, filp, 0);
+- sock_release(SOCKET_I(inode));
+- return 0;
+-}
+-
+-/*
+- * Update the socket async list
+- *
+- * Fasync_list locking strategy.
+- *
+- * 1. fasync_list is modified only under process context socket lock
+- * i.e. under semaphore.
+- * 2. fasync_list is used under read_lock(&sk->sk_callback_lock)
+- * or under socket lock.
+- * 3. fasync_list can be used from softirq context, so that
+- * modification under socket lock have to be enhanced with
+- * write_lock_bh(&sk->sk_callback_lock).
+- * --ANK (990710)
+- */
+-
+-static int sock_fasync(int fd, struct file *filp, int on)
+-{
+- struct fasync_struct *fa, *fna = NULL, **prev;
+- struct socket *sock;
+- struct sock *sk;
+-
+- if (on) {
+- fna = kmalloc(sizeof(struct fasync_struct), GFP_KERNEL);
+- if (fna == NULL)
+- return -ENOMEM;
+- }
+-
+- sock = filp->private_data;
+-
+- sk = sock->sk;
+- if (sk == NULL) {
+- kfree(fna);
+- return -EINVAL;
+- }
+-
+- lock_sock(sk);
+-
+- prev = &(sock->fasync_list);
+-
+- for (fa = *prev; fa != NULL; prev = &fa->fa_next, fa = *prev)
+- if (fa->fa_file == filp)
+- break;
+-
+- if (on) {
+- if (fa != NULL) {
+- write_lock_bh(&sk->sk_callback_lock);
+- fa->fa_fd = fd;
+- write_unlock_bh(&sk->sk_callback_lock);
+-
+- kfree(fna);
+- goto out;
+- }
+- fna->fa_file = filp;
+- fna->fa_fd = fd;
+- fna->magic = FASYNC_MAGIC;
+- fna->fa_next = sock->fasync_list;
+- write_lock_bh(&sk->sk_callback_lock);
+- sock->fasync_list = fna;
+- write_unlock_bh(&sk->sk_callback_lock);
+- } else {
+- if (fa != NULL) {
+- write_lock_bh(&sk->sk_callback_lock);
+- *prev = fa->fa_next;
+- write_unlock_bh(&sk->sk_callback_lock);
+- kfree(fa);
+- }
+- }
+-
+-out:
+- release_sock(sock->sk);
+- return 0;
+-}
+-
+-/* This function may be called only under socket lock or callback_lock */
+-
+-int sock_wake_async(struct socket *sock, int how, int band)
+-{
+- if (!sock || !sock->fasync_list)
+- return -1;
+- switch (how) {
+- case 1:
+-
+- if (test_bit(SOCK_ASYNC_WAITDATA, &sock->flags))
+- break;
+- goto call_kill;
+- case 2:
+- if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags))
+- break;
+- /* fall through */
+- case 0:
+-call_kill:
+- __kill_fasync(sock->fasync_list, SIGIO, band);
+- break;
+- case 3:
+- __kill_fasync(sock->fasync_list, SIGURG, band);
+- }
+- return 0;
+-}
+-
+-static int __sock_create(int family, int type, int protocol,
+- struct socket **res, int kern)
+-{
+- int err;
+- struct socket *sock;
+- const struct net_proto_family *pf;
+-
+- /*
+- * Check protocol is in range
+- */
+- if (family < 0 || family >= NPROTO)
+- return -EAFNOSUPPORT;
+- if (type < 0 || type >= SOCK_MAX)
+- return -EINVAL;
+-
+- /* Compatibility.
+-
+- This uglymoron is moved from INET layer to here to avoid
+- deadlock in module load.
+- */
+- if (family == PF_INET && type == SOCK_PACKET) {
+- static int warned;
+- if (!warned) {
+- warned = 1;
+- printk(KERN_INFO "%s uses obsolete (PF_INET,SOCK_PACKET)\n",
+- current->comm);
+- }
+- family = PF_PACKET;
+- }
+-
+- err = security_socket_create(family, type, protocol, kern);
+- if (err)
+- return err;
+-
+- /*
+- * Allocate the socket and allow the family to set things up. if
+- * the protocol is 0, the family is instructed to select an appropriate
+- * default.
+- */
+- sock = sock_alloc();
+- if (!sock) {
+- if (net_ratelimit())
+- printk(KERN_WARNING "socket: no more sockets\n");
+- return -ENFILE; /* Not exactly a match, but its the
+- closest posix thing */
+- }
+-
+- sock->type = type;
+-
+-#if defined(CONFIG_KMOD)
+- /* Attempt to load a protocol module if the find failed.
+- *
+- * 12/09/1996 Marcin: But! this makes REALLY only sense, if the user
+- * requested real, full-featured networking support upon configuration.
+- * Otherwise module support will break!
+- */
+- if (net_families[family] == NULL)
+- request_module("net-pf-%d", family);
-#endif
- default:
- probed = 1;
- break;
-diff -Nurb linux-2.6.22-570/net/ipv6/xfrm6_policy.c linux-2.6.22-590/net/ipv6/xfrm6_policy.c
---- linux-2.6.22-570/net/ipv6/xfrm6_policy.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/net/ipv6/xfrm6_policy.c 2008-03-15 10:35:47.000000000 -0400
-@@ -18,7 +18,7 @@
- #include <net/ip.h>
- #include <net/ipv6.h>
- #include <net/ip6_route.h>
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- #include <net/mip6.h>
- #endif
-
-@@ -318,7 +318,7 @@
- fl->proto = nexthdr;
- return;
-
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- case IPPROTO_MH:
- if (pskb_may_pull(skb, nh + offset + 3 - skb->data)) {
- struct ip6_mh *mh;
-diff -Nurb linux-2.6.22-570/net/ipv6/xfrm6_state.c linux-2.6.22-590/net/ipv6/xfrm6_state.c
---- linux-2.6.22-570/net/ipv6/xfrm6_state.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/ipv6/xfrm6_state.c 2008-03-15 10:35:47.000000000 -0400
-@@ -65,7 +65,7 @@
- goto end;
-
- /* Rule 2: select MIPv6 RO or inbound trigger */
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- for (i = 0; i < n; i++) {
- if (src[i] &&
- (src[i]->props.mode == XFRM_MODE_ROUTEOPTIMIZATION ||
-@@ -130,7 +130,7 @@
- goto end;
-
- /* Rule 2: select MIPv6 RO or inbound trigger */
--#ifdef CONFIG_IPV6_MIP6
-+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
- for (i = 0; i < n; i++) {
- if (src[i] &&
- (src[i]->mode == XFRM_MODE_ROUTEOPTIMIZATION ||
-diff -Nurb linux-2.6.22-570/net/ipv6/xfrm6_tunnel.c linux-2.6.22-590/net/ipv6/xfrm6_tunnel.c
---- linux-2.6.22-570/net/ipv6/xfrm6_tunnel.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/ipv6/xfrm6_tunnel.c 2008-03-15 10:35:47.000000000 -0400
-@@ -379,3 +379,4 @@
- module_init(xfrm6_tunnel_init);
- module_exit(xfrm6_tunnel_fini);
- MODULE_LICENSE("GPL");
-+MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_IPV6);
-diff -Nurb linux-2.6.22-570/net/irda/irias_object.c linux-2.6.22-590/net/irda/irias_object.c
---- linux-2.6.22-570/net/irda/irias_object.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/irda/irias_object.c 2008-03-15 10:35:47.000000000 -0400
-@@ -36,39 +36,6 @@
- */
- struct ias_value irias_missing = { IAS_MISSING, 0, 0, 0, {0}};
-
+-
+- rcu_read_lock();
+- pf = rcu_dereference(net_families[family]);
+- err = -EAFNOSUPPORT;
+- if (!pf)
+- goto out_release;
+-
+- /*
+- * We will call the ->create function, that possibly is in a loadable
+- * module, so we have to bump that loadable module refcnt first.
+- */
+- if (!try_module_get(pf->owner))
+- goto out_release;
+-
+- /* Now protected by module ref count */
+- rcu_read_unlock();
+-
+- err = pf->create(sock, protocol);
+- if (err < 0)
+- goto out_module_put;
+-
+- /*
+- * Now to bump the refcnt of the [loadable] module that owns this
+- * socket at sock_release time we decrement its refcnt.
+- */
+- if (!try_module_get(sock->ops->owner))
+- goto out_module_busy;
+-
+- /*
+- * Now that we're done with the ->create function, the [loadable]
+- * module can have its refcnt decremented
+- */
+- module_put(pf->owner);
+- err = security_socket_post_create(sock, family, type, protocol, kern);
+- if (err)
+- goto out_sock_release;
+- *res = sock;
+-
+- return 0;
+-
+-out_module_busy:
+- err = -EAFNOSUPPORT;
+-out_module_put:
+- sock->ops = NULL;
+- module_put(pf->owner);
+-out_sock_release:
+- sock_release(sock);
+- return err;
+-
+-out_release:
+- rcu_read_unlock();
+- goto out_sock_release;
+-}
+-
+-int sock_create(int family, int type, int protocol, struct socket **res)
+-{
+- return __sock_create(family, type, protocol, res, 0);
+-}
+-
+-int sock_create_kern(int family, int type, int protocol, struct socket **res)
+-{
+- return __sock_create(family, type, protocol, res, 1);
+-}
+-
+-asmlinkage long sys_socket(int family, int type, int protocol)
+-{
+- int retval;
+- struct socket *sock;
+-
+- retval = sock_create(family, type, protocol, &sock);
+- if (retval < 0)
+- goto out;
+-
+- retval = sock_map_fd(sock);
+- if (retval < 0)
+- goto out_release;
+-
+-out:
+- /* It may be already another descriptor 8) Not kernel problem. */
+- return retval;
+-
+-out_release:
+- sock_release(sock);
+- return retval;
+-}
+-
-/*
-- * Function strndup (str, max)
+- * Create a pair of connected sockets.
+- */
+-
+-asmlinkage long sys_socketpair(int family, int type, int protocol,
+- int __user *usockvec)
+-{
+- struct socket *sock1, *sock2;
+- int fd1, fd2, err;
+- struct file *newfile1, *newfile2;
+-
+- /*
+- * Obtain the first socket and check if the underlying protocol
+- * supports the socketpair call.
+- */
+-
+- err = sock_create(family, type, protocol, &sock1);
+- if (err < 0)
+- goto out;
+-
+- err = sock_create(family, type, protocol, &sock2);
+- if (err < 0)
+- goto out_release_1;
+-
+- err = sock1->ops->socketpair(sock1, sock2);
+- if (err < 0)
+- goto out_release_both;
+-
+- fd1 = sock_alloc_fd(&newfile1);
+- if (unlikely(fd1 < 0)) {
+- err = fd1;
+- goto out_release_both;
+- }
+-
+- fd2 = sock_alloc_fd(&newfile2);
+- if (unlikely(fd2 < 0)) {
+- err = fd2;
+- put_filp(newfile1);
+- put_unused_fd(fd1);
+- goto out_release_both;
+- }
+-
+- err = sock_attach_fd(sock1, newfile1);
+- if (unlikely(err < 0)) {
+- goto out_fd2;
+- }
+-
+- err = sock_attach_fd(sock2, newfile2);
+- if (unlikely(err < 0)) {
+- fput(newfile1);
+- goto out_fd1;
+- }
+-
+- err = audit_fd_pair(fd1, fd2);
+- if (err < 0) {
+- fput(newfile1);
+- fput(newfile2);
+- goto out_fd;
+- }
+-
+- fd_install(fd1, newfile1);
+- fd_install(fd2, newfile2);
+- /* fd1 and fd2 may be already another descriptors.
+- * Not kernel problem.
+- */
+-
+- err = put_user(fd1, &usockvec[0]);
+- if (!err)
+- err = put_user(fd2, &usockvec[1]);
+- if (!err)
+- return 0;
+-
+- sys_close(fd2);
+- sys_close(fd1);
+- return err;
+-
+-out_release_both:
+- sock_release(sock2);
+-out_release_1:
+- sock_release(sock1);
+-out:
+- return err;
+-
+-out_fd2:
+- put_filp(newfile1);
+- sock_release(sock1);
+-out_fd1:
+- put_filp(newfile2);
+- sock_release(sock2);
+-out_fd:
+- put_unused_fd(fd1);
+- put_unused_fd(fd2);
+- goto out;
+-}
+-
+-/*
+- * Bind a name to a socket. Nothing much to do here since it's
+- * the protocol's responsibility to handle the local address.
- *
-- * My own kernel version of strndup!
+- * We move the socket address to kernel space before we call
+- * the protocol layer (having also checked the address is ok).
+- */
+-
+-asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen)
+-{
+- struct socket *sock;
+- char address[MAX_SOCK_ADDR];
+- int err, fput_needed;
+-
+- sock = sockfd_lookup_light(fd, &err, &fput_needed);
+- if (sock) {
+- err = move_addr_to_kernel(umyaddr, addrlen, address);
+- if (err >= 0) {
+- err = security_socket_bind(sock,
+- (struct sockaddr *)address,
+- addrlen);
+- if (!err)
+- err = sock->ops->bind(sock,
+- (struct sockaddr *)
+- address, addrlen);
+- }
+- fput_light(sock->file, fput_needed);
+- }
+- return err;
+-}
+-
+-/*
+- * Perform a listen. Basically, we allow the protocol to do anything
+- * necessary for a listen, and if that works, we mark the socket as
+- * ready for listening.
+- */
+-
+-int sysctl_somaxconn __read_mostly = SOMAXCONN;
+-
+-asmlinkage long sys_listen(int fd, int backlog)
+-{
+- struct socket *sock;
+- int err, fput_needed;
+-
+- sock = sockfd_lookup_light(fd, &err, &fput_needed);
+- if (sock) {
+- if ((unsigned)backlog > sysctl_somaxconn)
+- backlog = sysctl_somaxconn;
+-
+- err = security_socket_listen(sock, backlog);
+- if (!err)
+- err = sock->ops->listen(sock, backlog);
+-
+- fput_light(sock->file, fput_needed);
+- }
+- return err;
+-}
+-
+-/*
+- * For accept, we attempt to create a new socket, set up the link
+- * with the client, wake up the client, then return the new
+- * connected fd. We collect the address of the connector in kernel
+- * space and move it to user at the very end. This is unclean because
+- * we open the socket then return an error.
- *
-- * Faster, check boundary... Jean II
+- * 1003.1g adds the ability to recvmsg() to query connection pending
+- * status to recvmsg. We need to add that support in a way thats
+- * clean when we restucture accept also.
- */
--static char *strndup(char *str, size_t max)
+-
+-asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr,
+- int __user *upeer_addrlen)
-{
-- char *new_str;
-- int len;
+- struct socket *sock, *newsock;
+- struct file *newfile;
+- int err, len, newfd, fput_needed;
+- char address[MAX_SOCK_ADDR];
-
-- /* Check string */
-- if (str == NULL)
-- return NULL;
-- /* Check length, truncate */
-- len = strlen(str);
-- if(len > max)
-- len = max;
+- sock = sockfd_lookup_light(fd, &err, &fput_needed);
+- if (!sock)
+- goto out;
-
-- /* Allocate new string */
-- new_str = kmalloc(len + 1, GFP_ATOMIC);
-- if (new_str == NULL) {
-- IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
-- return NULL;
+- err = -ENFILE;
+- if (!(newsock = sock_alloc()))
+- goto out_put;
+-
+- newsock->type = sock->type;
+- newsock->ops = sock->ops;
+-
+- /*
+- * We don't need try_module_get here, as the listening socket (sock)
+- * has the protocol module (sock->ops->owner) held.
+- */
+- __module_get(newsock->ops->owner);
+-
+- newfd = sock_alloc_fd(&newfile);
+- if (unlikely(newfd < 0)) {
+- err = newfd;
+- sock_release(newsock);
+- goto out_put;
- }
-
-- /* Copy and truncate */
-- memcpy(new_str, str, len);
-- new_str[len] = '\0';
+- err = sock_attach_fd(newsock, newfile);
+- if (err < 0)
+- goto out_fd_simple;
-
-- return new_str;
+- err = security_socket_accept(sock, newsock);
+- if (err)
+- goto out_fd;
+-
+- err = sock->ops->accept(sock, newsock, sock->file->f_flags);
+- if (err < 0)
+- goto out_fd;
+-
+- if (upeer_sockaddr) {
+- if (newsock->ops->getname(newsock, (struct sockaddr *)address,
+- &len, 2) < 0) {
+- err = -ECONNABORTED;
+- goto out_fd;
+- }
+- err = move_addr_to_user(address, len, upeer_sockaddr,
+- upeer_addrlen);
+- if (err < 0)
+- goto out_fd;
+- }
+-
+- /* File flags are not inherited via accept() unlike another OSes. */
+-
+- fd_install(newfd, newfile);
+- err = newfd;
+-
+- security_socket_post_accept(sock, newsock);
+-
+-out_put:
+- fput_light(sock->file, fput_needed);
+-out:
+- return err;
+-out_fd_simple:
+- sock_release(newsock);
+- put_filp(newfile);
+- put_unused_fd(newfd);
+- goto out_put;
+-out_fd:
+- fput(newfile);
+- put_unused_fd(newfd);
+- goto out_put;
-}
-
- /*
- * Function ias_new_object (name, id)
-@@ -90,7 +57,7 @@
- }
-
- obj->magic = IAS_OBJECT_MAGIC;
-- obj->name = strndup(name, IAS_MAX_CLASSNAME);
-+ obj->name = kstrndup(name, IAS_MAX_CLASSNAME, GFP_ATOMIC);
- if (!obj->name) {
- IRDA_WARNING("%s(), Unable to allocate name!\n",
- __FUNCTION__);
-@@ -360,7 +327,7 @@
- }
-
- attrib->magic = IAS_ATTRIB_MAGIC;
-- attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
-+ attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME, GFP_ATOMIC);
-
- /* Insert value */
- attrib->value = irias_new_integer_value(value);
-@@ -404,7 +371,7 @@
- }
-
- attrib->magic = IAS_ATTRIB_MAGIC;
-- attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
-+ attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME, GFP_ATOMIC);
-
- attrib->value = irias_new_octseq_value( octets, len);
- if (!attrib->name || !attrib->value) {
-@@ -446,7 +413,7 @@
- }
-
- attrib->magic = IAS_ATTRIB_MAGIC;
-- attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
-+ attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME, GFP_ATOMIC);
-
- attrib->value = irias_new_string_value(value);
- if (!attrib->name || !attrib->value) {
-@@ -506,7 +473,7 @@
-
- value->type = IAS_STRING;
- value->charset = CS_ASCII;
-- value->t.string = strndup(string, IAS_MAX_STRING);
-+ value->t.string = kstrndup(string, IAS_MAX_STRING, GFP_ATOMIC);
- if (!value->t.string) {
- IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
- kfree(value);
-diff -Nurb linux-2.6.22-570/net/mac80211/ieee80211_ioctl.c linux-2.6.22-590/net/mac80211/ieee80211_ioctl.c
---- linux-2.6.22-570/net/mac80211/ieee80211_ioctl.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/mac80211/ieee80211_ioctl.c 2008-03-15 10:35:47.000000000 -0400
-@@ -838,6 +838,29 @@
- }
-
-
-+static int ieee80211_ioctl_giwrate(struct net_device *dev,
-+ struct iw_request_info *info,
-+ struct iw_param *rate, char *extra)
-+{
-+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-+ struct sta_info *sta;
-+ struct ieee80211_sub_if_data *sdata;
-+
-+ sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-+ if (sdata->type == IEEE80211_IF_TYPE_STA)
-+ sta = sta_info_get(local, sdata->u.sta.bssid);
-+ else
-+ return -EOPNOTSUPP;
-+ if (!sta)
-+ return -ENODEV;
-+ if (sta->txrate < local->oper_hw_mode->num_rates)
-+ rate->value = local->oper_hw_mode->rates[sta->txrate].rate * 100000;
-+ else
-+ rate->value = 0;
-+ sta_info_put(sta);
-+ return 0;
-+}
-+
- static int ieee80211_ioctl_siwrts(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *rts, char *extra)
-@@ -1779,7 +1802,7 @@
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) NULL, /* SIOCSIWRATE */
-- (iw_handler) NULL, /* SIOCGIWRATE */
-+ (iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */
- (iw_handler) ieee80211_ioctl_siwrts, /* SIOCSIWRTS */
- (iw_handler) ieee80211_ioctl_giwrts, /* SIOCGIWRTS */
- (iw_handler) ieee80211_ioctl_siwfrag, /* SIOCSIWFRAG */
-diff -Nurb linux-2.6.22-570/net/netfilter/core.c linux-2.6.22-590/net/netfilter/core.c
---- linux-2.6.22-570/net/netfilter/core.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/netfilter/core.c 2008-03-15 10:35:47.000000000 -0400
-@@ -203,7 +203,9 @@
- return 0;
-
- /* Not exclusive use of packet? Must copy. */
-- if (skb_shared(*pskb) || skb_cloned(*pskb))
-+ if (skb_cloned(*pskb) && !skb_clone_writable(*pskb, writable_len))
-+ goto copy_skb;
-+ if (skb_shared(*pskb))
- goto copy_skb;
-
- return pskb_may_pull(*pskb, writable_len);
-diff -Nurb linux-2.6.22-570/net/netlink/attr.c linux-2.6.22-590/net/netlink/attr.c
---- linux-2.6.22-570/net/netlink/attr.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/netlink/attr.c 2008-03-15 10:35:47.000000000 -0400
-@@ -72,6 +72,17 @@
- return -ERANGE;
- break;
-
-+ case NLA_NESTED_COMPAT:
-+ if (attrlen < pt->len)
-+ return -ERANGE;
-+ if (attrlen < NLA_ALIGN(pt->len))
-+ break;
-+ if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN)
-+ return -ERANGE;
-+ nla = nla_data(nla) + NLA_ALIGN(pt->len);
-+ if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN + nla_len(nla))
-+ return -ERANGE;
-+ break;
- default:
- if (pt->len)
- minlen = pt->len;
-diff -Nurb linux-2.6.22-570/net/sched/sch_generic.c linux-2.6.22-590/net/sched/sch_generic.c
---- linux-2.6.22-570/net/sched/sch_generic.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/sched/sch_generic.c 2008-03-15 10:35:47.000000000 -0400
-@@ -59,122 +59,143 @@
- spin_unlock_bh(&dev->queue_lock);
- }
-
+-
-/*
-- dev->queue_lock serializes queue accesses for this device
-- AND dev->qdisc pointer itself.
-+static inline int qdisc_qlen(struct Qdisc *q)
-+{
-+ return q->q.qlen;
-+}
-
-- netif_tx_lock serializes accesses to device driver.
-+static inline int dev_requeue_skb(struct sk_buff *skb, struct net_device *dev,
-+ struct Qdisc *q)
-+{
-+ if (unlikely(skb->next))
-+ dev->gso_skb = skb;
-+ else
-+ q->ops->requeue(skb, q);
-
-- dev->queue_lock and netif_tx_lock are mutually exclusive,
-- if one is grabbed, another must be free.
+- * Attempt to connect to a socket with the server address. The address
+- * is in user space so we verify it is OK and move it to kernel space.
+- *
+- * For 1003.1g we need to add clean support for a bind to AF_UNSPEC to
+- * break bindings
+- *
+- * NOTE: 1003.1g draft 6.3 is broken with respect to AX.25/NetROM and
+- * other SEQPACKET protocols that take time to connect() as it doesn't
+- * include the -EINPROGRESS status for such sockets.
- */
-+ netif_schedule(dev);
-+ return 0;
-+}
-
-+static inline struct sk_buff *dev_dequeue_skb(struct net_device *dev,
-+ struct Qdisc *q)
-+{
-+ struct sk_buff *skb;
-
--/* Kick device.
-+ if ((skb = dev->gso_skb))
-+ dev->gso_skb = NULL;
-+ else
-+ skb = q->dequeue(q);
-
-- Returns: 0 - queue is empty or throttled.
-- >0 - queue is not empty.
-+ return skb;
-+}
-
-- NOTE: Called under dev->queue_lock with locally disabled BH.
--*/
-+static inline int handle_dev_cpu_collision(struct sk_buff *skb,
-+ struct net_device *dev,
-+ struct Qdisc *q)
-+{
-+ int ret;
-
-+ if (unlikely(dev->xmit_lock_owner == smp_processor_id())) {
-+ /*
-+ * Same CPU holding the lock. It may be a transient
-+ * configuration error, when hard_start_xmit() recurses. We
-+ * detect it by checking xmit owner and drop the packet when
-+ * deadloop is detected. Return OK to try the next skb.
-+ */
-+ kfree_skb(skb);
-+ if (net_ratelimit())
-+ printk(KERN_WARNING "Dead loop on netdevice %s, "
-+ "fix it urgently!\n", dev->name);
-+ ret = qdisc_qlen(q);
-+ } else {
-+ /*
-+ * Another cpu is holding lock, requeue & delay xmits for
-+ * some time.
-+ */
-+ __get_cpu_var(netdev_rx_stat).cpu_collision++;
-+ ret = dev_requeue_skb(skb, dev, q);
-+ }
-+
-+ return ret;
-+}
-+
-+/*
-+ * NOTE: Called under dev->queue_lock with locally disabled BH.
-+ *
-+ * __LINK_STATE_QDISC_RUNNING guarantees only one CPU can process this
-+ * device at a time. dev->queue_lock serializes queue accesses for
-+ * this device AND dev->qdisc pointer itself.
-+ *
-+ * netif_tx_lock serializes accesses to device driver.
-+ *
-+ * dev->queue_lock and netif_tx_lock are mutually exclusive,
-+ * if one is grabbed, another must be free.
-+ *
-+ * Note, that this procedure can be called by a watchdog timer
-+ *
-+ * Returns to the caller:
-+ * 0 - queue is empty or throttled.
-+ * >0 - queue is not empty.
-+ *
-+ */
- static inline int qdisc_restart(struct net_device *dev)
- {
- struct Qdisc *q = dev->qdisc;
- struct sk_buff *skb;
-+ unsigned lockless;
-+ int ret;
-
- /* Dequeue packet */
-- if (((skb = dev->gso_skb)) || ((skb = q->dequeue(q)))) {
-- unsigned nolock = (dev->features & NETIF_F_LLTX);
-
-- dev->gso_skb = NULL;
-+ if (unlikely((skb = dev_dequeue_skb(dev, q)) == NULL))
-+ return 0;
-
- /*
-- * When the driver has LLTX set it does its own locking
-- * in start_xmit. No need to add additional overhead by
-- * locking again. These checks are worth it because
-- * even uncongested locks can be quite expensive.
-- * The driver can do trylock like here too, in case
-- * of lock congestion it should return -1 and the packet
-- * will be requeued.
-- */
-- if (!nolock) {
-- if (!netif_tx_trylock(dev)) {
-- collision:
-- /* So, someone grabbed the driver. */
+-asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr,
+- int addrlen)
+-{
+- struct socket *sock;
+- char address[MAX_SOCK_ADDR];
+- int err, fput_needed;
-
-- /* It may be transient configuration error,
-- when hard_start_xmit() recurses. We detect
-- it by checking xmit owner and drop the
-- packet when deadloop is detected.
-+ * When the driver has LLTX set, it does its own locking in
-+ * start_xmit. These checks are worth it because even uncongested
-+ * locks can be quite expensive. The driver can do a trylock, as
-+ * is being done here; in case of lock contention it should return
-+ * NETDEV_TX_LOCKED and the packet will be requeued.
- */
-- if (dev->xmit_lock_owner == smp_processor_id()) {
-- kfree_skb(skb);
-- if (net_ratelimit())
-- printk(KERN_DEBUG "Dead loop on netdevice %s, fix it urgently!\n", dev->name);
-- goto out;
-- }
-- __get_cpu_var(netdev_rx_stat).cpu_collision++;
-- goto requeue;
-- }
-+ lockless = (dev->features & NETIF_F_LLTX);
-+
-+ if (!lockless && !netif_tx_trylock(dev)) {
-+ /* Another CPU grabbed the driver tx lock */
-+ return handle_dev_cpu_collision(skb, dev, q);
- }
-
-- {
- /* And release queue */
- spin_unlock(&dev->queue_lock);
-
-- if (!netif_queue_stopped(dev)) {
-- int ret;
+- sock = sockfd_lookup_light(fd, &err, &fput_needed);
+- if (!sock)
+- goto out;
+- err = move_addr_to_kernel(uservaddr, addrlen, address);
+- if (err < 0)
+- goto out_put;
-
- ret = dev_hard_start_xmit(skb, dev);
-- if (ret == NETDEV_TX_OK) {
-- if (!nolock) {
-- netif_tx_unlock(dev);
-- }
-- spin_lock(&dev->queue_lock);
-- q = dev->qdisc;
-- goto out;
-- }
-- if (ret == NETDEV_TX_LOCKED && nolock) {
-- spin_lock(&dev->queue_lock);
-- q = dev->qdisc;
-- goto collision;
-- }
-- }
-
-- /* NETDEV_TX_BUSY - we need to requeue */
-- /* Release the driver */
-- if (!nolock) {
-+ if (!lockless)
- netif_tx_unlock(dev);
-- }
-+
- spin_lock(&dev->queue_lock);
- q = dev->qdisc;
+- err =
+- security_socket_connect(sock, (struct sockaddr *)address, addrlen);
+- if (err)
+- goto out_put;
+-
+- err = sock->ops->connect(sock, (struct sockaddr *)address, addrlen,
+- sock->file->f_flags);
+-out_put:
+- fput_light(sock->file, fput_needed);
+-out:
+- return err;
+-}
+-
+-/*
+- * Get the local address ('name') of a socket object. Move the obtained
+- * name to user space.
+- */
+-
+-asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr,
+- int __user *usockaddr_len)
+-{
+- struct socket *sock;
+- char address[MAX_SOCK_ADDR];
+- int len, err, fput_needed;
+-
+- sock = sockfd_lookup_light(fd, &err, &fput_needed);
+- if (!sock)
+- goto out;
+-
+- err = security_socket_getsockname(sock);
+- if (err)
+- goto out_put;
+-
+- err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 0);
+- if (err)
+- goto out_put;
+- err = move_addr_to_user(address, len, usockaddr, usockaddr_len);
+-
+-out_put:
+- fput_light(sock->file, fput_needed);
+-out:
+- return err;
+-}
+-
+-/*
+- * Get the remote address ('name') of a socket object. Move the obtained
+- * name to user space.
+- */
+-
+-asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr,
+- int __user *usockaddr_len)
+-{
+- struct socket *sock;
+- char address[MAX_SOCK_ADDR];
+- int len, err, fput_needed;
+-
+- sock = sockfd_lookup_light(fd, &err, &fput_needed);
+- if (sock != NULL) {
+- err = security_socket_getpeername(sock);
+- if (err) {
+- fput_light(sock->file, fput_needed);
+- return err;
- }
-
-- /* Device kicked us out :(
-- This is possible in three cases:
-+ switch (ret) {
-+ case NETDEV_TX_OK:
-+ /* Driver sent out skb successfully */
-+ ret = qdisc_qlen(q);
-+ break;
-
-- 0. driver is locked
-- 1. fastroute is enabled
-- 2. device cannot determine busy state
-- before start of transmission (f.e. dialout)
-- 3. device is buggy (ppp)
-- */
-+ case NETDEV_TX_LOCKED:
-+ /* Driver try lock failed */
-+ ret = handle_dev_cpu_collision(skb, dev, q);
-+ break;
-
--requeue:
-- if (unlikely(q == &noop_qdisc))
-- kfree_skb(skb);
-- else if (skb->next)
-- dev->gso_skb = skb;
+-
+- err =
+- sock->ops->getname(sock, (struct sockaddr *)address, &len,
+- 1);
+- if (!err)
+- err = move_addr_to_user(address, len, usockaddr,
+- usockaddr_len);
+- fput_light(sock->file, fput_needed);
+- }
+- return err;
+-}
+-
+-/*
+- * Send a datagram to a given address. We move the address into kernel
+- * space and check the user space data area is readable before invoking
+- * the protocol.
+- */
+-
+-asmlinkage long sys_sendto(int fd, void __user *buff, size_t len,
+- unsigned flags, struct sockaddr __user *addr,
+- int addr_len)
+-{
+- struct socket *sock;
+- char address[MAX_SOCK_ADDR];
+- int err;
+- struct msghdr msg;
+- struct iovec iov;
+- int fput_needed;
+- struct file *sock_file;
+-
+- sock_file = fget_light(fd, &fput_needed);
+- err = -EBADF;
+- if (!sock_file)
+- goto out;
+-
+- sock = sock_from_file(sock_file, &err);
+- if (!sock)
+- goto out_put;
+- iov.iov_base = buff;
+- iov.iov_len = len;
+- msg.msg_name = NULL;
+- msg.msg_iov = &iov;
+- msg.msg_iovlen = 1;
+- msg.msg_control = NULL;
+- msg.msg_controllen = 0;
+- msg.msg_namelen = 0;
+- if (addr) {
+- err = move_addr_to_kernel(addr, addr_len, address);
+- if (err < 0)
+- goto out_put;
+- msg.msg_name = address;
+- msg.msg_namelen = addr_len;
+- }
+- if (sock->file->f_flags & O_NONBLOCK)
+- flags |= MSG_DONTWAIT;
+- msg.msg_flags = flags;
+- err = sock_sendmsg(sock, &msg, len);
+-
+-out_put:
+- fput_light(sock_file, fput_needed);
+-out:
+- return err;
+-}
+-
+-/*
+- * Send a datagram down a socket.
+- */
+-
+-asmlinkage long sys_send(int fd, void __user *buff, size_t len, unsigned flags)
+-{
+- return sys_sendto(fd, buff, len, flags, NULL, 0);
+-}
+-
+-/*
+- * Receive a frame from the socket and optionally record the address of the
+- * sender. We verify the buffers are writable and if needed move the
+- * sender address from kernel to user space.
+- */
+-
+-asmlinkage long sys_recvfrom(int fd, void __user *ubuf, size_t size,
+- unsigned flags, struct sockaddr __user *addr,
+- int __user *addr_len)
+-{
+- struct socket *sock;
+- struct iovec iov;
+- struct msghdr msg;
+- char address[MAX_SOCK_ADDR];
+- int err, err2;
+- struct file *sock_file;
+- int fput_needed;
+-
+- sock_file = fget_light(fd, &fput_needed);
+- err = -EBADF;
+- if (!sock_file)
+- goto out;
+-
+- sock = sock_from_file(sock_file, &err);
+- if (!sock)
+- goto out_put;
+-
+- msg.msg_control = NULL;
+- msg.msg_controllen = 0;
+- msg.msg_iovlen = 1;
+- msg.msg_iov = &iov;
+- iov.iov_len = size;
+- iov.iov_base = ubuf;
+- msg.msg_name = address;
+- msg.msg_namelen = MAX_SOCK_ADDR;
+- if (sock->file->f_flags & O_NONBLOCK)
+- flags |= MSG_DONTWAIT;
+- err = sock_recvmsg(sock, &msg, size, flags);
+-
+- if (err >= 0 && addr != NULL) {
+- err2 = move_addr_to_user(address, msg.msg_namelen, addr, addr_len);
+- if (err2 < 0)
+- err = err2;
+- }
+-out_put:
+- fput_light(sock_file, fput_needed);
+-out:
+- return err;
+-}
+-
+-/*
+- * Receive a datagram from a socket.
+- */
+-
+-asmlinkage long sys_recv(int fd, void __user *ubuf, size_t size,
+- unsigned flags)
+-{
+- return sys_recvfrom(fd, ubuf, size, flags, NULL, NULL);
+-}
+-
+-/*
+- * Set a socket option. Because we don't know the option lengths we have
+- * to pass the user mode parameter for the protocols to sort out.
+- */
+-
+-asmlinkage long sys_setsockopt(int fd, int level, int optname,
+- char __user *optval, int optlen)
+-{
+- int err, fput_needed;
+- struct socket *sock;
+-
+- if (optlen < 0)
+- return -EINVAL;
+-
+- sock = sockfd_lookup_light(fd, &err, &fput_needed);
+- if (sock != NULL) {
+- err = security_socket_setsockopt(sock, level, optname);
+- if (err)
+- goto out_put;
+-
+- if (level == SOL_SOCKET)
+- err =
+- sock_setsockopt(sock, level, optname, optval,
+- optlen);
- else
-- q->ops->requeue(skb, q);
-- netif_schedule(dev);
-+ default:
-+ /* Driver returned NETDEV_TX_BUSY - requeue skb */
-+ if (unlikely (ret != NETDEV_TX_BUSY && net_ratelimit()))
-+ printk(KERN_WARNING "BUG %s code %d qlen %d\n",
-+ dev->name, ret, q->q.qlen);
-+
-+ ret = dev_requeue_skb(skb, dev, q);
-+ break;
- }
-- return 0;
-
+- err =
+- sock->ops->setsockopt(sock, level, optname, optval,
+- optlen);
+-out_put:
+- fput_light(sock->file, fput_needed);
+- }
+- return err;
+-}
+-
+-/*
+- * Get a socket option. Because we don't know the option lengths we have
+- * to pass a user mode parameter for the protocols to sort out.
+- */
+-
+-asmlinkage long sys_getsockopt(int fd, int level, int optname,
+- char __user *optval, int __user *optlen)
+-{
+- int err, fput_needed;
+- struct socket *sock;
+-
+- sock = sockfd_lookup_light(fd, &err, &fput_needed);
+- if (sock != NULL) {
+- err = security_socket_getsockopt(sock, level, optname);
+- if (err)
+- goto out_put;
+-
+- if (level == SOL_SOCKET)
+- err =
+- sock_getsockopt(sock, level, optname, optval,
+- optlen);
+- else
+- err =
+- sock->ops->getsockopt(sock, level, optname, optval,
+- optlen);
+-out_put:
+- fput_light(sock->file, fput_needed);
+- }
+- return err;
+-}
+-
+-/*
+- * Shutdown a socket.
+- */
+-
+-asmlinkage long sys_shutdown(int fd, int how)
+-{
+- int err, fput_needed;
+- struct socket *sock;
+-
+- sock = sockfd_lookup_light(fd, &err, &fput_needed);
+- if (sock != NULL) {
+- err = security_socket_shutdown(sock, how);
+- if (!err)
+- err = sock->ops->shutdown(sock, how);
+- fput_light(sock->file, fput_needed);
+- }
+- return err;
+-}
+-
+-/* A couple of helpful macros for getting the address of the 32/64 bit
+- * fields which are the same type (int / unsigned) on our platforms.
+- */
+-#define COMPAT_MSG(msg, member) ((MSG_CMSG_COMPAT & flags) ? &msg##_compat->member : &msg->member)
+-#define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen)
+-#define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags)
+-
+-/*
+- * BSD sendmsg interface
+- */
+-
+-asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
+-{
+- struct compat_msghdr __user *msg_compat =
+- (struct compat_msghdr __user *)msg;
+- struct socket *sock;
+- char address[MAX_SOCK_ADDR];
+- struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
+- unsigned char ctl[sizeof(struct cmsghdr) + 20]
+- __attribute__ ((aligned(sizeof(__kernel_size_t))));
+- /* 20 is size of ipv6_pktinfo */
+- unsigned char *ctl_buf = ctl;
+- struct msghdr msg_sys;
+- int err, ctl_len, iov_size, total_len;
+- int fput_needed;
+-
+- err = -EFAULT;
+- if (MSG_CMSG_COMPAT & flags) {
+- if (get_compat_msghdr(&msg_sys, msg_compat))
+- return -EFAULT;
+- }
+- else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr)))
+- return -EFAULT;
+-
+- sock = sockfd_lookup_light(fd, &err, &fput_needed);
+- if (!sock)
+- goto out;
+-
+- /* do not move before msg_sys is valid */
+- err = -EMSGSIZE;
+- if (msg_sys.msg_iovlen > UIO_MAXIOV)
+- goto out_put;
+-
+- /* Check whether to allocate the iovec area */
+- err = -ENOMEM;
+- iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
+- if (msg_sys.msg_iovlen > UIO_FASTIOV) {
+- iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
+- if (!iov)
+- goto out_put;
+- }
+-
+- /* This will also move the address data into kernel space */
+- if (MSG_CMSG_COMPAT & flags) {
+- err = verify_compat_iovec(&msg_sys, iov, address, VERIFY_READ);
+- } else
+- err = verify_iovec(&msg_sys, iov, address, VERIFY_READ);
+- if (err < 0)
+- goto out_freeiov;
+- total_len = err;
+-
+- err = -ENOBUFS;
+-
+- if (msg_sys.msg_controllen > INT_MAX)
+- goto out_freeiov;
+- ctl_len = msg_sys.msg_controllen;
+- if ((MSG_CMSG_COMPAT & flags) && ctl_len) {
+- err =
+- cmsghdr_from_user_compat_to_kern(&msg_sys, sock->sk, ctl,
+- sizeof(ctl));
+- if (err)
+- goto out_freeiov;
+- ctl_buf = msg_sys.msg_control;
+- ctl_len = msg_sys.msg_controllen;
+- } else if (ctl_len) {
+- if (ctl_len > sizeof(ctl)) {
+- ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
+- if (ctl_buf == NULL)
+- goto out_freeiov;
+- }
+- err = -EFAULT;
+- /*
+- * Careful! Before this, msg_sys.msg_control contains a user pointer.
+- * Afterwards, it will be a kernel pointer. Thus the compiler-assisted
+- * checking falls down on this.
+- */
+- if (copy_from_user(ctl_buf, (void __user *)msg_sys.msg_control,
+- ctl_len))
+- goto out_freectl;
+- msg_sys.msg_control = ctl_buf;
+- }
+- msg_sys.msg_flags = flags;
+-
+- if (sock->file->f_flags & O_NONBLOCK)
+- msg_sys.msg_flags |= MSG_DONTWAIT;
+- err = sock_sendmsg(sock, &msg_sys, total_len);
+-
+-out_freectl:
+- if (ctl_buf != ctl)
+- sock_kfree_s(sock->sk, ctl_buf, ctl_len);
+-out_freeiov:
+- if (iov != iovstack)
+- sock_kfree_s(sock->sk, iov, iov_size);
+-out_put:
+- fput_light(sock->file, fput_needed);
-out:
-- BUG_ON((int) q->q.qlen < 0);
-- return q->q.qlen;
-+ return ret;
- }
-
- void __qdisc_run(struct net_device *dev)
+- return err;
+-}
+-
+-/*
+- * BSD recvmsg interface
+- */
+-
+-asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg,
+- unsigned int flags)
+-{
+- struct compat_msghdr __user *msg_compat =
+- (struct compat_msghdr __user *)msg;
+- struct socket *sock;
+- struct iovec iovstack[UIO_FASTIOV];
+- struct iovec *iov = iovstack;
+- struct msghdr msg_sys;
+- unsigned long cmsg_ptr;
+- int err, iov_size, total_len, len;
+- int fput_needed;
+-
+- /* kernel mode address */
+- char addr[MAX_SOCK_ADDR];
+-
+- /* user mode address pointers */
+- struct sockaddr __user *uaddr;
+- int __user *uaddr_len;
+-
+- if (MSG_CMSG_COMPAT & flags) {
+- if (get_compat_msghdr(&msg_sys, msg_compat))
+- return -EFAULT;
+- }
+- else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr)))
+- return -EFAULT;
+-
+- sock = sockfd_lookup_light(fd, &err, &fput_needed);
+- if (!sock)
+- goto out;
+-
+- err = -EMSGSIZE;
+- if (msg_sys.msg_iovlen > UIO_MAXIOV)
+- goto out_put;
+-
+- /* Check whether to allocate the iovec area */
+- err = -ENOMEM;
+- iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
+- if (msg_sys.msg_iovlen > UIO_FASTIOV) {
+- iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
+- if (!iov)
+- goto out_put;
+- }
+-
+- /*
+- * Save the user-mode address (verify_iovec will change the
+- * kernel msghdr to use the kernel address space)
+- */
+-
+- uaddr = (void __user *)msg_sys.msg_name;
+- uaddr_len = COMPAT_NAMELEN(msg);
+- if (MSG_CMSG_COMPAT & flags) {
+- err = verify_compat_iovec(&msg_sys, iov, addr, VERIFY_WRITE);
+- } else
+- err = verify_iovec(&msg_sys, iov, addr, VERIFY_WRITE);
+- if (err < 0)
+- goto out_freeiov;
+- total_len = err;
+-
+- cmsg_ptr = (unsigned long)msg_sys.msg_control;
+- msg_sys.msg_flags = 0;
+- if (MSG_CMSG_COMPAT & flags)
+- msg_sys.msg_flags = MSG_CMSG_COMPAT;
+-
+- if (sock->file->f_flags & O_NONBLOCK)
+- flags |= MSG_DONTWAIT;
+- err = sock_recvmsg(sock, &msg_sys, total_len, flags);
+- if (err < 0)
+- goto out_freeiov;
+- len = err;
+-
+- if (uaddr != NULL) {
+- err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr,
+- uaddr_len);
+- if (err < 0)
+- goto out_freeiov;
+- }
+- err = __put_user((msg_sys.msg_flags & ~MSG_CMSG_COMPAT),
+- COMPAT_FLAGS(msg));
+- if (err)
+- goto out_freeiov;
+- if (MSG_CMSG_COMPAT & flags)
+- err = __put_user((unsigned long)msg_sys.msg_control - cmsg_ptr,
+- &msg_compat->msg_controllen);
+- else
+- err = __put_user((unsigned long)msg_sys.msg_control - cmsg_ptr,
+- &msg->msg_controllen);
+- if (err)
+- goto out_freeiov;
+- err = len;
+-
+-out_freeiov:
+- if (iov != iovstack)
+- sock_kfree_s(sock->sk, iov, iov_size);
+-out_put:
+- fput_light(sock->file, fput_needed);
+-out:
+- return err;
+-}
+-
+-#ifdef __ARCH_WANT_SYS_SOCKETCALL
+-
+-/* Argument list sizes for sys_socketcall */
+-#define AL(x) ((x) * sizeof(unsigned long))
+-static const unsigned char nargs[18]={
+- AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
+- AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
+- AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)
+-};
+-
+-#undef AL
+-
+-/*
+- * System call vectors.
+- *
+- * Argument checking cleaned up. Saved 20% in size.
+- * This function doesn't need to set the kernel lock because
+- * it is set by the callees.
+- */
+-
+-asmlinkage long sys_socketcall(int call, unsigned long __user *args)
+-{
+- unsigned long a[6];
+- unsigned long a0, a1;
+- int err;
+-
+- if (call < 1 || call > SYS_RECVMSG)
+- return -EINVAL;
+-
+- /* copy_from_user should be SMP safe. */
+- if (copy_from_user(a, args, nargs[call]))
+- return -EFAULT;
+-
+- err = audit_socketcall(nargs[call] / sizeof(unsigned long), a);
+- if (err)
+- return err;
+-
+- a0 = a[0];
+- a1 = a[1];
+-
+- switch (call) {
+- case SYS_SOCKET:
+- err = sys_socket(a0, a1, a[2]);
+- break;
+- case SYS_BIND:
+- err = sys_bind(a0, (struct sockaddr __user *)a1, a[2]);
+- break;
+- case SYS_CONNECT:
+- err = sys_connect(a0, (struct sockaddr __user *)a1, a[2]);
+- break;
+- case SYS_LISTEN:
+- err = sys_listen(a0, a1);
+- break;
+- case SYS_ACCEPT:
+- err =
+- sys_accept(a0, (struct sockaddr __user *)a1,
+- (int __user *)a[2]);
+- break;
+- case SYS_GETSOCKNAME:
+- err =
+- sys_getsockname(a0, (struct sockaddr __user *)a1,
+- (int __user *)a[2]);
+- break;
+- case SYS_GETPEERNAME:
+- err =
+- sys_getpeername(a0, (struct sockaddr __user *)a1,
+- (int __user *)a[2]);
+- break;
+- case SYS_SOCKETPAIR:
+- err = sys_socketpair(a0, a1, a[2], (int __user *)a[3]);
+- break;
+- case SYS_SEND:
+- err = sys_send(a0, (void __user *)a1, a[2], a[3]);
+- break;
+- case SYS_SENDTO:
+- err = sys_sendto(a0, (void __user *)a1, a[2], a[3],
+- (struct sockaddr __user *)a[4], a[5]);
+- break;
+- case SYS_RECV:
+- err = sys_recv(a0, (void __user *)a1, a[2], a[3]);
+- break;
+- case SYS_RECVFROM:
+- err = sys_recvfrom(a0, (void __user *)a1, a[2], a[3],
+- (struct sockaddr __user *)a[4],
+- (int __user *)a[5]);
+- break;
+- case SYS_SHUTDOWN:
+- err = sys_shutdown(a0, a1);
+- break;
+- case SYS_SETSOCKOPT:
+- err = sys_setsockopt(a0, a1, a[2], (char __user *)a[3], a[4]);
+- break;
+- case SYS_GETSOCKOPT:
+- err =
+- sys_getsockopt(a0, a1, a[2], (char __user *)a[3],
+- (int __user *)a[4]);
+- break;
+- case SYS_SENDMSG:
+- err = sys_sendmsg(a0, (struct msghdr __user *)a1, a[2]);
+- break;
+- case SYS_RECVMSG:
+- err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]);
+- break;
+- default:
+- err = -EINVAL;
+- break;
+- }
+- return err;
+-}
+-
+-#endif /* __ARCH_WANT_SYS_SOCKETCALL */
+-
+-/**
+- * sock_register - add a socket protocol handler
+- * @ops: description of protocol
+- *
+- * This function is called by a protocol handler that wants to
+- * advertise its address family, and have it linked into the
+- * socket interface. The value ops->family coresponds to the
+- * socket system call protocol family.
+- */
+-int sock_register(const struct net_proto_family *ops)
+-{
+- int err;
+-
+- if (ops->family >= NPROTO) {
+- printk(KERN_CRIT "protocol %d >= NPROTO(%d)\n", ops->family,
+- NPROTO);
+- return -ENOBUFS;
+- }
+-
+- spin_lock(&net_family_lock);
+- if (net_families[ops->family])
+- err = -EEXIST;
+- else {
+- net_families[ops->family] = ops;
+- err = 0;
+- }
+- spin_unlock(&net_family_lock);
+-
+- printk(KERN_INFO "NET: Registered protocol family %d\n", ops->family);
+- return err;
+-}
+-
+-/**
+- * sock_unregister - remove a protocol handler
+- * @family: protocol family to remove
+- *
+- * This function is called by a protocol handler that wants to
+- * remove its address family, and have it unlinked from the
+- * new socket creation.
+- *
+- * If protocol handler is a module, then it can use module reference
+- * counts to protect against new references. If protocol handler is not
+- * a module then it needs to provide its own protection in
+- * the ops->create routine.
+- */
+-void sock_unregister(int family)
+-{
+- BUG_ON(family < 0 || family >= NPROTO);
+-
+- spin_lock(&net_family_lock);
+- net_families[family] = NULL;
+- spin_unlock(&net_family_lock);
+-
+- synchronize_rcu();
+-
+- printk(KERN_INFO "NET: Unregistered protocol family %d\n", family);
+-}
+-
+-static int __init sock_init(void)
+-{
+- /*
+- * Initialize sock SLAB cache.
+- */
+-
+- sk_init();
+-
+- /*
+- * Initialize skbuff SLAB cache
+- */
+- skb_init();
+-
+- /*
+- * Initialize the protocols module.
+- */
+-
+- init_inodecache();
+- register_filesystem(&sock_fs_type);
+- sock_mnt = kern_mount(&sock_fs_type);
+-
+- /* The real protocol initialization is performed in later initcalls.
+- */
+-
+-#ifdef CONFIG_NETFILTER
+- netfilter_init();
+-#endif
+-
+- return 0;
+-}
+-
+-core_initcall(sock_init); /* early initcall */
+-
+-#ifdef CONFIG_PROC_FS
+-void socket_seq_show(struct seq_file *seq)
+-{
+- int cpu;
+- int counter = 0;
+-
+- for_each_possible_cpu(cpu)
+- counter += per_cpu(sockets_in_use, cpu);
+-
+- /* It can be negative, by the way. 8) */
+- if (counter < 0)
+- counter = 0;
+-
+- seq_printf(seq, "sockets: used %d\n", counter);
+-}
+-#endif /* CONFIG_PROC_FS */
+-
+-#ifdef CONFIG_COMPAT
+-static long compat_sock_ioctl(struct file *file, unsigned cmd,
+- unsigned long arg)
+-{
+- struct socket *sock = file->private_data;
+- int ret = -ENOIOCTLCMD;
+-
+- if (sock->ops->compat_ioctl)
+- ret = sock->ops->compat_ioctl(sock, cmd, arg);
+-
+- return ret;
+-}
+-#endif
+-
+-int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen)
+-{
+- return sock->ops->bind(sock, addr, addrlen);
+-}
+-
+-int kernel_listen(struct socket *sock, int backlog)
+-{
+- return sock->ops->listen(sock, backlog);
+-}
+-
+-int kernel_accept(struct socket *sock, struct socket **newsock, int flags)
+-{
+- struct sock *sk = sock->sk;
+- int err;
+-
+- err = sock_create_lite(sk->sk_family, sk->sk_type, sk->sk_protocol,
+- newsock);
+- if (err < 0)
+- goto done;
+-
+- err = sock->ops->accept(sock, *newsock, flags);
+- if (err < 0) {
+- sock_release(*newsock);
+- goto done;
+- }
+-
+- (*newsock)->ops = sock->ops;
+-
+-done:
+- return err;
+-}
+-
+-int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,
+- int flags)
+-{
+- return sock->ops->connect(sock, addr, addrlen, flags);
+-}
+-
+-int kernel_getsockname(struct socket *sock, struct sockaddr *addr,
+- int *addrlen)
+-{
+- return sock->ops->getname(sock, addr, addrlen, 0);
+-}
+-
+-int kernel_getpeername(struct socket *sock, struct sockaddr *addr,
+- int *addrlen)
+-{
+- return sock->ops->getname(sock, addr, addrlen, 1);
+-}
+-
+-int kernel_getsockopt(struct socket *sock, int level, int optname,
+- char *optval, int *optlen)
+-{
+- mm_segment_t oldfs = get_fs();
+- int err;
+-
+- set_fs(KERNEL_DS);
+- if (level == SOL_SOCKET)
+- err = sock_getsockopt(sock, level, optname, optval, optlen);
+- else
+- err = sock->ops->getsockopt(sock, level, optname, optval,
+- optlen);
+- set_fs(oldfs);
+- return err;
+-}
+-
+-int kernel_setsockopt(struct socket *sock, int level, int optname,
+- char *optval, int optlen)
+-{
+- mm_segment_t oldfs = get_fs();
+- int err;
+-
+- set_fs(KERNEL_DS);
+- if (level == SOL_SOCKET)
+- err = sock_setsockopt(sock, level, optname, optval, optlen);
+- else
+- err = sock->ops->setsockopt(sock, level, optname, optval,
+- optlen);
+- set_fs(oldfs);
+- return err;
+-}
+-
+-int kernel_sendpage(struct socket *sock, struct page *page, int offset,
+- size_t size, int flags)
+-{
+- if (sock->ops->sendpage)
+- return sock->ops->sendpage(sock, page, offset, size, flags);
+-
+- return sock_no_sendpage(sock, page, offset, size, flags);
+-}
+-
+-int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg)
+-{
+- mm_segment_t oldfs = get_fs();
+- int err;
+-
+- set_fs(KERNEL_DS);
+- err = sock->ops->ioctl(sock, cmd, arg);
+- set_fs(oldfs);
+-
+- return err;
+-}
+-
+-/* ABI emulation layers need these two */
+-EXPORT_SYMBOL(move_addr_to_kernel);
+-EXPORT_SYMBOL(move_addr_to_user);
+-EXPORT_SYMBOL(sock_create);
+-EXPORT_SYMBOL(sock_create_kern);
+-EXPORT_SYMBOL(sock_create_lite);
+-EXPORT_SYMBOL(sock_map_fd);
+-EXPORT_SYMBOL(sock_recvmsg);
+-EXPORT_SYMBOL(sock_register);
+-EXPORT_SYMBOL(sock_release);
+-EXPORT_SYMBOL(sock_sendmsg);
+-EXPORT_SYMBOL(sock_unregister);
+-EXPORT_SYMBOL(sock_wake_async);
+-EXPORT_SYMBOL(sockfd_lookup);
+-EXPORT_SYMBOL(kernel_sendmsg);
+-EXPORT_SYMBOL(kernel_recvmsg);
+-EXPORT_SYMBOL(kernel_bind);
+-EXPORT_SYMBOL(kernel_listen);
+-EXPORT_SYMBOL(kernel_accept);
+-EXPORT_SYMBOL(kernel_connect);
+-EXPORT_SYMBOL(kernel_getsockname);
+-EXPORT_SYMBOL(kernel_getpeername);
+-EXPORT_SYMBOL(kernel_getsockopt);
+-EXPORT_SYMBOL(kernel_setsockopt);
+-EXPORT_SYMBOL(kernel_sendpage);
+-EXPORT_SYMBOL(kernel_sock_ioctl);
diff -Nurb linux-2.6.22-570/net/sunrpc/auth.c linux-2.6.22-590/net/sunrpc/auth.c
---- linux-2.6.22-570/net/sunrpc/auth.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/net/sunrpc/auth.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/net/sunrpc/auth.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/sunrpc/auth.c 2008-01-29 22:12:32.000000000 -0500
@@ -19,12 +19,16 @@
# define RPCDBG_FACILITY RPCDBG_AUTH
#endif
}
diff -Nurb linux-2.6.22-570/net/sunrpc/auth_gss/auth_gss.c linux-2.6.22-590/net/sunrpc/auth_gss/auth_gss.c
--- linux-2.6.22-570/net/sunrpc/auth_gss/auth_gss.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/sunrpc/auth_gss/auth_gss.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/sunrpc/auth_gss/auth_gss.c 2008-01-29 22:12:33.000000000 -0500
@@ -54,9 +54,9 @@
#include <linux/sunrpc/gss_api.h>
#include <asm/uaccess.h>
.cr_init = gss_cred_init,
diff -Nurb linux-2.6.22-570/net/sunrpc/auth_gss/gss_krb5_mech.c linux-2.6.22-590/net/sunrpc/auth_gss/gss_krb5_mech.c
--- linux-2.6.22-570/net/sunrpc/auth_gss/gss_krb5_mech.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/sunrpc/auth_gss/gss_krb5_mech.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/sunrpc/auth_gss/gss_krb5_mech.c 2008-01-29 22:12:33.000000000 -0500
@@ -201,7 +201,7 @@
kfree(kctx);
}
.gss_verify_mic = gss_verify_mic_kerberos,
diff -Nurb linux-2.6.22-570/net/sunrpc/auth_gss/gss_spkm3_mech.c linux-2.6.22-590/net/sunrpc/auth_gss/gss_spkm3_mech.c
--- linux-2.6.22-570/net/sunrpc/auth_gss/gss_spkm3_mech.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/sunrpc/auth_gss/gss_spkm3_mech.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/sunrpc/auth_gss/gss_spkm3_mech.c 2008-01-29 22:12:33.000000000 -0500
@@ -202,7 +202,7 @@
return err;
}
.gss_verify_mic = gss_verify_mic_spkm3,
diff -Nurb linux-2.6.22-570/net/sunrpc/auth_null.c linux-2.6.22-590/net/sunrpc/auth_null.c
--- linux-2.6.22-570/net/sunrpc/auth_null.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/sunrpc/auth_null.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/sunrpc/auth_null.c 2008-01-29 22:12:33.000000000 -0500
@@ -76,7 +76,7 @@
static int
nul_refresh(struct rpc_task *task)
.cr_magic = RPCAUTH_CRED_MAGIC,
#endif
diff -Nurb linux-2.6.22-570/net/sunrpc/auth_unix.c linux-2.6.22-590/net/sunrpc/auth_unix.c
---- linux-2.6.22-570/net/sunrpc/auth_unix.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/net/sunrpc/auth_unix.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/net/sunrpc/auth_unix.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/sunrpc/auth_unix.c 2008-01-29 22:12:33.000000000 -0500
@@ -22,11 +22,6 @@
gid_t uc_gids[NFS_NGROUPS];
};
__be32 *base, *hold;
int i, tag;
-@@ -183,7 +190,7 @@
+@@ -159,7 +166,6 @@
+ * Copy the UTS nodename captured when the client was created.
+ */
+ p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
+- tag = task->tk_client->cl_tag;
+
+ *p++ = htonl((u32) TAGINO_UID(tag,
+ cred->uc_uid, cred->uc_tag));
+@@ -183,7 +189,7 @@
static int
unx_refresh(struct rpc_task *task)
{
return 0;
}
-@@ -212,7 +219,12 @@
+@@ -212,7 +218,12 @@
return p;
}
.owner = THIS_MODULE,
.au_flavor = RPC_AUTH_UNIX,
#ifdef RPC_DEBUG
-@@ -226,7 +238,6 @@
+@@ -226,7 +237,6 @@
static
struct rpc_cred_cache unix_cred_cache = {
};
static
-@@ -240,7 +251,7 @@
+@@ -240,7 +250,7 @@
};
static
.crdestroy = unx_destroy_cred,
.crmatch = unx_match,
diff -Nurb linux-2.6.22-570/net/sunrpc/clnt.c linux-2.6.22-590/net/sunrpc/clnt.c
---- linux-2.6.22-570/net/sunrpc/clnt.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/net/sunrpc/clnt.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/net/sunrpc/clnt.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/sunrpc/clnt.c 2008-01-29 22:12:33.000000000 -0500
@@ -45,6 +45,12 @@
dprintk("RPC: %5u %s (status %d)\n", t->tk_pid, \
__FUNCTION__, t->tk_status)
+#endif
diff -Nurb linux-2.6.22-570/net/sunrpc/rpc_pipe.c linux-2.6.22-590/net/sunrpc/rpc_pipe.c
--- linux-2.6.22-570/net/sunrpc/rpc_pipe.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/sunrpc/rpc_pipe.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/sunrpc/rpc_pipe.c 2008-01-29 22:12:33.000000000 -0500
@@ -14,7 +14,7 @@
#include <linux/pagemap.h>
#include <linux/mount.h>
init_waitqueue_head(&rpci->waitq);
diff -Nurb linux-2.6.22-570/net/sunrpc/rpcb_clnt.c linux-2.6.22-590/net/sunrpc/rpcb_clnt.c
--- linux-2.6.22-570/net/sunrpc/rpcb_clnt.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/sunrpc/rpcb_clnt.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/sunrpc/rpcb_clnt.c 2008-01-29 22:12:33.000000000 -0500
@@ -184,8 +184,7 @@
.program = &rpcb_program,
.version = version,
dprintk("RPC: %5u rpcb_getport rpc_run_task failed\n",
diff -Nurb linux-2.6.22-570/net/sunrpc/sched.c linux-2.6.22-590/net/sunrpc/sched.c
--- linux-2.6.22-570/net/sunrpc/sched.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/sunrpc/sched.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/sunrpc/sched.c 2008-01-29 22:12:33.000000000 -0500
@@ -25,7 +25,6 @@
#ifdef RPC_DEBUG
#define RPCDBG_FACILITY RPCDBG_SCHED
void
rpc_destroy_mempool(void)
+diff -Nurb linux-2.6.22-570/net/sunrpc/stats.c linux-2.6.22-590/net/sunrpc/stats.c
+--- linux-2.6.22-570/net/sunrpc/stats.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/sunrpc/stats.c 2008-01-29 22:12:33.000000000 -0500
+@@ -21,6 +21,7 @@
+ #include <linux/sunrpc/clnt.h>
+ #include <linux/sunrpc/svcsock.h>
+ #include <linux/sunrpc/metrics.h>
++#include <net/net_namespace.h>
+
+ #define RPCDBG_FACILITY RPCDBG_MISC
+
+@@ -265,7 +266,7 @@
+ dprintk("RPC: registering /proc/net/rpc\n");
+ if (!proc_net_rpc) {
+ struct proc_dir_entry *ent;
+- ent = proc_mkdir("rpc", proc_net);
++ ent = proc_mkdir("rpc", init_net.proc_net);
+ if (ent) {
+ ent->owner = THIS_MODULE;
+ proc_net_rpc = ent;
+@@ -279,7 +280,7 @@
+ dprintk("RPC: unregistering /proc/net/rpc\n");
+ if (proc_net_rpc) {
+ proc_net_rpc = NULL;
+- remove_proc_entry("net/rpc", NULL);
++ remove_proc_entry("rpc", init_net.proc_net);
+ }
+ }
+
diff -Nurb linux-2.6.22-570/net/sunrpc/sunrpc_syms.c linux-2.6.22-590/net/sunrpc/sunrpc_syms.c
--- linux-2.6.22-570/net/sunrpc/sunrpc_syms.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/sunrpc/sunrpc_syms.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/sunrpc/sunrpc_syms.c 2008-01-29 22:12:33.000000000 -0500
@@ -28,15 +28,11 @@
EXPORT_SYMBOL(rpc_sleep_on);
EXPORT_SYMBOL(rpc_wake_up_next);
rpc_destroy_mempool();
diff -Nurb linux-2.6.22-570/net/sunrpc/xprt.c linux-2.6.22-590/net/sunrpc/xprt.c
--- linux-2.6.22-570/net/sunrpc/xprt.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/sunrpc/xprt.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/sunrpc/xprt.c 2008-01-29 22:12:33.000000000 -0500
@@ -127,7 +127,7 @@
clear_bit(XPRT_LOCKED, &xprt->state);
smp_mb__after_clear_bit();
spin_unlock(&xprt->transport_lock);
diff -Nurb linux-2.6.22-570/net/sunrpc/xprtsock.c linux-2.6.22-590/net/sunrpc/xprtsock.c
--- linux-2.6.22-570/net/sunrpc/xprtsock.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/sunrpc/xprtsock.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/sunrpc/xprtsock.c 2008-01-29 22:12:33.000000000 -0500
@@ -653,8 +653,7 @@
dprintk("RPC: xs_destroy xprt %p\n", xprt);
}
}
+diff -Nurb linux-2.6.22-570/net/sysctl_net.c linux-2.6.22-590/net/sysctl_net.c
+--- linux-2.6.22-570/net/sysctl_net.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/sysctl_net.c 2008-01-29 22:12:33.000000000 -0500
+@@ -54,3 +54,31 @@
+ #endif
+ { 0 },
+ };
++
++struct ctl_table multi_net_table[] = {
++ {
++ .ctl_name = NET_CORE,
++ .procname = "core",
++ .mode = 0555,
++ .child = multi_core_table,
++ },
++#ifdef CONFIG_INET
++ {
++ .ctl_name = NET_IPV4,
++ .procname = "ipv4",
++ .mode = 0555,
++ .child = multi_ipv4_table,
++ },
++#endif
++ {},
++};
++
++struct ctl_table net_root_table[] = {
++ {
++ .ctl_name = CTL_NET,
++ .procname = "net",
++ .mode = 0555,
++ .child = multi_net_table,
++ },
++ {},
++};
diff -Nurb linux-2.6.22-570/net/tipc/eth_media.c linux-2.6.22-590/net/tipc/eth_media.c
--- linux-2.6.22-570/net/tipc/eth_media.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/tipc/eth_media.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/tipc/eth_media.c 2008-01-29 22:12:33.000000000 -0500
@@ -1,8 +1,8 @@
/*
* net/tipc/eth_media.c: Ethernet bearer support for TIPC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
-@@ -87,6 +87,9 @@
+@@ -38,6 +38,7 @@
+ #include <net/tipc/tipc_bearer.h>
+ #include <net/tipc/tipc_msg.h>
+ #include <linux/netdevice.h>
++#include <net/net_namespace.h>
+
+ #define MAX_ETH_BEARERS 2
+ #define ETH_LINK_PRIORITY TIPC_DEF_LINK_PRI
+@@ -87,6 +88,9 @@
/**
* recv_msg - handle incoming TIPC message from an Ethernet interface
*
* Routine truncates any Ethernet padding/CRC appended to the message,
* and ensures message size matches actual length
*/
-@@ -98,9 +101,7 @@
+@@ -97,10 +101,13 @@
+ struct eth_bearer *eb_ptr = (struct eth_bearer *)pt->af_packet_priv;
u32 size;
++ if (dev->nd_net != &init_net) {
++ kfree_skb(buf);
++ return 0;
++ }
++
if (likely(eb_ptr->bearer)) {
- if (likely(!dev->promiscuity) ||
- !memcmp(skb_mac_header(buf), dev->dev_addr, ETH_ALEN) ||
size = msg_size((struct tipc_msg *)buf->data);
skb_trim(buf, size);
if (likely(buf->len == size)) {
+@@ -128,7 +135,7 @@
+
+ /* Find device with specified name */
+
+- for_each_netdev(pdev){
++ for_each_netdev(&init_net, pdev){
+ if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) {
+ dev = pdev;
+ break;
+@@ -191,6 +198,9 @@
+ struct eth_bearer *eb_ptr = ð_bearers[0];
+ struct eth_bearer *stop = ð_bearers[MAX_ETH_BEARERS];
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ while ((eb_ptr->dev != dev)) {
+ if (++eb_ptr == stop)
+ return NOTIFY_DONE; /* couldn't find device */
diff -Nurb linux-2.6.22-570/net/tipc/link.c linux-2.6.22-590/net/tipc/link.c
--- linux-2.6.22-570/net/tipc/link.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/tipc/link.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/tipc/link.c 2008-01-29 22:12:33.000000000 -0500
@@ -1,8 +1,8 @@
/*
* net/tipc/link.c: TIPC link code
buf = buf_chain->next;
diff -Nurb linux-2.6.22-570/net/tipc/port.c linux-2.6.22-590/net/tipc/port.c
--- linux-2.6.22-570/net/tipc/port.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/tipc/port.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/tipc/port.c 2008-01-29 22:12:33.000000000 -0500
@@ -1,8 +1,8 @@
/*
* net/tipc/port.c: TIPC port code
diff -Nurb linux-2.6.22-570/net/tipc/port.h linux-2.6.22-590/net/tipc/port.h
--- linux-2.6.22-570/net/tipc/port.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/tipc/port.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/tipc/port.h 2008-01-29 22:12:33.000000000 -0500
@@ -1,8 +1,8 @@
/*
* net/tipc/port.h: Include file for TIPC port code
u32 last_in_seqno;
diff -Nurb linux-2.6.22-570/net/tipc/socket.c linux-2.6.22-590/net/tipc/socket.c
--- linux-2.6.22-570/net/tipc/socket.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/net/tipc/socket.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/net/tipc/socket.c 2008-01-29 22:12:33.000000000 -0500
@@ -1,8 +1,8 @@
/*
* net/tipc/socket.c: TIPC socket API
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
-@@ -607,23 +607,24 @@
+@@ -162,13 +162,16 @@
+ *
+ * Returns 0 on success, errno otherwise
+ */
+-static int tipc_create(struct socket *sock, int protocol)
++static int tipc_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct tipc_sock *tsock;
+ struct tipc_port *port;
+ struct sock *sk;
+ u32 ref;
+
++ if (net != &init_net)
++ return -EAFNOSUPPORT;
++
+ if (unlikely(protocol != 0))
+ return -EPROTONOSUPPORT;
+
+@@ -198,7 +201,7 @@
+ return -EPROTOTYPE;
+ }
+
+- sk = sk_alloc(AF_TIPC, GFP_KERNEL, &tipc_proto, 1);
++ sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto, 1);
+ if (!sk) {
+ tipc_deleteport(ref);
+ return -ENOMEM;
+@@ -607,23 +610,24 @@
static int send_stream(struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t total_len)
{
return -EPIPE;
else
return -ENOTCONN;
-@@ -648,17 +649,25 @@
+@@ -648,17 +652,25 @@
my_msg.msg_name = NULL;
bytes_sent = 0;
}
curr_left -= bytes_to_send;
curr_start += bytes_to_send;
-@@ -1600,33 +1609,6 @@
+@@ -1363,7 +1375,7 @@
+ }
+ buf = skb_peek(&sock->sk->sk_receive_queue);
+
+- res = tipc_create(newsock, 0);
++ res = tipc_create(sock->sk->sk_net, newsock, 0);
+ if (!res) {
+ struct tipc_sock *new_tsock = tipc_sk(newsock->sk);
+ struct tipc_portid id;
+@@ -1600,33 +1612,6 @@
}
/**
* Protocol switches for the various types of TIPC sockets
*/
-@@ -1636,19 +1618,19 @@
+@@ -1636,19 +1621,19 @@
.release = release,
.bind = bind,
.connect = connect,
};
static struct proto_ops packet_ops = {
-@@ -1657,19 +1639,19 @@
+@@ -1657,19 +1642,19 @@
.release = release,
.bind = bind,
.connect = connect,
};
static struct proto_ops stream_ops = {
-@@ -1678,19 +1660,19 @@
+@@ -1678,19 +1663,19 @@
.release = release,
.bind = bind,
.connect = connect,
};
static struct net_proto_family tipc_family_ops = {
+diff -Nurb linux-2.6.22-570/net/unix/af_unix.c linux-2.6.22-590/net/unix/af_unix.c
+--- linux-2.6.22-570/net/unix/af_unix.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/unix/af_unix.c 2008-01-29 22:12:33.000000000 -0500
+@@ -117,8 +117,8 @@
+ #include <linux/security.h>
+ #include <linux/vs_context.h>
+ #include <linux/vs_limit.h>
++#include <net/net_namespace.h>
+
+-int sysctl_unix_max_dgram_qlen __read_mostly = 10;
+
+ struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
+ DEFINE_SPINLOCK(unix_table_lock);
+@@ -245,7 +245,8 @@
+ spin_unlock(&unix_table_lock);
+ }
+
+-static struct sock *__unix_find_socket_byname(struct sockaddr_un *sunname,
++static struct sock *__unix_find_socket_byname(struct net *net,
++ struct sockaddr_un *sunname,
+ int len, int type, unsigned hash)
+ {
+ struct sock *s;
+@@ -254,7 +255,7 @@
+ sk_for_each(s, node, &unix_socket_table[hash ^ type]) {
+ struct unix_sock *u = unix_sk(s);
+
+- if (!nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT))
++ if (!nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT) || (s->sk_net != net))
+ continue;
+ if (u->addr->len == len &&
+ !memcmp(u->addr->name, sunname, len))
+@@ -265,21 +266,22 @@
+ return s;
+ }
+
+-static inline struct sock *unix_find_socket_byname(struct sockaddr_un *sunname,
++static inline struct sock *unix_find_socket_byname(struct net *net,
++ struct sockaddr_un *sunname,
+ int len, int type,
+ unsigned hash)
+ {
+ struct sock *s;
+
+ spin_lock(&unix_table_lock);
+- s = __unix_find_socket_byname(sunname, len, type, hash);
++ s = __unix_find_socket_byname(net, sunname, len, type, hash);
+ if (s)
+ sock_hold(s);
+ spin_unlock(&unix_table_lock);
+ return s;
+ }
+
+-static struct sock *unix_find_socket_byinode(struct inode *i)
++static struct sock *unix_find_socket_byinode(struct net *net, struct inode *i)
+ {
+ struct sock *s;
+ struct hlist_node *node;
+@@ -289,6 +291,9 @@
+ &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
+ struct dentry *dentry = unix_sk(s)->dentry;
+
++ if (s->sk_net != net)
++ continue;
++
+ if(dentry && dentry->d_inode == i)
+ {
+ sock_hold(s);
+@@ -571,7 +576,7 @@
+ */
+ static struct lock_class_key af_unix_sk_receive_queue_lock_key;
+
+-static struct sock * unix_create1(struct socket *sock)
++static struct sock * unix_create1(struct net *net, struct socket *sock)
+ {
+ struct sock *sk = NULL;
+ struct unix_sock *u;
+@@ -579,7 +584,7 @@
+ if (atomic_read(&unix_nr_socks) >= 2*get_max_files())
+ goto out;
+
+- sk = sk_alloc(PF_UNIX, GFP_KERNEL, &unix_proto, 1);
++ sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto, 1);
+ if (!sk)
+ goto out;
+
+@@ -590,7 +595,7 @@
+ &af_unix_sk_receive_queue_lock_key);
+
+ sk->sk_write_space = unix_write_space;
+- sk->sk_max_ack_backlog = sysctl_unix_max_dgram_qlen;
++ sk->sk_max_ack_backlog = net->sysctl_unix_max_dgram_qlen;
+ sk->sk_destruct = unix_sock_destructor;
+ u = unix_sk(sk);
+ u->dentry = NULL;
+@@ -604,7 +609,7 @@
+ return sk;
+ }
+
+-static int unix_create(struct socket *sock, int protocol)
++static int unix_create(struct net *net, struct socket *sock, int protocol)
+ {
+ if (protocol && protocol != PF_UNIX)
+ return -EPROTONOSUPPORT;
+@@ -631,7 +636,7 @@
+ return -ESOCKTNOSUPPORT;
+ }
+
+- return unix_create1(sock) ? 0 : -ENOMEM;
++ return unix_create1(net, sock) ? 0 : -ENOMEM;
+ }
+
+ static int unix_release(struct socket *sock)
+@@ -649,6 +654,7 @@
+ static int unix_autobind(struct socket *sock)
+ {
+ struct sock *sk = sock->sk;
++ struct net *net = sk->sk_net;
+ struct unix_sock *u = unix_sk(sk);
+ static u32 ordernum = 1;
+ struct unix_address * addr;
+@@ -675,7 +681,7 @@
+ spin_lock(&unix_table_lock);
+ ordernum = (ordernum+1)&0xFFFFF;
+
+- if (__unix_find_socket_byname(addr->name, addr->len, sock->type,
++ if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type,
+ addr->hash)) {
+ spin_unlock(&unix_table_lock);
+ /* Sanity yield. It is unusual case, but yet... */
+@@ -695,7 +701,8 @@
+ return err;
+ }
+
+-static struct sock *unix_find_other(struct sockaddr_un *sunname, int len,
++static struct sock *unix_find_other(struct net *net,
++ struct sockaddr_un *sunname, int len,
+ int type, unsigned hash, int *error)
+ {
+ struct sock *u;
+@@ -713,7 +720,7 @@
+ err = -ECONNREFUSED;
+ if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
+ goto put_fail;
+- u=unix_find_socket_byinode(nd.dentry->d_inode);
++ u=unix_find_socket_byinode(net, nd.dentry->d_inode);
+ if (!u)
+ goto put_fail;
+
+@@ -729,7 +736,7 @@
+ }
+ } else {
+ err = -ECONNREFUSED;
+- u=unix_find_socket_byname(sunname, len, type, hash);
++ u=unix_find_socket_byname(net, sunname, len, type, hash);
+ if (u) {
+ struct dentry *dentry;
+ dentry = unix_sk(u)->dentry;
+@@ -751,6 +758,7 @@
+ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
+ {
+ struct sock *sk = sock->sk;
++ struct net *net = sk->sk_net;
+ struct unix_sock *u = unix_sk(sk);
+ struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
+ struct dentry * dentry = NULL;
+@@ -825,7 +833,7 @@
+
+ if (!sunaddr->sun_path[0]) {
+ err = -EADDRINUSE;
+- if (__unix_find_socket_byname(sunaddr, addr_len,
++ if (__unix_find_socket_byname(net, sunaddr, addr_len,
+ sk->sk_type, hash)) {
+ unix_release_addr(addr);
+ goto out_unlock;
+@@ -891,6 +899,7 @@
+ int alen, int flags)
+ {
+ struct sock *sk = sock->sk;
++ struct net *net = sk->sk_net;
+ struct sockaddr_un *sunaddr=(struct sockaddr_un*)addr;
+ struct sock *other;
+ unsigned hash;
+@@ -907,7 +916,7 @@
+ goto out;
+
+ restart:
+- other=unix_find_other(sunaddr, alen, sock->type, hash, &err);
++ other=unix_find_other(net, sunaddr, alen, sock->type, hash, &err);
+ if (!other)
+ goto out;
+
+@@ -987,6 +996,7 @@
+ {
+ struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
+ struct sock *sk = sock->sk;
++ struct net *net = sk->sk_net;
+ struct unix_sock *u = unix_sk(sk), *newu, *otheru;
+ struct sock *newsk = NULL;
+ struct sock *other = NULL;
+@@ -1015,7 +1025,7 @@
+ err = -ENOMEM;
+
+ /* create new sock for complete connection */
+- newsk = unix_create1(NULL);
++ newsk = unix_create1(sk->sk_net, NULL);
+ if (newsk == NULL)
+ goto out;
+
+@@ -1026,7 +1036,7 @@
+
+ restart:
+ /* Find listening sock. */
+- other = unix_find_other(sunaddr, addr_len, sk->sk_type, hash, &err);
++ other = unix_find_other(net, sunaddr, addr_len, sk->sk_type, hash, &err);
+ if (!other)
+ goto out;
+
+@@ -1305,6 +1315,7 @@
+ {
+ struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
+ struct sock *sk = sock->sk;
++ struct net *net = sk->sk_net;
+ struct unix_sock *u = unix_sk(sk);
+ struct sockaddr_un *sunaddr=msg->msg_name;
+ struct sock *other = NULL;
+@@ -1368,7 +1379,7 @@
+ if (sunaddr == NULL)
+ goto out_free;
+
+- other = unix_find_other(sunaddr, namelen, sk->sk_type,
++ other = unix_find_other(net, sunaddr, namelen, sk->sk_type,
+ hash, &err);
+ if (other==NULL)
+ goto out_free;
+@@ -1974,12 +1985,18 @@
+
+
+ #ifdef CONFIG_PROC_FS
+-static struct sock *unix_seq_idx(int *iter, loff_t pos)
++struct unix_iter_state {
++ struct net *net;
++ int i;
++};
++static struct sock *unix_seq_idx(struct unix_iter_state *iter, loff_t pos)
+ {
+ loff_t off = 0;
+ struct sock *s;
+
+- for (s = first_unix_socket(iter); s; s = next_unix_socket(iter, s)) {
++ for (s = first_unix_socket(&iter->i); s; s = next_unix_socket(&iter->i, s)) {
++ if (s->sk_net != iter->net)
++ continue;
+ if (off == pos)
+ return s;
+ ++off;
+@@ -1990,17 +2007,24 @@
+
+ static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
+ {
++ struct unix_iter_state *iter = seq->private;
+ spin_lock(&unix_table_lock);
+- return *pos ? unix_seq_idx(seq->private, *pos - 1) : ((void *) 1);
++ return *pos ? unix_seq_idx(iter, *pos - 1) : ((void *) 1);
+ }
+
+ static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
++ struct unix_iter_state *iter = seq->private;
++ struct sock *sk = v;
+ ++*pos;
+
+ if (v == (void *)1)
+- return first_unix_socket(seq->private);
+- return next_unix_socket(seq->private, v);
++ sk = first_unix_socket(&iter->i);
++ else
++ sk = next_unix_socket(&iter->i, sk);
++ while (sk && (sk->sk_net != iter->net))
++ sk = next_unix_socket(&iter->i, sk);
++ return sk;
+ }
+
+ static void unix_seq_stop(struct seq_file *seq, void *v)
+@@ -2064,7 +2088,7 @@
+ {
+ struct seq_file *seq;
+ int rc = -ENOMEM;
+- int *iter = kmalloc(sizeof(int), GFP_KERNEL);
++ struct unix_iter_state *iter = kmalloc(sizeof(*iter), GFP_KERNEL);
+
+ if (!iter)
+ goto out;
+@@ -2075,7 +2099,8 @@
+
+ seq = file->private_data;
+ seq->private = iter;
+- *iter = 0;
++ iter->net = get_net(PROC_NET(inode));
++ iter->i = 0;
+ out:
+ return rc;
+ out_kfree:
+@@ -2083,12 +2108,20 @@
+ goto out;
+ }
+
++static int unix_seq_release(struct inode *inode, struct file *file)
++{
++ struct seq_file *seq = file->private_data;
++ struct unix_iter_state *iter = seq->private;
++ put_net(iter->net);
++ return seq_release_private(inode, file);
++}
++
+ static const struct file_operations unix_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = unix_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+- .release = seq_release_private,
++ .release = unix_seq_release,
+ };
+
+ #endif
+@@ -2099,6 +2132,33 @@
+ .owner = THIS_MODULE,
+ };
+
++
++static int unix_net_init(struct net *net)
++{
++ int error = -ENOMEM;
++
++ net->sysctl_unix_max_dgram_qlen = 10;
++#ifdef CONFIG_PROC_FS
++ if (!proc_net_fops_create(net, "unix", 0, &unix_seq_fops))
++ goto out;
++#endif
++ unix_sysctl_register(net);
++ error = 0;
++out:
++ return 0;
++}
++
++static void unix_net_exit(struct net *net)
++{
++ unix_sysctl_unregister(net);
++ proc_net_remove(net, "unix");
++}
++
++static struct pernet_operations unix_net_ops = {
++ .init = unix_net_init,
++ .exit = unix_net_exit,
++};
++
+ static int __init af_unix_init(void)
+ {
+ int rc = -1;
+@@ -2114,10 +2174,7 @@
+ }
+
+ sock_register(&unix_family_ops);
+-#ifdef CONFIG_PROC_FS
+- proc_net_fops_create("unix", 0, &unix_seq_fops);
+-#endif
+- unix_sysctl_register();
++ register_pernet_subsys(&unix_net_ops);
+ out:
+ return rc;
+ }
+@@ -2125,9 +2182,8 @@
+ static void __exit af_unix_exit(void)
+ {
+ sock_unregister(PF_UNIX);
+- unix_sysctl_unregister();
+- proc_net_remove("unix");
+ proto_unregister(&unix_proto);
++ unregister_pernet_subsys(&unix_net_ops);
+ }
+
+ module_init(af_unix_init);
+diff -Nurb linux-2.6.22-570/net/unix/sysctl_net_unix.c linux-2.6.22-590/net/unix/sysctl_net_unix.c
+--- linux-2.6.22-570/net/unix/sysctl_net_unix.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/unix/sysctl_net_unix.c 2008-01-29 22:12:33.000000000 -0500
+@@ -14,47 +14,71 @@
+
+ #include <net/af_unix.h>
+
+-static ctl_table unix_table[] = {
++static struct unix_sysctl_table {
++ struct ctl_table_header *sysctl_header;
++ struct ctl_table unix_table[2];
++ struct ctl_table unix_net_table[2];
++ struct ctl_table unix_root_table[2];
++} unix_sysctl = {
++ .unix_table = {
+ {
+ .ctl_name = NET_UNIX_MAX_DGRAM_QLEN,
+ .procname = "max_dgram_qlen",
+- .data = &sysctl_unix_max_dgram_qlen,
++ .data = &init_net.sysctl_unix_max_dgram_qlen,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec
+ },
+- { .ctl_name = 0 }
+-};
+-
+-static ctl_table unix_net_table[] = {
++ {}
++ },
++ .unix_net_table = {
+ {
+ .ctl_name = NET_UNIX,
+ .procname = "unix",
+ .mode = 0555,
+- .child = unix_table
++ .child = unix_sysctl.unix_table
+ },
+- { .ctl_name = 0 }
+-};
+-
+-static ctl_table unix_root_table[] = {
++ {}
++ },
++ .unix_root_table = {
+ {
+ .ctl_name = CTL_NET,
+ .procname = "net",
+ .mode = 0555,
+- .child = unix_net_table
++ .child = unix_sysctl.unix_net_table
+ },
+- { .ctl_name = 0 }
++ {}
++ }
+ };
+
+-static struct ctl_table_header * unix_sysctl_header;
+-
+-void unix_sysctl_register(void)
++void unix_sysctl_register(struct net *net)
+ {
+- unix_sysctl_header = register_sysctl_table(unix_root_table);
++ struct unix_sysctl_table *table;
++ int i;
++
++ table = kmemdup(&unix_sysctl, sizeof(*table), GFP_KERNEL);
++ if (!table)
++ return;
++ for (i = 0; i < ARRAY_SIZE(table->unix_table) - 1; i++)
++ table->unix_table[i].data += (char *)net - (char *)&init_net;
++
++ table->unix_net_table[0].child = table->unix_table;
++ table->unix_root_table[0].child = table->unix_net_table;
++
++ table->sysctl_header =
++ register_net_sysctl_table(net, table->unix_root_table);
++ if (!table->sysctl_header) {
++ kfree(table);
++ return;
++ }
++ net->unix_sysctl = table;
+ }
+
+-void unix_sysctl_unregister(void)
++void unix_sysctl_unregister(struct net *net)
+ {
+- unregister_sysctl_table(unix_sysctl_header);
++ struct unix_sysctl_table *table = net->unix_sysctl;
++ if (table)
++ unregister_net_sysctl_table(table->sysctl_header);
++ kfree(table);
+ }
+
+diff -Nurb linux-2.6.22-570/net/wanrouter/wanproc.c linux-2.6.22-590/net/wanrouter/wanproc.c
+--- linux-2.6.22-570/net/wanrouter/wanproc.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/wanrouter/wanproc.c 2008-01-29 22:12:33.000000000 -0500
+@@ -28,6 +28,7 @@
+ #include <linux/wanrouter.h> /* WAN router API definitions */
+ #include <linux/seq_file.h>
+ #include <linux/smp_lock.h>
++#include <net/net_namespace.h>
+
+ #include <asm/io.h>
+
+@@ -287,7 +288,7 @@
+ int __init wanrouter_proc_init(void)
+ {
+ struct proc_dir_entry *p;
+- proc_router = proc_mkdir(ROUTER_NAME, proc_net);
++ proc_router = proc_mkdir(ROUTER_NAME, init_net.proc_net);
+ if (!proc_router)
+ goto fail;
+
+@@ -303,7 +304,7 @@
+ fail_stat:
+ remove_proc_entry("config", proc_router);
+ fail_config:
+- remove_proc_entry(ROUTER_NAME, proc_net);
++ remove_proc_entry(ROUTER_NAME, init_net.proc_net);
+ fail:
+ return -ENOMEM;
+ }
+@@ -316,7 +317,7 @@
+ {
+ remove_proc_entry("config", proc_router);
+ remove_proc_entry("status", proc_router);
+- remove_proc_entry(ROUTER_NAME, proc_net);
++ remove_proc_entry(ROUTER_NAME, init_net.proc_net);
+ }
+
+ /*
+diff -Nurb linux-2.6.22-570/net/wireless/wext.c linux-2.6.22-590/net/wireless/wext.c
+--- linux-2.6.22-570/net/wireless/wext.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/wireless/wext.c 2008-01-29 22:12:33.000000000 -0500
+@@ -95,6 +95,7 @@
+ #include <linux/interrupt.h>
+
+ #include <linux/wireless.h> /* Pretty obvious */
++#include <net/net_namespace.h>
+ #include <net/iw_handler.h> /* New driver API */
+ #include <net/netlink.h>
+ #include <net/wext.h>
+@@ -672,7 +673,22 @@
+
+ static int wireless_seq_open(struct inode *inode, struct file *file)
+ {
+- return seq_open(file, &wireless_seq_ops);
++ struct seq_file *seq;
++ int res;
++ res = seq_open(file, &wireless_seq_ops);
++ if (!res) {
++ seq = file->private_data;
++ seq->private = get_net(PROC_NET(inode));
++ }
++ return res;
++}
++
++static int wireless_seq_release(struct inode *inode, struct file *file)
++{
++ struct seq_file *seq = file->private_data;
++ struct net *net = seq->private;
++ put_net(net);
++ return seq_release(inode, file);
+ }
+
+ static const struct file_operations wireless_seq_fops = {
+@@ -680,17 +696,22 @@
+ .open = wireless_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+- .release = seq_release,
++ .release = wireless_seq_release,
+ };
+
+-int __init wext_proc_init(void)
++int wext_proc_init(struct net *net)
+ {
+ /* Create /proc/net/wireless entry */
+- if (!proc_net_fops_create("wireless", S_IRUGO, &wireless_seq_fops))
++ if (!proc_net_fops_create(net, "wireless", S_IRUGO, &wireless_seq_fops))
+ return -ENOMEM;
+
+ return 0;
+ }
++
++void wext_proc_exit(struct net *net)
++{
++ proc_net_remove(net, "wireless");
++}
+ #endif /* CONFIG_PROC_FS */
+
+ /************************** IOCTL SUPPORT **************************/
+@@ -1010,7 +1031,7 @@
+ * Main IOCTl dispatcher.
+ * Check the type of IOCTL and call the appropriate wrapper...
+ */
+-static int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd)
++static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd)
+ {
+ struct net_device *dev;
+ iw_handler handler;
+@@ -1019,7 +1040,7 @@
+ * The copy_to/from_user() of ifr is also dealt with in there */
+
+ /* Make sure the device exist */
+- if ((dev = __dev_get_by_name(ifr->ifr_name)) == NULL)
++ if ((dev = __dev_get_by_name(net, ifr->ifr_name)) == NULL)
+ return -ENODEV;
+
+ /* A bunch of special cases, then the generic case...
+@@ -1053,7 +1074,7 @@
+ }
+
+ /* entry point from dev ioctl */
+-int wext_handle_ioctl(struct ifreq *ifr, unsigned int cmd,
++int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd,
+ void __user *arg)
+ {
+ int ret;
+@@ -1065,9 +1086,9 @@
+ && !capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+- dev_load(ifr->ifr_name);
++ dev_load(net, ifr->ifr_name);
+ rtnl_lock();
+- ret = wireless_process_ioctl(ifr, cmd);
++ ret = wireless_process_ioctl(net, ifr, cmd);
+ rtnl_unlock();
+ if (IW_IS_GET(cmd) && copy_to_user(arg, ifr, sizeof(struct ifreq)))
+ return -EFAULT;
+@@ -1111,8 +1132,13 @@
+ {
+ struct sk_buff *skb;
+
+- while ((skb = skb_dequeue(&wireless_nlevent_queue)))
+- rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
++ while ((skb = skb_dequeue(&wireless_nlevent_queue))) {
++ struct net_device *dev = skb->dev;
++ struct net *net = dev->nd_net;
++ skb->dev = NULL;
++ rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
++ dev_put(dev);
++ }
+ }
+
+ static DECLARE_TASKLET(wireless_nlevent_tasklet, wireless_nlevent_process, 0);
+@@ -1173,6 +1199,9 @@
+ kfree_skb(skb);
+ return;
+ }
++ /* Remember the device until we are in process context */
++ dev_hold(dev);
++ skb->dev = dev;
+ NETLINK_CB(skb).dst_group = RTNLGRP_LINK;
+ skb_queue_tail(&wireless_nlevent_queue, skb);
+ tasklet_schedule(&wireless_nlevent_tasklet);
+diff -Nurb linux-2.6.22-570/net/x25/af_x25.c linux-2.6.22-590/net/x25/af_x25.c
+--- linux-2.6.22-570/net/x25/af_x25.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/net/x25/af_x25.c 2008-01-29 22:12:33.000000000 -0500
+@@ -191,6 +191,9 @@
+ struct net_device *dev = ptr;
+ struct x25_neigh *nb;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ if (dev->type == ARPHRD_X25
+ #if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE)
+ || dev->type == ARPHRD_ETHER
+@@ -466,10 +469,10 @@
+ .obj_size = sizeof(struct x25_sock),
+ };
+
+-static struct sock *x25_alloc_socket(void)
++static struct sock *x25_alloc_socket(struct net *net)
+ {
+ struct x25_sock *x25;
+- struct sock *sk = sk_alloc(AF_X25, GFP_ATOMIC, &x25_proto, 1);
++ struct sock *sk = sk_alloc(net, AF_X25, GFP_ATOMIC, &x25_proto, 1);
+
+ if (!sk)
+ goto out;
+@@ -485,17 +488,20 @@
+ return sk;
+ }
+
+-static int x25_create(struct socket *sock, int protocol)
++static int x25_create(struct net *net, struct socket *sock, int protocol)
+ {
+ struct sock *sk;
+ struct x25_sock *x25;
+ int rc = -ESOCKTNOSUPPORT;
+
++ if (net != &init_net)
++ return -EAFNOSUPPORT;
++
+ if (sock->type != SOCK_SEQPACKET || protocol)
+ goto out;
+
+ rc = -ENOMEM;
+- if ((sk = x25_alloc_socket()) == NULL)
++ if ((sk = x25_alloc_socket(net)) == NULL)
+ goto out;
+
+ x25 = x25_sk(sk);
+@@ -546,7 +552,7 @@
+ if (osk->sk_type != SOCK_SEQPACKET)
+ goto out;
+
+- if ((sk = x25_alloc_socket()) == NULL)
++ if ((sk = x25_alloc_socket(osk->sk_net)) == NULL)
+ goto out;
+
+ x25 = x25_sk(sk);
+diff -Nurb linux-2.6.22-570/net/x25/x25_dev.c linux-2.6.22-590/net/x25/x25_dev.c
+--- linux-2.6.22-570/net/x25/x25_dev.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/x25/x25_dev.c 2008-01-29 22:12:33.000000000 -0500
+@@ -95,6 +95,9 @@
+ struct sk_buff *nskb;
+ struct x25_neigh *nb;
+
++ if (dev->nd_net != &init_net)
++ goto drop;
++
+ nskb = skb_copy(skb, GFP_ATOMIC);
+ if (!nskb)
+ goto drop;
+diff -Nurb linux-2.6.22-570/net/x25/x25_proc.c linux-2.6.22-590/net/x25/x25_proc.c
+--- linux-2.6.22-570/net/x25/x25_proc.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/x25/x25_proc.c 2008-01-29 22:12:33.000000000 -0500
+@@ -20,6 +20,7 @@
+ #include <linux/init.h>
+ #include <linux/proc_fs.h>
+ #include <linux/seq_file.h>
++#include <net/net_namespace.h>
+ #include <net/sock.h>
+ #include <net/x25.h>
+
+@@ -301,7 +302,7 @@
+ struct proc_dir_entry *p;
+ int rc = -ENOMEM;
+
+- x25_proc_dir = proc_mkdir("x25", proc_net);
++ x25_proc_dir = proc_mkdir("x25", init_net.proc_net);
+ if (!x25_proc_dir)
+ goto out;
+
+@@ -328,7 +329,7 @@
+ out_socket:
+ remove_proc_entry("route", x25_proc_dir);
+ out_route:
+- remove_proc_entry("x25", proc_net);
++ remove_proc_entry("x25", init_net.proc_net);
+ goto out;
+ }
+
+@@ -337,7 +338,7 @@
+ remove_proc_entry("forward", x25_proc_dir);
+ remove_proc_entry("route", x25_proc_dir);
+ remove_proc_entry("socket", x25_proc_dir);
+- remove_proc_entry("x25", proc_net);
++ remove_proc_entry("x25", init_net.proc_net);
+ }
+
+ #else /* CONFIG_PROC_FS */
+diff -Nurb linux-2.6.22-570/net/x25/x25_route.c linux-2.6.22-590/net/x25/x25_route.c
+--- linux-2.6.22-570/net/x25/x25_route.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/x25/x25_route.c 2008-01-29 22:12:33.000000000 -0500
+@@ -129,7 +129,7 @@
+ */
+ struct net_device *x25_dev_get(char *devname)
+ {
+- struct net_device *dev = dev_get_by_name(devname);
++ struct net_device *dev = dev_get_by_name(&init_net, devname);
+
+ if (dev &&
+ (!(dev->flags & IFF_UP) || (dev->type != ARPHRD_X25
+diff -Nurb linux-2.6.22-570/net/xfrm/xfrm_policy.c linux-2.6.22-590/net/xfrm/xfrm_policy.c
+--- linux-2.6.22-570/net/xfrm/xfrm_policy.c 2008-01-29 22:12:18.000000000 -0500
++++ linux-2.6.22-590/net/xfrm/xfrm_policy.c 2008-01-29 22:12:33.000000000 -0500
+@@ -30,8 +30,6 @@
+
+ #include "xfrm_hash.h"
+
+-int sysctl_xfrm_larval_drop __read_mostly;
+-
+ DEFINE_MUTEX(xfrm_cfg_mutex);
+ EXPORT_SYMBOL(xfrm_cfg_mutex);
+
+@@ -1570,7 +1568,7 @@
+
+ if (unlikely(nx<0)) {
+ err = nx;
+- if (err == -EAGAIN && sysctl_xfrm_larval_drop) {
++ if (err == -EAGAIN && init_net.sysctl_xfrm_larval_drop) {
+ /* EREMOTE tells the caller to generate
+ * a one-shot blackhole route.
+ */
+@@ -1954,8 +1952,8 @@
+ void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev)
+ {
+ while ((dst = dst->child) && dst->xfrm && dst->dev == dev) {
+- dst->dev = &loopback_dev;
+- dev_hold(&loopback_dev);
++ dst->dev = &init_net.loopback_dev;
++ dev_hold(dst->dev);
+ dev_put(dev);
+ }
+ }
+@@ -2357,6 +2355,11 @@
+
+ static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
+ {
++ struct net_device *dev = ptr;
++
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ switch (event) {
+ case NETDEV_DOWN:
+ xfrm_flush_bundles();
+diff -Nurb linux-2.6.22-570/net/xfrm/xfrm_state.c linux-2.6.22-590/net/xfrm/xfrm_state.c
+--- linux-2.6.22-570/net/xfrm/xfrm_state.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/xfrm/xfrm_state.c 2008-01-29 22:12:33.000000000 -0500
+@@ -28,14 +28,6 @@
+ struct sock *xfrm_nl;
+ EXPORT_SYMBOL(xfrm_nl);
+
+-u32 sysctl_xfrm_aevent_etime __read_mostly = XFRM_AE_ETIME;
+-EXPORT_SYMBOL(sysctl_xfrm_aevent_etime);
+-
+-u32 sysctl_xfrm_aevent_rseqth __read_mostly = XFRM_AE_SEQT_SIZE;
+-EXPORT_SYMBOL(sysctl_xfrm_aevent_rseqth);
+-
+-u32 sysctl_xfrm_acq_expires __read_mostly = 30;
+-
+ /* Each xfrm_state may be linked to two tables:
+
+ 1. Hash table by (spi,daddr,ah/esp) to find SA by SPI. (input,ctl)
+@@ -665,8 +657,8 @@
+ h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, family);
+ hlist_add_head(&x->byspi, xfrm_state_byspi+h);
+ }
+- x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires;
+- x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
++ x->lft.hard_add_expires_seconds = init_net.sysctl_xfrm_acq_expires;
++ x->timer.expires = jiffies + init_net.sysctl_xfrm_acq_expires*HZ;
+ add_timer(&x->timer);
+ xfrm_state_num++;
+ xfrm_hash_grow_check(x->bydst.next != NULL);
+@@ -815,9 +807,9 @@
+ x->props.family = family;
+ x->props.mode = mode;
+ x->props.reqid = reqid;
+- x->lft.hard_add_expires_seconds = sysctl_xfrm_acq_expires;
++ x->lft.hard_add_expires_seconds = init_net.sysctl_xfrm_acq_expires;
+ xfrm_state_hold(x);
+- x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
++ x->timer.expires = jiffies + init_net.sysctl_xfrm_acq_expires*HZ;
+ add_timer(&x->timer);
+ hlist_add_head(&x->bydst, xfrm_state_bydst+h);
+ h = xfrm_src_hash(daddr, saddr, family);
+@@ -1775,6 +1767,19 @@
+
+ EXPORT_SYMBOL(xfrm_init_state);
+
++
++static int xfrm_state_pernet_init(struct net *net)
++{
++ net->sysctl_xfrm_aevent_etime = XFRM_AE_ETIME;
++ net->sysctl_xfrm_aevent_rseqth = XFRM_AE_SEQT_SIZE;
++ net->sysctl_xfrm_acq_expires = 30;
++ return 0;
++}
++
++static struct pernet_operations xfrm_state_net_ops = {
++ .init = xfrm_state_pernet_init,
++};
++
+ void __init xfrm_state_init(void)
+ {
+ unsigned int sz;
+@@ -1789,5 +1794,7 @@
+ xfrm_state_hmask = ((sz / sizeof(struct hlist_head)) - 1);
+
+ INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task);
++
++ register_pernet_subsys(&xfrm_state_net_ops);
+ }
+
+diff -Nurb linux-2.6.22-570/net/xfrm/xfrm_user.c linux-2.6.22-590/net/xfrm/xfrm_user.c
+--- linux-2.6.22-570/net/xfrm/xfrm_user.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/net/xfrm/xfrm_user.c 2008-01-29 22:12:33.000000000 -0500
+@@ -374,7 +374,8 @@
+ return err;
+ }
+
+-static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
++static struct xfrm_state *xfrm_state_construct(struct net *net,
++ struct xfrm_usersa_info *p,
+ struct rtattr **xfrma,
+ int *errp)
+ {
+@@ -410,9 +411,9 @@
+ goto error;
+
+ x->km.seq = p->seq;
+- x->replay_maxdiff = sysctl_xfrm_aevent_rseqth;
++ x->replay_maxdiff = net->sysctl_xfrm_aevent_rseqth;
+ /* sysctl_xfrm_aevent_etime is in 100ms units */
+- x->replay_maxage = (sysctl_xfrm_aevent_etime*HZ)/XFRM_AE_ETH_M;
++ x->replay_maxage = (net->sysctl_xfrm_aevent_etime*HZ)/XFRM_AE_ETH_M;
+ x->preplay.bitmap = 0;
+ x->preplay.seq = x->replay.seq+x->replay_maxdiff;
+ x->preplay.oseq = x->replay.oseq +x->replay_maxdiff;
+@@ -436,6 +437,7 @@
+ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
+ struct rtattr **xfrma)
+ {
++ struct net *net = skb->sk->sk_net;
+ struct xfrm_usersa_info *p = NLMSG_DATA(nlh);
+ struct xfrm_state *x;
+ int err;
+@@ -445,7 +447,7 @@
+ if (err)
+ return err;
+
+- x = xfrm_state_construct(p, xfrma, &err);
++ x = xfrm_state_construct(net, p, xfrma, &err);
+ if (!x)
+ return err;
+
+@@ -2559,7 +2561,7 @@
+
+ printk(KERN_INFO "Initializing XFRM netlink socket\n");
+
+- nlsk = netlink_kernel_create(NETLINK_XFRM, XFRMNLGRP_MAX,
++ nlsk = netlink_kernel_create(&init_net, NETLINK_XFRM, XFRMNLGRP_MAX,
+ xfrm_netlink_rcv, NULL, THIS_MODULE);
+ if (nlsk == NULL)
+ return -ENOMEM;
diff -Nurb linux-2.6.22-570/rej linux-2.6.22-590/rej
--- linux-2.6.22-570/rej 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/rej 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/rej 2008-01-29 22:12:33.000000000 -0500
@@ -0,0 +1,28 @@
+vi -o ./drivers/dma/ioatdma.c ./drivers/dma/ioatdma.c.rej
+vi -o ./fs/nfs/super.c ./fs/nfs/super.c.rej
+vi -o ./net/bridge/br_if.c ./net/bridge/br_if.c.rej
+vi -o ./net/sunrpc/auth_unix.c ./net/sunrpc/auth_unix.c.rej
+vi -o ./scripts/checksyscalls.sh ./scripts/checksyscalls.sh.rej
+diff -Nurb linux-2.6.22-570/scripts/Makefile.build.orig linux-2.6.22-590/scripts/Makefile.build.orig
+--- linux-2.6.22-570/scripts/Makefile.build.orig 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/scripts/Makefile.build.orig 1969-12-31 19:00:00.000000000 -0500
+@@ -1,348 +0,0 @@
+-# ==========================================================================
+-# Building
+-# ==========================================================================
+-
+-src := $(obj)
+-
+-PHONY := __build
+-__build:
+-
+-# Read .config if it exist, otherwise ignore
+--include include/config/auto.conf
+-
+-include scripts/Kbuild.include
+-
+-# The filename Kbuild has precedence over Makefile
+-kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
+-include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile)
+-
+-include scripts/Makefile.lib
+-
+-ifdef host-progs
+-ifneq ($(hostprogs-y),$(host-progs))
+-$(warning kbuild: $(obj)/Makefile - Usage of host-progs is deprecated. Please replace with hostprogs-y!)
+-hostprogs-y += $(host-progs)
+-endif
+-endif
+-
+-# Do not include host rules unles needed
+-ifneq ($(hostprogs-y)$(hostprogs-m),)
+-include scripts/Makefile.host
+-endif
+-
+-ifneq ($(KBUILD_SRC),)
+-# Create output directory if not already present
+-_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
+-
+-# Create directories for object files if directory does not exist
+-# Needed when obj-y := dir/file.o syntax is used
+-_dummy := $(foreach d,$(obj-dirs), $(shell [ -d $(d) ] || mkdir -p $(d)))
+-endif
+-
+-
+-ifdef EXTRA_TARGETS
+-$(warning kbuild: $(obj)/Makefile - Usage of EXTRA_TARGETS is obsolete in 2.6. Please fix!)
+-endif
+-
+-ifdef build-targets
+-$(warning kbuild: $(obj)/Makefile - Usage of build-targets is obsolete in 2.6. Please fix!)
+-endif
+-
+-ifdef export-objs
+-$(warning kbuild: $(obj)/Makefile - Usage of export-objs is obsolete in 2.6. Please fix!)
+-endif
+-
+-ifdef O_TARGET
+-$(warning kbuild: $(obj)/Makefile - Usage of O_TARGET := $(O_TARGET) is obsolete in 2.6. Please fix!)
+-endif
+-
+-ifdef L_TARGET
+-$(error kbuild: $(obj)/Makefile - Use of L_TARGET is replaced by lib-y in 2.6. Please fix!)
+-endif
+-
+-ifdef list-multi
+-$(warning kbuild: $(obj)/Makefile - list-multi := $(list-multi) is obsolete in 2.6. Please fix!)
+-endif
+-
+-ifndef obj
+-$(warning kbuild: Makefile.build is included improperly)
+-endif
+-
+-# ===========================================================================
+-
+-ifneq ($(strip $(lib-y) $(lib-m) $(lib-n) $(lib-)),)
+-lib-target := $(obj)/lib.a
+-endif
+-
+-ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(lib-target)),)
+-builtin-target := $(obj)/built-in.o
+-endif
+-
+-# We keep a list of all modules in $(MODVERDIR)
+-
+-__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
+- $(if $(KBUILD_MODULES),$(obj-m)) \
+- $(subdir-ym) $(always)
+- @:
+-
+-# Linus' kernel sanity checking tool
+-ifneq ($(KBUILD_CHECKSRC),0)
+- ifeq ($(KBUILD_CHECKSRC),2)
+- quiet_cmd_force_checksrc = CHECK $<
+- cmd_force_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< ;
+- else
+- quiet_cmd_checksrc = CHECK $<
+- cmd_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< ;
+- endif
+-endif
+-
+-
+-# Compile C sources (.c)
+-# ---------------------------------------------------------------------------
+-
+-# Default is built-in, unless we know otherwise
+-modkern_cflags := $(CFLAGS_KERNEL)
+-quiet_modtag := $(empty) $(empty)
+-
+-$(real-objs-m) : modkern_cflags := $(CFLAGS_MODULE)
+-$(real-objs-m:.o=.i) : modkern_cflags := $(CFLAGS_MODULE)
+-$(real-objs-m:.o=.s) : modkern_cflags := $(CFLAGS_MODULE)
+-$(real-objs-m:.o=.lst): modkern_cflags := $(CFLAGS_MODULE)
+-
+-$(real-objs-m) : quiet_modtag := [M]
+-$(real-objs-m:.o=.i) : quiet_modtag := [M]
+-$(real-objs-m:.o=.s) : quiet_modtag := [M]
+-$(real-objs-m:.o=.lst): quiet_modtag := [M]
+-
+-$(obj-m) : quiet_modtag := [M]
+-
+-# Default for not multi-part modules
+-modname = $(basetarget)
+-
+-$(multi-objs-m) : modname = $(modname-multi)
+-$(multi-objs-m:.o=.i) : modname = $(modname-multi)
+-$(multi-objs-m:.o=.s) : modname = $(modname-multi)
+-$(multi-objs-m:.o=.lst) : modname = $(modname-multi)
+-$(multi-objs-y) : modname = $(modname-multi)
+-$(multi-objs-y:.o=.i) : modname = $(modname-multi)
+-$(multi-objs-y:.o=.s) : modname = $(modname-multi)
+-$(multi-objs-y:.o=.lst) : modname = $(modname-multi)
+-
+-quiet_cmd_cc_s_c = CC $(quiet_modtag) $@
+-cmd_cc_s_c = $(CC) $(c_flags) -fverbose-asm -S -o $@ $<
+-
+-$(obj)/%.s: $(src)/%.c FORCE
+- $(call if_changed_dep,cc_s_c)
+-
+-quiet_cmd_cc_i_c = CPP $(quiet_modtag) $@
+-cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $<
+-
+-$(obj)/%.i: $(src)/%.c FORCE
+- $(call if_changed_dep,cc_i_c)
+-
+-quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
+-cmd_cc_symtypes_c = \
+- $(CPP) -D__GENKSYMS__ $(c_flags) $< \
+- | $(GENKSYMS) -T $@ >/dev/null; \
+- test -s $@ || rm -f $@
+-
+-$(obj)/%.symtypes : $(src)/%.c FORCE
+- $(call if_changed_dep,cc_symtypes_c)
+-
+-# C (.c) files
+-# The C file is compiled and updated dependency information is generated.
+-# (See cmd_cc_o_c + relevant part of rule_cc_o_c)
+-
+-quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
+-
+-ifndef CONFIG_MODVERSIONS
+-cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
+-
+-else
+-# When module versioning is enabled the following steps are executed:
+-# o compile a .tmp_<file>.o from <file>.c
+-# o if .tmp_<file>.o doesn't contain a __ksymtab version, i.e. does
+-# not export symbols, we just rename .tmp_<file>.o to <file>.o and
+-# are done.
+-# o otherwise, we calculate symbol versions using the good old
+-# genksyms on the preprocessed source and postprocess them in a way
+-# that they are usable as a linker script
+-# o generate <file>.o from .tmp_<file>.o using the linker to
+-# replace the unresolved symbols __crc_exported_symbol with
+-# the actual value of the checksum generated by genksyms
+-
+-cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
+-cmd_modversions = \
+- if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \
+- $(CPP) -D__GENKSYMS__ $(c_flags) $< \
+- | $(GENKSYMS) $(if $(KBUILD_SYMTYPES), \
+- -T $(@D)/$(@F:.o=.symtypes)) -a $(ARCH) \
+- > $(@D)/.tmp_$(@F:.o=.ver); \
+- \
+- $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
+- -T $(@D)/.tmp_$(@F:.o=.ver); \
+- rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \
+- else \
+- mv -f $(@D)/.tmp_$(@F) $@; \
+- fi;
+-endif
+-
+-define rule_cc_o_c
+- $(call echo-cmd,checksrc) $(cmd_checksrc) \
+- $(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \
+- $(cmd_modversions) \
+- scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \
+- $(dot-target).tmp; \
+- rm -f $(depfile); \
+- mv -f $(dot-target).tmp $(dot-target).cmd
+-endef
+-
+-# Built-in and composite module parts
+-$(obj)/%.o: $(src)/%.c FORCE
+- $(call cmd,force_checksrc)
+- $(call if_changed_rule,cc_o_c)
+-
+-# Single-part modules are special since we need to mark them in $(MODVERDIR)
+-
+-$(single-used-m): $(obj)/%.o: $(src)/%.c FORCE
+- $(call cmd,force_checksrc)
+- $(call if_changed_rule,cc_o_c)
+- @{ echo $(@:.o=.ko); echo $@; } > $(MODVERDIR)/$(@F:.o=.mod)
+-
+-quiet_cmd_cc_lst_c = MKLST $@
+- cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \
+- $(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \
+- System.map $(OBJDUMP) > $@
+-
+-$(obj)/%.lst: $(src)/%.c FORCE
+- $(call if_changed_dep,cc_lst_c)
+-
+-# Compile assembler sources (.S)
+-# ---------------------------------------------------------------------------
+-
+-modkern_aflags := $(AFLAGS_KERNEL)
+-
+-$(real-objs-m) : modkern_aflags := $(AFLAGS_MODULE)
+-$(real-objs-m:.o=.s): modkern_aflags := $(AFLAGS_MODULE)
+-
+-quiet_cmd_as_s_S = CPP $(quiet_modtag) $@
+-cmd_as_s_S = $(CPP) $(a_flags) -o $@ $<
+-
+-$(obj)/%.s: $(src)/%.S FORCE
+- $(call if_changed_dep,as_s_S)
+-
+-quiet_cmd_as_o_S = AS $(quiet_modtag) $@
+-cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $<
+-
+-$(obj)/%.o: $(src)/%.S FORCE
+- $(call if_changed_dep,as_o_S)
+-
+-targets += $(real-objs-y) $(real-objs-m) $(lib-y)
+-targets += $(extra-y) $(MAKECMDGOALS) $(always)
+-
+-# Linker scripts preprocessor (.lds.S -> .lds)
+-# ---------------------------------------------------------------------------
+-quiet_cmd_cpp_lds_S = LDS $@
+- cmd_cpp_lds_S = $(CPP) $(cpp_flags) -D__ASSEMBLY__ -o $@ $<
+-
+-$(obj)/%.lds: $(src)/%.lds.S FORCE
+- $(call if_changed_dep,cpp_lds_S)
+-
+-# Build the compiled-in targets
+-# ---------------------------------------------------------------------------
+-
+-# To build objects in subdirs, we need to descend into the directories
+-$(sort $(subdir-obj-y)): $(subdir-ym) ;
+-
+-#
+-# Rule to compile a set of .o files into one .o file
+-#
+-ifdef builtin-target
+-quiet_cmd_link_o_target = LD $@
+-# If the list of objects to link is empty, just create an empty built-in.o
+-cmd_link_o_target = $(if $(strip $(obj-y)),\
+- $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^),\
+- rm -f $@; $(AR) rcs $@)
+-
+-$(builtin-target): $(obj-y) FORCE
+- $(call if_changed,link_o_target)
+-
+-targets += $(builtin-target)
+-endif # builtin-target
+-
+-#
+-# Rule to compile a set of .o files into one .a file
+-#
+-ifdef lib-target
+-quiet_cmd_link_l_target = AR $@
+-cmd_link_l_target = rm -f $@; $(AR) $(EXTRA_ARFLAGS) rcs $@ $(lib-y)
+-
+-$(lib-target): $(lib-y) FORCE
+- $(call if_changed,link_l_target)
+-
+-targets += $(lib-target)
+-endif
+-
+-#
+-# Rule to link composite objects
+-#
+-# Composite objects are specified in kbuild makefile as follows:
+-# <composite-object>-objs := <list of .o files>
+-# or
+-# <composite-object>-y := <list of .o files>
+-link_multi_deps = \
+-$(filter $(addprefix $(obj)/, \
+-$($(subst $(obj)/,,$(@:.o=-objs))) \
+-$($(subst $(obj)/,,$(@:.o=-y)))), $^)
+-
+-quiet_cmd_link_multi-y = LD $@
+-cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps)
+-
+-quiet_cmd_link_multi-m = LD [M] $@
+-cmd_link_multi-m = $(LD) $(ld_flags) $(LDFLAGS_MODULE) -o $@ $(link_multi_deps)
+-
+-# We would rather have a list of rules like
+-# foo.o: $(foo-objs)
+-# but that's not so easy, so we rather make all composite objects depend
+-# on the set of all their parts
+-$(multi-used-y) : %.o: $(multi-objs-y) FORCE
+- $(call if_changed,link_multi-y)
+-
+-$(multi-used-m) : %.o: $(multi-objs-m) FORCE
+- $(call if_changed,link_multi-m)
+- @{ echo $(@:.o=.ko); echo $(link_multi_deps); } > $(MODVERDIR)/$(@F:.o=.mod)
+-
+-targets += $(multi-used-y) $(multi-used-m)
+-
+-
+-# Descending
+-# ---------------------------------------------------------------------------
+-
+-PHONY += $(subdir-ym)
+-$(subdir-ym):
+- $(Q)$(MAKE) $(build)=$@
+-
+-# Add FORCE to the prequisites of a target to force it to be always rebuilt.
+-# ---------------------------------------------------------------------------
+-
+-PHONY += FORCE
+-
+-FORCE:
+-
+-# Read all saved command lines and dependencies for the $(targets) we
+-# may be building above, using $(if_changed{,_dep}). As an
+-# optimization, we don't need to read them if the target does not
+-# exist, we will rebuild anyway in that case.
+-
+-targets := $(wildcard $(sort $(targets)))
+-cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
+-
+-ifneq ($(cmd_files),)
+- include $(cmd_files)
+-endif
+-
+-
+-# Declare the contents of the .PHONY variable as phony. We keep that
+-# information in a variable se we can use it in if_changed and friends.
+-
+-.PHONY: $(PHONY)
+diff -Nurb linux-2.6.22-570/scripts/Makefile.modpost.orig linux-2.6.22-590/scripts/Makefile.modpost.orig
+--- linux-2.6.22-570/scripts/Makefile.modpost.orig 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/scripts/Makefile.modpost.orig 1969-12-31 19:00:00.000000000 -0500
+@@ -1,132 +0,0 @@
+-# ===========================================================================
+-# Module versions
+-# ===========================================================================
+-#
+-# Stage one of module building created the following:
+-# a) The individual .o files used for the module
+-# b) A <module>.o file which is the .o files above linked together
+-# c) A <module>.mod file in $(MODVERDIR)/, listing the name of the
+-# the preliminary <module>.o file, plus all .o files
+-
+-# Stage 2 is handled by this file and does the following
+-# 1) Find all modules from the files listed in $(MODVERDIR)/
+-# 2) modpost is then used to
+-# 3) create one <module>.mod.c file pr. module
+-# 4) create one Module.symvers file with CRC for all exported symbols
+-# 5) compile all <module>.mod.c files
+-# 6) final link of the module to a <module.ko> file
+-
+-# Step 3 is used to place certain information in the module's ELF
+-# section, including information such as:
+-# Version magic (see include/vermagic.h for full details)
+-# - Kernel release
+-# - SMP is CONFIG_SMP
+-# - PREEMPT is CONFIG_PREEMPT
+-# - GCC Version
+-# Module info
+-# - Module version (MODULE_VERSION)
+-# - Module alias'es (MODULE_ALIAS)
+-# - Module license (MODULE_LICENSE)
+-# - See include/linux/module.h for more details
+-
+-# Step 4 is solely used to allow module versioning in external modules,
+-# where the CRC of each module is retrieved from the Module.symers file.
+-
+-# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined
+-# symbols in the final module linking stage
+-# KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules.
+-# This is solely usefull to speed up test compiles
+-PHONY := _modpost
+-_modpost: __modpost
+-
+-include include/config/auto.conf
+-include scripts/Kbuild.include
+-include scripts/Makefile.lib
+-
+-kernelsymfile := $(objtree)/Module.symvers
+-modulesymfile := $(firstword $(KBUILD_EXTMOD))/Module.symvers
+-
+-# Step 1), find all modules listed in $(MODVERDIR)/
+-__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
+-modules := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o)))
+-
+-# Stop after building .o files if NOFINAL is set. Makes compile tests quicker
+-_modpost: $(if $(KBUILD_MODPOST_NOFINAL), $(modules:.ko:.o),$(modules))
+-
+-
+-# Step 2), invoke modpost
+-# Includes step 3,4
+-quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules
+- cmd_modpost = scripts/mod/modpost \
+- $(if $(CONFIG_MODVERSIONS),-m) \
+- $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a,) \
+- $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \
+- $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \
+- $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
+- $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w)
+-
+-PHONY += __modpost
+-__modpost: $(modules:.ko=.o) FORCE
+- $(call cmd,modpost) $(wildcard vmlinux) $(filter-out FORCE,$^)
+-
+-quiet_cmd_kernel-mod = MODPOST $@
+- cmd_kernel-mod = $(cmd_modpost) $(KBUILD_VMLINUX_OBJS)
+-
+-PHONY += vmlinux
+-vmlinux: FORCE
+- $(call cmd,kernel-mod)
+-
+-# Declare generated files as targets for modpost
+-$(symverfile): __modpost ;
+-$(modules:.ko=.mod.c): __modpost ;
+-
+-
+-# Step 5), compile all *.mod.c files
+-
+-# modname is set to make c_flags define KBUILD_MODNAME
+-modname = $(notdir $(@:.mod.o=))
+-
+-quiet_cmd_cc_o_c = CC $@
+- cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE) \
+- -c -o $@ $<
+-
+-$(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE
+- $(call if_changed_dep,cc_o_c)
+-
+-targets += $(modules:.ko=.mod.o)
+-
+-# Step 6), final link of the modules
+-quiet_cmd_ld_ko_o = LD [M] $@
+- cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \
+- $(filter-out FORCE,$^)
+-
+-$(modules): %.ko :%.o %.mod.o FORCE
+- $(call if_changed,ld_ko_o)
+-
+-targets += $(modules)
+-
+-
+-# Add FORCE to the prequisites of a target to force it to be always rebuilt.
+-# ---------------------------------------------------------------------------
+-
+-PHONY += FORCE
+-
+-FORCE:
+-
+-# Read all saved command lines and dependencies for the $(targets) we
+-# may be building above, using $(if_changed{,_dep}). As an
+-# optimization, we don't need to read them if the target does not
+-# exist, we will rebuild anyway in that case.
+-
+-targets := $(wildcard $(sort $(targets)))
+-cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
+-
+-ifneq ($(cmd_files),)
+- include $(cmd_files)
+-endif
+-
+-
+-# Declare the contents of the .PHONY variable as phony. We keep that
+-# information in a variable se we can use it in if_changed and friends.
+-
+-.PHONY: $(PHONY)
diff -Nurb linux-2.6.22-570/security/commoncap.c linux-2.6.22-590/security/commoncap.c
---- linux-2.6.22-570/security/commoncap.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/security/commoncap.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/security/commoncap.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/security/commoncap.c 2008-01-29 22:12:33.000000000 -0500
@@ -150,7 +150,7 @@
if (bprm->e_uid != current->uid || bprm->e_gid != current->gid ||
if (unsafe & ~LSM_UNSAFE_PTRACE_CAP) {
if (!capable(CAP_SETUID)) {
diff -Nurb linux-2.6.22-570/security/dummy.c linux-2.6.22-590/security/dummy.c
---- linux-2.6.22-570/security/dummy.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/security/dummy.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/security/dummy.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/security/dummy.c 2008-01-29 22:12:33.000000000 -0500
@@ -131,7 +131,7 @@
static void dummy_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
{
diff -Nurb linux-2.6.22-570/security/keys/request_key.c linux-2.6.22-590/security/keys/request_key.c
--- linux-2.6.22-570/security/keys/request_key.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/security/keys/request_key.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/security/keys/request_key.c 2008-01-29 22:12:33.000000000 -0500
@@ -108,7 +108,8 @@
argv[i] = NULL;
key_put(keyring);
diff -Nurb linux-2.6.22-570/security/security.c linux-2.6.22-590/security/security.c
--- linux-2.6.22-570/security/security.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/security/security.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/security/security.c 2008-01-29 22:12:33.000000000 -0500
@@ -24,6 +24,7 @@
extern void security_fixup_ops(struct security_operations *ops);
EXPORT_SYMBOL(security_ops);
diff -Nurb linux-2.6.22-570/security/selinux/avc.c linux-2.6.22-590/security/selinux/avc.c
--- linux-2.6.22-570/security/selinux/avc.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/security/selinux/avc.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/security/selinux/avc.c 2008-01-29 22:12:33.000000000 -0500
@@ -586,7 +586,7 @@
}
}
return rc;
}
diff -Nurb linux-2.6.22-570/security/selinux/hooks.c linux-2.6.22-590/security/selinux/hooks.c
---- linux-2.6.22-570/security/selinux/hooks.c 2008-03-15 10:34:24.000000000 -0400
-+++ linux-2.6.22-590/security/selinux/hooks.c 2008-03-15 10:35:47.000000000 -0400
+--- linux-2.6.22-570/security/selinux/hooks.c 2008-01-29 22:12:21.000000000 -0500
++++ linux-2.6.22-590/security/selinux/hooks.c 2008-01-29 22:12:33.000000000 -0500
@@ -111,6 +111,9 @@
/* Original (dummy) security module. */
static struct security_operations *original_ops = NULL;
return rc;
if (selinux_checkreqprot)
-@@ -4628,7 +4636,7 @@
+@@ -3223,8 +3231,8 @@
+ /* Range of port numbers used to automatically bind.
+ Need to determine whether we should perform a name_bind
+ permission check between the socket and the port number. */
+-#define ip_local_port_range_0 sysctl_local_port_range[0]
+-#define ip_local_port_range_1 sysctl_local_port_range[1]
++#define ip_local_port_range_0 (sk->sk_net->sysctl_local_port_range[0])
++#define ip_local_port_range_1 (sk->sk_net->sysctl_local_port_range[1])
+
+ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
+ {
+@@ -3968,6 +3976,10 @@
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ return selinux_ip_postroute_last(hooknum, pskb, in, out, okfn, PF_INET);
+ }
+
+@@ -3979,6 +3991,10 @@
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++ /* Only filter packets in the initial network namespace */
++ if ((in?in:out)->nd_net != &init_net)
++ return NF_ACCEPT;
++
+ return selinux_ip_postroute_last(hooknum, pskb, in, out, okfn, PF_INET6);
+ }
+
+@@ -4628,7 +4644,7 @@
if (p->ptrace & PT_PTRACED) {
error = avc_has_perm_noaudit(tsec->ptrace_sid, sid,
SECCLASS_PROCESS,
if (!error)
tsec->sid = sid;
task_unlock(p);
-@@ -4910,6 +4918,16 @@
+@@ -4910,6 +4926,16 @@
sel_inode_cache = kmem_cache_create("selinux_inode_security",
sizeof(struct inode_security_struct),
0, SLAB_PANIC, NULL, NULL);
avc_init();
original_ops = secondary_ops = security_ops;
-@@ -5060,6 +5078,10 @@
+@@ -5060,6 +5086,10 @@
selinux_disabled = 1;
selinux_enabled = 0;
diff -Nurb linux-2.6.22-570/security/selinux/include/av_perm_to_string.h linux-2.6.22-590/security/selinux/include/av_perm_to_string.h
--- linux-2.6.22-570/security/selinux/include/av_perm_to_string.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/security/selinux/include/av_perm_to_string.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/security/selinux/include/av_perm_to_string.h 2008-01-29 22:12:33.000000000 -0500
@@ -158,3 +158,4 @@
S_(SECCLASS_KEY, KEY__CREATE, "create")
S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NODE_BIND, "node_bind")
+ S_(SECCLASS_MEMPROTECT, MEMPROTECT__MMAP_ZERO, "mmap_zero")
diff -Nurb linux-2.6.22-570/security/selinux/include/av_permissions.h linux-2.6.22-590/security/selinux/include/av_permissions.h
--- linux-2.6.22-570/security/selinux/include/av_permissions.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/security/selinux/include/av_permissions.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/security/selinux/include/av_permissions.h 2008-01-29 22:12:33.000000000 -0500
@@ -823,3 +823,4 @@
#define DCCP_SOCKET__NAME_BIND 0x00200000UL
#define DCCP_SOCKET__NODE_BIND 0x00400000UL
+#define MEMPROTECT__MMAP_ZERO 0x00000001UL
diff -Nurb linux-2.6.22-570/security/selinux/include/avc.h linux-2.6.22-590/security/selinux/include/avc.h
--- linux-2.6.22-570/security/selinux/include/avc.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/security/selinux/include/avc.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/security/selinux/include/avc.h 2008-01-29 22:12:33.000000000 -0500
@@ -102,8 +102,10 @@
u16 tclass, u32 requested,
struct av_decision *avd, int result, struct avc_audit_data *auditdata);
int avc_has_perm(u32 ssid, u32 tsid,
diff -Nurb linux-2.6.22-570/security/selinux/include/class_to_string.h linux-2.6.22-590/security/selinux/include/class_to_string.h
--- linux-2.6.22-570/security/selinux/include/class_to_string.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/security/selinux/include/class_to_string.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/security/selinux/include/class_to_string.h 2008-01-29 22:12:33.000000000 -0500
@@ -63,3 +63,4 @@
S_("key")
S_(NULL)
+ S_("memprotect")
diff -Nurb linux-2.6.22-570/security/selinux/include/flask.h linux-2.6.22-590/security/selinux/include/flask.h
--- linux-2.6.22-570/security/selinux/include/flask.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/security/selinux/include/flask.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/security/selinux/include/flask.h 2008-01-29 22:12:33.000000000 -0500
@@ -49,6 +49,7 @@
#define SECCLASS_PACKET 57
#define SECCLASS_KEY 58
* Security identifier indices for initial entities
diff -Nurb linux-2.6.22-570/security/selinux/include/security.h linux-2.6.22-590/security/selinux/include/security.h
--- linux-2.6.22-570/security/selinux/include/security.h 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/security/selinux/include/security.h 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/security/selinux/include/security.h 2008-01-29 22:12:33.000000000 -0500
@@ -41,6 +41,7 @@
int security_load_policy(void * data, size_t len);
#define SECURITY_FS_USE_XATTR 1 /* use xattr */
#define SECURITY_FS_USE_TRANS 2 /* use transition SIDs, e.g. devpts/tmpfs */
#define SECURITY_FS_USE_TASK 3 /* use task SIDs, e.g. pipefs/sockfs */
+diff -Nurb linux-2.6.22-570/security/selinux/netif.c linux-2.6.22-590/security/selinux/netif.c
+--- linux-2.6.22-570/security/selinux/netif.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/security/selinux/netif.c 2008-01-29 22:12:33.000000000 -0500
+@@ -20,6 +20,7 @@
+ #include <linux/notifier.h>
+ #include <linux/netdevice.h>
+ #include <linux/rcupdate.h>
++#include <net/net_namespace.h>
+
+ #include "security.h"
+ #include "objsec.h"
+@@ -234,6 +235,9 @@
+ {
+ struct net_device *dev = ptr;
+
++ if (dev->nd_net != &init_net)
++ return NOTIFY_DONE;
++
+ if (event == NETDEV_DOWN)
+ sel_netif_kill(dev);
+
+diff -Nurb linux-2.6.22-570/security/selinux/netlink.c linux-2.6.22-590/security/selinux/netlink.c
+--- linux-2.6.22-570/security/selinux/netlink.c 2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-590/security/selinux/netlink.c 2008-01-29 22:12:33.000000000 -0500
+@@ -17,6 +17,7 @@
+ #include <linux/skbuff.h>
+ #include <linux/netlink.h>
+ #include <linux/selinux_netlink.h>
++#include <net/net_namespace.h>
+
+ static struct sock *selnl;
+
+@@ -104,8 +105,8 @@
+
+ static int __init selnl_init(void)
+ {
+- selnl = netlink_kernel_create(NETLINK_SELINUX, SELNLGRP_MAX, NULL, NULL,
+- THIS_MODULE);
++ selnl = netlink_kernel_create(&init_net, NETLINK_SELINUX,
++ SELNLGRP_MAX, NULL, NULL, THIS_MODULE);
+ if (selnl == NULL)
+ panic("SELinux: Cannot create netlink socket.");
+ netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV);
diff -Nurb linux-2.6.22-570/security/selinux/selinuxfs.c linux-2.6.22-590/security/selinux/selinuxfs.c
--- linux-2.6.22-570/security/selinux/selinuxfs.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/security/selinux/selinuxfs.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/security/selinux/selinuxfs.c 2008-01-29 22:12:33.000000000 -0500
@@ -67,6 +67,10 @@
static int bool_num = 0;
static int *bool_pending_values = NULL;
err:
diff -Nurb linux-2.6.22-570/security/selinux/ss/policydb.c linux-2.6.22-590/security/selinux/ss/policydb.c
--- linux-2.6.22-570/security/selinux/ss/policydb.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/security/selinux/ss/policydb.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/security/selinux/ss/policydb.c 2008-01-29 22:12:33.000000000 -0500
@@ -21,6 +21,7 @@
*/
ebitmap_destroy(&lrt->target_range.level[1].cat);
diff -Nurb linux-2.6.22-570/security/selinux/ss/services.c linux-2.6.22-590/security/selinux/ss/services.c
--- linux-2.6.22-570/security/selinux/ss/services.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-590/security/selinux/ss/services.c 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/security/selinux/ss/services.c 2008-01-29 22:12:33.000000000 -0500
@@ -1587,19 +1587,18 @@
u32 *nel)
{
struct selinux_audit_rule {
u32 au_seqno;
struct context au_ctxt;
+diff -Nurb linux-2.6.22-570/toapply linux-2.6.22-590/toapply
+--- linux-2.6.22-570/toapply 1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.22-590/toapply 2008-01-29 22:12:33.000000000 -0500
+@@ -0,0 +1,51 @@
++cat ../broken-out/cpuidle-fix-the-uninitialized-variable-in-sysfs-routine.patch | patch -p1
++cat ../broken-out/cpuidle-make-cpuidle-sysfs-driver-governor-switch-off-by-default.patch | patch -p1
++cat ../broken-out/acpi-video-dont-export-sysfs-backlight-interface-if-query-_bcl-fail.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-rules.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-move-release_sysfs_dirent-to-dirc.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-allocate-inode-number-using-ida.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-make-sysfs_put-ignore-null-sd.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-fix-error-handling-in-binattr-write.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-flatten-cleanup-paths-in-sysfs_add_link-and-create_dir.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-flatten-and-fix-sysfs_rename_dir-error-handling.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-consolidate-sysfs_dirent-creation-functions.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-add-sysfs_dirent-s_parent.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-add-sysfs_dirent-s_name.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-make-sysfs_dirent-s_element-a-union.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-implement-kobj_sysfs_assoc_lock.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-reimplement-symlink-using-sysfs_dirent-tree.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-implement-bin_buffer.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-implement-sysfs_dirent-active-reference-and-immediate-disconnect.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-kill-attribute-file-orphaning.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-separate-out-sysfs_attach_dentry.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-reimplement-sysfs_drop_dentry.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-kill-unnecessary-attribute-owner.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-make-sysfs_alloc_ino-static.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-fix-parent-refcounting-during-rename-and-move.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-reorganize-sysfs_new_indoe-and-sysfs_create.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-use-iget_locked-instead-of-new_inode.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-fix-root-sysfs_dirent-root-dentry-association.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-move-s_active-functions-to-fs-sysfs-dirc.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-slim-down-sysfs_dirent-s_active.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-use-singly-linked-list-for-sysfs_dirent-tree.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-fix-oops-in-sysfs_drop_dentry-on-x86_64.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-make-sysfs_drop_dentry-access-inodes-using-ilookup.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-rename-sysfs_dirent-s_type-to-s_flags-and-make-room-for-flags.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-implement-sysfs_flag_removed-flag.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-implement-sysfs_find_dirent-and-sysfs_get_dirent.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-make-kobj-point-to-sysfs_dirent-instead-of-dentry.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-consolidate-sysfs-spinlocks.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-use-sysfs_mutex-to-protect-the-sysfs_dirent-tree.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-restructure-add-remove-paths-and-fix-inode-update.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-move-sysfs_drop_dentry-to-dirc-and-make-it-static.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-implement-sysfs_get_dentry.patch | patch -p1
++cat ../broken-out/gregkh-driver-sysfs-make-directory-dentries-and-inodes-reclaimable.patch | patch -p1
++cat ../broken-out/driver-core-check-return-code-of-sysfs_create_link.patch | patch -p1
++cat ../broken-out/driver-core-check-return-code-of-sysfs_create_link-fix.patch | patch -p1
++cat ../broken-out/git-scsi-misc-vs-greg-sysfs-stuff.patch | patch -p1
++cat ../broken-out/gregkh-usb-usb-cxacru-cleanup-sysfs-attribute-code.patch | patch -p1
++cat ../broken-out/gregkh-usb-usb-add-iad-support-to-usbfs-and-sysfs.patch | patch -p1
++cat ../broken-out/x86_64-mm-xen-add-the-xenbus-sysfs-and-virtual-device-hotplug-driver.patch | patch -p1
++cat ../broken-out/drivers-edac-mc-sysfs-add-missing-mem-types.patch | patch -p1
++cat ../broken-out/drivers-edac-edac_device-sysfs-cleanup.patch | patch -p1
++cat ../broken-out/drivers-edac-add-device-sysfs-attributes.patch | patch -p1
diff -Nurb linux-2.6.22-570/trellis-mm1-1.sh linux-2.6.22-590/trellis-mm1-1.sh
--- linux-2.6.22-570/trellis-mm1-1.sh 1969-12-31 19:00:00.000000000 -0500
-+++ linux-2.6.22-590/trellis-mm1-1.sh 2008-03-15 10:35:47.000000000 -0400
++++ linux-2.6.22-590/trellis-mm1-1.sh 2008-01-29 22:12:33.000000000 -0500
@@ -0,0 +1,142 @@
+cat ../broken-out/origin.patch | patch -p1
+cat ../broken-out/ioatdma-fix-section-mismatches.patch | patch -p1