From: Sapan Bhatia Date: Tue, 18 Mar 2008 19:33:30 +0000 (+0000) Subject: Rolled back to when the repository didn't go berzerk. X-Git-Tag: trellis-2.6.22-Jan-2009~39 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=26778ede145c49fe1d4b615f98bd34237229804a;p=linux-2.6.git Rolled back to when the repository didn't go berzerk. --- diff --git a/linux-2.6-520-vnet+.patch b/linux-2.6-520-vnet+.patch index 512dda8c5..fa1e4fcce 100644 --- a/linux-2.6-520-vnet+.patch +++ b/linux-2.6-520-vnet+.patch @@ -1,7 +1,7 @@ -diff -Nurb linux-2.6.22-510/include/linux/netfilter/xt_MARK.h linux-2.6.22-520/include/linux/netfilter/xt_MARK.h ---- linux-2.6.22-510/include/linux/netfilter/xt_MARK.h 2007-07-08 19:32:17.000000000 -0400 -+++ linux-2.6.22-520/include/linux/netfilter/xt_MARK.h 2008-03-14 16:29:22.000000000 -0400 -@@ -11,6 +11,7 @@ +diff -Nurp linux-2.6.22-510/include/linux/netfilter/xt_MARK.h linux-2.6.22-520/include/linux/netfilter/xt_MARK.h +--- linux-2.6.22-510/include/linux/netfilter/xt_MARK.h 2006-06-17 21:49:35.000000000 -0400 ++++ linux-2.6.22-520/include/linux/netfilter/xt_MARK.h 2007-12-03 15:11:08.000000000 -0500 +@@ -11,6 +11,7 @@ enum { XT_MARK_SET=0, XT_MARK_AND, XT_MARK_OR, @@ -9,9 +9,9 @@ diff -Nurb linux-2.6.22-510/include/linux/netfilter/xt_MARK.h linux-2.6.22-520/i }; struct xt_mark_target_info_v1 { -diff -Nurb linux-2.6.22-510/include/linux/netfilter/xt_SETXID.h linux-2.6.22-520/include/linux/netfilter/xt_SETXID.h +diff -Nurp linux-2.6.22-510/include/linux/netfilter/xt_SETXID.h linux-2.6.22-520/include/linux/netfilter/xt_SETXID.h --- linux-2.6.22-510/include/linux/netfilter/xt_SETXID.h 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-520/include/linux/netfilter/xt_SETXID.h 2008-03-14 16:29:22.000000000 -0400 ++++ linux-2.6.22-520/include/linux/netfilter/xt_SETXID.h 2007-12-03 15:11:08.000000000 -0500 @@ -0,0 +1,14 @@ +#ifndef _XT_SETXID_H_target +#define _XT_SETXID_H_target @@ -27,20 +27,26 @@ diff -Nurb linux-2.6.22-510/include/linux/netfilter/xt_SETXID.h linux-2.6.22-520 +}; + +#endif /*_XT_SETXID_H_target*/ -diff -Nurb linux-2.6.22-510/include/linux/netfilter_ipv4/ipt_MARK.h linux-2.6.22-520/include/linux/netfilter_ipv4/ipt_MARK.h ---- linux-2.6.22-510/include/linux/netfilter_ipv4/ipt_MARK.h 2007-07-08 19:32:17.000000000 -0400 -+++ linux-2.6.22-520/include/linux/netfilter_ipv4/ipt_MARK.h 2008-03-14 16:29:22.000000000 -0400 -@@ -12,6 +12,7 @@ - #define IPT_MARK_SET XT_MARK_SET - #define IPT_MARK_AND XT_MARK_AND - #define IPT_MARK_OR XT_MARK_OR +diff -Nurp linux-2.6.22-510/include/linux/netfilter_ipv4/ipt_MARK.h linux-2.6.22-520/include/linux/netfilter_ipv4/ipt_MARK.h +--- linux-2.6.22-510/include/linux/netfilter_ipv4/ipt_MARK.h 2006-06-17 21:49:35.000000000 -0400 ++++ linux-2.6.22-520/include/linux/netfilter_ipv4/ipt_MARK.h 2007-12-03 15:11:08.000000000 -0500 +@@ -9,9 +9,10 @@ + #define ipt_mark_target_info xt_mark_target_info + + /* Version 1 */ +-#define IPT_MARK_SET XT_MARK_SET +-#define IPT_MARK_AND XT_MARK_AND +-#define IPT_MARK_OR XT_MARK_OR ++#define IPT_MARK_SET XT_MARK_SET ++#define IPT_MARK_AND XT_MARK_AND ++#define IPT_MARK_OR XT_MARK_OR +#define IPT_MARK_COPYXID XT_MARK_COPYXID #define ipt_mark_target_info_v1 xt_mark_target_info_v1 -diff -Nurb linux-2.6.22-510/include/linux/netfilter_ipv4/ipt_SETXID.h linux-2.6.22-520/include/linux/netfilter_ipv4/ipt_SETXID.h +diff -Nurp linux-2.6.22-510/include/linux/netfilter_ipv4/ipt_SETXID.h linux-2.6.22-520/include/linux/netfilter_ipv4/ipt_SETXID.h --- linux-2.6.22-510/include/linux/netfilter_ipv4/ipt_SETXID.h 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-520/include/linux/netfilter_ipv4/ipt_SETXID.h 2008-03-14 16:29:22.000000000 -0400 ++++ linux-2.6.22-520/include/linux/netfilter_ipv4/ipt_SETXID.h 2007-12-03 15:11:08.000000000 -0500 @@ -0,0 +1,13 @@ +#ifndef _IPT_SETXID_H_target +#define _IPT_SETXID_H_target @@ -55,10 +61,10 @@ diff -Nurb linux-2.6.22-510/include/linux/netfilter_ipv4/ipt_SETXID.h linux-2.6. +#define ipt_setxid_target_info_v1 xt_setxid_target_info_v1 + +#endif /*_IPT_SETXID_H_target*/ -diff -Nurb linux-2.6.22-510/include/linux/skbuff.h linux-2.6.22-520/include/linux/skbuff.h ---- linux-2.6.22-510/include/linux/skbuff.h 2007-07-08 19:32:17.000000000 -0400 -+++ linux-2.6.22-520/include/linux/skbuff.h 2008-03-14 16:29:22.000000000 -0400 -@@ -302,6 +302,7 @@ +diff -Nurp linux-2.6.22-510/include/linux/skbuff.h linux-2.6.22-520/include/linux/skbuff.h +--- linux-2.6.22-510/include/linux/skbuff.h 2007-07-21 18:00:24.000000000 -0400 ++++ linux-2.6.22-520/include/linux/skbuff.h 2007-12-03 15:20:15.000000000 -0500 +@@ -302,6 +302,7 @@ struct sk_buff { #endif __u32 mark; @@ -66,10 +72,10 @@ diff -Nurb linux-2.6.22-510/include/linux/skbuff.h linux-2.6.22-520/include/linu sk_buff_data_t transport_header; sk_buff_data_t network_header; -diff -Nurb linux-2.6.22-510/include/linux/socket.h linux-2.6.22-520/include/linux/socket.h ---- linux-2.6.22-510/include/linux/socket.h 2007-07-08 19:32:17.000000000 -0400 -+++ linux-2.6.22-520/include/linux/socket.h 2008-03-14 16:29:22.000000000 -0400 -@@ -288,6 +288,8 @@ +diff -Nurp linux-2.6.22-510/include/linux/socket.h linux-2.6.22-520/include/linux/socket.h +--- linux-2.6.22-510/include/linux/socket.h 2007-07-21 18:00:24.000000000 -0400 ++++ linux-2.6.22-520/include/linux/socket.h 2007-12-03 15:11:08.000000000 -0500 +@@ -288,6 +288,8 @@ struct ucred { #define SOL_TIPC 271 #define SOL_RXRPC 272 @@ -78,10 +84,10 @@ diff -Nurb linux-2.6.22-510/include/linux/socket.h linux-2.6.22-520/include/linu /* IPX options */ #define IPX_TYPE 1 -diff -Nurb linux-2.6.22-510/include/linux/vserver/network.h linux-2.6.22-520/include/linux/vserver/network.h ---- linux-2.6.22-510/include/linux/vserver/network.h 2008-03-14 16:28:36.000000000 -0400 -+++ linux-2.6.22-520/include/linux/vserver/network.h 2008-03-14 16:29:22.000000000 -0400 -@@ -44,6 +44,8 @@ +diff -Nurp linux-2.6.22-510/include/linux/vserver/network.h linux-2.6.22-520/include/linux/vserver/network.h +--- linux-2.6.22-510/include/linux/vserver/network.h 2007-12-03 15:10:48.000000000 -0500 ++++ linux-2.6.22-520/include/linux/vserver/network.h 2007-12-03 15:11:08.000000000 -0500 +@@ -44,6 +44,8 @@ static inline uint64_t __nxf_init_set(vo /* network caps */ #define NXC_RAW_ICMP 0x00000100 @@ -90,304 +96,10 @@ diff -Nurb linux-2.6.22-510/include/linux/vserver/network.h linux-2.6.22-520/inc /* address types */ -diff -Nurb linux-2.6.22-510/include/linux/vserver/network.h.orig linux-2.6.22-520/include/linux/vserver/network.h.orig ---- linux-2.6.22-510/include/linux/vserver/network.h.orig 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-520/include/linux/vserver/network.h.orig 2008-03-14 16:29:27.000000000 -0400 -@@ -0,0 +1,143 @@ -+#ifndef _VX_NETWORK_H -+#define _VX_NETWORK_H -+ -+#include -+ -+ -+#define MAX_N_CONTEXT 65535 /* Arbitrary limit */ -+ -+ -+/* network flags */ -+ -+#define NXF_INFO_PRIVATE 0x00000008 -+ -+#define NXF_SINGLE_IP 0x00000100 -+#define NXF_LBACK_REMAP 0x00000200 -+ -+#define NXF_HIDE_NETIF 0x02000000 -+#define NXF_HIDE_LBACK 0x04000000 -+ -+#define NXF_STATE_SETUP (1ULL << 32) -+#define NXF_STATE_ADMIN (1ULL << 34) -+ -+#define NXF_SC_HELPER (1ULL << 36) -+#define NXF_PERSISTENT (1ULL << 38) -+ -+#define NXF_ONE_TIME (0x0005ULL << 32) -+ -+ -+#define NXF_INIT_SET (__nxf_init_set()) -+ -+static inline uint64_t __nxf_init_set(void) { -+ return NXF_STATE_ADMIN -+#ifdef CONFIG_VSERVER_AUTO_LBACK -+ | NXF_LBACK_REMAP -+ | NXF_HIDE_LBACK -+#endif -+#ifdef CONFIG_VSERVER_AUTO_SINGLE -+ | NXF_SINGLE_IP -+#endif -+ | NXF_HIDE_NETIF; -+} -+ -+ -+/* network caps */ -+ -+#define NXC_RAW_ICMP 0x00000100 -+ -+ -+/* address types */ -+ -+#define NXA_TYPE_IPV4 0x0001 -+#define NXA_TYPE_IPV6 0x0002 -+ -+#define NXA_TYPE_NONE 0x0000 -+#define NXA_TYPE_ANY 0x00FF -+ -+#define NXA_TYPE_ADDR 0x0010 -+#define NXA_TYPE_MASK 0x0020 -+#define NXA_TYPE_RANGE 0x0040 -+ -+#define NXA_MASK_ALL (NXA_TYPE_ADDR | NXA_TYPE_MASK | NXA_TYPE_RANGE) -+ -+#define NXA_MOD_BCAST 0x0100 -+#define NXA_MOD_LBACK 0x0200 -+ -+#define NXA_LOOPBACK 0x1000 -+ -+#define NXA_MASK_BIND (NXA_MASK_ALL | NXA_MOD_BCAST | NXA_MOD_LBACK) -+#define NXA_MASK_SHOW (NXA_MASK_ALL | NXA_LOOPBACK) -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct nx_addr_v4 { -+ struct nx_addr_v4 *next; -+ struct in_addr ip[2]; -+ struct in_addr mask; -+ uint16_t type; -+ uint16_t flags; -+}; -+ -+struct nx_addr_v6 { -+ struct nx_addr_v6 *next; -+ struct in6_addr ip; -+ struct in6_addr mask; -+ uint32_t prefix; -+ uint16_t type; -+ uint16_t flags; -+}; -+ -+struct nx_info { -+ struct hlist_node nx_hlist; /* linked list of nxinfos */ -+ nid_t nx_id; /* vnet id */ -+ atomic_t nx_usecnt; /* usage count */ -+ atomic_t nx_tasks; /* tasks count */ -+ int nx_state; /* context state */ -+ -+ uint64_t nx_flags; /* network flag word */ -+ uint64_t nx_ncaps; /* network capabilities */ -+ -+ struct in_addr v4_lback; /* Loopback address */ -+ struct in_addr v4_bcast; /* Broadcast address */ -+ struct nx_addr_v4 v4; /* First/Single ipv4 address */ -+#ifdef CONFIG_IPV6 -+ struct nx_addr_v6 v6; /* First/Single ipv6 address */ -+#endif -+ char nx_name[65]; /* network context name */ -+}; -+ -+ -+/* status flags */ -+ -+#define NXS_HASHED 0x0001 -+#define NXS_SHUTDOWN 0x0100 -+#define NXS_RELEASED 0x8000 -+ -+extern struct nx_info *lookup_nx_info(int); -+ -+extern int get_nid_list(int, unsigned int *, int); -+extern int nid_is_hashed(nid_t); -+ -+extern int nx_migrate_task(struct task_struct *, struct nx_info *); -+ -+extern long vs_net_change(struct nx_info *, unsigned int); -+ -+struct sock; -+ -+ -+#define NX_IPV4(n) ((n)->v4.type != NXA_TYPE_NONE) -+#ifdef CONFIG_IPV6 -+#define NX_IPV6(n) ((n)->v6.type != NXA_TYPE_NONE) -+#else -+#define NX_IPV6(n) (0) -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* _VX_NETWORK_H */ -diff -Nurb linux-2.6.22-510/include/linux/vserver/network.h.orig.orig linux-2.6.22-520/include/linux/vserver/network.h.orig.orig ---- linux-2.6.22-510/include/linux/vserver/network.h.orig.orig 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-520/include/linux/vserver/network.h.orig.orig 2008-03-14 16:28:36.000000000 -0400 -@@ -0,0 +1,143 @@ -+#ifndef _VX_NETWORK_H -+#define _VX_NETWORK_H -+ -+#include -+ -+ -+#define MAX_N_CONTEXT 65535 /* Arbitrary limit */ -+ -+ -+/* network flags */ -+ -+#define NXF_INFO_PRIVATE 0x00000008 -+ -+#define NXF_SINGLE_IP 0x00000100 -+#define NXF_LBACK_REMAP 0x00000200 -+ -+#define NXF_HIDE_NETIF 0x02000000 -+#define NXF_HIDE_LBACK 0x04000000 -+ -+#define NXF_STATE_SETUP (1ULL << 32) -+#define NXF_STATE_ADMIN (1ULL << 34) -+ -+#define NXF_SC_HELPER (1ULL << 36) -+#define NXF_PERSISTENT (1ULL << 38) -+ -+#define NXF_ONE_TIME (0x0005ULL << 32) -+ -+ -+#define NXF_INIT_SET (__nxf_init_set()) -+ -+static inline uint64_t __nxf_init_set(void) { -+ return NXF_STATE_ADMIN -+#ifdef CONFIG_VSERVER_AUTO_LBACK -+ | NXF_LBACK_REMAP -+ | NXF_HIDE_LBACK -+#endif -+#ifdef CONFIG_VSERVER_AUTO_SINGLE -+ | NXF_SINGLE_IP -+#endif -+ | NXF_HIDE_NETIF; -+} -+ -+ -+/* network caps */ -+ -+#define NXC_RAW_ICMP 0x00000100 -+ -+ -+/* address types */ -+ -+#define NXA_TYPE_IPV4 0x0001 -+#define NXA_TYPE_IPV6 0x0002 -+ -+#define NXA_TYPE_NONE 0x0000 -+#define NXA_TYPE_ANY 0x00FF -+ -+#define NXA_TYPE_ADDR 0x0010 -+#define NXA_TYPE_MASK 0x0020 -+#define NXA_TYPE_RANGE 0x0040 -+ -+#define NXA_MASK_ALL (NXA_TYPE_ADDR | NXA_TYPE_MASK | NXA_TYPE_RANGE) -+ -+#define NXA_MOD_BCAST 0x0100 -+#define NXA_MOD_LBACK 0x0200 -+ -+#define NXA_LOOPBACK 0x1000 -+ -+#define NXA_MASK_BIND (NXA_MASK_ALL | NXA_MOD_BCAST | NXA_MOD_LBACK) -+#define NXA_MASK_SHOW (NXA_MASK_ALL | NXA_LOOPBACK) -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct nx_addr_v4 { -+ struct nx_addr_v4 *next; -+ struct in_addr ip[2]; -+ struct in_addr mask; -+ uint16_t type; -+ uint16_t flags; -+}; -+ -+struct nx_addr_v6 { -+ struct nx_addr_v6 *next; -+ struct in6_addr ip; -+ struct in6_addr mask; -+ uint32_t prefix; -+ uint16_t type; -+ uint16_t flags; -+}; -+ -+struct nx_info { -+ struct hlist_node nx_hlist; /* linked list of nxinfos */ -+ nid_t nx_id; /* vnet id */ -+ atomic_t nx_usecnt; /* usage count */ -+ atomic_t nx_tasks; /* tasks count */ -+ int nx_state; /* context state */ -+ -+ uint64_t nx_flags; /* network flag word */ -+ uint64_t nx_ncaps; /* network capabilities */ -+ -+ struct in_addr v4_lback; /* Loopback address */ -+ struct in_addr v4_bcast; /* Broadcast address */ -+ struct nx_addr_v4 v4; /* First/Single ipv4 address */ -+#ifdef CONFIG_IPV6 -+ struct nx_addr_v6 v6; /* First/Single ipv6 address */ -+#endif -+ char nx_name[65]; /* network context name */ -+}; -+ -+ -+/* status flags */ -+ -+#define NXS_HASHED 0x0001 -+#define NXS_SHUTDOWN 0x0100 -+#define NXS_RELEASED 0x8000 -+ -+extern struct nx_info *lookup_nx_info(int); -+ -+extern int get_nid_list(int, unsigned int *, int); -+extern int nid_is_hashed(nid_t); -+ -+extern int nx_migrate_task(struct task_struct *, struct nx_info *); -+ -+extern long vs_net_change(struct nx_info *, unsigned int); -+ -+struct sock; -+ -+ -+#define NX_IPV4(n) ((n)->v4.type != NXA_TYPE_NONE) -+#ifdef CONFIG_IPV6 -+#define NX_IPV6(n) ((n)->v6.type != NXA_TYPE_NONE) -+#else -+#define NX_IPV6(n) (0) -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* _VX_NETWORK_H */ -diff -Nurb linux-2.6.22-510/include/net/netfilter/nf_conntrack.h linux-2.6.22-520/include/net/netfilter/nf_conntrack.h ---- linux-2.6.22-510/include/net/netfilter/nf_conntrack.h 2007-07-08 19:32:17.000000000 -0400 -+++ linux-2.6.22-520/include/net/netfilter/nf_conntrack.h 2008-03-14 16:29:27.000000000 -0400 -@@ -131,6 +131,9 @@ +diff -Nurp linux-2.6.22-510/include/net/netfilter/nf_conntrack.h linux-2.6.22-520/include/net/netfilter/nf_conntrack.h +--- linux-2.6.22-510/include/net/netfilter/nf_conntrack.h 2007-07-21 18:00:24.000000000 -0400 ++++ linux-2.6.22-520/include/net/netfilter/nf_conntrack.h 2007-12-03 15:11:08.000000000 -0500 +@@ -131,6 +131,9 @@ struct nf_conn /* Storage reserved for other modules: */ union nf_conntrack_proto proto; @@ -397,10 +109,10 @@ diff -Nurb linux-2.6.22-510/include/net/netfilter/nf_conntrack.h linux-2.6.22-52 /* features dynamically at the end: helper, nat (both optional) */ char data[0]; }; -diff -Nurb linux-2.6.22-510/include/net/raw.h linux-2.6.22-520/include/net/raw.h ---- linux-2.6.22-510/include/net/raw.h 2007-07-08 19:32:17.000000000 -0400 -+++ linux-2.6.22-520/include/net/raw.h 2008-03-14 16:29:27.000000000 -0400 -@@ -36,7 +36,7 @@ +diff -Nurp linux-2.6.22-510/include/net/raw.h linux-2.6.22-520/include/net/raw.h +--- linux-2.6.22-510/include/net/raw.h 2007-05-04 09:55:46.000000000 -0400 ++++ linux-2.6.22-520/include/net/raw.h 2007-12-03 15:11:08.000000000 -0500 +@@ -36,7 +36,7 @@ extern rwlock_t raw_v4_lock; extern struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num, __be32 raddr, __be32 laddr, @@ -409,9 +121,9 @@ diff -Nurb linux-2.6.22-510/include/net/raw.h linux-2.6.22-520/include/net/raw.h extern int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash); -diff -Nurb linux-2.6.22-510/net/core/skbuff.c linux-2.6.22-520/net/core/skbuff.c ---- linux-2.6.22-510/net/core/skbuff.c 2007-07-08 19:32:17.000000000 -0400 -+++ linux-2.6.22-520/net/core/skbuff.c 2008-03-14 16:29:27.000000000 -0400 +diff -Nurp linux-2.6.22-510/net/core/skbuff.c linux-2.6.22-520/net/core/skbuff.c +--- linux-2.6.22-510/net/core/skbuff.c 2007-07-21 18:00:25.000000000 -0400 ++++ linux-2.6.22-520/net/core/skbuff.c 2007-12-03 15:11:08.000000000 -0500 @@ -56,6 +56,7 @@ #include #include @@ -420,7 +132,7 @@ diff -Nurb linux-2.6.22-510/net/core/skbuff.c linux-2.6.22-520/net/core/skbuff.c #include #include -@@ -174,6 +175,7 @@ +@@ -174,6 +175,7 @@ struct sk_buff *__alloc_skb(unsigned int skb->data = data; skb_reset_tail_pointer(skb); skb->end = skb->tail + size; @@ -428,7 +140,7 @@ diff -Nurb linux-2.6.22-510/net/core/skbuff.c linux-2.6.22-520/net/core/skbuff.c /* make sure we initialize shinfo sequentially */ shinfo = skb_shinfo(skb); atomic_set(&shinfo->dataref, 1); -@@ -443,6 +445,8 @@ +@@ -443,6 +445,8 @@ struct sk_buff *skb_clone(struct sk_buff C(tail); C(end); @@ -437,7 +149,7 @@ diff -Nurb linux-2.6.22-510/net/core/skbuff.c linux-2.6.22-520/net/core/skbuff.c atomic_inc(&(skb_shinfo(skb)->dataref)); skb->cloned = 1; -@@ -492,6 +496,7 @@ +@@ -492,6 +496,7 @@ static void copy_skb_header(struct sk_bu new->tc_index = old->tc_index; #endif skb_copy_secmark(new, old); @@ -445,10 +157,10 @@ diff -Nurb linux-2.6.22-510/net/core/skbuff.c linux-2.6.22-520/net/core/skbuff.c atomic_set(&new->users, 1); skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size; skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs; -diff -Nurb linux-2.6.22-510/net/core/sock.c linux-2.6.22-520/net/core/sock.c ---- linux-2.6.22-510/net/core/sock.c 2008-03-14 16:28:36.000000000 -0400 -+++ linux-2.6.22-520/net/core/sock.c 2008-03-14 16:29:27.000000000 -0400 -@@ -444,6 +444,19 @@ +diff -Nurp linux-2.6.22-510/net/core/sock.c linux-2.6.22-520/net/core/sock.c +--- linux-2.6.22-510/net/core/sock.c 2007-12-03 15:10:56.000000000 -0500 ++++ linux-2.6.22-520/net/core/sock.c 2007-12-03 15:11:08.000000000 -0500 +@@ -444,6 +444,19 @@ set_sndbuf: } goto set_sndbuf; @@ -468,7 +180,7 @@ diff -Nurb linux-2.6.22-510/net/core/sock.c linux-2.6.22-520/net/core/sock.c case SO_RCVBUF: /* Don't error on this BSD doesn't and if you think about it this is right. Otherwise apps have to -@@ -573,7 +586,7 @@ +@@ -573,7 +586,7 @@ set_rcvbuf: char devname[IFNAMSIZ]; /* Sorry... */ @@ -477,10 +189,10 @@ diff -Nurb linux-2.6.22-510/net/core/sock.c linux-2.6.22-520/net/core/sock.c ret = -EPERM; break; } -diff -Nurb linux-2.6.22-510/net/ipv4/af_inet.c linux-2.6.22-520/net/ipv4/af_inet.c ---- linux-2.6.22-510/net/ipv4/af_inet.c 2008-03-14 16:28:36.000000000 -0400 -+++ linux-2.6.22-520/net/ipv4/af_inet.c 2008-03-14 16:29:27.000000000 -0400 -@@ -178,6 +178,8 @@ +diff -Nurp linux-2.6.22-510/net/ipv4/af_inet.c linux-2.6.22-520/net/ipv4/af_inet.c +--- linux-2.6.22-510/net/ipv4/af_inet.c 2007-12-03 15:10:56.000000000 -0500 ++++ linux-2.6.22-520/net/ipv4/af_inet.c 2007-12-03 15:11:08.000000000 -0500 +@@ -178,6 +178,8 @@ static int inet_autobind(struct sock *sk return -EAGAIN; } inet->sport = htons(inet->num); @@ -489,20 +201,10 @@ diff -Nurb linux-2.6.22-510/net/ipv4/af_inet.c linux-2.6.22-520/net/ipv4/af_inet } release_sock(sk); return 0; -@@ -312,6 +314,9 @@ - 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: -diff -Nurb linux-2.6.22-510/net/ipv4/icmp.c linux-2.6.22-520/net/ipv4/icmp.c ---- linux-2.6.22-510/net/ipv4/icmp.c 2008-03-14 16:28:42.000000000 -0400 -+++ linux-2.6.22-520/net/ipv4/icmp.c 2008-03-14 16:29:27.000000000 -0400 -@@ -709,7 +709,7 @@ +diff -Nurp linux-2.6.22-510/net/ipv4/icmp.c linux-2.6.22-520/net/ipv4/icmp.c +--- linux-2.6.22-510/net/ipv4/icmp.c 2007-12-03 15:11:06.000000000 -0500 ++++ linux-2.6.22-520/net/ipv4/icmp.c 2007-12-03 15:11:08.000000000 -0500 +@@ -709,7 +709,7 @@ static void icmp_unreach(struct sk_buff if ((raw_sk = sk_head(&raw_v4_htable[hash])) != NULL) { while ((raw_sk = __raw_v4_lookup(raw_sk, protocol, iph->daddr, iph->saddr, @@ -511,10 +213,10 @@ diff -Nurb linux-2.6.22-510/net/ipv4/icmp.c linux-2.6.22-520/net/ipv4/icmp.c raw_err(raw_sk, skb, info); raw_sk = sk_next(raw_sk); iph = (struct iphdr *)skb->data; -diff -Nurb linux-2.6.22-510/net/ipv4/ip_options.c linux-2.6.22-520/net/ipv4/ip_options.c ---- linux-2.6.22-510/net/ipv4/ip_options.c 2007-07-08 19:32:17.000000000 -0400 -+++ linux-2.6.22-520/net/ipv4/ip_options.c 2008-03-14 16:29:27.000000000 -0400 -@@ -409,7 +409,7 @@ +diff -Nurp linux-2.6.22-510/net/ipv4/ip_options.c linux-2.6.22-520/net/ipv4/ip_options.c +--- linux-2.6.22-510/net/ipv4/ip_options.c 2007-07-21 18:00:25.000000000 -0400 ++++ linux-2.6.22-520/net/ipv4/ip_options.c 2007-12-03 15:11:08.000000000 -0500 +@@ -409,7 +409,7 @@ int ip_options_compile(struct ip_options optptr[2] += 8; break; default: @@ -523,7 +225,7 @@ diff -Nurb linux-2.6.22-510/net/ipv4/ip_options.c linux-2.6.22-520/net/ipv4/ip_o pp_ptr = optptr + 3; goto error; } -@@ -445,7 +445,7 @@ +@@ -445,7 +445,7 @@ int ip_options_compile(struct ip_options opt->router_alert = optptr - iph; break; case IPOPT_CIPSO: @@ -532,7 +234,7 @@ diff -Nurb linux-2.6.22-510/net/ipv4/ip_options.c linux-2.6.22-520/net/ipv4/ip_o pp_ptr = optptr; goto error; } -@@ -458,7 +458,7 @@ +@@ -458,7 +458,7 @@ int ip_options_compile(struct ip_options case IPOPT_SEC: case IPOPT_SID: default: @@ -541,10 +243,10 @@ diff -Nurb linux-2.6.22-510/net/ipv4/ip_options.c linux-2.6.22-520/net/ipv4/ip_o pp_ptr = optptr; goto error; } -diff -Nurb linux-2.6.22-510/net/ipv4/netfilter/ipt_LOG.c linux-2.6.22-520/net/ipv4/netfilter/ipt_LOG.c ---- linux-2.6.22-510/net/ipv4/netfilter/ipt_LOG.c 2008-03-14 16:28:20.000000000 -0400 -+++ linux-2.6.22-520/net/ipv4/netfilter/ipt_LOG.c 2008-03-14 16:29:27.000000000 -0400 -@@ -49,6 +49,8 @@ +diff -Nurp linux-2.6.22-510/net/ipv4/netfilter/ipt_LOG.c linux-2.6.22-520/net/ipv4/netfilter/ipt_LOG.c +--- linux-2.6.22-510/net/ipv4/netfilter/ipt_LOG.c 2007-12-03 15:10:26.000000000 -0500 ++++ linux-2.6.22-520/net/ipv4/netfilter/ipt_LOG.c 2007-12-03 15:11:08.000000000 -0500 +@@ -49,6 +49,8 @@ static void dump_packet(const struct nf_ else logflags = NF_LOG_MASK; @@ -553,10 +255,10 @@ diff -Nurb linux-2.6.22-510/net/ipv4/netfilter/ipt_LOG.c linux-2.6.22-520/net/ip ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph); if (ih == NULL) { printk("TRUNCATED"); -diff -Nurb linux-2.6.22-510/net/ipv4/raw.c linux-2.6.22-520/net/ipv4/raw.c ---- linux-2.6.22-510/net/ipv4/raw.c 2008-03-14 16:28:36.000000000 -0400 -+++ linux-2.6.22-520/net/ipv4/raw.c 2008-03-14 16:29:27.000000000 -0400 -@@ -103,7 +103,7 @@ +diff -Nurp linux-2.6.22-510/net/ipv4/raw.c linux-2.6.22-520/net/ipv4/raw.c +--- linux-2.6.22-510/net/ipv4/raw.c 2007-12-03 15:10:56.000000000 -0500 ++++ linux-2.6.22-520/net/ipv4/raw.c 2007-12-03 15:11:08.000000000 -0500 +@@ -103,7 +103,7 @@ static void raw_v4_unhash(struct sock *s struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num, __be32 raddr, __be32 laddr, @@ -565,7 +267,7 @@ diff -Nurb linux-2.6.22-510/net/ipv4/raw.c linux-2.6.22-520/net/ipv4/raw.c { struct hlist_node *node; -@@ -112,6 +112,7 @@ +@@ -112,6 +112,7 @@ struct sock *__raw_v4_lookup(struct sock if (inet->num == num && !(inet->daddr && inet->daddr != raddr) && @@ -573,7 +275,7 @@ diff -Nurb linux-2.6.22-510/net/ipv4/raw.c linux-2.6.22-520/net/ipv4/raw.c v4_sock_addr_match(sk->sk_nx_info, inet, laddr) && !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) goto found; /* gotcha */ -@@ -161,7 +162,7 @@ +@@ -161,7 +162,7 @@ int raw_v4_input(struct sk_buff *skb, st goto out; sk = __raw_v4_lookup(__sk_head(head), iph->protocol, iph->saddr, iph->daddr, @@ -582,7 +284,7 @@ diff -Nurb linux-2.6.22-510/net/ipv4/raw.c linux-2.6.22-520/net/ipv4/raw.c while (sk) { delivered = 1; -@@ -174,7 +175,7 @@ +@@ -174,7 +175,7 @@ int raw_v4_input(struct sk_buff *skb, st } sk = __raw_v4_lookup(sk_next(sk), iph->protocol, iph->saddr, iph->daddr, @@ -591,7 +293,7 @@ diff -Nurb linux-2.6.22-510/net/ipv4/raw.c linux-2.6.22-520/net/ipv4/raw.c } out: read_unlock(&raw_v4_lock); -@@ -315,7 +316,7 @@ +@@ -315,7 +316,7 @@ static int raw_send_hdrinc(struct sock * } err = -EPERM; @@ -600,10 +302,10 @@ diff -Nurb linux-2.6.22-510/net/ipv4/raw.c linux-2.6.22-520/net/ipv4/raw.c sk->sk_nx_info && !v4_addr_in_nx_info(sk->sk_nx_info, iph->saddr, NXA_MASK_BIND)) goto error_free; -diff -Nurb linux-2.6.22-510/net/netfilter/Kconfig linux-2.6.22-520/net/netfilter/Kconfig ---- linux-2.6.22-510/net/netfilter/Kconfig 2007-07-08 19:32:17.000000000 -0400 -+++ linux-2.6.22-520/net/netfilter/Kconfig 2008-03-14 16:29:27.000000000 -0400 -@@ -389,6 +389,13 @@ +diff -Nurp linux-2.6.22-510/net/netfilter/Kconfig linux-2.6.22-520/net/netfilter/Kconfig +--- linux-2.6.22-510/net/netfilter/Kconfig 2007-07-21 18:00:27.000000000 -0400 ++++ linux-2.6.22-520/net/netfilter/Kconfig 2007-12-03 15:11:08.000000000 -0500 +@@ -389,6 +389,13 @@ config NETFILTER_XT_TARGET_TCPMSS To compile it as a module, choose M here. If unsure, say N. @@ -617,10 +319,10 @@ diff -Nurb linux-2.6.22-510/net/netfilter/Kconfig linux-2.6.22-520/net/netfilter config NETFILTER_XT_MATCH_COMMENT tristate '"comment" match support' depends on NETFILTER_XTABLES -diff -Nurb linux-2.6.22-510/net/netfilter/Makefile linux-2.6.22-520/net/netfilter/Makefile ---- linux-2.6.22-510/net/netfilter/Makefile 2007-07-08 19:32:17.000000000 -0400 -+++ linux-2.6.22-520/net/netfilter/Makefile 2008-03-14 16:29:27.000000000 -0400 -@@ -37,6 +37,7 @@ +diff -Nurp linux-2.6.22-510/net/netfilter/Makefile linux-2.6.22-520/net/netfilter/Makefile +--- linux-2.6.22-510/net/netfilter/Makefile 2007-07-21 17:58:59.000000000 -0400 ++++ linux-2.6.22-520/net/netfilter/Makefile 2007-12-03 15:11:08.000000000 -0500 +@@ -37,6 +37,7 @@ obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_co obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o # targets @@ -628,10 +330,10 @@ diff -Nurb linux-2.6.22-510/net/netfilter/Makefile linux-2.6.22-520/net/netfilte obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o -diff -Nurb linux-2.6.22-510/net/netfilter/nf_conntrack_core.c linux-2.6.22-520/net/netfilter/nf_conntrack_core.c ---- linux-2.6.22-510/net/netfilter/nf_conntrack_core.c 2007-07-08 19:32:17.000000000 -0400 -+++ linux-2.6.22-520/net/netfilter/nf_conntrack_core.c 2008-03-14 16:29:27.000000000 -0400 -@@ -726,6 +726,8 @@ +diff -Nurp linux-2.6.22-510/net/netfilter/nf_conntrack_core.c linux-2.6.22-520/net/netfilter/nf_conntrack_core.c +--- linux-2.6.22-510/net/netfilter/nf_conntrack_core.c 2007-07-21 18:00:27.000000000 -0400 ++++ linux-2.6.22-520/net/netfilter/nf_conntrack_core.c 2007-12-03 15:11:08.000000000 -0500 +@@ -726,6 +726,8 @@ init_conntrack(const struct nf_conntrack /* Overload tuple linked list to put us in unconfirmed list. */ list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed); @@ -640,9 +342,9 @@ diff -Nurb linux-2.6.22-510/net/netfilter/nf_conntrack_core.c linux-2.6.22-520/n write_unlock_bh(&nf_conntrack_lock); -diff -Nurb linux-2.6.22-510/net/netfilter/xt_MARK.c linux-2.6.22-520/net/netfilter/xt_MARK.c ---- linux-2.6.22-510/net/netfilter/xt_MARK.c 2007-07-08 19:32:17.000000000 -0400 -+++ linux-2.6.22-520/net/netfilter/xt_MARK.c 2008-03-14 16:29:27.000000000 -0400 +diff -Nurp linux-2.6.22-510/net/netfilter/xt_MARK.c linux-2.6.22-520/net/netfilter/xt_MARK.c +--- linux-2.6.22-510/net/netfilter/xt_MARK.c 2007-07-21 17:59:00.000000000 -0400 ++++ linux-2.6.22-520/net/netfilter/xt_MARK.c 2007-12-03 15:11:08.000000000 -0500 @@ -5,13 +5,18 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -662,7 +364,7 @@ diff -Nurb linux-2.6.22-510/net/netfilter/xt_MARK.c linux-2.6.22-520/net/netfilt #include #include -@@ -21,6 +26,48 @@ +@@ -21,6 +26,48 @@ MODULE_DESCRIPTION("ip[6]tables MARK mod MODULE_ALIAS("ipt_MARK"); MODULE_ALIAS("ip6t_MARK"); @@ -711,7 +413,7 @@ diff -Nurb linux-2.6.22-510/net/netfilter/xt_MARK.c linux-2.6.22-520/net/netfilt static unsigned int target_v0(struct sk_buff **pskb, const struct net_device *in, -@@ -44,7 +91,7 @@ +@@ -44,7 +91,7 @@ target_v1(struct sk_buff **pskb, const void *targinfo) { const struct xt_mark_target_info_v1 *markinfo = targinfo; @@ -720,7 +422,7 @@ diff -Nurb linux-2.6.22-510/net/netfilter/xt_MARK.c linux-2.6.22-520/net/netfilt switch (markinfo->mode) { case XT_MARK_SET: -@@ -58,8 +105,58 @@ +@@ -58,9 +105,52 @@ target_v1(struct sk_buff **pskb, case XT_MARK_OR: mark = (*pskb)->mark | markinfo->mark; break; @@ -733,13 +435,12 @@ diff -Nurb linux-2.6.22-510/net/netfilter/xt_MARK.c linux-2.6.22-520/net/netfilt + struct nf_conn *ct = nf_ct_get((*pskb), &ctinfo); + extern struct inet_hashinfo tcp_hashinfo; + enum ip_conntrack_dir dir; ++ + if (!ct) + break; -+ + dir = CTINFO2DIR(ctinfo); + u_int32_t src_ip = ct->tuplehash[dir].tuple.src.u3.ip; + u_int16_t src_port = get_src_port(&ct->tuplehash[dir].tuple); -+ u_int16_t proto = ct->tuplehash[dir].tuple.dst.protonum; + + u_int32_t ip; + u_int16_t port; @@ -748,38 +449,34 @@ diff -Nurb linux-2.6.22-510/net/netfilter/xt_MARK.c linux-2.6.22-520/net/netfilt + ip = ct->tuplehash[dir].tuple.dst.u3.ip; + port = get_dst_port(&ct->tuplehash[dir].tuple); + -+ if (proto == 1 || proto == 17) { -+ if (((*pskb)->mark!=-1) && (*pskb)->mark) -+ ct->xid[0]=(*pskb)->mark; -+ if (ct->xid[0]) -+ mark = ct->xid[0]; -+ ++ if ((*pskb)->sk) ++ connection_sk = (*pskb)->sk; ++ else { ++ connection_sk = inet_lookup(&tcp_hashinfo, src_ip, src_port, ip, port, dif); + } -+ else if (proto == 6) { -+ if ((*pskb)->sk) -+ connection_sk = (*pskb)->sk; -+ else { -+ connection_sk = inet_lookup(&tcp_hashinfo, src_ip, src_port, ip, port, dif); -+ } + -+ if (connection_sk) { -+ connection_sk->sk_peercred.gid = connection_sk->sk_peercred.uid = ct->xid[dir]; -+ ct->xid[!dir]=connection_sk->sk_xid; -+ if (connection_sk->sk_xid != 0) -+ mark = connection_sk->sk_xid; -+ if (connection_sk != (*pskb)->sk) -+ sock_put(connection_sk); -+ } -+ break; -+ } -+ } ++ if (connection_sk) { ++#ifdef REQUIRESFIXFROMSAPAN ++ connection_sk->sk_peercred.gid = connection_sk->sk_peercred.uid = ct->xid[dir]; ++ ct->xid[!dir]=connection_sk->sk_xid; ++ /*connection_sk->sk_peercred.gid = connection_sk->sk_peercred.uid = connection_sk->sk_xid;*/ ++ if (connection_sk->sk_xid != 0) ++ mark = connection_sk->sk_xid; ++#endif ++ if (connection_sk != (*pskb)->sk) ++ sock_put(connection_sk); ++ } ++ break; ++ } } +- (*pskb)->mark = mark; + if (mark != -1) - (*pskb)->mark = mark; ++ (*pskb)->mark = mark; return XT_CONTINUE; } -@@ -92,7 +189,8 @@ + +@@ -92,7 +182,8 @@ checkentry_v1(const char *tablename, if (markinfo->mode != XT_MARK_SET && markinfo->mode != XT_MARK_AND @@ -789,297 +486,9 @@ diff -Nurb linux-2.6.22-510/net/netfilter/xt_MARK.c linux-2.6.22-520/net/netfilt printk(KERN_WARNING "MARK: unknown mode %u\n", markinfo->mode); return 0; -diff -Nurb linux-2.6.22-510/net/netfilter/xt_MARK.c.orig linux-2.6.22-520/net/netfilter/xt_MARK.c.orig ---- linux-2.6.22-510/net/netfilter/xt_MARK.c.orig 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-520/net/netfilter/xt_MARK.c.orig 2008-03-14 16:29:27.000000000 -0400 -@@ -0,0 +1,284 @@ -+/* This is a module which is used for setting the NFMARK field of an skb. */ -+ -+/* (C) 1999-2001 Marc Boucher -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Marc Boucher "); -+MODULE_DESCRIPTION("ip[6]tables MARK modification module"); -+MODULE_ALIAS("ipt_MARK"); -+MODULE_ALIAS("ip6t_MARK"); -+ -+static inline u_int16_t -+get_dst_port(struct nf_conntrack_tuple *tuple) -+{ -+ switch (tuple->dst.protonum) { -+ case IPPROTO_GRE: -+ /* XXX Truncate 32-bit GRE key to 16 bits */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) -+ return tuple->dst.u.gre.key; -+#else -+ return htons(ntohl(tuple->dst.u.gre.key)); -+#endif -+ case IPPROTO_ICMP: -+ /* Bind on ICMP echo ID */ -+ return tuple->src.u.icmp.id; -+ case IPPROTO_TCP: -+ return tuple->dst.u.tcp.port; -+ case IPPROTO_UDP: -+ return tuple->dst.u.udp.port; -+ default: -+ return tuple->dst.u.all; -+ } -+} -+ -+static inline u_int16_t -+get_src_port(struct nf_conntrack_tuple *tuple) -+{ -+ switch (tuple->dst.protonum) { -+ case IPPROTO_GRE: -+ /* XXX Truncate 32-bit GRE key to 16 bits */ -+ return htons(ntohl(tuple->src.u.gre.key)); -+ case IPPROTO_ICMP: -+ /* Bind on ICMP echo ID */ -+ return tuple->src.u.icmp.id; -+ case IPPROTO_TCP: -+ return tuple->src.u.tcp.port; -+ case IPPROTO_UDP: -+ return tuple->src.u.udp.port; -+ default: -+ return tuple->src.u.all; -+ } -+} -+ -+static unsigned int -+target_v0(struct sk_buff **pskb, -+ const struct net_device *in, -+ const struct net_device *out, -+ unsigned int hooknum, -+ const struct xt_target *target, -+ const void *targinfo) -+{ -+ const struct xt_mark_target_info *markinfo = targinfo; -+ -+ (*pskb)->mark = markinfo->mark; -+ return XT_CONTINUE; -+} -+ -+static unsigned int -+target_v1(struct sk_buff **pskb, -+ const struct net_device *in, -+ const struct net_device *out, -+ unsigned int hooknum, -+ const struct xt_target *target, -+ const void *targinfo) -+{ -+ const struct xt_mark_target_info_v1 *markinfo = targinfo; -+ int mark = -1; -+ -+ switch (markinfo->mode) { -+ case XT_MARK_SET: -+ mark = markinfo->mark; -+ break; -+ -+ case XT_MARK_AND: -+ mark = (*pskb)->mark & markinfo->mark; -+ break; -+ -+ case XT_MARK_OR: -+ mark = (*pskb)->mark | markinfo->mark; -+ break; -+ -+ case XT_MARK_COPYXID: { -+ enum ip_conntrack_info ctinfo; -+ struct sock *connection_sk; -+ int dif; -+ -+ struct nf_conn *ct = nf_ct_get((*pskb), &ctinfo); -+ extern struct inet_hashinfo tcp_hashinfo; -+ enum ip_conntrack_dir dir; -+ if (!ct) -+ break; -+ -+ dir = CTINFO2DIR(ctinfo); -+ u_int32_t src_ip = ct->tuplehash[dir].tuple.src.u3.ip; -+ u_int16_t src_port = get_src_port(&ct->tuplehash[dir].tuple); -+ u_int16_t proto = ct->tuplehash[dir].tuple.dst.protonum; -+ -+ u_int32_t ip; -+ u_int16_t port; -+ -+ dif = ((struct rtable *)(*pskb)->dst)->rt_iif; -+ ip = ct->tuplehash[dir].tuple.dst.u3.ip; -+ port = get_dst_port(&ct->tuplehash[dir].tuple); -+ -+ if (proto == 1) { -+ if (((*pskb)->mark!=-1) && (*pskb)->mark) -+ ct->xid[0]=(*pskb)->mark; -+ if (ct->xid[0]) -+ mark = ct->xid[0]; -+ printk(KERN_CRIT "%d %d\n",ct->xid[0],(*pskb)->mark); -+ -+ } -+ else if (proto == 6) { -+ if ((*pskb)->sk) -+ connection_sk = (*pskb)->sk; -+ else { -+ connection_sk = inet_lookup(&tcp_hashinfo, src_ip, src_port, ip, port, dif); -+ } -+ -+ if (connection_sk) { -+ connection_sk->sk_peercred.gid = connection_sk->sk_peercred.uid = ct->xid[dir]; -+ ct->xid[!dir]=connection_sk->sk_xid; -+ if (connection_sk->sk_xid != 0) -+ mark = connection_sk->sk_xid; -+ if (connection_sk != (*pskb)->sk) -+ sock_put(connection_sk); -+ } -+ break; -+ } -+ } -+ } -+ -+ if (mark != -1) -+ (*pskb)->mark = mark; -+ return XT_CONTINUE; -+} -+ -+ -+static int -+checkentry_v0(const char *tablename, -+ const void *entry, -+ const struct xt_target *target, -+ void *targinfo, -+ unsigned int hook_mask) -+{ -+ struct xt_mark_target_info *markinfo = targinfo; -+ -+ if (markinfo->mark > 0xffffffff) { -+ printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); -+ return 0; -+ } -+ return 1; -+} -+ -+static int -+checkentry_v1(const char *tablename, -+ const void *entry, -+ const struct xt_target *target, -+ void *targinfo, -+ unsigned int hook_mask) -+{ -+ struct xt_mark_target_info_v1 *markinfo = targinfo; -+ -+ if (markinfo->mode != XT_MARK_SET -+ && markinfo->mode != XT_MARK_AND -+ && markinfo->mode != XT_MARK_OR -+ && markinfo->mode != XT_MARK_COPYXID) { -+ printk(KERN_WARNING "MARK: unknown mode %u\n", -+ markinfo->mode); -+ return 0; -+ } -+ if (markinfo->mark > 0xffffffff) { -+ printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); -+ return 0; -+ } -+ return 1; -+} -+ -+#ifdef CONFIG_COMPAT -+struct compat_xt_mark_target_info_v1 { -+ compat_ulong_t mark; -+ u_int8_t mode; -+ u_int8_t __pad1; -+ u_int16_t __pad2; -+}; -+ -+static void compat_from_user_v1(void *dst, void *src) -+{ -+ struct compat_xt_mark_target_info_v1 *cm = src; -+ struct xt_mark_target_info_v1 m = { -+ .mark = cm->mark, -+ .mode = cm->mode, -+ }; -+ memcpy(dst, &m, sizeof(m)); -+} -+ -+static int compat_to_user_v1(void __user *dst, void *src) -+{ -+ struct xt_mark_target_info_v1 *m = src; -+ struct compat_xt_mark_target_info_v1 cm = { -+ .mark = m->mark, -+ .mode = m->mode, -+ }; -+ return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0; -+} -+#endif /* CONFIG_COMPAT */ -+ -+static struct xt_target xt_mark_target[] = { -+ { -+ .name = "MARK", -+ .family = AF_INET, -+ .revision = 0, -+ .checkentry = checkentry_v0, -+ .target = target_v0, -+ .targetsize = sizeof(struct xt_mark_target_info), -+ .table = "mangle", -+ .me = THIS_MODULE, -+ }, -+ { -+ .name = "MARK", -+ .family = AF_INET, -+ .revision = 1, -+ .checkentry = checkentry_v1, -+ .target = target_v1, -+ .targetsize = sizeof(struct xt_mark_target_info_v1), -+#ifdef CONFIG_COMPAT -+ .compatsize = sizeof(struct compat_xt_mark_target_info_v1), -+ .compat_from_user = compat_from_user_v1, -+ .compat_to_user = compat_to_user_v1, -+#endif -+ .table = "mangle", -+ .me = THIS_MODULE, -+ }, -+ { -+ .name = "MARK", -+ .family = AF_INET6, -+ .revision = 0, -+ .checkentry = checkentry_v0, -+ .target = target_v0, -+ .targetsize = sizeof(struct xt_mark_target_info), -+ .table = "mangle", -+ .me = THIS_MODULE, -+ }, -+}; -+ -+static int __init xt_mark_init(void) -+{ -+ return xt_register_targets(xt_mark_target, ARRAY_SIZE(xt_mark_target)); -+} -+ -+static void __exit xt_mark_fini(void) -+{ -+ xt_unregister_targets(xt_mark_target, ARRAY_SIZE(xt_mark_target)); -+} -+ -+module_init(xt_mark_init); -+module_exit(xt_mark_fini); -diff -Nurb linux-2.6.22-510/net/netfilter/xt_SETXID.c linux-2.6.22-520/net/netfilter/xt_SETXID.c +diff -Nurp linux-2.6.22-510/net/netfilter/xt_SETXID.c linux-2.6.22-520/net/netfilter/xt_SETXID.c --- linux-2.6.22-510/net/netfilter/xt_SETXID.c 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-520/net/netfilter/xt_SETXID.c 2008-03-14 16:29:27.000000000 -0400 ++++ linux-2.6.22-520/net/netfilter/xt_SETXID.c 2007-12-03 15:11:08.000000000 -0500 @@ -0,0 +1,79 @@ +#include +#include @@ -1160,9 +569,9 @@ diff -Nurb linux-2.6.22-510/net/netfilter/xt_SETXID.c linux-2.6.22-520/net/netfi + +module_init(init); +module_exit(fini); -diff -Nurb linux-2.6.22-510/net/packet/af_packet.c linux-2.6.22-520/net/packet/af_packet.c ---- linux-2.6.22-510/net/packet/af_packet.c 2007-07-08 19:32:17.000000000 -0400 -+++ linux-2.6.22-520/net/packet/af_packet.c 2008-03-14 16:29:27.000000000 -0400 +diff -Nurp linux-2.6.22-510/net/packet/af_packet.c linux-2.6.22-520/net/packet/af_packet.c +--- linux-2.6.22-510/net/packet/af_packet.c 2007-07-21 18:00:27.000000000 -0400 ++++ linux-2.6.22-520/net/packet/af_packet.c 2007-12-03 15:11:08.000000000 -0500 @@ -78,6 +78,7 @@ #include #include @@ -1171,17 +580,7 @@ diff -Nurb linux-2.6.22-510/net/packet/af_packet.c linux-2.6.22-520/net/packet/a #ifdef CONFIG_INET #include -@@ -324,6 +325,9 @@ - __be16 proto=0; - int err; - -+ if (!nx_capable(CAP_NET_RAW, NXC_RAW_SEND)) -+ return -EPERM; -+ - /* - * Get and verify the address. - */ -@@ -420,6 +424,10 @@ +@@ -420,6 +421,10 @@ static inline unsigned int run_filter(st unsigned int res) { struct sk_filter *filter; @@ -1192,22 +591,12 @@ diff -Nurb linux-2.6.22-510/net/packet/af_packet.c linux-2.6.22-520/net/packet/a rcu_read_lock_bh(); filter = rcu_dereference(sk->sk_filter); -@@ -711,6 +719,9 @@ - unsigned char *addr; - int ifindex, err, reserve = 0; - -+ if (!nx_capable(CAP_NET_RAW, NXC_RAW_SEND)) -+ return -EPERM; -+ - /* - * Get and verify the address. - */ -@@ -984,7 +995,7 @@ +@@ -984,7 +989,7 @@ static int packet_create(struct socket * __be16 proto = (__force __be16)protocol; /* weird, but documented */ int err; - if (!capable(CAP_NET_RAW)) -+ if (!nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET)) ++ if (!nx_capable(CAP_NET_RAW, NXC_RAW_SEND)) return -EPERM; if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW && sock->type != SOCK_PACKET) diff --git a/linux-2.6-590-trellis-mm1-netns.patch b/linux-2.6-590-trellis-mm1-netns.patch index 0673fafcf..bf6b6a90e 100644 --- a/linux-2.6-590-trellis-mm1-netns.patch +++ b/linux-2.6-590-trellis-mm1-netns.patch @@ -1,6 +1,6 @@ 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 \ @@ -12,7 +12,7 @@ diff -Nurb linux-2.6.22-570/Documentation/DocBook/Makefile linux-2.6.22-590/Docu # 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 @@ + + 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; @@ -330,7 +330,7 @@ diff -Nurb linux-2.6.22-570/Documentation/accounting/getdelays.c linux-2.6.22-59 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. @@ -351,7 +351,7 @@ diff -Nurb linux-2.6.22-570/Documentation/accounting/taskstats-struct.txt linux- } 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() @@ -363,7 +363,7 @@ diff -Nurb linux-2.6.22-570/Documentation/cachetlb.txt linux-2.6.22-590/Document 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 + ------- @@ -910,7 +910,7 @@ diff -Nurb linux-2.6.22-570/Documentation/containers.txt linux-2.6.22-590/Docume + 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 @@ -931,7 +931,7 @@ diff -Nurb linux-2.6.22-570/Documentation/cpuidle/core.txt linux-2.6.22-590/Docu + 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 @@ + + @@ -959,7 +959,7 @@ diff -Nurb linux-2.6.22-570/Documentation/cpuidle/driver.txt linux-2.6.22-590/Do +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 @@ + + @@ -987,7 +987,7 @@ diff -Nurb linux-2.6.22-570/Documentation/cpuidle/governor.txt linux-2.6.22-590/ + 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 @@ + + @@ -1018,7 +1018,7 @@ diff -Nurb linux-2.6.22-570/Documentation/cpuidle/sysfs.txt linux-2.6.22-590/Doc + 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 @@ -1253,7 +1253,7 @@ diff -Nurb linux-2.6.22-570/Documentation/cpusets.txt linux-2.6.22-590/Documenta 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 @@ --------------------------- @@ -1316,7 +1316,7 @@ diff -Nurb linux-2.6.22-570/Documentation/feature-removal-schedule.txt linux-2.6 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 @@ -1328,7 +1328,7 @@ diff -Nurb linux-2.6.22-570/Documentation/filesystems/00-INDEX linux-2.6.22-590/ 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*); @@ -1346,7 +1346,7 @@ diff -Nurb linux-2.6.22-570/Documentation/filesystems/Locking linux-2.6.22-590/D ================================================================================ 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); @@ -1409,7 +1409,7 @@ diff -Nurb linux-2.6.22-570/Documentation/filesystems/configfs/configfs.txt linu 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. @@ -1423,7 +1423,7 @@ diff -Nurb linux-2.6.22-570/Documentation/filesystems/unionfs/00-INDEX linux-2.6 + - 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: +===================== @@ -1502,7 +1502,7 @@ diff -Nurb linux-2.6.22-570/Documentation/filesystems/unionfs/concepts.txt linux +For more information, see . 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: +========================= @@ -1545,7 +1545,7 @@ diff -Nurb linux-2.6.22-570/Documentation/filesystems/unionfs/issues.txt linux-2 +For more information, see . 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. @@ -1580,7 +1580,7 @@ diff -Nurb linux-2.6.22-570/Documentation/filesystems/unionfs/rename.txt linux-2 + 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 @@ -1674,7 +1674,7 @@ diff -Nurb linux-2.6.22-570/Documentation/filesystems/unionfs/usage.txt linux-2. +For more information, see . 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); @@ -1693,7 +1693,7 @@ diff -Nurb linux-2.6.22-570/Documentation/firmware_class/firmware_sample_firmwar 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 , GPL @@ -1901,7 +1901,7 @@ diff -Nurb linux-2.6.22-570/Documentation/power/kernel_threads.txt linux-2.6.22- -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. @@ -1930,7 +1930,7 @@ diff -Nurb linux-2.6.22-570/Documentation/power/swsusp.txt linux-2.6.22-590/Docu 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 + ============================================= @@ -2384,7 +2384,7 @@ diff -Nurb linux-2.6.22-570/Documentation/scsi/scsi_fc_transport.txt linux-2.6.2 + 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 ] @@ -2413,9 +2413,179 @@ diff -Nurb linux-2.6.22-570/Documentation/sysctl/kernel.txt linux-2.6.22-590/Doc 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//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/ and /sys/bus/, 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 :-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 @@ -2468,8 +2638,17 @@ diff -Nurb linux-2.6.22-570/MAINTAINERS linux-2.6.22-590/MAINTAINERS 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 @@ -2482,9 +2661,1506 @@ diff -Nurb linux-2.6.22-570/Makefile linux-2.6.22-590/Makefile 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 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" @@ -2496,7 +4172,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/Kconfig linux-2.6.22-590/arch/arm/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 **** @@ -2510,7 +4186,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/boot/.gitignore.rej linux-2.6.22-590/arch/a ++ 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 @@ -2521,7 +4197,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/kernel/Makefile linux-2.6.22-590/arch/arm/k 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 @@ -2557,7 +4233,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/kernel/kgdb-jmp.S linux-2.6.22-590/arch/arm + 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 @@ -2763,7 +4439,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/kernel/kgdb.c linux-2.6.22-590/arch/arm/ker +}; 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 @@ -2777,8 +4453,8 @@ diff -Nurb linux-2.6.22-570/arch/arm/kernel/setup.c linux-2.6.22-590/arch/arm/ke 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; @@ -2820,7 +4496,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/kernel/traps.c linux-2.6.22-590/arch/arm/ke 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 #include @@ -3084,7 +4760,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/mach-iop13xx/setup.c linux-2.6.22-590/arch/ __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); @@ -3096,7 +4772,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/mach-iop32x/glantank.c linux-2.6.22-590/arc } 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); @@ -3114,7 +4790,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/mach-iop32x/iq31244.c linux-2.6.22-590/arch 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); @@ -3127,7 +4803,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/mach-iop32x/iq80321.c linux-2.6.22-590/arch 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); @@ -3139,7 +4815,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/mach-iop32x/n2100.c linux-2.6.22-590/arch/a 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); @@ -3152,7 +4828,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/mach-iop33x/iq80331.c linux-2.6.22-590/arch 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); @@ -3165,7 +4841,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/mach-iop33x/iq80332.c linux-2.6.22-590/arch 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 #include @@ -3186,7 +4862,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/mach-ixp2000/core.c linux-2.6.22-590/arch/a 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 #include @@ -3209,7 +4885,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/mach-ixp2000/ixdp2x01.c linux-2.6.22-590/ar 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 @@ } @@ -3223,7 +4899,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/mach-ixp4xx/coyote-setup.c linux-2.6.22-590 #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, @@ -3279,7 +4955,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/mach-ixp4xx/ixdp425-setup.c linux-2.6.22-59 .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 #include @@ -3300,7 +4976,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/mach-omap1/serial.c linux-2.6.22-590/arch/a 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 */ @@ -3314,7 +4990,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/mach-pnx4008/core.c linux-2.6.22-590/arch/a 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 @@ -3325,7 +5001,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/mach-pxa/Makefile linux-2.6.22-590/arch/arm 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 @@ -3426,7 +5102,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/mach-pxa/kgdb-serial.c linux-2.6.22-590/arc +}; 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 }, @@ -3444,7 +5120,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/mach-versatile/core.c linux-2.6.22-590/arch .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 */ @@ -3468,7 +5144,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/mm/extable.c linux-2.6.22-590/arch/arm/mm/e } 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 @@ -3487,7 +5163,7 @@ diff -Nurb linux-2.6.22-570/arch/arm/plat-iop/Makefile linux-2.6.22-590/arch/arm 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 @@ -3699,8 +5375,8 @@ diff -Nurb linux-2.6.22-570/arch/arm/plat-iop/adma.c linux-2.6.22-590/arch/arm/p + +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" @@ -3711,8 +5387,8 @@ diff -Nurb linux-2.6.22-570/arch/i386/Kconfig linux-2.6.22-590/arch/i386/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 @@ -3723,7 +5399,7 @@ diff -Nurb linux-2.6.22-570/arch/i386/kernel/Makefile linux-2.6.22-590/arch/i386 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 @@ }, { @@ -3741,7 +5417,7 @@ diff -Nurb linux-2.6.22-570/arch/i386/kernel/acpi/boot.c linux-2.6.22-590/arch/i 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 #include @@ -3759,8 +5435,8 @@ diff -Nurb linux-2.6.22-570/arch/i386/kernel/apm.c linux-2.6.22-590/arch/i386/ke 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)); } @@ -3771,7 +5447,7 @@ diff -Nurb linux-2.6.22-570/arch/i386/kernel/io_apic.c linux-2.6.22-590/arch/i38 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 @@ -3849,7 +5525,7 @@ diff -Nurb linux-2.6.22-570/arch/i386/kernel/kgdb-jmp.S linux-2.6.22-590/arch/i3 + 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 @@ +/* + * @@ -4240,8 +5916,8 @@ diff -Nurb linux-2.6.22-570/arch/i386/kernel/kgdb.c linux-2.6.22-590/arch/i386/k + .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 */ @@ -4259,7 +5935,7 @@ diff -Nurb linux-2.6.22-570/arch/i386/kernel/process.c linux-2.6.22-590/arch/i38 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 @@ -4278,7 +5954,7 @@ diff -Nurb linux-2.6.22-570/arch/i386/kernel/setup.c linux-2.6.22-590/arch/i386/ * 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; @@ -4294,8 +5970,8 @@ diff -Nurb linux-2.6.22-570/arch/i386/kernel/signal.c linux-2.6.22-590/arch/i386 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 @@ -4304,8 +5980,8 @@ diff -Nurb linux-2.6.22-570/arch/i386/kernel/syscall_table.S linux-2.6.22-590/ar + .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; @@ -4472,7 +6148,7 @@ diff -Nurb linux-2.6.22-570/arch/i386/kernel/traps.c linux-2.6.22-590/arch/i386/ +#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 @@ -4512,7 +6188,7 @@ diff -Nurb linux-2.6.22-570/arch/i386/kernel/unwind.S linux-2.6.22-590/arch/i386 +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, }; @@ -4523,8 +6199,8 @@ diff -Nurb linux-2.6.22-570/arch/i386/mach-voyager/voyager_thread.c linux-2.6.22 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; } @@ -4560,9 +6236,22 @@ diff -Nurb linux-2.6.22-570/arch/i386/mm/fault.c linux-2.6.22-590/arch/i386/mm/f /* * 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 @@ -4573,7 +6262,7 @@ diff -Nurb linux-2.6.22-570/arch/ia64/kernel/Makefile linux-2.6.22-590/arch/ia64 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. + @@ -4815,7 +6504,7 @@ diff -Nurb linux-2.6.22-570/arch/ia64/kernel/kgdb-jmp.S linux-2.6.22-590/arch/ia +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 @@ +/* + * @@ -5763,7 +7452,7 @@ diff -Nurb linux-2.6.22-570/arch/ia64/kernel/kgdb.c linux-2.6.22-590/arch/ia64/k +}; 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 #include @@ -5810,8 +7499,8 @@ diff -Nurb linux-2.6.22-570/arch/ia64/kernel/smp.c linux-2.6.22-590/arch/ia64/ke * 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; @@ -5828,7 +7517,7 @@ diff -Nurb linux-2.6.22-570/arch/ia64/kernel/traps.c linux-2.6.22-590/arch/ia64/ 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 @@ */ @@ -5850,8 +7539,8 @@ diff -Nurb linux-2.6.22-570/arch/ia64/mm/extable.c linux-2.6.22-590/arch/ia64/mm } 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); @@ -5864,8 +7553,8 @@ diff -Nurb linux-2.6.22-570/arch/ia64/mm/fault.c linux-2.6.22-590/arch/ia64/mm/f 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 @@ -5957,7 +7646,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/Kconfig linux-2.6.22-590/arch/mips/Kconfig 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. @@ -5989,7 +7678,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/Kconfig.debug linux-2.6.22-590/arch/mips/K 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 @@ -6123,7 +7812,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/au1000/common/dbg_io.c linux-2.6.22-590/ar -#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 @@ -6257,7 +7946,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/basler/excite/excite_dbg_io.c linux-2.6.22 -} 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(); @@ -6281,7 +7970,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/basler/excite/excite_irq.c linux-2.6.22-59 } 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); @@ -6300,7 +7989,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/basler/excite/excite_setup.c linux-2.6.22- * 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 @@ -6448,7 +8137,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/ddb5xxx/ddb5477/kgdb_io.c linux-2.6.22-590 -} 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 @@ # @@ -6582,7 +8271,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/gt64120/momenco_ocelot/dbg_io.c linux-2.6. -} 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 @@ # @@ -6699,7 +8388,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/jmr3927/rbhma3100/kgdb_io.c linux-2.6.22-5 -} 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 @@ -6712,7 +8401,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/kernel/Makefile linux-2.6.22-590/arch/mips 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; @@ -8289,7 +9978,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/kernel/gdb-stub.c linux-2.6.22-590/arch/mi -#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 #include @@ -8344,7 +10033,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/kernel/irq.c linux-2.6.22-590/arch/mips/ke } 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 @@ -8458,7 +10147,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/kernel/kgdb-jmp.c linux-2.6.22-590/arch/mi +#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 @@ -8490,7 +10179,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/kernel/kgdb-setjmp.S linux-2.6.22-590/arch + .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 @@ -8793,7 +10482,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/kernel/kgdb.c linux-2.6.22-590/arch/mips/k +} 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 @@ -9135,8 +10824,8 @@ diff -Nurb linux-2.6.22-570/arch/mips/kernel/kgdb_handler.S linux-2.6.22-590/arc + 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. @@ -9176,7 +10865,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/kernel/traps.c linux-2.6.22-590/arch/mips/ 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 @@ # @@ -9285,7 +10974,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/mips-boards/atlas/atlas_gdb.c linux-2.6.22 -} 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); @@ -9446,7 +11135,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/mips-boards/generic/gdb_hook.c linux-2.6.2 -} 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 @@ -9525,7 +11214,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/mips-boards/generic/init.c linux-2.6.22-59 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); @@ -9550,7 +11239,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/mips-boards/malta/malta_setup.c linux-2.6. 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 @@ -9574,7 +11263,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/mm/extable.c linux-2.6.22-590/arch/mips/mm } 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 \ @@ -9708,7 +11397,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/momentum/ocelot_c/dbg_io.c linux-2.6.22-59 -} 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; @@ -9736,7 +11425,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/pci/fixup-atlas.c linux-2.6.22-590/arch/mi -#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 @@ -9857,7 +11546,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/philips/pnx8550/common/gdb_hook.c linux-2. -} 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; } @@ -9877,7 +11566,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/philips/pnx8550/common/setup.c linux-2.6.2 } 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 @@ -10070,7 +11759,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/pmc-sierra/yosemite/dbg_io.c linux-2.6.22- -} 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 @@ } } @@ -10096,7 +11785,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/pmc-sierra/yosemite/irq.c linux-2.6.22-590 #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); } @@ -10130,7 +11819,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/sgi-ip22/ip22-setup.c linux-2.6.22-590/arc 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 @@ -10203,7 +11892,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/sgi-ip27/ip27-dbgio.c linux-2.6.22-590/arc -} 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 @@ -10312,7 +12001,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/sibyte/bcm1480/irq.c linux-2.6.22-590/arch 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 @@ -10350,7 +12039,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/sibyte/cfe/setup.c linux-2.6.22-590/arch/m 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 @@ -10358,7 +12047,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/sibyte/sb1250/Makefile linux-2.6.22-590/ar +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 #include @@ -10468,7 +12157,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/sibyte/sb1250/irq.c linux-2.6.22-590/arch/ #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 @@ -10616,7 +12305,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/sibyte/sb1250/kgdb_sibyte.c linux-2.6.22-5 +}; 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 - @@ -10703,7 +12392,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/sibyte/swarm/dbg_io.c linux-2.6.22-590/arc - 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 @@ -10762,7 +12451,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/tx4927/common/tx4927_dbgio.c linux-2.6.22- -} 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 #include @@ -10808,7 +12497,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_s 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 @@ # @@ -10871,7 +12560,7 @@ diff -Nurb linux-2.6.22-570/arch/mips/tx4938/common/dbgio.c linux-2.6.22-590/arc - 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 #include @@ -10907,8 +12596,8 @@ diff -Nurb linux-2.6.22-570/arch/mips/tx4938/toshiba_rbtx4938/setup.c linux-2.6. } #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" @@ -11196,7 +12885,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/Kconfig linux-2.6.22-590/arch/powerpc/K 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. @@ -11265,7 +12954,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/Kconfig.debug linux-2.6.22-590/arch/pow 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); @@ -11317,7 +13006,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/boot/44x.c linux-2.6.22-590/arch/powerp +} 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_ @@ -11330,7 +13019,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/boot/44x.h linux-2.6.22-590/arch/powerp #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 \ @@ -11344,7 +13033,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/boot/Makefile linux-2.6.22-590/arch/pow 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" @@ -11379,7 +13068,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/boot/cuboot-83xx.c linux-2.6.22-590/arc 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" @@ -11414,7 +13103,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/boot/cuboot-85xx.c linux-2.6.22-590/arc 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" @@ -11448,7 +13137,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/boot/cuboot-ebony.c linux-2.6.22-590/ar } 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 @@ -11487,7 +13176,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/boot/cuboot.c linux-2.6.22-590/arch/pow +} 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_ @@ -11505,7 +13194,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/boot/cuboot.h linux-2.6.22-590/arch/pow +#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)) @@ -11552,7 +13241,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/boot/dcr.h linux-2.6.22-590/arch/powerp #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>; @@ -11570,7 +13259,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/boot/dts/ebony.dts linux-2.6.22-590/arc 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 { @@ -11707,7 +13396,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/boot/dts/holly.dts linux-2.6.22-590/arc }; 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>; @@ -11796,7 +13485,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/boot/dts/mpc7448hpc2.dts linux-2.6.22-5 #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(); @@ -11830,7 +13519,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/boot/ebony.c linux-2.6.22-590/arch/powe 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" @@ -12076,7 +13765,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/boot/of.c linux-2.6.22-590/arch/powerpc 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_ @@ -12095,7 +13784,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/boot/of.h linux-2.6.22-590/arch/powerpc +#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 @@ -12144,7 +13833,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/boot/ofconsole.c linux-2.6.22-590/arch/ +} 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. @@ -12320,7 +14009,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/boot/oflib.c linux-2.6.22-590/arch/powe +} 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 @@ -12333,7 +14022,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/configs/holly_defconfig linux-2.6.22-59 # 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 \ @@ -12364,7 +14053,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/Makefile linux-2.6.22-590/arch/p 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. @@ -12573,8 +14262,8 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/head_32.S linux-2.6.22-590/arch/ #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 @@ -12585,7 +14274,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/irq.c linux-2.6.22-590/arch/powe * 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 @@ -12860,7 +14549,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/isa-bridge.c linux-2.6.22-590/ar +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 @@ -13363,7 +15052,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/kgdb.c linux-2.6.22-590/arch/pow +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 @@ -13408,7 +15097,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/kgdb_setjmp32.S linux-2.6.22-590 + 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 @@ -13489,7 +15178,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/kgdb_setjmp64.S linux-2.6.22-590 + 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 #include @@ -13511,8 +15200,8 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/legacy_serial.c linux-2.6.22-590 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 @@ -13553,7 +15242,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/misc_32.S linux-2.6.22-590/arch/ 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); @@ -13571,7 +15260,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/of_platform.c linux-2.6.22-590/a 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. */ @@ -14077,8 +15766,8 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/pci_64.c linux-2.6.22-590/arch/p } } 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 */ @@ -14137,7 +15826,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/process.c linux-2.6.22-590/arch/ 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 @@ -14323,7 +16012,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/ptrace-common.h linux-2.6.22-590 -#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 #include @@ -14817,7 +16506,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/ptrace.c linux-2.6.22-590/arch/p 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 #include @@ -15137,7 +16826,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/ptrace32.c linux-2.6.22-590/arch 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; @@ -15170,7 +16859,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/rtas_pci.c linux-2.6.22-590/arch __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...) @@ -15217,7 +16906,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/setup_32.c linux-2.6.22-590/arch 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 @@ -15401,7 +17090,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/signal.c linux-2.6.22-590/arch/p +} 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 @@ -15460,7 +17149,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/signal.h linux-2.6.22-590/arch/p +#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 #endif @@ -15749,7 +17438,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/signal_32.c linux-2.6.22-590/arc -} 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 #include @@ -15987,8 +17676,8 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/signal_64.c linux-2.6.22-590/arc -} -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); } @@ -16004,8 +17693,8 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/sys_ppc32.c linux-2.6.22-590/arc 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 @@ -16017,7 +17706,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/kernel/vdso.c linux-2.6.22-590/arch/pow 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) @@ -16028,7 +17717,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/mm/44x_mmu.c linux-2.6.22-590/arch/powe * 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) @@ -16039,7 +17728,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/mm/4xx_mmu.c linux-2.6.22-590/arch/powe * 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 \ @@ -16051,8 +17740,8 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/mm/Makefile linux-2.6.22-590/arch/power 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 #include @@ -16086,7 +17775,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/mm/fault.c linux-2.6.22-590/arch/powerp 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) @@ -16097,7 +17786,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/mm/fsl_booke_mmu.c linux-2.6.22-590/arc * 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); } @@ -16216,7 +17905,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/mm/hash_native_64.c linux-2.6.22-590/ar 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]; @@ -16545,7 +18234,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/mm/imalloc.c linux-2.6.22-590/arch/powe -} 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) @@ -16556,7 +18245,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/mm/init_32.c linux-2.6.22-590/arch/powe * 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) @@ -16567,7 +18256,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/mm/init_64.c linux-2.6.22-590/arch/powe * 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) @@ -16578,7 +18267,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/mm/mem.c linux-2.6.22-590/arch/powerpc/ * 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) @@ -16589,7 +18278,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/mm/mmu_context_32.c linux-2.6.22-590/ar * 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) @@ -16628,7 +18317,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/mm/mmu_decl.h linux-2.6.22-590/arch/pow #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) @@ -16782,7 +18471,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/mm/pgtable_32.c linux-2.6.22-590/arch/p 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) @@ -17099,7 +18788,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/mm/pgtable_64.c linux-2.6.22-590/arch/p -} 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) @@ -17134,7 +18823,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/mm/ppc_mmu_32.c linux-2.6.22-590/arch/p 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) @@ -17145,7 +18834,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/mm/tlb_32.c linux-2.6.22-590/arch/power * 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) @@ -17216,7 +18905,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/mm/tlb_64.c linux-2.6.22-590/arch/power +#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) @@ -17233,7 +18922,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/Kconfig linux-2.6.22-590/arch 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" @@ -17623,7 +19312,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/apus/Kconfig linux-2.6.22-590 - 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); @@ -17635,7 +19324,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/cell/io-workarounds.c linux-2 /* 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 #include @@ -17700,7 +19389,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/cell/spufs/file.c linux-2.6.2 { "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); @@ -17742,7 +19431,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/cell/spufs/run.c linux-2.6.22 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; } @@ -17775,7 +19464,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/iseries/call_hpt.h linux-2.6. } 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) { @@ -17814,7 +19503,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/iseries/htab.c linux-2.6.22-5 /* 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; @@ -17829,7 +19518,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/iseries/pci.c linux-2.6.22-59 "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"); } @@ -17881,7 +19570,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/maple/pci.c linux-2.6.22-590/ 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"); @@ -17923,7 +19612,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/pasemi/pci.c linux-2.6.22-590 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 */ } @@ -17972,7 +19661,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/powermac/pci.c linux-2.6.22-5 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 @@ -17995,7 +19684,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/powermac/setup.c linux-2.6.22 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 @@ -18045,7 +19734,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/ps3/htab.c linux-2.6.22-590/a 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 @@ -18057,7 +19746,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/pseries/Makefile linux-2.6.22 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 @@ -18158,7 +19847,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/pseries/eeh.c linux-2.6.22-59 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 @@ -18180,7 +19869,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/pseries/eeh_cache.c linux-2.6 #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. @@ -18202,7 +19891,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/pseries/eeh_driver.c linux-2. #include 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. @@ -18293,7 +19982,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/pseries/eeh_sysfs.c linux-2.6 + 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 @@ } } @@ -18347,7 +20036,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/pseries/pci_dlpar.c linux-2.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 @@ -18359,7 +20048,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/pseries/pseries.h linux-2.6.2 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. */ @@ -18378,7 +20067,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/platforms/pseries/setup.c linux-2.6.22- 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; @@ -18444,7 +20133,7 @@ diff -Nurb linux-2.6.22-570/arch/powerpc/sysdev/tsi108_dev.c linux-2.6.22-590/ar 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 { @@ -18459,7 +20148,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/8260_io/enet.c linux-2.6.22-590/arch/ppc/82 } 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 { @@ -18474,7 +20163,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/8260_io/fcc_enet.c linux-2.6.22-590/arch/pp } 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 { @@ -18489,7 +20178,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/8xx_io/enet.c linux-2.6.22-590/arch/ppc/8xx } 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 { @@ -18501,7 +20190,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/8xx_io/fec.c linux-2.6.22-590/arch/ppc/8xx_ } 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" @@ -18547,7 +20236,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/Kconfig.debug linux-2.6.22-590/arch/ppc/Kco 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) @@ -18568,7 +20257,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/amiga/config.c linux-2.6.22-590/arch/ppc/am #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 @@ -18580,7 +20269,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/kernel/Makefile linux-2.6.22-590/arch/ppc/k 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 @@ -18932,7 +20621,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/kernel/kgdb.c linux-2.6.22-590/arch/ppc/ker +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 @@ -18976,8 +20665,8 @@ diff -Nurb linux-2.6.22-570/arch/ppc/kernel/kgdb_setjmp32.S linux-2.6.22-590/arc + 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 @@ -19886,7 +21575,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/kernel/ppc-stub.c linux-2.6.22-590/arch/ppc -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 #endif @@ -19925,8 +21614,8 @@ diff -Nurb linux-2.6.22-570/arch/ppc/kernel/setup.c linux-2.6.22-590/arch/ppc/ke 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 #include @@ -19952,7 +21641,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/mm/fault.c linux-2.6.22-590/arch/ppc/mm/fau 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 #include @@ -20028,7 +21717,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/4xx/bamboo.c linux-2.6.22-590/arc 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 @@ -20096,7 +21785,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/4xx/bubinga.c linux-2.6.22-590/ar - 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 #include @@ -20162,7 +21851,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/4xx/ebony.c linux-2.6.22-590/arch - 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 #include @@ -20211,7 +21900,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/4xx/luan.c linux-2.6.22-590/arch/ } 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 #include @@ -20277,7 +21966,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/4xx/ocotea.c linux-2.6.22-590/arc } 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"); @@ -20308,7 +21997,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/4xx/taishan.c linux-2.6.22-590/ar 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 #include @@ -20330,7 +22019,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/4xx/xilinx_ml300.c linux-2.6.22-5 * 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 @@ -20343,7 +22032,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/4xx/xilinx_ml403.c linux-2.6.22-5 * 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() */ @@ -20354,7 +22043,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/4xx/yucca.c linux-2.6.22-590/arch } 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 #include @@ -20388,7 +22077,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/83xx/mpc834x_sys.c linux-2.6.22-5 #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 #include @@ -20423,7 +22112,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/85xx/mpc8540_ads.c linux-2.6.22-5 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 #include @@ -20434,7 +22123,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/85xx/mpc8560_ads.c linux-2.6.22-5 #include 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 #include @@ -20470,7 +22159,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/85xx/mpc85xx_cds_common.c linux-2 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 #include @@ -20562,7 +22251,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/85xx/sbc8560.c linux-2.6.22-590/a 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 #include @@ -20600,7 +22289,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/85xx/tqm85xx.c linux-2.6.22-590/a 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 */ @@ -20616,7 +22305,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/apus_setup.c linux-2.6.22-590/arc 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 #include @@ -20649,7 +22338,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/chestnut.c linux-2.6.22-590/arch/ 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; @@ -20691,7 +22380,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/ev64260.c linux-2.6.22-590/arch/p 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) @@ -20720,7 +22409,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/hdpu.c linux-2.6.22-590/arch/ppc/ 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 #include @@ -20733,7 +22422,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/lopec.c linux-2.6.22-590/arch/ppc * 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 #include @@ -20757,7 +22446,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/pplus.c linux-2.6.22-590/arch/ppc #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 *****************************************************************************/ @@ -20803,7 +22492,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/radstone_ppc7d.c linux-2.6.22-590 * 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 #include @@ -20827,7 +22516,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/sandpoint.c linux-2.6.22-590/arch #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 #include @@ -20896,7 +22585,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/platforms/spruce.c linux-2.6.22-590/arch/pp } 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 @@ -20907,7 +22596,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/syslib/Makefile linux-2.6.22-590/arch/ppc/s 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); @@ -21002,7 +22691,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/syslib/gen550_kgdb.c linux-2.6.22-590/arch/ -} 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; @@ -21015,7 +22704,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/syslib/ibm44x_common.c linux-2.6.22-590/arc * 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, @@ -21113,7 +22802,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/syslib/mv64x60.c linux-2.6.22-590/arch/ppc/ .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) @@ -21179,7 +22868,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/syslib/mv64x60_dbg.c linux-2.6.22-590/arch/ -#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 #include @@ -21190,7 +22879,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/syslib/ppc4xx_setup.c linux-2.6.22-590/arch #include 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 /* for linux/serial_core.h */ #include @@ -21272,7 +22961,7 @@ diff -Nurb linux-2.6.22-570/arch/ppc/syslib/ppc83xx_setup.c linux-2.6.22-590/arc 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 /* for linux/serial_core.h */ #include @@ -21355,9 +23044,29 @@ diff -Nurb linux-2.6.22-570/arch/ppc/syslib/ppc85xx_setup.c linux-2.6.22-590/arc #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 + #include + #include ++#include + + #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", @@ -21376,7 +23085,7 @@ diff -Nurb linux-2.6.22-570/arch/s390/kernel/ipl.c linux-2.6.22-590/arch/s390/ke .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. @@ -21462,7 +23171,7 @@ diff -Nurb linux-2.6.22-570/arch/sh/Kconfig.debug linux-2.6.22-590/arch/sh/Kconf 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 @@ -21474,7 +23183,7 @@ diff -Nurb linux-2.6.22-570/arch/sh/kernel/Makefile linux-2.6.22-590/arch/sh/ker 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*/ @@ -21486,7 +23195,7 @@ diff -Nurb linux-2.6.22-570/arch/sh/kernel/cpu/sh3/ex.S linux-2.6.22-590/arch/sh .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 + @@ -21522,7 +23231,7 @@ diff -Nurb linux-2.6.22-570/arch/sh/kernel/kgdb-jmp.S linux-2.6.22-590/arch/sh/k + 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 @@ -23023,7 +24732,7 @@ diff -Nurb linux-2.6.22-570/arch/sh/kernel/kgdb_stub.c linux-2.6.22-590/arch/sh/ -#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); @@ -23038,7 +24747,7 @@ diff -Nurb linux-2.6.22-570/arch/sh/kernel/time.c linux-2.6.22-590/arch/sh/kerne } 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 #include @@ -23094,7 +24803,7 @@ diff -Nurb linux-2.6.22-570/arch/sh/kernel/traps.c linux-2.6.22-590/arch/sh/kern } 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 @@ */ @@ -23118,7 +24827,7 @@ diff -Nurb linux-2.6.22-570/arch/sh/mm/extable.c linux-2.6.22-590/arch/sh/mm/ext } 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 #include @@ -23155,8 +24864,8 @@ diff -Nurb linux-2.6.22-570/arch/sh/mm/fault-nommu.c linux-2.6.22-590/arch/sh/mm 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 #include @@ -23199,7 +24908,7 @@ diff -Nurb linux-2.6.22-570/arch/sh/mm/fault.c linux-2.6.22-590/arch/sh/mm/fault * 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 #include @@ -23274,9 +24983,29 @@ diff -Nurb linux-2.6.22-570/arch/sparc64/kernel/power.c linux-2.6.22-590/arch/sp 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 + + #include ++#include + + #include + #include +@@ -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. @@ -23293,15 +25022,15 @@ diff -Nurb linux-2.6.22-570/arch/um/Kconfig.debug linux-2.6.22-590/arch/um/Kconf 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" @@ -23313,7 +25042,7 @@ diff -Nurb linux-2.6.22-570/arch/x86_64/Kconfig linux-2.6.22-590/arch/x86_64/Kco 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. @@ -23323,8 +25052,8 @@ diff -Nurb linux-2.6.22-570/arch/x86_64/Kconfig.debug linux-2.6.22-590/arch/x86_ - 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 @@ -23336,8 +25065,8 @@ diff -Nurb linux-2.6.22-570/arch/x86_64/Makefile linux-2.6.22-590/arch/x86_64/Ma # -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 @@ -23347,8 +25076,8 @@ diff -Nurb linux-2.6.22-570/arch/x86_64/ia32/ia32entry.S linux-2.6.22-590/arch/x + .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 @@ -23364,7 +25093,7 @@ diff -Nurb linux-2.6.22-570/arch/x86_64/kernel/Makefile linux-2.6.22-590/arch/x8 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 @@ -23433,7 +25162,7 @@ diff -Nurb linux-2.6.22-570/arch/x86_64/kernel/kgdb-jmp.S linux-2.6.22-590/arch/ + 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 @@ +/* + * @@ -23898,7 +25627,7 @@ diff -Nurb linux-2.6.22-570/arch/x86_64/kernel/kgdb.c linux-2.6.22-590/arch/x86_ +}; 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. */ @@ -23910,7 +25639,7 @@ diff -Nurb linux-2.6.22-570/arch/x86_64/kernel/mce.c linux-2.6.22-590/arch/x86_6 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) { @@ -23921,8 +25650,8 @@ diff -Nurb linux-2.6.22-570/arch/x86_64/kernel/signal.c linux-2.6.22-590/arch/x8 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 @@ } @@ -24062,7 +25791,7 @@ diff -Nurb linux-2.6.22-570/arch/x86_64/kernel/traps.c linux-2.6.22-590/arch/x86 +#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 @@ -24104,7 +25833,7 @@ diff -Nurb linux-2.6.22-570/arch/x86_64/kernel/unwind.S linux-2.6.22-590/arch/x8 + 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/ : { @@ -24116,8 +25845,8 @@ diff -Nurb linux-2.6.22-570/arch/x86_64/kernel/vmlinux.lds.S linux-2.6.22-590/ar 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; } @@ -24156,8 +25885,8 @@ diff -Nurb linux-2.6.22-570/arch/x86_64/mm/fault.c linux-2.6.22-590/arch/x86_64/ * 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)); } @@ -24200,9 +25929,25 @@ diff -Nurb linux-2.6.22-570/arch/x86_64/mm/init.c linux-2.6.22-590/arch/x86_64/m /* 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 @@ -24224,7 +25969,7 @@ diff -Nurb linux-2.6.22-570/crypto/Kconfig linux-2.6.22-590/crypto/Kconfig 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 @@ -24237,7 +25982,7 @@ diff -Nurb linux-2.6.22-570/crypto/Makefile linux-2.6.22-590/crypto/Makefile +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 @@ -24257,7 +26002,7 @@ diff -Nurb linux-2.6.22-570/crypto/async_tx/Kconfig linux-2.6.22-590/crypto/asyn + 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 @@ -24265,7 +26010,7 @@ diff -Nurb linux-2.6.22-570/crypto/async_tx/Makefile linux-2.6.22-590/crypto/asy +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 @@ -24400,7 +26145,7 @@ diff -Nurb linux-2.6.22-570/crypto/async_tx/async_memcpy.c linux-2.6.22-590/cryp +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 @@ -24513,7 +26258,7 @@ diff -Nurb linux-2.6.22-570/crypto/async_tx/async_memset.c linux-2.6.22-590/cryp +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 @@ -25014,7 +26759,7 @@ diff -Nurb linux-2.6.22-570/crypto/async_tx/async_tx.c linux-2.6.22-590/crypto/a +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 @@ -25345,7 +27090,7 @@ diff -Nurb linux-2.6.22-570/crypto/async_tx/async_xor.c linux-2.6.22-590/crypto/ +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 @@ -25504,7 +27249,7 @@ diff -Nurb linux-2.6.22-570/crypto/xor.c linux-2.6.22-590/crypto/xor.c +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/ @@ -25515,7 +27260,7 @@ diff -Nurb linux-2.6.22-570/drivers/Makefile linux-2.6.22-590/drivers/Makefile 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 @@ -25542,7 +27287,7 @@ diff -Nurb linux-2.6.22-570/drivers/acpi/Kconfig linux-2.6.22-590/drivers/acpi/K 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" @@ -26597,7 +28342,7 @@ diff -Nurb linux-2.6.22-570/drivers/acpi/battery.c linux-2.6.22-590/drivers/acpi 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); @@ -26634,8 +28379,8 @@ diff -Nurb linux-2.6.22-570/drivers/acpi/bay.c linux-2.6.22-590/drivers/acpi/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"); @@ -26763,7 +28508,7 @@ diff -Nurb linux-2.6.22-570/drivers/acpi/dock.c linux-2.6.22-590/drivers/acpi/do * @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 #include @@ -27192,7 +28937,7 @@ diff -Nurb linux-2.6.22-570/drivers/acpi/ec.c linux-2.6.22-590/drivers/acpi/ec.c 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]; @@ -27290,8 +29035,8 @@ diff -Nurb linux-2.6.22-570/drivers/acpi/osl.c linux-2.6.22-590/drivers/acpi/osl }; #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 #include @@ -27344,8 +29089,8 @@ diff -Nurb linux-2.6.22-570/drivers/acpi/processor_core.c linux-2.6.22-590/drive 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 /* need_resched() */ #include @@ -27983,7 +29728,7 @@ diff -Nurb linux-2.6.22-570/drivers/acpi/processor_idle.c linux-2.6.22-590/drive +}; 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"); @@ -28475,7 +30220,7 @@ diff -Nurb linux-2.6.22-570/drivers/acpi/processor_throttling.c linux-2.6.22-590 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", @@ -28568,7 +30313,7 @@ diff -Nurb linux-2.6.22-570/drivers/acpi/sbs.c linux-2.6.22-590/drivers/acpi/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" @@ -28813,7 +30558,7 @@ diff -Nurb linux-2.6.22-570/drivers/acpi/system.c linux-2.6.22-590/drivers/acpi/ 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 #include @@ -28876,7 +30621,7 @@ diff -Nurb linux-2.6.22-570/drivers/acpi/thermal.c linux-2.6.22-590/drivers/acpi 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 */ @@ -28903,7 +30648,7 @@ diff -Nurb linux-2.6.22-570/drivers/acpi/utilities/uteval.c linux-2.6.22-590/dri 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 @@ -28960,7 +30705,50 @@ diff -Nurb linux-2.6.22-570/drivers/acpi/video.c linux-2.6.22-590/drivers/acpi/v /* -------------------------------------------------------------------------- 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); } @@ -28978,7 +30766,7 @@ diff -Nurb linux-2.6.22-570/drivers/acpi/video.c linux-2.6.22-590/drivers/acpi/v return; } -@@ -1669,6 +1708,7 @@ +@@ -1669,6 +1712,7 @@ ACPI_DEVICE_NOTIFY, acpi_video_device_notify); backlight_device_unregister(device->backlight); @@ -28986,9 +30774,21 @@ diff -Nurb linux-2.6.22-570/drivers/acpi/video.c linux-2.6.22-590/drivers/acpi/v 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: + */ + 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"; @@ -29007,8 +30807,53 @@ diff -Nurb linux-2.6.22-570/drivers/base/bus.c linux-2.6.22-590/drivers/base/bus 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); @@ -29018,7 +30863,7 @@ diff -Nurb linux-2.6.22-570/drivers/base/class.c linux-2.6.22-590/drivers/base/c 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); } @@ -29028,7 +30873,7 @@ diff -Nurb linux-2.6.22-570/drivers/base/class.c linux-2.6.22-590/drivers/base/c 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; } @@ -29038,7 +30883,7 @@ diff -Nurb linux-2.6.22-570/drivers/base/class.c linux-2.6.22-590/drivers/base/c 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; @@ -29077,7 +30922,7 @@ diff -Nurb linux-2.6.22-570/drivers/base/class.c linux-2.6.22-590/drivers/base/c 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: @@ -29091,7 +30936,7 @@ diff -Nurb linux-2.6.22-570/drivers/base/class.c linux-2.6.22-590/drivers/base/c 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"); @@ -29106,7 +30951,7 @@ diff -Nurb linux-2.6.22-570/drivers/base/class.c linux-2.6.22-590/drivers/base/c 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; } @@ -29127,7 +30972,23 @@ diff -Nurb linux-2.6.22-570/drivers/base/core.c linux-2.6.22-590/drivers/base/co /* * 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; } @@ -29145,12 +31006,12 @@ diff -Nurb linux-2.6.22-570/drivers/base/core.c linux-2.6.22-590/drivers/base/co + * 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, @@ -29178,6 +31039,7 @@ diff -Nurb linux-2.6.22-570/drivers/base/core.c linux-2.6.22-590/drivers/base/co + 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"); @@ -29201,6 +31063,7 @@ diff -Nurb linux-2.6.22-570/drivers/base/core.c linux-2.6.22-590/drivers/base/co +#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"); +} @@ -29208,7 +31071,7 @@ diff -Nurb linux-2.6.22-570/drivers/base/core.c linux-2.6.22-590/drivers/base/co /** * 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; @@ -29216,7 +31079,7 @@ diff -Nurb linux-2.6.22-570/drivers/base/core.c linux-2.6.22-590/drivers/base/co 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); @@ -29280,7 +31143,7 @@ diff -Nurb linux-2.6.22-570/drivers/base/core.c linux-2.6.22-590/drivers/base/co 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: @@ -29288,7 +31151,7 @@ diff -Nurb linux-2.6.22-570/drivers/base/core.c linux-2.6.22-590/drivers/base/co put_device(dev); return error; BusError: -@@ -767,10 +804,10 @@ +@@ -767,10 +812,10 @@ BUS_NOTIFY_DEL_DEVICE, dev); device_remove_attrs(dev); AttrsError: @@ -29303,7 +31166,7 @@ diff -Nurb linux-2.6.22-570/drivers/base/core.c linux-2.6.22-590/drivers/base/co if (dev->class) { sysfs_remove_link(&dev->kobj, "subsystem"); -@@ -792,7 +829,7 @@ +@@ -792,7 +837,7 @@ } } ueventattrError: @@ -29312,7 +31175,7 @@ diff -Nurb linux-2.6.22-570/drivers/base/core.c linux-2.6.22-590/drivers/base/co 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); @@ -29325,7 +31188,16 @@ diff -Nurb linux-2.6.22-570/drivers/base/core.c linux-2.6.22-590/drivers/base/co 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); } } @@ -29334,7 +31206,7 @@ diff -Nurb linux-2.6.22-570/drivers/base/core.c linux-2.6.22-590/drivers/base/co 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; @@ -29343,7 +31215,7 @@ diff -Nurb linux-2.6.22-570/drivers/base/core.c linux-2.6.22-590/drivers/base/co 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 @@ -29362,6 +31234,13 @@ diff -Nurb linux-2.6.22-570/drivers/base/core.c linux-2.6.22-590/drivers/base/co + 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); @@ -29370,32 +31249,29 @@ diff -Nurb linux-2.6.22-570/drivers/base/core.c linux-2.6.22-590/drivers/base/co #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); @@ -29407,9 +31283,23 @@ diff -Nurb linux-2.6.22-570/drivers/base/core.c linux-2.6.22-590/drivers/base/co 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); @@ -29439,7 +31329,7 @@ diff -Nurb linux-2.6.22-570/drivers/base/firmware_class.c linux-2.6.22-590/drive .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; @@ -29449,9 +31339,50 @@ diff -Nurb linux-2.6.22-570/drivers/block/acsi_slm.c linux-2.6.22-590/drivers/bl 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 + #include + #include ++#include + #include + #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 + #include + #include ++#include + #include + #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; @@ -29554,8 +31485,8 @@ diff -Nurb linux-2.6.22-570/drivers/block/cciss_scsi.c linux-2.6.22-590/drivers/ } 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 #include @@ -29580,7 +31511,7 @@ diff -Nurb linux-2.6.22-570/drivers/block/loop.c linux-2.6.22-590/drivers/block/ 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 @@ **********************************************************/ @@ -29601,7 +31532,7 @@ diff -Nurb linux-2.6.22-570/drivers/block/pktcdvd.c linux-2.6.22-590/drivers/blo 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 #include @@ -29648,7 +31579,7 @@ diff -Nurb linux-2.6.22-570/drivers/char/apm-emulation.c linux-2.6.22-590/driver #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. @@ -29665,7 +31596,7 @@ diff -Nurb linux-2.6.22-570/drivers/char/hvc_console.c linux-2.6.22-590/drivers/ 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; @@ -29721,7 +31652,7 @@ diff -Nurb linux-2.6.22-570/drivers/char/ipmi/ipmi_msghandler.c linux-2.6.22-590 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) { @@ -29730,9 +31661,21 @@ diff -Nurb linux-2.6.22-570/drivers/char/keyboard.c linux-2.6.22-590/drivers/cha 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) \ @@ -29745,7 +31688,7 @@ diff -Nurb linux-2.6.22-570/drivers/cpufreq/cpufreq_stats.c linux-2.6.22-590/dri 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 = @@ -29757,7 +31700,7 @@ diff -Nurb linux-2.6.22-570/drivers/cpufreq/cpufreq_userspace.c linux-2.6.22-590 }; 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", @@ -29768,7 +31711,7 @@ diff -Nurb linux-2.6.22-570/drivers/cpufreq/freq_table.c linux-2.6.22-590/driver }; 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" + @@ -29811,7 +31754,7 @@ diff -Nurb linux-2.6.22-570/drivers/cpuidle/Kconfig linux-2.6.22-590/drivers/cpu +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. @@ -29820,8 +31763,8 @@ diff -Nurb linux-2.6.22-570/drivers/cpuidle/Makefile linux-2.6.22-590/drivers/cp +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 + * @@ -29849,7 +31792,6 @@ diff -Nurb linux-2.6.22-570/drivers/cpuidle/cpuidle.c linux-2.6.22-590/drivers/c +LIST_HEAD(cpuidle_detected_devices); +static void (*pm_idle_old)(void); + -+ +/** + * cpuidle_idle_call - the main idle loop + * @@ -30131,7 +32073,7 @@ diff -Nurb linux-2.6.22-570/drivers/cpuidle/cpuidle.c linux-2.6.22-590/drivers/c +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 @@ -30185,7 +32127,7 @@ diff -Nurb linux-2.6.22-570/drivers/cpuidle/cpuidle.h linux-2.6.22-590/drivers/c +#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 @@ -30465,7 +32407,7 @@ diff -Nurb linux-2.6.22-570/drivers/cpuidle/driver.c linux-2.6.22-590/drivers/cp + 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 @@ -30629,7 +32571,7 @@ diff -Nurb linux-2.6.22-570/drivers/cpuidle/governor.c linux-2.6.22-590/drivers/ +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. @@ -30639,7 +32581,7 @@ diff -Nurb linux-2.6.22-570/drivers/cpuidle/governors/Makefile linux-2.6.22-590/ +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 @@ -30870,7 +32812,7 @@ diff -Nurb linux-2.6.22-570/drivers/cpuidle/governors/ladder.c linux-2.6.22-590/ +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 @@ -31026,8 +32968,8 @@ diff -Nurb linux-2.6.22-570/drivers/cpuidle/governors/menu.c linux-2.6.22-590/dr +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 + * @@ -31043,6 +32985,14 @@ diff -Nurb linux-2.6.22-570/drivers/cpuidle/sysfs.c linux-2.6.22-590/drivers/cpu + +#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; @@ -31157,6 +33107,15 @@ diff -Nurb linux-2.6.22-570/drivers/cpuidle/sysfs.c linux-2.6.22-590/drivers/cpu + 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, @@ -31164,7 +33123,7 @@ diff -Nurb linux-2.6.22-570/drivers/cpuidle/sysfs.c linux-2.6.22-590/drivers/cpu +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, @@ -31182,6 +33141,9 @@ diff -Nurb linux-2.6.22-570/drivers/cpuidle/sysfs.c linux-2.6.22-590/drivers/cpu + */ +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); +} + @@ -31331,7 +33293,7 @@ diff -Nurb linux-2.6.22-570/drivers/cpuidle/sysfs.c linux-2.6.22-590/drivers/cpu + */ +int cpuidle_add_driver_sysfs(struct cpuidle_device *device) +{ -+ int i, ret; ++ int i, ret = -ENOMEM; + struct cpuidle_state_kobj *kobj; + + /* state statistics */ @@ -31403,7 +33365,7 @@ diff -Nurb linux-2.6.22-570/drivers/cpuidle/sysfs.c linux-2.6.22-590/drivers/cpu +} 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" @@ -31429,7 +33391,7 @@ diff -Nurb linux-2.6.22-570/drivers/dma/Kconfig linux-2.6.22-590/drivers/dma/Kco 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 @@ -31437,7 +33399,7 @@ diff -Nurb linux-2.6.22-570/drivers/dma/Makefile linux-2.6.22-590/drivers/dma/Ma +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. @@ -32000,7 +33962,7 @@ diff -Nurb linux-2.6.22-570/drivers/dma/dmaengine.c linux-2.6.22-590/drivers/dma 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) @@ -32408,7 +34370,7 @@ diff -Nurb linux-2.6.22-570/drivers/dma/ioatdma.c linux-2.6.22-590/drivers/dma/i 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 @@ -32448,7 +34410,7 @@ diff -Nurb linux-2.6.22-570/drivers/dma/ioatdma.h linux-2.6.22-590/drivers/dma/i - 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 @@ -33917,7 +35879,7 @@ diff -Nurb linux-2.6.22-570/drivers/dma/iop-adma.c linux-2.6.22-590/drivers/dma/ +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) @@ -33928,7 +35890,7 @@ diff -Nurb linux-2.6.22-570/drivers/edac/edac_mc.c linux-2.6.22-590/drivers/edac 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; } @@ -33955,7 +35917,7 @@ diff -Nurb linux-2.6.22-570/drivers/firmware/dcdbas.c linux-2.6.22-590/drivers/f 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 = { \ @@ -33968,7 +35930,7 @@ diff -Nurb linux-2.6.22-570/drivers/firmware/dcdbas.h linux-2.6.22-590/drivers/f } 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; } @@ -34053,7 +36015,7 @@ diff -Nurb linux-2.6.22-570/drivers/firmware/dell_rbu.c linux-2.6.22-590/drivers }; 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) \ @@ -34065,7 +36027,7 @@ diff -Nurb linux-2.6.22-570/drivers/firmware/edd.c linux-2.6.22-590/drivers/firm }; 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) \ @@ -34092,8 +36054,8 @@ diff -Nurb linux-2.6.22-570/drivers/firmware/efivars.c linux-2.6.22-590/drivers/ .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); } @@ -34114,7 +36076,7 @@ diff -Nurb linux-2.6.22-570/drivers/i2c/chips/eeprom.c linux-2.6.22-590/drivers/ .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); } @@ -34136,8 +36098,8 @@ diff -Nurb linux-2.6.22-570/drivers/i2c/chips/max6875.c linux-2.6.22-590/drivers .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 #include @@ -34157,7 +36119,7 @@ diff -Nurb linux-2.6.22-570/drivers/ieee1394/ieee1394_core.c linux-2.6.22-590/dr 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; @@ -34167,8 +36129,8 @@ diff -Nurb linux-2.6.22-570/drivers/ieee1394/nodemgr.c linux-2.6.22-590/drivers/ 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 @@ } } @@ -34273,9 +36235,94 @@ diff -Nurb linux-2.6.22-570/drivers/ieee1394/sbp2.c linux-2.6.22-590/drivers/iee 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; @@ -34286,7 +36333,7 @@ diff -Nurb linux-2.6.22-570/drivers/infiniband/core/sysfs.c linux-2.6.22-590/dri 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; @@ -34380,7 +36427,7 @@ diff -Nurb linux-2.6.22-570/drivers/infiniband/ulp/iser/iscsi_iser.c linux-2.6.2 .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) */ @@ -34401,7 +36448,7 @@ diff -Nurb linux-2.6.22-570/drivers/infiniband/ulp/iser/iscsi_iser.h linux-2.6.2 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]; @@ -34427,7 +36474,7 @@ diff -Nurb linux-2.6.22-570/drivers/infiniband/ulp/iser/iser_initiator.c linux-2 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 * @@ -34441,7 +36488,7 @@ diff -Nurb linux-2.6.22-570/drivers/infiniband/ulp/iser/iser_verbs.c linux-2.6.2 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) @@ -34589,7 +36636,7 @@ diff -Nurb linux-2.6.22-570/drivers/infiniband/ulp/srp/ib_srp.c linux-2.6.22-590 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; @@ -34604,7 +36651,7 @@ diff -Nurb linux-2.6.22-570/drivers/infiniband/ulp/srp/ib_srp.h linux-2.6.22-590 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) @@ -34615,7 +36662,7 @@ diff -Nurb linux-2.6.22-570/drivers/input/gameport/gameport.c linux-2.6.22-590/d 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), \ @@ -34626,7 +36673,7 @@ diff -Nurb linux-2.6.22-570/drivers/input/mouse/psmouse.h linux-2.6.22-590/drive .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) @@ -34637,7 +36684,7 @@ diff -Nurb linux-2.6.22-570/drivers/input/serio/serio.c linux-2.6.22-590/drivers 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); @@ -34646,9 +36693,92 @@ diff -Nurb linux-2.6.22-570/drivers/input/touchscreen/ucb1400_ts.c linux-2.6.22- 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 + #endif + #include ++#include + #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 + #include + #include ++#include + + #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; @@ -34659,7 +36789,7 @@ diff -Nurb linux-2.6.22-570/drivers/macintosh/therm_adt746x.c linux-2.6.22-590/d 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 }; @@ -34672,7 +36802,7 @@ diff -Nurb linux-2.6.22-570/drivers/macintosh/therm_pm72.c linux-2.6.22-590/driv 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 }; @@ -34709,7 +36839,7 @@ diff -Nurb linux-2.6.22-570/drivers/macintosh/windfarm_core.c linux-2.6.22-590/d 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" @@ -34733,7 +36863,7 @@ diff -Nurb linux-2.6.22-570/drivers/md/Kconfig linux-2.6.22-590/drivers/md/Kconf 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 @@ -34765,7 +36895,7 @@ diff -Nurb linux-2.6.22-570/drivers/md/Makefile linux-2.6.22-590/drivers/md/Make $(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) @@ -34872,7 +37002,7 @@ diff -Nurb linux-2.6.22-570/drivers/md/dm-netlink.c linux-2.6.22-590/drivers/md/ +} 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 @@ -34925,8 +37055,8 @@ diff -Nurb linux-2.6.22-570/drivers/md/dm-netlink.h linux-2.6.22-590/drivers/md/ + +#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" @@ -34953,7 +37083,7 @@ diff -Nurb linux-2.6.22-570/drivers/md/dm.c linux-2.6.22-590/drivers/md/dm.c 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. */ @@ -34973,7 +37103,7 @@ diff -Nurb linux-2.6.22-570/drivers/md/md.c linux-2.6.22-590/drivers/md/md.c 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" @@ -38589,7 +40719,7 @@ diff -Nurb linux-2.6.22-570/drivers/md/xor.c linux-2.6.22-590/drivers/md/xor.c -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); @@ -38600,7 +40730,7 @@ diff -Nurb linux-2.6.22-570/drivers/media/dvb/dvb-core/dvb_frontend.c linux-2.6. 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; @@ -38611,7 +40741,7 @@ diff -Nurb linux-2.6.22-570/drivers/media/video/cx88/cx88-tvaudio.c linux-2.6.22 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 #include @@ -38648,7 +40778,7 @@ diff -Nurb linux-2.6.22-570/drivers/media/video/msp3400-kthreads.c linux-2.6.22- 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; @@ -38660,7 +40790,7 @@ diff -Nurb linux-2.6.22-570/drivers/media/video/tvaudio.c linux-2.6.22-590/drive 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; @@ -38671,7 +40801,7 @@ diff -Nurb linux-2.6.22-570/drivers/media/video/video-buf-dvb.c linux-2.6.22-590 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"); @@ -38695,7 +40825,7 @@ diff -Nurb linux-2.6.22-570/drivers/message/fusion/linux_compat.h linux-2.6.22-5 -#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. @@ -38730,7 +40860,7 @@ diff -Nurb linux-2.6.22-570/drivers/message/fusion/lsi/mpi.h linux-2.6.22-590/dr #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. @@ -38903,7 +41033,7 @@ diff -Nurb linux-2.6.22-570/drivers/message/fusion/lsi/mpi_cnfg.h linux-2.6.22-5 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 ============================== @@ -39265,7 +41395,7 @@ diff -Nurb linux-2.6.22-570/drivers/message/fusion/lsi/mpi_inb.h linux-2.6.22-59 - 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. @@ -39307,7 +41437,7 @@ diff -Nurb linux-2.6.22-570/drivers/message/fusion/lsi/mpi_init.h linux-2.6.22-5 { 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. @@ -39375,7 +41505,7 @@ diff -Nurb linux-2.6.22-570/drivers/message/fusion/lsi/mpi_ioc.h linux-2.6.22-59 { 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. @@ -39421,7 +41551,7 @@ diff -Nurb linux-2.6.22-570/drivers/message/fusion/lsi/mpi_raid.h linux-2.6.22-5 /* 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. * @@ -39486,7 +41616,7 @@ diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptbase.c linux-2.6.22-590/dr /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 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. * @@ -39509,7 +41639,7 @@ diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptbase.h linux-2.6.22-590/dr #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. * @@ -39521,7 +41651,7 @@ diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptctl.c linux-2.6.22-590/dri /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 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. * @@ -39533,7 +41663,7 @@ diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptctl.h linux-2.6.22-590/dri /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 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. * @@ -39553,7 +41683,7 @@ diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptfc.c linux-2.6.22-590/driv #include 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. * @@ -39565,7 +41695,7 @@ diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptlan.c linux-2.6.22-590/dri /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 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. * @@ -39577,7 +41707,7 @@ diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptlan.h linux-2.6.22-590/dri /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 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. * @@ -39589,7 +41719,7 @@ diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptsas.c linux-2.6.22-590/dri /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 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. * @@ -40076,7 +42206,7 @@ diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptscsih.c linux-2.6.22-590/d 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. * @@ -40088,7 +42218,7 @@ diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptscsih.h linux-2.6.22-590/d /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 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. * @@ -40108,7 +42238,7 @@ diff -Nurb linux-2.6.22-570/drivers/message/fusion/mptspi.c linux-2.6.22-590/dri #include 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); @@ -40153,7 +42283,7 @@ diff -Nurb linux-2.6.22-570/drivers/message/i2o/i2o_scsi.c linux-2.6.22-590/driv 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; @@ -40164,7 +42294,7 @@ diff -Nurb linux-2.6.22-570/drivers/mfd/ucb1x00-ts.c linux-2.6.22-590/drivers/mf 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 = { \ @@ -40177,7 +42307,7 @@ diff -Nurb linux-2.6.22-570/drivers/misc/asus-laptop.c linux-2.6.22-590/drivers/ } 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. @@ -40202,7 +42332,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/card/Kconfig linux-2.6.22-590/drivers/mm + 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 @@ } @@ -40226,7 +42356,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/card/block.c linux-2.6.22-590/drivers/mm 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 @@ -40484,7 +42614,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/card/queue.c linux-2.6.22-590/drivers/mm + 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; @@ -40506,7 +42636,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/card/queue.h linux-2.6.22-590/drivers/mm #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. @@ -40526,7 +42656,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/core/Kconfig linux-2.6.22-590/drivers/mm + 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 @@ -40537,7 +42667,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/core/Makefile linux-2.6.22-590/drivers/m 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 @@ -40786,7 +42916,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/core/bus.c linux-2.6.22-590/drivers/mmc/ + 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 @@ -40812,7 +42942,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/core/bus.h linux-2.6.22-590/drivers/mmc/ + 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 @@ -41029,7 +43159,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/core/core.c linux-2.6.22-590/drivers/mmc 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); @@ -41051,7 +43181,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/core/core.h linux-2.6.22-590/drivers/mmc 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 @@ -41211,7 +43341,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/core/host.c linux-2.6.22-590/drivers/mmc + 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 @@ -41233,7 +43363,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/core/host.h linux-2.6.22-590/drivers/mmc + 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 @@ -41436,7 +43566,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/core/lock.c linux-2.6.22-590/drivers/mmc + 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 @@ -41491,7 +43621,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/core/lock.h linux-2.6.22-590/drivers/mmc +#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" @@ -41657,7 +43787,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/core/mmc.c linux-2.6.22-590/drivers/mmc/ 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 * @@ -41799,7 +43929,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/core/mmc_ops.c linux-2.6.22-590/drivers/ + 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 @@ -41819,7 +43949,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/core/mmc_ops.h linux-2.6.22-590/drivers/ 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" @@ -41975,7 +44105,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/core/sd.c linux-2.6.22-590/drivers/mmc/c 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 * @@ -42353,7 +44483,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/core/sysfs.c linux-2.6.22-590/drivers/mm -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 @@ -42383,7 +44513,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/core/sysfs.h linux-2.6.22-590/drivers/mm #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, }, @@ -42401,7 +44531,7 @@ diff -Nurb linux-2.6.22-570/drivers/mmc/host/sdhci.c linux-2.6.22-590/drivers/mm }, 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 #include @@ -42421,7 +44551,7 @@ diff -Nurb linux-2.6.22-570/drivers/mtd/mtd_blkdevs.c linux-2.6.22-590/drivers/m 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); @@ -42432,7 +44562,7 @@ diff -Nurb linux-2.6.22-570/drivers/mtd/ubi/wl.c linux-2.6.22-590/drivers/mtd/ub 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 */ @@ -42444,7 +44574,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/3c523.c linux-2.6.22-590/drivers/net/3c5 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 */ @@ -42459,7 +44589,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/7990.c linux-2.6.22-590/drivers/net/7990 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); @@ -42470,9 +44600,30 @@ diff -Nurb linux-2.6.22-570/drivers/net/8139too.c linux-2.6.22-590/drivers/net/8 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" @@ -42492,9 +44643,17 @@ diff -Nurb linux-2.6.22-570/drivers/net/Kconfig linux-2.6.22-590/drivers/net/Kco 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 @@ -42507,7 +44666,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/Makefile linux-2.6.22-590/drivers/net/Ma + 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 */ @@ -42522,7 +44681,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/a2065.c linux-2.6.22-590/drivers/net/a20 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 */ @@ -42534,7 +44693,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/ariadne.c linux-2.6.22-590/drivers/net/a 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, @@ -42546,7 +44705,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/arm/ep93xx_eth.c linux-2.6.22-590/driver 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; } @@ -42560,7 +44719,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/au1000_eth.c linux-2.6.22-590/drivers/ne 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; @@ -42575,9 +44734,138 @@ diff -Nurb linux-2.6.22-570/drivers/net/bnx2.c linux-2.6.22-590/drivers/net/bnx2 #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 + #include + #include ++#include + #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 + #include + #include ++#include + #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 + #include + #include ++#include + + /* #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 */ @@ -42592,7 +44880,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/dl2k.c linux-2.6.22-590/drivers/net/dl2k 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 #include @@ -42779,7 +45067,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/dummy.c linux-2.6.22-590/drivers/net/dum +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 @@ -42791,7 +45079,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/eepro100.c linux-2.6.22-590/drivers/net/ 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, @@ -42801,9 +45089,549 @@ diff -Nurb linux-2.6.22-570/drivers/net/epic100.c linux-2.6.22-590/drivers/net/e 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 + #include + #include ++#include + + #include + #include +@@ -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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++/* 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 "); ++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. */ @@ -42817,7 +45645,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/fealnx.c linux-2.6.22-590/drivers/net/fe 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 { @@ -42829,7 +45657,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/fec.c linux-2.6.22-590/drivers/net/fec.c } 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. */ @@ -42843,7 +45671,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/hamachi.c linux-2.6.22-590/drivers/net/h 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); @@ -42853,10 +45681,152 @@ diff -Nurb linux-2.6.22-570/drivers/net/hamradio/baycom_epp.c linux-2.6.22-590/d } /* ---------------------------------------------------------------------- */ +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 + #include ++#include + + #include + +@@ -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 + #include + ++#include + #include + + #include +@@ -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 "); +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 + #include + #include ++#include + + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 = { \ @@ -42867,7 +45837,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/ibmveth.c linux-2.6.22-590/drivers/net/i 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 #include @@ -43036,7 +46006,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/ifb.c linux-2.6.22-590/drivers/net/ifb.c +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)) { @@ -43048,7 +46018,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/ixp2000/ixpdev.c linux-2.6.22-590/driver 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 @@ -43346,7 +46316,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/kgdboe.c linux-2.6.22-590/drivers/net/kg + "[tgt-port]@/\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 */ @@ -43359,9 +46329,93 @@ diff -Nurb linux-2.6.22-570/drivers/net/lance.c linux-2.6.22-590/drivers/net/lan 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 + #include + #include ++#include + + 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, @@ -43375,7 +46429,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/natsemi.c linux-2.6.22-590/drivers/net/n 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); @@ -43387,7 +46441,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/ni52.c linux-2.6.22-590/drivers/net/ni52 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) { @@ -43408,7 +46462,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/ni65.c linux-2.6.22-590/drivers/net/ni65 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. */ @@ -43420,7 +46474,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/pci-skeleton.c linux-2.6.22-590/drivers/ 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, @@ -43433,9 +46487,128 @@ diff -Nurb linux-2.6.22-570/drivers/net/pcnet32.c linux-2.6.22-590/drivers/net/p 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 + #include + ++#include + #include + + #include +@@ -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) { @@ -43447,7 +46620,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/r8169.c linux-2.6.22-590/drivers/net/r81 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 */ @@ -43462,7 +46635,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/saa9730.c linux-2.6.22-590/drivers/net/s 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); @@ -43472,9 +46645,29 @@ diff -Nurb linux-2.6.22-570/drivers/net/sgiseeq.c linux-2.6.22-590/drivers/net/s 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 + #include ++#include + + 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) { @@ -43486,7 +46679,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/sis190.c linux-2.6.22-590/drivers/net/si 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, @@ -43498,7 +46691,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/starfire.c linux-2.6.22-590/drivers/net/ 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); @@ -43510,7 +46703,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/sun3_82586.c linux-2.6.22-590/drivers/ne 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 */ @@ -43526,7 +46719,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/sun3lance.c linux-2.6.22-590/drivers/net 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, @@ -43538,7 +46731,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/sunbmac.c linux-2.6.22-590/drivers/net/s 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); @@ -43550,7 +46743,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/sundance.c linux-2.6.22-590/drivers/net/ 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 */ @@ -43565,7 +46758,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/sunlance.c linux-2.6.22-590/drivers/net/ 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); @@ -43579,7 +46772,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/sunqe.c linux-2.6.22-590/drivers/net/sun 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. */ @@ -43596,9 +46789,65 @@ diff -Nurb linux-2.6.22-570/drivers/net/tg3.c linux-2.6.22-590/drivers/net/tg3.c 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 + #include + ++#include + #include + + #include +@@ -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); @@ -43623,7 +46872,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/tulip/interrupt.c linux-2.6.22-590/drive 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, @@ -43635,7 +46884,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/tulip/winbond-840.c linux-2.6.22-590/dri 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; } @@ -43647,7 +46896,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/tulip/xircom_cb.c linux-2.6.22-590/drive 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 */ @@ -43661,8 +46910,16 @@ diff -Nurb linux-2.6.22-570/drivers/net/tulip/xircom_tulip_cb.c linux-2.6.22-590 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 + #include + #include ++#include + + #include + #include +@@ -432,6 +433,7 @@ init_waitqueue_head(&tun->read_wait); tun->owner = -1; @@ -43670,7 +46927,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/tun.c linux-2.6.22-590/drivers/net/tun.c SET_MODULE_OWNER(dev); dev->open = tun_net_open; -@@ -467,8 +468,11 @@ +@@ -467,11 +469,14 @@ return -EBUSY; /* Check permissions */ @@ -43683,8 +46940,12 @@ diff -Nurb linux-2.6.22-570/drivers/net/tun.c linux-2.6.22-590/drivers/net/tun.c + !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; @@ -43700,7 +46961,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/tun.c linux-2.6.22-590/drivers/net/tun.c 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, @@ -43712,7 +46973,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/typhoon.c linux-2.6.22-590/drivers/net/t 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; @@ -43724,7 +46985,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/usb/catc.c linux-2.6.22-590/drivers/net/ 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 */ @@ -43736,7 +46997,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/usb/kaweth.c linux-2.6.22-590/drivers/ne 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); @@ -43749,9 +47010,140 @@ diff -Nurb linux-2.6.22-570/drivers/net/via-rhine.c linux-2.6.22-590/drivers/net 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 + #include + #include ++#include + + + 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 + #include + ++#include + #include + + #include +@@ -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 + #include + ++#include + #include + + #include +@@ -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; @@ -43760,9 +47152,40 @@ diff -Nurb linux-2.6.22-570/drivers/net/wireless/airo.c linux-2.6.22-590/drivers 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 + #include + #include ++#include + #include + #include + #include +@@ -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); @@ -43771,9 +47194,47 @@ diff -Nurb linux-2.6.22-570/drivers/net/wireless/libertas/main.c linux-2.6.22-59 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 + #include + #include ++#include + + #include + #include +@@ -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; @@ -43785,7 +47246,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/wireless/wl3501_cs.c linux-2.6.22-590/dr 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. @@ -45784,7 +49245,7 @@ diff -Nurb linux-2.6.22-570/drivers/net/xen-netfront.c linux-2.6.22-590/drivers/ +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; @@ -45794,9 +49255,21 @@ diff -Nurb linux-2.6.22-570/drivers/net/yellowfin.c linux-2.6.22-590/drivers/net 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) \ @@ -45816,7 +49289,7 @@ diff -Nurb linux-2.6.22-570/drivers/parisc/pdc_stable.c linux-2.6.22-590/drivers }; 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); @@ -45843,7 +49316,7 @@ diff -Nurb linux-2.6.22-570/drivers/pci/hotplug/acpiphp_ibm.c linux-2.6.22-590/d 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); @@ -45866,7 +49339,7 @@ diff -Nurb linux-2.6.22-570/drivers/pci/hotplug/rpadlpar_core.c linux-2.6.22-590 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 @@ }; @@ -45960,8 +49433,8 @@ diff -Nurb linux-2.6.22-570/drivers/pci/pci-sysfs.c linux-2.6.22-590/drivers/pci 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; @@ -45979,8 +49452,8 @@ diff -Nurb linux-2.6.22-570/drivers/pci/probe.c linux-2.6.22-590/drivers/pci/pro 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); @@ -45991,7 +49464,7 @@ diff -Nurb linux-2.6.22-570/drivers/pcmcia/cs.c linux-2.6.22-590/drivers/pcmcia/ 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); } @@ -46025,7 +49498,7 @@ diff -Nurb linux-2.6.22-570/drivers/pcmcia/socket_sysfs.c linux-2.6.22-590/drive .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; } @@ -46047,7 +49520,7 @@ diff -Nurb linux-2.6.22-570/drivers/pnp/driver.c linux-2.6.22-590/drivers/pnp/dr 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; } @@ -46074,7 +49547,7 @@ diff -Nurb linux-2.6.22-570/drivers/pnp/pnpacpi/core.c linux-2.6.22-590/drivers/ 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; @@ -46094,7 +49567,7 @@ diff -Nurb linux-2.6.22-570/drivers/pnp/pnpbios/core.c linux-2.6.22-590/drivers/ 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 @@ }; @@ -46125,7 +49598,7 @@ diff -Nurb linux-2.6.22-570/drivers/rapidio/rio-sysfs.c linux-2.6.22-590/drivers .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, }; @@ -46160,7 +49633,7 @@ diff -Nurb linux-2.6.22-570/drivers/rtc/rtc-ds1553.c linux-2.6.22-590/drivers/rt .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, }; @@ -46195,7 +49668,7 @@ diff -Nurb linux-2.6.22-570/drivers/rtc/rtc-ds1742.c linux-2.6.22-590/drivers/rt .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 @@ -46236,9 +49709,21 @@ diff -Nurb linux-2.6.22-570/drivers/s390/cio/chp.c linux-2.6.22-590/drivers/s390 }, .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) \ @@ -46250,7 +49735,7 @@ diff -Nurb linux-2.6.22-570/drivers/s390/net/qeth_sys.c linux-2.6.22-590/drivers }; 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) @@ -46287,7 +49772,7 @@ diff -Nurb linux-2.6.22-570/drivers/s390/scsi/zfcp_aux.c linux-2.6.22-590/driver 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); @@ -46311,7 +49796,7 @@ diff -Nurb linux-2.6.22-570/drivers/s390/scsi/zfcp_erp.c linux-2.6.22-590/driver 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 #include @@ -46340,7 +49825,7 @@ diff -Nurb linux-2.6.22-570/drivers/sbus/char/bbc_envctrl.c linux-2.6.22-590/dri 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 #include @@ -46370,8 +49855,8 @@ diff -Nurb linux-2.6.22-570/drivers/sbus/char/envctrl.c linux-2.6.22-590/drivers 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); } @@ -46595,7 +50080,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/3w-9xxx.c linux-2.6.22-590/drivers/scsi /* 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"); @@ -46749,7 +50234,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/3w-xxxx.c linux-2.6.22-590/drivers/scsi 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) { @@ -46902,7 +50387,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/53c700.c linux-2.6.22-590/drivers/scsi/ 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 @@ -59235,7 +62720,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/53c7xx_u.h_shipped linux-2.6.22-590/dri -#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) { @@ -59329,7 +62814,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/BusLogic.c linux-2.6.22-590/drivers/scs 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 @@ -59431,7 +62916,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/Kconfig linux-2.6.22-590/drivers/scsi/K 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 @@ -59479,7 +62964,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/Makefile linux-2.6.22-590/drivers/scsi/ 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; @@ -59531,7 +63016,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/NCR5380.c linux-2.6.22-590/drivers/scsi 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 @@ -59554,7 +63039,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/NCR5380.h linux-2.6.22-590/drivers/scsi 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; @@ -59634,7 +63119,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/NCR53c406a.c linux-2.6.22-590/drivers/s #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. @@ -61308,7 +64793,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/a100u2w.c linux-2.6.22-590/drivers/scsi 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. @@ -61688,7 +65173,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/a100u2w.h linux-2.6.22-590/drivers/scsi -#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. @@ -61835,7 +65320,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/a4000t.c linux-2.6.22-590/drivers/scsi/ +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."); @@ -62554,7 +66039,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/aacraid/aachba.c linux-2.6.22-590/drive 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 @@ *----------------------------------------------------------------------------*/ @@ -62664,7 +66149,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/aacraid/aacraid.h linux-2.6.22-590/driv +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 @@ } @@ -62932,8 +66417,8 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/aacraid/commsup.c linux-2.6.22-590/driv 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 #include @@ -63129,7 +66614,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/aacraid/linit.c linux-2.6.22-590/driver 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; @@ -63158,7 +66643,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/aacraid/rx.c linux-2.6.22-590/drivers/s * 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 #include @@ -63386,7 +66871,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/advansys.h linux-2.6.22-590/drivers/scs -#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 #include @@ -63518,7 +67003,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/aha152x.c linux-2.6.22-590/drivers/scsi 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; } @@ -63602,7 +67087,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/aha1740.c linux-2.6.22-590/drivers/scsi 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) { @@ -63687,7 +67172,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/aic7xxx/aic79xx_osm.c linux-2.6.22-590/ 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) @@ -63708,7 +67193,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/aic7xxx/aic79xx_osm.h linux-2.6.22-590/ 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; @@ -63811,7 +67296,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/aic7xxx/aic7xxx_osm.c linux-2.6.22-590/ 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) @@ -63832,7 +67317,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/aic7xxx/aic7xxx_osm.h linux-2.6.22-590/ 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; @@ -64118,7 +67603,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/amiga7xx.h linux-2.6.22-590/drivers/scs -#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 @@ -64138,7 +67623,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/arcmsr/arcmsr.h linux-2.6.22-590/driver - 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[]; @@ -64201,7 +67686,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/arcmsr/arcmsr_attr.c linux-2.6.22-590/d .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 #include @@ -65123,7 +68608,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/bvme6000.h linux-2.6.22-590/drivers/scs -#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. @@ -65262,7 +68747,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/bvme6000_scsi.c linux-2.6.22-590/driver +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; @@ -65337,7 +68822,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/dpt_i2o.c linux-2.6.22-590/drivers/scsi 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) @@ -65421,8 +68906,8 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/eata.c linux-2.6.22-590/drivers/scsi/ea 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) { @@ -65545,7 +69030,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/esp_scsi.c linux-2.6.22-590/drivers/scs 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; }; @@ -65557,7 +69042,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/esp_scsi.h linux-2.6.22-590/drivers/scs * 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); @@ -65710,7 +69195,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/fdomain.c linux-2.6.22-590/drivers/scsi 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. @@ -65730,8 +69215,8 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/gdth.c linux-2.6.22-590/drivers/scsi/gd *(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; @@ -65833,7 +69318,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/hptiop.c linux-2.6.22-590/drivers/scsi/ 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 #include @@ -68082,7 +71567,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/ibmmca.h linux-2.6.22-590/drivers/scsi/ -#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 @@ } } @@ -68820,7 +72305,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/ibmvscsi/ibmvscsi.c linux-2.6.22-590/dr 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 @@ -68839,7 +72324,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/ibmvscsi/ibmvscsi.h linux-2.6.22-590/dr 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)); @@ -68903,7 +72388,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/ibmvscsi/rpa_vscsi.c linux-2.6.22-590/d } 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 @@ -73741,7 +77226,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/initio.c linux-2.6.22-590/drivers/scsi/ +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. @@ -74147,7 +77632,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/initio.h linux-2.6.22-590/drivers/scsi/ #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 @@ } @@ -74384,7 +77869,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/ipr.c linux-2.6.22-590/drivers/scsi/ipr } 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 @@ -74975,7 +78460,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/ips.c linux-2.6.22-590/drivers/scsi/ips /* 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 @@ -75054,7 +78539,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/ips.h linux-2.6.22-590/drivers/scsi/ips * 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 #include @@ -76005,7 +79490,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/iscsi_tcp.c linux-2.6.22-590/drivers/sc .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 @@ -76041,7 +79526,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/iscsi_tcp.h linux-2.6.22-590/drivers/sc 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. * @@ -76061,7 +79546,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/jazz_esp.c linux-2.6.22-590/drivers/scs 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. */ @@ -77235,7 +80720,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/libiscsi.c linux-2.6.22-590/drivers/scs 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 @@ -77283,7 +80768,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/libsas/sas_expander.c linux-2.6.22-590/ 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 @@ -77327,7 +80812,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/libsas/sas_scsi_host.c linux-2.6.22-590 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 * @@ -77346,7 +80831,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/Makefile linux-2.6.22-590/drivers/ + 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. * *******************************************************************/ @@ -77836,7 +81321,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc.h linux-2.6.22-590/drivers/sc + 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" @@ -79261,7 +82746,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_attr.c linux-2.6.22-590/drive 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); @@ -79551,7 +83036,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_crtn.h linux-2.6.22-590/drive #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" @@ -80964,7 +84449,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_ct.c linux-2.6.22-590/drivers 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 * @@ -81476,7 +84961,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_debugfs.c linux-2.6.22-590/dr + 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 * @@ -81530,7 +85015,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_debugfs.h linux-2.6.22-590/dr +#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, @@ -81582,7 +85067,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_disc.h linux-2.6.22-590/drive * 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" @@ -86985,7 +90470,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_els.c linux-2.6.22-590/driver + 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" @@ -90297,7 +93782,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_hbadisc.c linux-2.6.22-590/dr 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 @@ -91074,7 +94559,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_hw.h linux-2.6.22-590/drivers +} 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 #include @@ -92025,7 +95510,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_init.c linux-2.6.22-590/drive /* 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--; } @@ -92132,14 +95617,11 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_init.c linux-2.6.22-590/drive - 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: @@ -92282,7 +95764,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_init.c linux-2.6.22-590/drive 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; @@ -92292,7 +95774,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_init.c linux-2.6.22-590/drive 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) = @@ -92303,7 +95785,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_init.c linux-2.6.22-590/drive /* 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; @@ -92328,7 +95810,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_init.c linux-2.6.22-590/drive 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; @@ -92413,7 +95895,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_init.c linux-2.6.22-590/drive pci_set_master(pdev); retval = pci_set_mwi(pdev); -@@ -1623,13 +1816,22 @@ +@@ -1623,13 +1813,22 @@ memset(phba->slim2p, 0, SLI2_SLIM_SIZE); @@ -92437,7 +95919,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_init.c linux-2.6.22-590/drive /* 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; } @@ -92451,7 +95933,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_init.c linux-2.6.22-590/drive } /* Initialize HBA structure */ -@@ -1677,22 +1880,22 @@ +@@ -1677,22 +1877,22 @@ goto out_free_iocbq; } @@ -92486,7 +95968,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_init.c linux-2.6.22-590/drive 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); @@ -92558,7 +96040,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_init.c linux-2.6.22-590/drive 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); @@ -92592,7 +96074,8 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_init.c linux-2.6.22-590/drive + + kfree(vport->vname); + lpfc_free_sysfs_attr(vport); -+ + +- lpfc_remove_device(phba); + fc_remove_host(shost); + scsi_remove_host(shost); + @@ -92608,8 +96091,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_init.c linux-2.6.22-590/drive + 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); @@ -92650,7 +96132,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_init.c linux-2.6.22-590/drive } /** -@@ -1822,10 +2113,13 @@ +@@ -1822,10 +2110,13 @@ pci_set_master(pdev); /* Re-establishing Link */ @@ -92667,7 +96149,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_init.c linux-2.6.22-590/drive /* Take device offline; this will perform cleanup */ -@@ -1948,11 +2242,15 @@ +@@ -1948,11 +2239,15 @@ lpfc_transport_template = fc_attach_transport(&lpfc_transport_functions); @@ -92685,7 +96167,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_init.c linux-2.6.22-590/drive return error; } -@@ -1962,6 +2260,7 @@ +@@ -1962,6 +2257,7 @@ { pci_unregister_driver(&lpfc_driver); fc_release_transport(lpfc_transport_template); @@ -92695,7 +96177,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_init.c linux-2.6.22-590/drive 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 */ @@ -92706,7 +96188,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_logmsg.h linux-2.6.22-590/dri #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 @@ } @@ -93214,7 +96696,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_mbox.c linux-2.6.22-590/drive { 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 * @@ -93404,7 +96886,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_mem.c linux-2.6.22-590/driver + 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 @@ -/******************************************************************* + /******************************************************************* @@ -95662,7 +99144,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_nportdisc.c linux-2.6.22-590/ 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" @@ -96752,7 +100234,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_scsi.c linux-2.6.22-590/drive }; 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 * @@ -96772,7 +100254,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_scsi.h linux-2.6.22-590/drive 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" @@ -100240,7 +103722,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_sli.c linux-2.6.22-590/driver 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 */ @@ -100360,7 +103842,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_sli.h linux-2.6.22-590/driver #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. * *******************************************************************/ @@ -100372,7 +103854,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_version.h linux-2.6.22-590/dr 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 * @@ -100899,7 +104381,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_vport.c linux-2.6.22-590/driv +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 * @@ -101016,7 +104498,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/lpfc/lpfc_vport.h linux-2.6.22-590/driv +#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]); @@ -101116,7 +104598,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/mac53c94.c linux-2.6.22-590/drivers/scs 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; @@ -101332,7 +104814,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/megaraid/megaraid_mbox.c linux-2.6.22-5 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; @@ -101489,7 +104971,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.22-59 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 @@ -101736,7 +105218,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/megaraid.c linux-2.6.22-590/drivers/scs 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]); @@ -101941,7 +105423,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/mvme16x.h linux-2.6.22-590/drivers/scsi -#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. @@ -102103,7 +105585,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/mvme16x_scsi.c linux-2.6.22-590/drivers +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 #include @@ -102563,7 +106045,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/nsp32.c linux-2.6.22-590/drivers/scsi/n .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; @@ -102644,7 +106126,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/pcmcia/sym53c500_cs.c linux-2.6.22-590/ 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 --------------------------------------------------------- */ @@ -102814,7 +106296,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/qla2xxx/qla_attr.c linux-2.6.22-590/dri .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]); } @@ -102829,7 +106311,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/qla2xxx/qla_dbg.c linux-2.6.22-590/driv 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; @@ -103135,7 +106617,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/qla2xxx/qla_iocb.c linux-2.6.22-590/dri 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)) { @@ -103214,7 +106696,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/qla2xxx/qla_isr.c linux-2.6.22-590/driv 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; @@ -103232,7 +106714,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/qla2xxx/qla_os.c linux-2.6.22-590/drive 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 @@ */ @@ -103420,7 +106902,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_dbg.c linux-2.6.22-590/driv -#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 */ @@ -103537,7 +107019,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_def.h linux-2.6.22-590/driv #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 @@ *************************************************************************/ @@ -104039,7 +107521,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_fw.h linux-2.6.22-590/drive /*************************************************************************/ 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 @@ -104067,7 +107549,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_glbl.h linux-2.6.22-590/dri 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 @@ */ @@ -104345,7 +107827,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_init.c linux-2.6.22-590/dri 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 @@ */ @@ -104492,7 +107974,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_iocb.c linux-2.6.22-590/dri 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 @@ */ @@ -104654,7 +108136,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_isr.c linux-2.6.22-590/driv 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 @@ */ @@ -105153,7 +108635,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_mbx.c linux-2.6.22-590/driv 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 @@ */ @@ -105166,7 +108648,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_nvram.c linux-2.6.22-590/dr { 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 @@ -105355,7 +108837,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_os.c linux-2.6.22-590/drive 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. */ @@ -105365,7 +108847,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/qla4xxx/ql4_version.h linux-2.6.22-590/ + 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 */ @@ -105417,7 +108899,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/qlogicfas408.c linux-2.6.22-590/drivers 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)"); @@ -105429,7 +108911,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/scsi_debug.c linux-2.6.22-590/drivers/s 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 #include @@ -105494,7 +108976,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/scsi_error.c linux-2.6.22-590/drivers/s * 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); } @@ -105537,9 +109019,21 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/scsi_lib.c linux-2.6.22-590/drivers/scs + } +} +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 @@ -105559,7 +109053,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/scsi_scan.c linux-2.6.22-590/drivers/sc * 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; @@ -105618,7 +109112,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/scsi_sysfs.c linux-2.6.22-590/drivers/s 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 @@ * * ======== @@ -106726,7 +110220,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/scsi_transport_fc.c linux-2.6.22-590/dr 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 #include @@ -106955,9 +110449,18 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/scsi_transport_iscsi.c linux-2.6.22-590 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; @@ -106969,7 +110472,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/sd.c linux-2.6.22-590/drivers/scsi/sd.c "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; @@ -106981,7 +110484,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/sg.c linux-2.6.22-590/drivers/scsi/sg.c ++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) @@ -107164,7 +110667,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/stex.c linux-2.6.22-590/drivers/scsi/st 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; @@ -107176,7 +110679,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/sun_esp.c linux-2.6.22-590/drivers/scsi 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; @@ -107246,7 +110749,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/sym53c416.c linux-2.6.22-590/drivers/sc 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)); @@ -107447,7 +110950,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/tmscsim.c linux-2.6.22-590/drivers/scsi /* 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 @@ -107473,7 +110976,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/tmscsim.h linux-2.6.22-590/drivers/scsi #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; @@ -107560,7 +111063,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/u14-34f.c linux-2.6.22-590/drivers/scsi 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) @@ -107605,7 +111108,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/ultrastor.c linux-2.6.22-590/drivers/sc 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; @@ -107655,7 +111158,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/wd7000.c linux-2.6.22-590/drivers/scsi/ /* 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. @@ -107839,7 +111342,7 @@ diff -Nurb linux-2.6.22-570/drivers/scsi/zorro7xx.c linux-2.6.22-590/drivers/scs +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); @@ -107868,7 +111371,7 @@ diff -Nurb linux-2.6.22-570/drivers/serial/8250.c linux-2.6.22-590/drivers/seria 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. @@ -108386,8 +111889,8 @@ diff -Nurb linux-2.6.22-570/drivers/serial/8250_kgdb.c linux-2.6.22-590/drivers/ +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 @@ -108399,7 +111902,7 @@ diff -Nurb linux-2.6.22-570/drivers/serial/Kconfig linux-2.6.22-590/drivers/seri 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 @@ -108428,7 +111931,7 @@ diff -Nurb linux-2.6.22-570/drivers/serial/Makefile linux-2.6.22-590/drivers/ser +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 @@ -108440,7 +111943,7 @@ diff -Nurb linux-2.6.22-570/drivers/serial/amba-pl011.c linux-2.6.22-590/drivers 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 @@ -108450,7 +111953,7 @@ diff -Nurb linux-2.6.22-570/drivers/serial/cpm_uart/Makefile linux-2.6.22-590/dr 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 @@ -108511,7 +112014,7 @@ diff -Nurb linux-2.6.22-570/drivers/serial/cpm_uart/cpm_uart.h linux-2.6.22-590/ #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; } @@ -108691,7 +112194,7 @@ diff -Nurb linux-2.6.22-570/drivers/serial/cpm_uart/cpm_uart_core.c linux-2.6.22 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; @@ -108749,7 +112252,7 @@ diff -Nurb linux-2.6.22-570/drivers/serial/cpm_uart/cpm_uart_cpm1.c linux-2.6.22 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"); @@ -108763,7 +112266,7 @@ diff -Nurb linux-2.6.22-570/drivers/serial/cpm_uart/cpm_uart_cpm2.c linux-2.6.22 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 @@ -108952,7 +112455,7 @@ diff -Nurb linux-2.6.22-570/drivers/serial/cpm_uart/cpm_uart_kgdb.c linux-2.6.22 + 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 @@ -109301,7 +112804,7 @@ diff -Nurb linux-2.6.22-570/drivers/serial/mpsc_kgdb.c linux-2.6.22-590/drivers/ +}; 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 @@ -109416,7 +112919,7 @@ diff -Nurb linux-2.6.22-570/drivers/serial/pl011_kgdb.c linux-2.6.22-590/drivers +}; 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 #include @@ -109438,7 +112941,7 @@ diff -Nurb linux-2.6.22-570/drivers/serial/pxa.c linux-2.6.22-590/drivers/serial #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 /* for serial_state and serial_icounter_struct */ #include @@ -109507,7 +113010,7 @@ diff -Nurb linux-2.6.22-570/drivers/serial/serial_core.c linux-2.6.22-590/driver 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"; @@ -109551,7 +113054,7 @@ diff -Nurb linux-2.6.22-570/drivers/serial/serial_txx9.c linux-2.6.22-590/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 @@ -109705,7 +113208,7 @@ diff -Nurb linux-2.6.22-570/drivers/serial/serial_txx9_kgdb.c linux-2.6.22-590/d +}; 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); @@ -109767,7 +113270,7 @@ diff -Nurb linux-2.6.22-570/drivers/serial/sh-sci.c linux-2.6.22-590/drivers/ser * 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 @@ } @@ -109796,9 +113299,121 @@ diff -Nurb linux-2.6.22-570/drivers/spi/at25.c linux-2.6.22-590/drivers/spi/at25 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; @@ -109807,9 +113422,98 @@ diff -Nurb linux-2.6.22-570/drivers/usb/atm/ueagle-atm.c linux-2.6.22-590/driver 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) @@ -109818,9 +113522,120 @@ diff -Nurb linux-2.6.22-570/drivers/usb/core/hub.c linux-2.6.22-590/drivers/usb/ 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); @@ -109833,7 +113648,7 @@ diff -Nurb linux-2.6.22-570/drivers/usb/gadget/file_storage.c linux-2.6.22-590/d * 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); @@ -109853,7 +113668,7 @@ diff -Nurb linux-2.6.22-570/drivers/usb/storage/usb.c linux-2.6.22-590/drivers/u 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 @@ -109870,7 +113685,7 @@ diff -Nurb linux-2.6.22-570/drivers/video/Kconfig linux-2.6.22-590/drivers/video ---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 @@ -109880,7 +113695,7 @@ diff -Nurb linux-2.6.22-570/drivers/video/Makefile linux-2.6.22-590/drivers/vide +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 @@ } @@ -109921,7 +113736,7 @@ diff -Nurb linux-2.6.22-570/drivers/video/aty/radeon_base.c linux-2.6.22-590/dri .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) \ @@ -109933,7 +113748,7 @@ diff -Nurb linux-2.6.22-570/drivers/video/backlight/backlight.c linux-2.6.22-590 } 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) \ @@ -109945,7 +113760,7 @@ diff -Nurb linux-2.6.22-570/drivers/video/backlight/lcd.c linux-2.6.22-590/drive } 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) @@ -109956,7 +113771,7 @@ diff -Nurb linux-2.6.22-570/drivers/video/ps3fb.c linux-2.6.22-590/drivers/video 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 */ @@ -109991,7 +113806,7 @@ diff -Nurb linux-2.6.22-570/drivers/w1/slaves/w1_ds2433.c linux-2.6.22-590/drive .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 @@ {} }; @@ -110021,7 +113836,7 @@ diff -Nurb linux-2.6.22-570/drivers/w1/slaves/w1_therm.c linux-2.6.22-590/driver 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); } @@ -110081,7 +113896,7 @@ diff -Nurb linux-2.6.22-570/drivers/w1/w1.c linux-2.6.22-590/drivers/w1/w1.c 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); @@ -110102,9 +113917,42 @@ diff -Nurb linux-2.6.22-570/drivers/zorro/zorro-sysfs.c linux-2.6.22-590/drivers }, .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 @@ -110168,7 +114016,7 @@ diff -Nurb linux-2.6.22-570/fs/Kconfig linux-2.6.22-590/fs/Kconfig 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 @@ -110182,9 +114030,38 @@ diff -Nurb linux-2.6.22-570/fs/Makefile linux-2.6.22-590/fs/Makefile 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 + #include + #include ++#include + #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; @@ -110206,7 +114083,7 @@ diff -Nurb linux-2.6.22-570/fs/buffer.c linux-2.6.22-590/fs/buffer.c 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; @@ -110217,7 +114094,7 @@ diff -Nurb linux-2.6.22-570/fs/cifs/cifsfs.c linux-2.6.22-590/fs/cifs/cifsfs.c 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); } @@ -110226,9 +114103,44 @@ diff -Nurb linux-2.6.22-570/fs/cifs/connect.c linux-2.6.22-590/fs/cifs/connect.c 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 { @@ -110239,7 +114151,7 @@ diff -Nurb linux-2.6.22-570/fs/configfs/configfs_internal.h linux-2.6.22-590/fs/ 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; @@ -110565,7 +114477,7 @@ diff -Nurb linux-2.6.22-570/fs/configfs/dir.c linux-2.6.22-590/fs/configfs/dir.c 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 #include @@ -110668,7 +114580,7 @@ diff -Nurb linux-2.6.22-570/fs/configfs/file.c linux-2.6.22-590/fs/configfs/file 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. @@ -110725,7 +114637,7 @@ diff -Nurb linux-2.6.22-570/fs/configfs/item.c linux-2.6.22-590/fs/configfs/item 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 @@ */ @@ -110752,8 +114664,8 @@ diff -Nurb linux-2.6.22-570/fs/drop_caches.c linux-2.6.22-590/fs/drop_caches.c 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; @@ -110782,7 +114694,7 @@ diff -Nurb linux-2.6.22-570/fs/ecryptfs/inode.c linux-2.6.22-590/fs/ecryptfs/ino 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; } @@ -110793,8 +114705,8 @@ diff -Nurb linux-2.6.22-570/fs/ecryptfs/main.c linux-2.6.22-590/fs/ecryptfs/main 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; @@ -110807,7 +114719,13 @@ diff -Nurb linux-2.6.22-570/fs/exec.c linux-2.6.22-590/fs/exec.c 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); @@ -110897,7 +114815,7 @@ diff -Nurb linux-2.6.22-570/fs/exec.c linux-2.6.22-590/fs/exec.c 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; @@ -110909,7 +114827,7 @@ diff -Nurb linux-2.6.22-570/fs/gfs2/ops_address.c linux-2.6.22-590/fs/gfs2/ops_a 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; @@ -110921,7 +114839,7 @@ diff -Nurb linux-2.6.22-570/fs/gfs2/ops_file.c linux-2.6.22-590/fs/gfs2/ops_file 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" @@ -111006,8 +114924,8 @@ diff -Nurb linux-2.6.22-570/fs/gfs2/ops_vm.c linux-2.6.22-590/fs/gfs2/ops_vm.c }; 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; @@ -111034,7 +114952,7 @@ diff -Nurb linux-2.6.22-570/fs/inode.c linux-2.6.22-590/fs/inode.c { 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), @@ -111055,7 +114973,7 @@ diff -Nurb linux-2.6.22-570/fs/jbd/journal.c linux-2.6.22-590/fs/jbd/journal.c 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", @@ -111078,7 +114996,7 @@ diff -Nurb linux-2.6.22-570/fs/jbd/revoke.c linux-2.6.22-590/fs/jbd/revoke.c 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); @@ -111089,7 +115007,7 @@ diff -Nurb linux-2.6.22-570/fs/jffs2/background.c linux-2.6.22-590/fs/jffs2/back 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); @@ -111111,7 +115029,7 @@ diff -Nurb linux-2.6.22-570/fs/lockd/host.c linux-2.6.22-590/fs/lockd/host.c 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 @@ -111130,7 +115048,7 @@ diff -Nurb linux-2.6.22-570/fs/lockd/mon.c linux-2.6.22-590/fs/lockd/mon.c 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 #include @@ -111165,8 +115083,8 @@ diff -Nurb linux-2.6.22-570/fs/lockd/svc.c linux-2.6.22-590/fs/lockd/svc.c 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; } @@ -111196,8 +115114,8 @@ diff -Nurb linux-2.6.22-570/fs/namei.c linux-2.6.22-590/fs/namei.c 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); @@ -111227,7 +115145,7 @@ diff -Nurb linux-2.6.22-570/fs/namespace.c linux-2.6.22-590/fs/namespace.c 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 @@ -111291,7 +115209,7 @@ diff -Nurb linux-2.6.22-570/fs/ncpfs/mmap.c linux-2.6.22-590/fs/ncpfs/mmap.c } 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 #include @@ -111309,8 +115227,8 @@ diff -Nurb linux-2.6.22-570/fs/nfs/callback.c linux-2.6.22-590/fs/nfs/callback.c 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) { @@ -111353,7 +115271,7 @@ diff -Nurb linux-2.6.22-570/fs/nfs/client.c linux-2.6.22-590/fs/nfs/client.c 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); @@ -111365,7 +115283,7 @@ diff -Nurb linux-2.6.22-570/fs/nfs/delegation.c linux-2.6.22-590/fs/nfs/delegati 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 */ @@ -111376,8 +115294,8 @@ diff -Nurb linux-2.6.22-570/fs/nfs/delegation.h linux-2.6.22-590/fs/nfs/delegati 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; } @@ -111434,7 +115352,7 @@ diff -Nurb linux-2.6.22-570/fs/nfs/dir.c linux-2.6.22-590/fs/nfs/dir.c } 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) { @@ -111516,8 +115434,8 @@ diff -Nurb linux-2.6.22-570/fs/nfs/direct.c linux-2.6.22-590/fs/nfs/direct.c 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); @@ -111634,7 +115552,7 @@ diff -Nurb linux-2.6.22-570/fs/nfs/inode.c linux-2.6.22-590/fs/nfs/inode.c 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]; @@ -111655,7 +115573,7 @@ diff -Nurb linux-2.6.22-570/fs/nfs/mount_clnt.c linux-2.6.22-590/fs/nfs/mount_cl 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) */ @@ -111669,7 +115587,7 @@ diff -Nurb linux-2.6.22-570/fs/nfs/nfs3proc.c linux-2.6.22-590/fs/nfs/nfs3proc.c 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 *); @@ -111699,7 +115617,7 @@ diff -Nurb linux-2.6.22-570/fs/nfs/nfs4_fs.h linux-2.6.22-590/fs/nfs/nfs4_fs.h #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 @@ } @@ -112265,7 +116183,7 @@ diff -Nurb linux-2.6.22-570/fs/nfs/nfs4proc.c linux-2.6.22-590/fs/nfs/nfs4proc.c 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. @@ -112291,7 +116209,7 @@ diff -Nurb linux-2.6.22-570/fs/nfs/nfs4state.c linux-2.6.22-590/fs/nfs/nfs4state /* 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) { @@ -112317,7 +116235,7 @@ diff -Nurb linux-2.6.22-570/fs/nfs/nfs4xdr.c linux-2.6.22-590/fs/nfs/nfs4xdr.c 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; @@ -112463,7 +116381,7 @@ diff -Nurb linux-2.6.22-570/fs/nfs/pagelist.c linux-2.6.22-590/fs/nfs/pagelist.c 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); @@ -112557,8 +116475,8 @@ diff -Nurb linux-2.6.22-570/fs/nfs/read.c linux-2.6.22-590/fs/nfs/read.c 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", "" }, @@ -112770,7 +116688,7 @@ diff -Nurb linux-2.6.22-570/fs/nfs/super.c linux-2.6.22-590/fs/nfs/super.c 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); @@ -112999,7 +116917,7 @@ diff -Nurb linux-2.6.22-570/fs/nfs/write.c linux-2.6.22-590/fs/nfs/write.c 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; } @@ -113035,7 +116953,7 @@ diff -Nurb linux-2.6.22-570/fs/nfsd/nfs4callback.c linux-2.6.22-590/fs/nfsd/nfs4 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; @@ -113046,7 +116964,7 @@ diff -Nurb linux-2.6.22-570/fs/nfsd/nfs4state.c linux-2.6.22-590/fs/nfsd/nfs4sta 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 #include @@ -113065,7 +116983,7 @@ diff -Nurb linux-2.6.22-570/fs/nfsd/nfssvc.c linux-2.6.22-590/fs/nfsd/nfssvc.c * 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" @@ -115635,7 +119553,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/alloc.c linux-2.6.22-590/fs/ocfs2/alloc.c 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, @@ -115689,8 +119607,8 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/alloc.h linux-2.6.22-590/fs/ocfs2/alloc.h /* * 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 @@ -116914,7 +120832,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/aops.c linux-2.6.22-590/fs/ocfs2/aops.c 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)); @@ -116991,7 +120909,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/aops.h linux-2.6.22-590/fs/ocfs2/aops.h #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); @@ -117140,7 +121058,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/cluster/heartbeat.c linux-2.6.22-590/fs/ocf 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, @@ -117156,7 +121074,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/cluster/heartbeat.h linux-2.6.22-590/fs/ocf 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 = { \ @@ -117167,7 +121085,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/cluster/masklog.c linux-2.6.22-590/fs/ocfs2 .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 @@ }, }; @@ -117217,7 +121135,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/cluster/nodemanager.c linux-2.6.22-590/fs/o 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); @@ -117230,7 +121148,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/cluster/nodemanager.h linux-2.6.22-590/fs/o #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) @@ -117289,7 +121207,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/cluster/tcp.c linux-2.6.22-590/fs/ocfs2/clu 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; @@ -117301,7 +121219,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/dir.c linux-2.6.22-590/fs/ocfs2/dir.c 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) @@ -117331,7 +121249,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/dlm/dlmdomain.c linux-2.6.22-590/fs/ocfs2/d 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) { @@ -117472,7 +121390,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/dlm/dlmmaster.c linux-2.6.22-590/fs/ocfs2/d 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); @@ -117746,8 +121664,8 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/dlm/dlmrecovery.c linux-2.6.22-590/fs/ocfs2 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) @@ -117768,7 +121686,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/dlmglue.c linux-2.6.22-590/fs/ocfs2/dlmglue 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); } @@ -117783,7 +121701,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/endian.h linux-2.6.22-590/fs/ocfs2/endian.h *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) @@ -117853,8 +121771,8 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/extent_map.c linux-2.6.22-590/fs/ocfs2/exte 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); @@ -118531,7 +122449,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/file.c linux-2.6.22-590/fs/ocfs2/file.c 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, @@ -118562,7 +122480,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/file.h linux-2.6.22-590/fs/ocfs2/file.h #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; @@ -118604,8 +122522,8 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/heartbeat.c linux-2.6.22-590/fs/ocfs2/heart 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" @@ -118647,7 +122565,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/ioctl.c linux-2.6.22-590/fs/ocfs2/ioctl.c } 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; @@ -118670,7 +122588,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/journal.c linux-2.6.22-590/fs/ocfs2/journal 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" @@ -118897,8 +122815,8 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/mmap.c linux-2.6.22-590/fs/ocfs2/mmap.c } 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; @@ -118909,8 +122827,8 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/namei.c linux-2.6.22-590/fs/ocfs2/namei.c 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; @@ -118940,8 +122858,8 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/ocfs2.h linux-2.6.22-590/fs/ocfs2/ocfs2.h * 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 \ @@ -118998,7 +122916,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/ocfs2_fs.h linux-2.6.22-590/fs/ocfs2/ocfs2_ #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; } @@ -119037,7 +122955,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/slot_map.c linux-2.6.22-590/fs/ocfs2/slot_m 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, @@ -119112,7 +123030,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/suballoc.c linux-2.6.22-590/fs/ocfs2/suball 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); @@ -119148,8 +123066,8 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/suballoc.h linux-2.6.22-590/fs/ocfs2/suball 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"); @@ -119233,7 +123151,7 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/super.c linux-2.6.22-590/fs/ocfs2/super.c 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) @@ -119242,8 +123160,8 @@ diff -Nurb linux-2.6.22-570/fs/ocfs2/super.h linux-2.6.22-590/fs/ocfs2/super.h + #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 @@ -119339,7 +123257,7 @@ diff -Nurb linux-2.6.22-570/fs/open.c linux-2.6.22-590/fs/open.c * 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", @@ -119348,9 +123266,20 @@ diff -Nurb linux-2.6.22-570/fs/partitions/check.c linux-2.6.22-590/fs/partitions }; 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; } @@ -119388,8 +123317,8 @@ diff -Nurb linux-2.6.22-570/fs/proc/array.c linux-2.6.22-590/fs/proc/array.c 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 #include @@ -119764,8 +123693,8 @@ diff -Nurb linux-2.6.22-570/fs/proc/base.c linux-2.6.22-590/fs/proc/base.c 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; @@ -119776,9 +123705,21 @@ diff -Nurb linux-2.6.22-570/fs/proc/generic.c linux-2.6.22-590/fs/proc/generic.c 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 *); @@ -119798,9 +123739,17 @@ diff -Nurb linux-2.6.22-570/fs/proc/internal.h linux-2.6.22-590/fs/proc/internal 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; @@ -119818,9 +123767,202 @@ diff -Nurb linux-2.6.22-570/fs/proc/proc_misc.c linux-2.6.22-590/fs/proc/proc_mi 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 ++ * ++ * proc net directory handling functions ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 #include @@ -120601,7 +124743,7 @@ diff -Nurb linux-2.6.22-570/fs/proc/task_mmu.c linux-2.6.22-590/fs/proc/task_mmu +#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; @@ -120612,7 +124754,7 @@ diff -Nurb linux-2.6.22-570/fs/ramfs/inode.c linux-2.6.22-590/fs/ramfs/inode.c 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. @@ -121393,7 +125535,7 @@ diff -Nurb linux-2.6.22-570/fs/revoke.c linux-2.6.22-590/fs/revoke.c +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 @@ -121813,8 +125955,8 @@ diff -Nurb linux-2.6.22-570/fs/revoked_inode.c linux-2.6.22-590/fs/revoked_inode + 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 #include @@ -121834,29 +125976,18 @@ diff -Nurb linux-2.6.22-570/fs/splice.c linux-2.6.22-590/fs/splice.c 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) { @@ -121864,7 +125995,7 @@ diff -Nurb linux-2.6.22-570/fs/splice.c linux-2.6.22-590/fs/splice.c 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; @@ -121877,7 +126008,7 @@ diff -Nurb linux-2.6.22-570/fs/splice.c linux-2.6.22-590/fs/splice.c 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 @@ -121912,25 +126043,20 @@ diff -Nurb linux-2.6.22-570/fs/stack.c linux-2.6.22-590/fs/stack.c 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" @@ -122217,14 +126343,14 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/bin.c linux-2.6.22-590/fs/sysfs/bin.c 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 #include #include @@ -122235,12 +126361,33 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c -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 @@ -122251,6 +126398,18 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + * 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; @@ -122259,6 +126418,114 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + 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 @@ -122268,7 +126535,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + * 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) +{ @@ -122298,88 +126565,6 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + * 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 @@ -122391,28 +126576,6 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + * 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 @@ -122503,6 +126666,73 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + 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; @@ -122544,7 +126774,8 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + 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; @@ -122567,7 +126798,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c /* 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; @@ -122576,7 +126807,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c sysfs_put(sd); } iput(inode); -@@ -42,260 +358,402 @@ +@@ -42,344 +463,594 @@ .d_iput = sysfs_d_iput, }; @@ -122656,6 +126887,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + sd->s_dentry = dentry; + spin_unlock(&sysfs_assoc_lock); + ++ if (dentry->d_flags & DCACHE_UNHASHED) + d_rehash(dentry); } @@ -122707,11 +126939,9 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c - 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 @@ -122734,11 +126964,12 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + 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 @@ -122765,10 +126996,8 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + 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 @@ -122787,34 +127016,21 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + * 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 @@ -122831,19 +127047,26 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + */ +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); @@ -122855,11 +127078,14 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + 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) { @@ -122875,7 +127101,24 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + } } --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 @@ -122892,8 +127135,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + */ +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) { @@ -122903,13 +127145,13 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + 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; @@ -122917,6 +127159,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + 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); @@ -122925,7 +127168,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + 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 @@ -122942,18 +127185,20 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c +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 @@ -122971,10 +127216,16 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c +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); @@ -122992,6 +127243,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c 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)); @@ -123007,6 +127259,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c - 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) @@ -123015,10 +127268,17 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + + /* 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; @@ -123037,7 +127297,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c - error = PTR_ERR(*d); - mutex_unlock(&p->d_inode->i_mutex); - return error; -+ return -EEXIST; ++ return err; } - @@ -123053,12 +127313,10 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c * 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; @@ -123069,10 +127327,9 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c - 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; @@ -123084,19 +127341,23 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + 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; @@ -123104,7 +127365,12 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c - 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); @@ -123113,77 +127379,39 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c - 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) @@ -123198,7 +127426,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + 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; @@ -123213,29 +127441,92 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + 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); @@ -123244,25 +127535,57 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c - 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) @@ -123270,7 +127593,6 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c - struct sysfs_dirent * parent_sd; - struct sysfs_dirent * sd, * tmp; + struct sysfs_addrm_cxt acxt; -+ struct sysfs_dirent **pos; - dget(dentry); - if (!dentry) @@ -123286,20 +127608,14 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c - 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); @@ -123311,7 +127627,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c } /** -@@ -393,102 +875,166 @@ +@@ -393,102 +1064,154 @@ void sysfs_remove_dir(struct kobject * kobj) { @@ -123327,119 +127643,111 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c } -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; } @@ -123469,15 +127777,15 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + 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 */ @@ -123522,9 +127830,9 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c + 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); @@ -123535,7 +127843,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c 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; @@ -123572,7 +127880,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c 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; @@ -123581,7 +127889,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c ino_t ino; int i = filp->f_pos; -@@ -543,38 +1093,52 @@ +@@ -543,38 +1270,55 @@ i++; /* fallthrough */ case 1: @@ -123596,8 +127904,11 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c 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; @@ -123645,7 +127956,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c } return 0; } -@@ -583,7 +1147,6 @@ +@@ -583,7 +1327,6 @@ { struct dentry * dentry = file->f_path.dentry; @@ -123653,7 +127964,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c switch (origin) { case 1: offset += file->f_pos; -@@ -591,31 +1154,35 @@ +@@ -591,127 +1334,224 @@ if (offset >= 0) break; default: @@ -123701,124 +128012,263 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/dir.c linux-2.6.22-590/fs/sysfs/dir.c 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, }; @@ -123908,8 +128358,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/file.c linux-2.6.22-590/fs/sysfs/file.c + 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; @@ -123917,12 +128366,13 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/file.c linux-2.6.22-590/fs/sysfs/file.c + 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); @@ -123948,34 +128398,49 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/file.c linux-2.6.22-590/fs/sysfs/file.c + 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) @@ -123984,7 +128449,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/file.c linux-2.6.22-590/fs/sysfs/file.c } -@@ -309,48 +296,38 @@ +@@ -309,48 +286,38 @@ */ if (file->f_mode & FMODE_READ) { if (!(inode->i_mode & S_IRUGO) || !ops->show) @@ -124048,26 +128513,26 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/file.c linux-2.6.22-590/fs/sysfs/file.c 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); @@ -124131,7 +128596,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/file.c linux-2.6.22-590/fs/sysfs/file.c } EXPORT_SYMBOL_GPL(sysfs_notify); -@@ -441,19 +404,30 @@ +@@ -441,19 +394,30 @@ }; @@ -124171,7 +128636,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/file.c linux-2.6.22-590/fs/sysfs/file.c } -@@ -465,9 +439,9 @@ +@@ -465,9 +429,9 @@ int sysfs_create_file(struct kobject * kobj, const struct attribute * attr) { @@ -124183,7 +128648,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/file.c linux-2.6.22-590/fs/sysfs/file.c } -@@ -481,16 +455,16 @@ +@@ -481,16 +445,16 @@ int sysfs_add_file_to_group(struct kobject *kobj, const struct attribute *attr, const char *group) { @@ -124208,7 +128673,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/file.c linux-2.6.22-590/fs/sysfs/file.c 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) { @@ -124261,7 +128726,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/file.c linux-2.6.22-590/fs/sysfs/file.c } -@@ -539,30 +514,34 @@ +@@ -539,30 +504,34 @@ */ int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode) { @@ -124312,16 +128777,16 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/file.c linux-2.6.22-590/fs/sysfs/file.c } 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) { @@ -124334,33 +128799,38 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/file.c linux-2.6.22-590/fs/sysfs/file.c - 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 + #include + #include +-#include + #include #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; @@ -124373,11 +128843,11 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/group.c linux-2.6.22-590/fs/sysfs/group.c + 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) { @@ -124399,7 +128869,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/group.c linux-2.6.22-590/fs/sysfs/group.c - 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); @@ -124430,7 +128900,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/group.c linux-2.6.22-590/fs/sysfs/group.c + 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 */ @@ -124443,8 +128913,25 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/group.c linux-2.6.22-590/fs/sysfs/group.c 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; @@ -124456,16 +128943,15 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/inode.c linux-2.6.22-590/fs/sysfs/inode.c 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; @@ -124499,8 +128985,9 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/inode.c linux-2.6.22-590/fs/sysfs/inode.c - 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 +/** @@ -124587,13 +129074,15 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/inode.c linux-2.6.22-590/fs/sysfs/inode.c { - 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) @@ -124622,16 +129111,14 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/inode.c linux-2.6.22-590/fs/sysfs/inode.c - 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; @@ -124646,15 +129133,18 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/inode.c linux-2.6.22-590/fs/sysfs/inode.c - 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)) { @@ -124670,15 +129160,16 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/inode.c linux-2.6.22-590/fs/sysfs/inode.c } } - 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; @@ -124687,8 +129178,9 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/mount.c linux-2.6.22-590/fs/sysfs/mount.c - 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 = { @@ -124738,10 +129230,18 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/mount.c linux-2.6.22-590/fs/sysfs/mount.c 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" @@ -124752,8 +129252,11 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/symlink.c linux-2.6.22-590/fs/sysfs/symlink 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; } @@ -124768,8 +129271,11 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/symlink.c linux-2.6.22-590/fs/sysfs/symlink - 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; } @@ -124779,11 +129285,15 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/symlink.c linux-2.6.22-590/fs/sysfs/symlink { - 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; @@ -124827,7 +129337,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/symlink.c linux-2.6.22-590/fs/sysfs/symlink /** * 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) { @@ -124872,14 +129382,17 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/symlink.c linux-2.6.22-590/fs/sysfs/symlink + 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; @@ -124895,16 +129408,52 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/symlink.c linux-2.6.22-590/fs/sysfs/symlink 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) { @@ -124918,7 +129467,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/symlink.c linux-2.6.22-590/fs/sysfs/symlink if (size > PATH_MAX) return -ENAMETOOLONG; -@@ -133,7 +134,7 @@ +@@ -133,7 +178,7 @@ for (s = path; depth--; s += 3) strcpy(s,"../"); @@ -124927,7 +129476,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/symlink.c linux-2.6.22-590/fs/sysfs/symlink 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) { @@ -124943,10 +129492,6 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/symlink.c linux-2.6.22-590/fs/sysfs/symlink - 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; @@ -124955,7 +129500,11 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/symlink.c linux-2.6.22-590/fs/sysfs/symlink + 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; @@ -124965,7 +129514,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/symlink.c linux-2.6.22-590/fs/sysfs/symlink 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; @@ -125011,7 +129560,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/sysfs.h linux-2.6.22-590/fs/sysfs/sysfs.h umode_t s_mode; ino_t s_ino; struct dentry * s_dentry; -@@ -11,30 +42,60 @@ +@@ -11,30 +42,77 @@ atomic_t s_event; }; @@ -125023,6 +129572,17 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/sysfs.h linux-2.6.22-590/fs/sysfs/sysfs.h + 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; @@ -125031,9 +129591,22 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/sysfs.h linux-2.6.22-590/fs/sysfs/sysfs.h -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); @@ -125045,14 +129618,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/sysfs.h linux-2.6.22-590/fs/sysfs/sysfs.h +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); @@ -125067,7 +129633,8 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/sysfs.h linux-2.6.22-590/fs/sysfs/sysfs.h + +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 **); @@ -125087,7 +129654,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/sysfs.h linux-2.6.22-590/fs/sysfs/sysfs.h 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; @@ -125163,7 +129730,7 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/sysfs.h linux-2.6.22-590/fs/sysfs/sysfs.h } 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) { @@ -125171,10 +129738,14 @@ diff -Nurb linux-2.6.22-570/fs/sysfs/sysfs.h linux-2.6.22-590/fs/sysfs/sysfs.h + 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 + @@ -125185,7 +129756,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/Makefile linux-2.6.22-590/fs/unionfs/Make +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 @@ -125937,7 +130508,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/commonfops.c linux-2.6.22-590/fs/unionfs/ +} 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 @@ -126747,7 +131318,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/copyup.c linux-2.6.22-590/fs/unionfs/copy +} 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 @@ -127104,7 +131675,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/dentry.c linux-2.6.22-590/fs/unionfs/dent +}; 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 @@ -127384,7 +131955,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/dirfops.c linux-2.6.22-590/fs/unionfs/dir +}; 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 @@ -127661,7 +132232,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/dirhelper.c linux-2.6.22-590/fs/unionfs/d +} 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 @@ -127973,7 +132544,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/fanout.h linux-2.6.22-590/fs/unionfs/fano +#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 @@ -128126,7 +132697,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/file.c linux-2.6.22-590/fs/unionfs/file.c +}; 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 @@ -129268,7 +133839,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/inode.c linux-2.6.22-590/fs/unionfs/inode +}; 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 @@ -129821,7 +134392,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/lookup.c linux-2.6.22-590/fs/unionfs/look +} 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 @@ -130554,7 +135125,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/main.c linux-2.6.22-590/fs/unionfs/main.c +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 @@ -130906,7 +135477,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/mmap.c linux-2.6.22-590/fs/unionfs/mmap.c +}; 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 @@ -131192,7 +135763,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/rdstate.c linux-2.6.22-590/fs/unionfs/rds +} 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 @@ -131673,7 +136244,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/rename.c linux-2.6.22-590/fs/unionfs/rena +} 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 @@ -131795,7 +136366,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/sioq.c linux-2.6.22-590/fs/unionfs/sioq.c +} 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 @@ -131890,7 +136461,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/sioq.h linux-2.6.22-590/fs/unionfs/sioq.h +#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 @@ -132132,7 +136703,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/subr.c linux-2.6.22-590/fs/unionfs/subr.c +} 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 @@ -133138,7 +137709,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/super.c linux-2.6.22-590/fs/unionfs/super +}; 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 @@ -133609,7 +138180,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/union.h linux-2.6.22-590/fs/unionfs/union +#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 @@ -133789,7 +138360,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/unlink.c linux-2.6.22-590/fs/unionfs/unli +} 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 @@ -133954,7 +138525,7 @@ diff -Nurb linux-2.6.22-570/fs/unionfs/xattr.c linux-2.6.22-590/fs/unionfs/xattr +} 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 @@ -134008,8 +138579,8 @@ diff -Nurb linux-2.6.22-570/fs/xfs/linux-2.6/xfs_file.c linux-2.6.22-590/fs/xfs/ .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); @@ -134020,7 +138591,7 @@ diff -Nurb linux-2.6.22-570/fs/xfs/linux-2.6/xfs_super.c linux-2.6.22-590/fs/xfs 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 @@ -134060,7 +138631,7 @@ diff -Nurb linux-2.6.22-570/include/acpi/acmacros.h linux-2.6.22-590/include/acp #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 */ @@ -134074,7 +138645,7 @@ diff -Nurb linux-2.6.22-570/include/acpi/acoutput.h linux-2.6.22-590/include/acp #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 */ @@ -134086,7 +138657,7 @@ diff -Nurb linux-2.6.22-570/include/acpi/platform/acenv.h linux-2.6.22-590/inclu #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 @@ -134099,8 +138670,8 @@ diff -Nurb linux-2.6.22-570/include/acpi/platform/aclinux.h linux-2.6.22-590/inc #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 @@ -134205,7 +138776,7 @@ diff -Nurb linux-2.6.22-570/include/acpi/processor.h linux-2.6.22-590/include/ac 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) @@ -134218,7 +138789,7 @@ diff -Nurb linux-2.6.22-570/include/asm-alpha/page.h linux-2.6.22-590/include/as 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. @@ -134766,7 +139337,7 @@ diff -Nurb linux-2.6.22-570/include/asm-arm/arch-iop13xx/adma.h linux-2.6.22-590 +#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) @@ -134818,7 +139389,7 @@ diff -Nurb linux-2.6.22-570/include/asm-arm/arch-iop13xx/iop13xx.h linux-2.6.22- #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 @@ -134827,7 +139398,7 @@ diff -Nurb linux-2.6.22-570/include/asm-arm/arch-iop32x/adma.h linux-2.6.22-590/ + 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 @@ -134836,7 +139407,7 @@ diff -Nurb linux-2.6.22-570/include/asm-arm/arch-iop33x/adma.h linux-2.6.22-590/ + 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. @@ -135731,7 +140302,7 @@ diff -Nurb linux-2.6.22-570/include/asm-arm/hardware/iop3xx-adma.h linux-2.6.22- +#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) @@ -135823,7 +140394,7 @@ diff -Nurb linux-2.6.22-570/include/asm-arm/hardware/iop3xx.h linux-2.6.22-590/i 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. @@ -135947,7 +140518,7 @@ diff -Nurb linux-2.6.22-570/include/asm-arm/hardware/iop_adma.h linux-2.6.22-590 +#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 @@ -136054,7 +140625,7 @@ diff -Nurb linux-2.6.22-570/include/asm-arm/kgdb.h linux-2.6.22-590/include/asm- +#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); @@ -136099,7 +140670,7 @@ diff -Nurb linux-2.6.22-570/include/asm-arm/system.h linux-2.6.22-590/include/as #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) @@ -136112,7 +140683,7 @@ diff -Nurb linux-2.6.22-570/include/asm-cris/page.h linux-2.6.22-590/include/asm /* 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 @@ -136216,7 +140787,7 @@ diff -Nurb linux-2.6.22-570/include/asm-generic/kgdb.h linux-2.6.22-590/include/ +#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) \ } \ @@ -136255,7 +140826,7 @@ diff -Nurb linux-2.6.22-570/include/asm-generic/vmlinux.lds.h linux-2.6.22-590/i 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) @@ -136268,7 +140839,7 @@ diff -Nurb linux-2.6.22-570/include/asm-h8300/page.h linux-2.6.22-590/include/as /* 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, @@ -136279,7 +140850,7 @@ diff -Nurb linux-2.6.22-570/include/asm-i386/kdebug.h linux-2.6.22-590/include/a #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_ @@ -136334,7 +140905,7 @@ diff -Nurb linux-2.6.22-570/include/asm-i386/kgdb.h linux-2.6.22-590/include/asm +#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) @@ -136347,7 +140918,7 @@ diff -Nurb linux-2.6.22-570/include/asm-i386/page.h linux-2.6.22-590/include/asm /* 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 @@ -136365,7 +140936,7 @@ diff -Nurb linux-2.6.22-570/include/asm-i386/unistd.h linux-2.6.22-590/include/a #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 @@ -136471,7 +141042,7 @@ diff -Nurb linux-2.6.22-570/include/asm-i386/unwind.h linux-2.6.22-590/include/a #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, @@ -136482,7 +141053,7 @@ diff -Nurb linux-2.6.22-570/include/asm-ia64/kdebug.h linux-2.6.22-590/include/a #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_ @@ -136523,7 +141094,7 @@ diff -Nurb linux-2.6.22-570/include/asm-ia64/kgdb.h linux-2.6.22-590/include/asm +#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) @@ -136539,7 +141110,7 @@ diff -Nurb linux-2.6.22-570/include/asm-ia64/page.h linux-2.6.22-590/include/asm 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; \ @@ -136554,7 +141125,7 @@ diff -Nurb linux-2.6.22-570/include/asm-ia64/processor.h linux-2.6.22-590/includ * 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) @@ -136567,7 +141138,7 @@ diff -Nurb linux-2.6.22-570/include/asm-m32r/page.h linux-2.6.22-590/include/asm /* 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) @@ -136580,7 +141151,7 @@ diff -Nurb linux-2.6.22-570/include/asm-m68knommu/page.h linux-2.6.22-590/includ /* 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 #include @@ -136640,7 +141211,7 @@ diff -Nurb linux-2.6.22-570/include/asm-mips/asmmacro-32.h linux-2.6.22-590/incl 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 #include @@ -136777,7 +141348,7 @@ diff -Nurb linux-2.6.22-570/include/asm-mips/asmmacro-64.h linux-2.6.22-590/incl 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 +/* @@ -136812,7 +141383,7 @@ diff -Nurb linux-2.6.22-570/include/asm-mips/kdebug.h linux-2.6.22-590/include/a +#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_ @@ -136857,7 +141428,7 @@ diff -Nurb linux-2.6.22-570/include/asm-mips/kgdb.h linux-2.6.22-590/include/asm +#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. */ @@ -136869,7 +141440,7 @@ diff -Nurb linux-2.6.22-570/include/asm-mips/ptrace.h linux-2.6.22-590/include/a #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 */ @@ -137107,7 +141678,7 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/cputable.h linux-2.6.22-590/incl #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); @@ -137134,7 +141705,7 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/floppy.h linux-2.6.22-590/includ 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 @@ -137183,7 +141754,7 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/io.h linux-2.6.22-590/include/as #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 @@ -137262,7 +141833,7 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/kgdb.h linux-2.6.22-590/include/ +#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 @@ -137274,7 +141845,7 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/lppaca.h linux-2.6.22-590/includ 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_ @@ -137369,7 +141940,7 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/mmu-hash32.h linux-2.6.22-590/in +#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__ @@ -137388,7 +141959,7 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/mmu-hash64.h linux-2.6.22-590/in 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 */ @@ -137401,7 +141972,7 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/mmu.h linux-2.6.22-590/include/a # include 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; @@ -137454,7 +142025,7 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/pci-bridge.h linux-2.6.22-590/in #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; } @@ -137468,7 +142039,7 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/pci.h linux-2.6.22-590/include/a 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 @@ -137550,7 +142121,7 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/pgtable-ppc32.h linux-2.6.22-590 */ 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__ @@ -137655,7 +142226,7 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/pgtable-ppc64.h linux-2.6.22-590 /* 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__ @@ -137700,7 +142271,7 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/pgtable.h linux-2.6.22-590/inclu 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); @@ -137733,7 +142304,7 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/ppc-pci.h linux-2.6.22-590/inclu #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) @@ -137791,7 +142362,7 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/ptrace.h linux-2.6.22-590/includ #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, @@ -137810,8 +142381,8 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/syscalls.h linux-2.6.22-590/incl #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) @@ -137819,7 +142390,7 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/systbl.h linux-2.6.22-590/includ +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 */ @@ -137862,7 +142433,7 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/thread_info.h linux-2.6.22-590/i #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 @@ { } @@ -137876,8 +142447,8 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/tlbflush.h linux-2.6.22-590/incl /* 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 @@ -137893,7 +142464,7 @@ diff -Nurb linux-2.6.22-570/include/asm-powerpc/unistd.h linux-2.6.22-590/includ #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 @@ -137962,7 +142533,7 @@ diff -Nurb linux-2.6.22-570/include/asm-ppc/kgdb.h linux-2.6.22-590/include/asm- #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); @@ -137975,7 +142546,7 @@ diff -Nurb linux-2.6.22-570/include/asm-ppc/machdep.h linux-2.6.22-590/include/a 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); @@ -137987,7 +142558,7 @@ diff -Nurb linux-2.6.22-570/include/asm-ppc/mv64x60.h linux-2.6.22-590/include/a 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 @@ -138000,7 +142571,7 @@ diff -Nurb linux-2.6.22-570/include/asm-ppc/mv64x60_defs.h linux-2.6.22-590/incl #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) @@ -138013,7 +142584,7 @@ diff -Nurb linux-2.6.22-570/include/asm-s390/page.h linux-2.6.22-590/include/asm /* 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. @@ -138118,7 +142689,7 @@ diff -Nurb linux-2.6.22-570/include/asm-sh/kgdb.h linux-2.6.22-590/include/asm-s #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 @@ -138167,7 +142738,7 @@ diff -Nurb linux-2.6.22-570/include/asm-sh/system.h linux-2.6.22-590/include/asm */ 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; } @@ -138194,7 +142765,7 @@ diff -Nurb linux-2.6.22-570/include/asm-um/thread_info.h linux-2.6.22-590/includ 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, @@ -138205,7 +142776,7 @@ diff -Nurb linux-2.6.22-570/include/asm-x86_64/kdebug.h linux-2.6.22-590/include 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_ @@ -138261,7 +142832,7 @@ diff -Nurb linux-2.6.22-570/include/asm-x86_64/kgdb.h linux-2.6.22-590/include/a +#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) @@ -138274,7 +142845,7 @@ diff -Nurb linux-2.6.22-570/include/asm-x86_64/page.h linux-2.6.22-590/include/a * 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); @@ -138286,7 +142857,7 @@ diff -Nurb linux-2.6.22-570/include/asm-x86_64/proto.h linux-2.6.22-590/include/ 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 */ @@ -138308,8 +142879,8 @@ diff -Nurb linux-2.6.22-570/include/asm-x86_64/system.h linux-2.6.22-590/include : [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 @@ -138321,7 +142892,7 @@ diff -Nurb linux-2.6.22-570/include/asm-x86_64/unistd.h linux-2.6.22-590/include #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 @@ -138431,8 +143002,8 @@ diff -Nurb linux-2.6.22-570/include/asm-x86_64/unwind.h linux-2.6.22-590/include + #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 @@ -138443,7 +143014,7 @@ diff -Nurb linux-2.6.22-570/include/linux/Kbuild linux-2.6.22-590/include/linux/ 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; @@ -138460,7 +143031,7 @@ diff -Nurb linux-2.6.22-570/include/linux/acpi.h linux-2.6.22-590/include/linux/ 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. @@ -138620,7 +143191,7 @@ diff -Nurb linux-2.6.22-570/include/linux/async_tx.h linux-2.6.22-590/include/li +#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, @@ -138651,7 +143222,7 @@ diff -Nurb linux-2.6.22-570/include/linux/configfs.h linux-2.6.22-590/include/li #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 @@ -138950,7 +143521,7 @@ diff -Nurb linux-2.6.22-570/include/linux/container.h linux-2.6.22-590/include/l +#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() in this + * file. Surround each one by a line of comment markers so that @@ -138986,7 +143557,7 @@ diff -Nurb linux-2.6.22-570/include/linux/container_subsys.h linux-2.6.22-590/in +/* */ 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 @@ -139004,7 +143575,7 @@ diff -Nurb linux-2.6.22-570/include/linux/cpu_acct.h linux-2.6.22-590/include/li +#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 @@ -139197,7 +143768,7 @@ diff -Nurb linux-2.6.22-570/include/linux/cpuidle.h linux-2.6.22-590/include/lin +#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 #include @@ -139245,8 +143816,17 @@ diff -Nurb linux-2.6.22-570/include/linux/cpuset.h linux-2.6.22-590/include/linu #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. @@ -139254,7 +143834,7 @@ diff -Nurb linux-2.6.22-570/include/linux/device.h linux-2.6.22-590/include/linu * @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" */ @@ -139263,7 +143843,7 @@ diff -Nurb linux-2.6.22-570/include/linux/device.h linux-2.6.22-590/include/linu 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; @@ -139274,7 +143854,7 @@ diff -Nurb linux-2.6.22-570/include/linux/device.h linux-2.6.22-590/include/linu * 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 @@ -139719,7 +144299,7 @@ diff -Nurb linux-2.6.22-570/include/linux/dmaengine.h linux-2.6.22-590/include/l #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); @@ -139735,7 +144315,7 @@ diff -Nurb linux-2.6.22-570/include/linux/etherdevice.h linux-2.6.22-590/include * 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); } @@ -139758,8 +144338,8 @@ diff -Nurb linux-2.6.22-570/include/linux/freezer.h linux-2.6.22-590/include/lin +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 @@ -139829,7 +144409,7 @@ diff -Nurb linux-2.6.22-570/include/linux/fs.h linux-2.6.22-590/include/linux/fs #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 @@ -139863,7 +144443,7 @@ diff -Nurb linux-2.6.22-570/include/linux/fs_stack.h linux-2.6.22-590/include/li 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. * @@ -139934,7 +144514,7 @@ diff -Nurb linux-2.6.22-570/include/linux/gfp.h linux-2.6.22-590/include/linux/g * 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 @@ } @@ -140004,7 +144584,7 @@ diff -Nurb linux-2.6.22-570/include/linux/highmem.h linux-2.6.22-590/include/lin 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 @@ } @@ -140022,9 +144602,58 @@ diff -Nurb linux-2.6.22-570/include/linux/hugetlb.h linux-2.6.22-590/include/lin 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 + +-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, @@ -140084,9 +144713,21 @@ diff -Nurb linux-2.6.22-570/include/linux/if_link.h linux-2.6.22-590/include/lin +}; + #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; @@ -140105,7 +144746,16 @@ diff -Nurb linux-2.6.22-570/include/linux/if_tun.h linux-2.6.22-590/include/linu #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 @@ } @@ -140138,20 +144788,84 @@ diff -Nurb linux-2.6.22-570/include/linux/if_vlan.h linux-2.6.22-590/include/lin 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 #include #include +#include ++#include #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, \ } @@ -140159,7 +144873,7 @@ diff -Nurb linux-2.6.22-570/include/linux/init_task.h linux-2.6.22-590/include/l #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); @@ -140222,8 +144936,8 @@ diff -Nurb linux-2.6.22-570/include/linux/ip_mp_alg.h linux-2.6.22-590/include/l -#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 @@ -140264,7 +144978,7 @@ diff -Nurb linux-2.6.22-570/include/linux/ipc.h linux-2.6.22-590/include/linux/i - 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; @@ -140276,7 +144990,7 @@ diff -Nurb linux-2.6.22-570/include/linux/ipv6.h linux-2.6.22-590/include/linux/ 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 @@ -140571,7 +145285,7 @@ diff -Nurb linux-2.6.22-570/include/linux/kgdb.h linux-2.6.22-590/include/linux/ +#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))) @@ -140636,7 +145350,7 @@ diff -Nurb linux-2.6.22-570/include/linux/kmod.h linux-2.6.22-590/include/linux/ 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; @@ -140646,25 +145360,23 @@ diff -Nurb linux-2.6.22-570/include/linux/kobject.h linux-2.6.22-590/include/lin 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; } @@ -140683,8 +145395,8 @@ diff -Nurb linux-2.6.22-570/include/linux/ktime.h linux-2.6.22-590/include/linux * 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" @@ -140700,7 +145412,7 @@ diff -Nurb linux-2.6.22-570/include/linux/magic.h linux-2.6.22-590/include/linux #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); @@ -140747,8 +145459,17 @@ diff -Nurb linux-2.6.22-570/include/linux/mempolicy.h linux-2.6.22-590/include/l 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 */ @@ -140762,7 +145483,7 @@ diff -Nurb linux-2.6.22-570/include/linux/mm.h linux-2.6.22-590/include/linux/mm #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]; @@ -140788,7 +145509,7 @@ diff -Nurb linux-2.6.22-570/include/linux/mm.h linux-2.6.22-590/include/linux/mm /* * 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); @@ -140807,7 +145528,7 @@ diff -Nurb linux-2.6.22-570/include/linux/mm.h linux-2.6.22-590/include/linux/mm /* 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)) @@ -140815,7 +145536,7 @@ diff -Nurb linux-2.6.22-570/include/linux/mm.h linux-2.6.22-590/include/linux/mm /* * 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 *); @@ -140832,7 +145553,7 @@ diff -Nurb linux-2.6.22-570/include/linux/mm.h linux-2.6.22-590/include/linux/mm 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 *); @@ -140840,7 +145561,7 @@ diff -Nurb linux-2.6.22-570/include/linux/mm.h linux-2.6.22-590/include/linux/mm 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 */ @@ -140855,7 +145576,7 @@ diff -Nurb linux-2.6.22-570/include/linux/mm.h linux-2.6.22-590/include/linux/mm /* 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); @@ -140865,7 +145586,7 @@ diff -Nurb linux-2.6.22-570/include/linux/mm.h linux-2.6.22-590/include/linux/mm 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 */ @@ -140893,7 +145614,7 @@ diff -Nurb linux-2.6.22-570/include/linux/mmc/card.h linux-2.6.22-590/include/li #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 */ @@ -140910,7 +145631,7 @@ diff -Nurb linux-2.6.22-570/include/linux/mmc/mmc.h linux-2.6.22-590/include/lin 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 #include @@ -140988,7 +145709,7 @@ diff -Nurb linux-2.6.22-570/include/linux/mmzone.h linux-2.6.22-590/include/linu #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; }; @@ -141000,7 +145721,7 @@ diff -Nurb linux-2.6.22-570/include/linux/mnt_namespace.h linux-2.6.22-590/inclu 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, @@ -141035,7 +145756,7 @@ diff -Nurb linux-2.6.22-570/include/linux/module.h linux-2.6.22-590/include/linu 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 @@ -141079,10 +145800,38 @@ diff -Nurb linux-2.6.22-570/include/linux/namei.h linux-2.6.22-590/include/linux +} + #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 + #include + ++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. */ @@ -141094,7 +145843,15 @@ diff -Nurb linux-2.6.22-570/include/linux/netdevice.h linux-2.6.22-590/include/l #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) @@ -141107,7 +145864,17 @@ diff -Nurb linux-2.6.22-570/include/linux/netdevice.h linux-2.6.22-590/include/l 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]; @@ -141125,10 +145892,184 @@ diff -Nurb linux-2.6.22-570/include/linux/netdevice.h linux-2.6.22-590/include/l { return (char *)dev + ((sizeof(struct net_device) + NETDEV_ALIGN_CONST) +@@ -576,45 +588,48 @@ + #include + #include + +-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 +-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 + 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 @@ -141137,9 +146078,34 @@ diff -Nurb linux-2.6.22-570/include/linux/netlink.h linux-2.6.22-590/include/lin #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]; @@ -141151,7 +146117,7 @@ diff -Nurb linux-2.6.22-570/include/linux/netpoll.h linux-2.6.22-590/include/lin 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 @@ -141162,7 +146128,7 @@ diff -Nurb linux-2.6.22-570/include/linux/nfs4.h linux-2.6.22-590/include/linux/ #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 */ @@ -141173,7 +146139,7 @@ diff -Nurb linux-2.6.22-570/include/linux/nfs4_mount.h linux-2.6.22-590/include/ #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__ @@ -141212,7 +146178,7 @@ diff -Nurb linux-2.6.22-570/include/linux/nfs_fs.h linux-2.6.22-590/include/linu /* 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 */ @@ -141222,8 +146188,8 @@ diff -Nurb linux-2.6.22-570/include/linux/nfs_fs_sb.h linux-2.6.22-590/include/l #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 */ @@ -141234,7 +146200,7 @@ diff -Nurb linux-2.6.22-570/include/linux/nfs_mount.h linux-2.6.22-590/include/l 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 #include @@ -141331,7 +146297,7 @@ diff -Nurb linux-2.6.22-570/include/linux/nfs_page.h linux-2.6.22-590/include/li 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; @@ -141341,8 +146307,8 @@ diff -Nurb linux-2.6.22-570/include/linux/nfs_xdr.h linux-2.6.22-590/include/lin /* 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; @@ -141356,17 +146322,23 @@ diff -Nurb linux-2.6.22-570/include/linux/nsproxy.h linux-2.6.22-590/include/lin /* * 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 @@ -141421,8 +146393,8 @@ diff -Nurb linux-2.6.22-570/include/linux/pageblock-flags.h linux-2.6.22-590/inc + +#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 @@ -141433,7 +146405,7 @@ diff -Nurb linux-2.6.22-570/include/linux/pci_ids.h linux-2.6.22-590/include/lin #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); } @@ -141445,7 +146417,7 @@ diff -Nurb linux-2.6.22-570/include/linux/pid_namespace.h linux-2.6.22-590/inclu 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); @@ -141459,7 +146431,7 @@ diff -Nurb linux-2.6.22-570/include/linux/pnp.h linux-2.6.22-590/include/linux/p 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 */ @@ -141470,9 +146442,18 @@ diff -Nurb linux-2.6.22-570/include/linux/prctl.h linux-2.6.22-590/include/linux + #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 *); @@ -141480,9 +146461,64 @@ diff -Nurb linux-2.6.22-570/include/linux/proc_fs.h linux-2.6.22-590/include/lin 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 @@ -141623,7 +146659,7 @@ diff -Nurb linux-2.6.22-570/include/linux/raid/raid5.h linux-2.6.22-590/include/ * 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 @@ -141639,7 +146675,7 @@ diff -Nurb linux-2.6.22-570/include/linux/raid/xor.h linux-2.6.22-590/include/li 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); @@ -141654,7 +146690,7 @@ diff -Nurb linux-2.6.22-570/include/linux/reboot.h linux-2.6.22-590/include/linu */ 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 @@ -141676,7 +146712,7 @@ diff -Nurb linux-2.6.22-570/include/linux/revoked_fs_i.h linux-2.6.22-590/includ +#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, @@ -141686,7 +146722,7 @@ diff -Nurb linux-2.6.22-570/include/linux/rtnetlink.h linux-2.6.22-590/include/l 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); @@ -141696,13 +146732,22 @@ diff -Nurb linux-2.6.22-570/include/linux/rtnetlink.h linux-2.6.22-590/include/l #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; }) @@ -141723,17 +146768,19 @@ diff -Nurb linux-2.6.22-570/include/linux/rtnetlink.h linux-2.6.22-590/include/l ({ 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; @@ -141741,7 +146788,7 @@ diff -Nurb linux-2.6.22-570/include/linux/sched.h linux-2.6.22-590/include/linux /* 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) @@ -141769,7 +146816,7 @@ diff -Nurb linux-2.6.22-570/include/linux/sched.h linux-2.6.22-590/include/linux 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; @@ -141778,7 +146825,7 @@ diff -Nurb linux-2.6.22-570/include/linux/sched.h linux-2.6.22-590/include/linux /* coredumping support */ int core_waiters; -@@ -757,9 +780,6 @@ +@@ -757,9 +781,6 @@ #endif }; @@ -141788,7 +146835,7 @@ diff -Nurb linux-2.6.22-570/include/linux/sched.h linux-2.6.22-590/include/linux /* * 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 */ @@ -141797,7 +146844,7 @@ diff -Nurb linux-2.6.22-570/include/linux/sched.h linux-2.6.22-590/include/linux #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 */ @@ -141806,7 +146853,7 @@ diff -Nurb linux-2.6.22-570/include/linux/sched.h linux-2.6.22-590/include/linux /* 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 @@ -141824,7 +146871,7 @@ diff -Nurb linux-2.6.22-570/include/linux/sched.h linux-2.6.22-590/include/linux 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 @@ -141836,7 +146883,7 @@ diff -Nurb linux-2.6.22-570/include/linux/sched.h linux-2.6.22-590/include/linux * 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 @@ -141875,7 +146922,7 @@ diff -Nurb linux-2.6.22-570/include/linux/seccomp.h linux-2.6.22-590/include/lin #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); @@ -141924,7 +146971,7 @@ diff -Nurb linux-2.6.22-570/include/linux/security.h linux-2.6.22-590/include/li } 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 *); @@ -141935,7 +146982,7 @@ diff -Nurb linux-2.6.22-570/include/linux/serial_8250.h linux-2.6.22-590/include 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); @@ -141953,8 +147000,8 @@ diff -Nurb linux-2.6.22-570/include/linux/signal.h linux-2.6.22-590/include/linu * 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 @@ -142009,7 +147056,7 @@ diff -Nurb linux-2.6.22-570/include/linux/skbuff.h linux-2.6.22-590/include/linu * @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 */ @@ -142026,9 +147073,20 @@ diff -Nurb linux-2.6.22-570/include/linux/slab.h linux-2.6.22-590/include/linux/ /* * 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 /* pid_t */ + #include /* __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 @@ -142043,8 +147101,8 @@ diff -Nurb linux-2.6.22-570/include/linux/string.h linux-2.6.22-590/include/linu } #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 @@ -142152,7 +147210,7 @@ diff -Nurb linux-2.6.22-570/include/linux/sunrpc/auth.h linux-2.6.22-590/include 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; }; @@ -142166,8 +147224,8 @@ diff -Nurb linux-2.6.22-570/include/linux/sunrpc/auth_gss.h linux-2.6.22-590/inc #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 */ @@ -142233,7 +147291,7 @@ diff -Nurb linux-2.6.22-570/include/linux/sunrpc/clnt.h linux-2.6.22-590/include 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; @@ -142245,7 +147303,7 @@ diff -Nurb linux-2.6.22-570/include/linux/sunrpc/gss_api.h linux-2.6.22-590/incl 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; @@ -142260,7 +147318,7 @@ diff -Nurb linux-2.6.22-570/include/linux/sunrpc/rpc_pipe_fs.h linux-2.6.22-590/ 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)) @@ -142274,8 +147332,8 @@ diff -Nurb linux-2.6.22-570/include/linux/sunrpc/sched.h linux-2.6.22-590/includ 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); @@ -142299,9 +147357,17 @@ diff -Nurb linux-2.6.22-570/include/linux/syscalls.h linux-2.6.22-590/include/li + #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 */ @@ -142309,7 +147375,7 @@ diff -Nurb linux-2.6.22-570/include/linux/sysctl.h linux-2.6.22-590/include/linu }; -@@ -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 */ @@ -142317,7 +147383,7 @@ diff -Nurb linux-2.6.22-570/include/linux/sysctl.h linux-2.6.22-590/include/linu /* s390 vm cmm sysctls */ VM_CMM_PAGES=1111, -@@ -843,6 +845,9 @@ +@@ -843,6 +846,9 @@ }; /* CTL_DEBUG names: */ @@ -142327,9 +147393,30 @@ diff -Nurb linux-2.6.22-570/include/linux/sysctl.h linux-2.6.22-590/include/linu /* 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) \ @@ -142341,13 +147428,14 @@ diff -Nurb linux-2.6.22-570/include/linux/sysdev.h linux-2.6.22-590/include/linu .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 @@ -142356,7 +147444,7 @@ diff -Nurb linux-2.6.22-570/include/linux/sysfs.h linux-2.6.22-590/include/linux struct attribute { const char * name; struct module * owner; -@@ -41,13 +46,13 @@ +@@ -41,13 +43,13 @@ */ #define __ATTR(_name,_mode,_show,_store) { \ @@ -142372,7 +147460,7 @@ diff -Nurb linux-2.6.22-570/include/linux/sysfs.h linux-2.6.22-590/include/linux .show = _name##_show, \ } -@@ -61,8 +66,10 @@ +@@ -61,8 +63,10 @@ struct attribute attr; size_t size; void *private; @@ -142385,10 +147473,15 @@ diff -Nurb linux-2.6.22-570/include/linux/sysfs.h linux-2.6.22-590/include/linux 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 @@ -142396,65 +147489,110 @@ diff -Nurb linux-2.6.22-570/include/linux/sysfs.h linux-2.6.22-590/include/linux #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 @@ */ @@ -142476,7 +147614,7 @@ diff -Nurb linux-2.6.22-570/include/linux/taskstats.h linux-2.6.22-590/include/l 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 @@ -142512,9 +147650,21 @@ diff -Nurb linux-2.6.22-570/include/linux/tick.h linux-2.6.22-590/include/linux/ # 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 @@ -142547,7 +147697,7 @@ diff -Nurb linux-2.6.22-570/include/linux/union_fs.h linux-2.6.22-590/include/li + 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; @@ -142634,9 +147784,43 @@ diff -Nurb linux-2.6.22-570/include/linux/unwind.h linux-2.6.22-590/include/linu +#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 @@ -142701,7 +147885,7 @@ diff -Nurb linux-2.6.22-570/include/linux/user_namespace.h linux-2.6.22-590/incl +#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); } @@ -142733,7 +147917,7 @@ diff -Nurb linux-2.6.22-570/include/linux/utsname.h linux-2.6.22-590/include/lin 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); @@ -142747,8 +147931,8 @@ diff -Nurb linux-2.6.22-570/include/linux/vmalloc.h linux-2.6.22-590/include/lin /* * 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, @@ -142758,9 +147942,41 @@ diff -Nurb linux-2.6.22-570/include/net/addrconf.h linux-2.6.22-590/include/net/ 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 @@ -142769,10 +147985,51 @@ diff -Nurb linux-2.6.22-570/include/net/dst.h linux-2.6.22-590/include/net/dst.h 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 ++#include + #include + + struct flowi { ++ struct net *fl_net; + int oif; + int iif; + __u32 mark; +@@ -67,20 +69,16 @@ __be32 spi; @@ -142793,9 +148050,368 @@ diff -Nurb linux-2.6.22-570/include/net/flow.h linux-2.6.22-590/include/net/flow __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 + #include + ++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; @@ -142804,17 +148420,15 @@ diff -Nurb linux-2.6.22-570/include/net/ip_fib.h linux-2.6.22-590/include/net/ip 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; @@ -142825,7 +148439,7 @@ diff -Nurb linux-2.6.22-570/include/net/ip_fib.h linux-2.6.22-590/include/net/ip 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) @@ -142840,6 +148454,99 @@ diff -Nurb linux-2.6.22-570/include/net/ip_fib.h linux-2.6.22-590/include/net/ip 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 @@ -142940,9 +148647,21 @@ diff -Nurb linux-2.6.22-570/include/net/ip_mp_alg.h linux-2.6.22-590/include/net -} - -#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 @@ -142952,9 +148671,304 @@ diff -Nurb linux-2.6.22-570/include/net/mip6.h linux-2.6.22-590/include/net/mip6 -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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 @@ -142989,7 +149003,15 @@ diff -Nurb linux-2.6.22-570/include/net/netlink.h linux-2.6.22-590/include/net/n * 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); } @@ -143029,7 +149051,7 @@ diff -Nurb linux-2.6.22-570/include/net/netlink.h linux-2.6.22-590/include/net/n /** * 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 @@ } /** @@ -143081,9 +149103,52 @@ diff -Nurb linux-2.6.22-570/include/net/netlink.h linux-2.6.22-590/include/net/n * 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 ++#include + #include + #include + +@@ -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__ @@ -143108,9 +149173,17 @@ diff -Nurb linux-2.6.22-570/include/net/rawv6.h linux-2.6.22-590/include/net/raw #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 + #include + #include ++#include + #include + #include + #include +@@ -66,7 +67,6 @@ unsigned rt_flags; __u16 rt_type; @@ -143118,9 +149191,39 @@ diff -Nurb linux-2.6.22-570/include/net/route.h linux-2.6.22-590/include/net/rou __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; } @@ -143184,9 +149287,100 @@ diff -Nurb linux-2.6.22-570/include/net/rtnetlink.h linux-2.6.22-590/include/net +#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 + #include + #include ++#include + + /* + * 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 @@ -143214,10 +149408,63 @@ diff -Nurb linux-2.6.22-570/include/net/tipc/tipc_port.h linux-2.6.22-590/includ 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 #include @@ -143236,8 +149483,12 @@ diff -Nurb linux-2.6.22-570/include/net/xfrm.h linux-2.6.22-590/include/net/xfrm + 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; @@ -143251,7 +149502,7 @@ diff -Nurb linux-2.6.22-570/include/net/xfrm.h linux-2.6.22-590/include/net/xfrm } 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, @@ -143330,7 +149581,7 @@ diff -Nurb linux-2.6.22-570/include/scsi/iscsi_if.h linux-2.6.22-590/include/scs * 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 @@ -143499,7 +149750,7 @@ diff -Nurb linux-2.6.22-570/include/scsi/libiscsi.h linux-2.6.22-590/include/scs 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); @@ -143527,7 +149778,7 @@ diff -Nurb linux-2.6.22-570/include/scsi/scsi_cmnd.h linux-2.6.22-590/include/sc #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 *); @@ -143538,7 +149789,7 @@ diff -Nurb linux-2.6.22-570/include/scsi/scsi_device.h linux-2.6.22-590/include/ 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 *); @@ -143565,7 +149816,7 @@ diff -Nurb linux-2.6.22-570/include/scsi/scsi_host.h linux-2.6.22-590/include/sc 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 @@ * * ======== @@ -143849,7 +150100,7 @@ diff -Nurb linux-2.6.22-570/include/scsi/scsi_transport_fc.h linux-2.6.22-590/in #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; @@ -143901,8 +150152,8 @@ diff -Nurb linux-2.6.22-570/include/scsi/scsi_transport_iscsi.h linux-2.6.22-590 }; 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 . @@ -144047,7 +150298,7 @@ diff -Nurb linux-2.6.22-570/init/Kconfig linux-2.6.22-590/init/Kconfig 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("."); @@ -144064,8 +150315,8 @@ diff -Nurb linux-2.6.22-570/init/do_mounts_initrd.c linux-2.6.22-590/init/do_mou /* 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 #include @@ -144091,8 +150342,8 @@ diff -Nurb linux-2.6.22-570/init/main.c linux-2.6.22-590/init/main.c 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 @@ -144119,8 +150370,8 @@ diff -Nurb linux-2.6.22-570/ipc/msg.c linux-2.6.22-590/ipc/msg.c 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] @@ -144147,8 +150398,8 @@ diff -Nurb linux-2.6.22-570/ipc/sem.c linux-2.6.22-590/ipc/sem.c 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 @@ -144209,8 +150460,8 @@ diff -Nurb linux-2.6.22-570/ipc/shm.c linux-2.6.22-590/ipc/shm.c .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 @@ }, }; @@ -144245,7 +150496,7 @@ diff -Nurb linux-2.6.22-570/ipc/util.c linux-2.6.22-590/ipc/util.c 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 @@ }; @@ -144262,8 +150513,8 @@ diff -Nurb linux-2.6.22-570/ipc/util.h linux-2.6.22-590/ipc/util.h 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 \ @@ -144312,7 +150563,7 @@ diff -Nurb linux-2.6.22-570/kernel/Makefile linux-2.6.22-590/kernel/Makefile 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; @@ -144321,9 +150572,20 @@ diff -Nurb linux-2.6.22-570/kernel/audit.c linux-2.6.22-590/kernel/audit.c 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; } @@ -144334,7 +150596,7 @@ diff -Nurb linux-2.6.22-570/kernel/auditsc.c linux-2.6.22-590/kernel/auditsc.c * 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 @@ -146698,7 +152960,7 @@ diff -Nurb linux-2.6.22-570/kernel/container.c linux-2.6.22-590/kernel/container + } + + /* 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) { @@ -146883,7 +153145,7 @@ diff -Nurb linux-2.6.22-570/kernel/container.c linux-2.6.22-590/kernel/container +} 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 @@ -146976,7 +153238,7 @@ diff -Nurb linux-2.6.22-570/kernel/container_debug.c linux-2.6.22-590/kernel/con +}; 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 @@ -147165,7 +153427,7 @@ diff -Nurb linux-2.6.22-570/kernel/cpu_acct.c linux-2.6.22-590/kernel/cpu_acct.c +}; 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. @@ -149044,8 +155306,8 @@ diff -Nurb linux-2.6.22-570/kernel/cpuset.c linux-2.6.22-590/kernel/cpuset.c /* Display task cpus_allowed, mems_allowed in /proc//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 #include @@ -149115,8 +155377,8 @@ diff -Nurb linux-2.6.22-570/kernel/exit.c linux-2.6.22-590/kernel/exit.c 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 #include @@ -149148,7 +155410,7 @@ diff -Nurb linux-2.6.22-570/kernel/fork.c linux-2.6.22-590/kernel/fork.c { 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; @@ -149238,7 +155500,7 @@ diff -Nurb linux-2.6.22-570/kernel/fork.c linux-2.6.22-590/kernel/fork.c 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 @@ -151108,7 +157370,7 @@ diff -Nurb linux-2.6.22-570/kernel/kgdb.c linux-2.6.22-590/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; @@ -151404,7 +157666,7 @@ diff -Nurb linux-2.6.22-570/kernel/kmod.c linux-2.6.22-590/kernel/kmod.c 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); @@ -151572,7 +157834,7 @@ diff -Nurb linux-2.6.22-570/kernel/module.c linux-2.6.22-590/kernel/module.c 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 @@ -151674,9 +157936,14 @@ diff -Nurb linux-2.6.22-570/kernel/ns_container.c linux-2.6.22-590/kernel/ns_con + .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 + #include + #include ++#include + #include #include #include @@ -151685,23 +157952,40 @@ diff -Nurb linux-2.6.22-570/kernel/nsproxy.c linux-2.6.22-590/kernel/nsproxy.c 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: @@ -151716,7 +158000,7 @@ diff -Nurb linux-2.6.22-570/kernel/nsproxy.c linux-2.6.22-590/kernel/nsproxy.c 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. */ @@ -151725,16 +158009,24 @@ diff -Nurb linux-2.6.22-570/kernel/nsproxy.c linux-2.6.22-590/kernel/nsproxy.c { 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; } @@ -151749,13 +158041,13 @@ diff -Nurb linux-2.6.22-570/kernel/nsproxy.c linux-2.6.22-590/kernel/nsproxy.c 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 @@ -151765,8 +158057,10 @@ diff -Nurb linux-2.6.22-570/kernel/nsproxy.c linux-2.6.22-590/kernel/nsproxy.c - -#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; @@ -151795,9 +158089,277 @@ diff -Nurb linux-2.6.22-570/kernel/nsproxy.c linux-2.6.22-590/kernel/nsproxy.c +} + +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 ++ * ++ * 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 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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; @@ -151807,8 +158369,8 @@ diff -Nurb linux-2.6.22-570/kernel/params.c linux-2.6.22-590/kernel/params.c *(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); @@ -151819,8 +158381,8 @@ diff -Nurb linux-2.6.22-570/kernel/pid.c linux-2.6.22-590/kernel/pid.c 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(); @@ -151832,7 +158394,7 @@ diff -Nurb linux-2.6.22-570/kernel/ptrace.c linux-2.6.22-590/kernel/ptrace.c 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 #include @@ -151867,7 +158429,7 @@ diff -Nurb linux-2.6.22-570/kernel/rcutorture.c linux-2.6.22-590/kernel/rcutortu 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; @@ -151877,8 +158439,8 @@ diff -Nurb linux-2.6.22-570/kernel/rtmutex-tester.c linux-2.6.22-590/kernel/rtmu 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 #include @@ -151995,7 +158557,7 @@ diff -Nurb linux-2.6.22-570/kernel/sched.c linux-2.6.22-590/kernel/sched.c 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 @@ -152034,8 +158596,8 @@ diff -Nurb linux-2.6.22-570/kernel/seccomp.c linux-2.6.22-590/kernel/seccomp.c + 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 @@ } } @@ -152054,8 +158616,8 @@ diff -Nurb linux-2.6.22-570/kernel/signal.c linux-2.6.22-590/kernel/signal.c /* 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 #include @@ -152086,7 +158648,7 @@ diff -Nurb linux-2.6.22-570/kernel/softirq.c linux-2.6.22-590/kernel/softirq.c 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 #include @@ -152118,8 +158680,8 @@ diff -Nurb linux-2.6.22-570/kernel/softlockup.c linux-2.6.22-590/kernel/softlock /* 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 #include @@ -152310,14 +158872,15 @@ diff -Nurb linux-2.6.22-570/kernel/sys.c linux-2.6.22-590/kernel/sys.c +} +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 #include #include +#include +#include ++#include #include #include @@ -152328,7 +158891,18 @@ diff -Nurb linux-2.6.22-570/kernel/sysctl.c linux-2.6.22-590/kernel/sysctl.c #ifdef CONFIG_X86 #include #include -@@ -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, }, @@ -152340,7 +158914,7 @@ diff -Nurb linux-2.6.22-570/kernel/sysctl.c linux-2.6.22-590/kernel/sysctl.c { .ctl_name = 0 } }; -@@ -217,6 +219,15 @@ +@@ -217,6 +224,15 @@ .proc_handler = &proc_dointvec, }, { @@ -152356,7 +158930,7 @@ diff -Nurb linux-2.6.22-570/kernel/sysctl.c linux-2.6.22-590/kernel/sysctl.c .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 @@ -152378,7 +158952,7 @@ diff -Nurb linux-2.6.22-570/kernel/sysctl.c linux-2.6.22-590/kernel/sysctl.c { .ctl_name = 0 } }; -@@ -744,6 +768,14 @@ +@@ -744,6 +773,14 @@ .mode = 0644, .proc_handler = &proc_dointvec, }, @@ -152393,7 +158967,7 @@ diff -Nurb linux-2.6.22-570/kernel/sysctl.c linux-2.6.22-590/kernel/sysctl.c #endif { .ctl_name = VM_LOWMEM_RESERVE_RATIO, -@@ -892,6 +924,10 @@ +@@ -892,6 +929,10 @@ .extra1 = &zero, }, #endif @@ -152404,7 +158978,7 @@ diff -Nurb linux-2.6.22-570/kernel/sysctl.c linux-2.6.22-590/kernel/sysctl.c { .ctl_name = 0 } }; -@@ -1032,10 +1068,28 @@ +@@ -1032,10 +1073,28 @@ .child = binfmt_misc_table, }, #endif @@ -152433,9 +159007,252 @@ diff -Nurb linux-2.6.22-570/kernel/sysctl.c linux-2.6.22-590/kernel/sysctl.c { .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 */ @@ -152456,7 +159273,7 @@ diff -Nurb linux-2.6.22-570/kernel/taskstats.c linux-2.6.22-590/kernel/taskstats 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; @@ -152500,9 +159317,72 @@ diff -Nurb linux-2.6.22-570/kernel/time/tick-sched.c linux-2.6.22-590/kernel/tim * 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 #include @@ -152523,9 +159403,17 @@ diff -Nurb linux-2.6.22-570/kernel/timer.c linux-2.6.22-590/kernel/timer.c 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. @@ -153816,8 +160704,8 @@ diff -Nurb linux-2.6.22-570/kernel/unwind.c linux-2.6.22-590/kernel/unwind.c +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 #include @@ -153835,51 +160723,261 @@ diff -Nurb linux-2.6.22-570/kernel/user.c linux-2.6.22-590/kernel/user.c #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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * 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 @@ -153969,9 +161067,17 @@ diff -Nurb linux-2.6.22-570/kernel/user_namespace.c linux-2.6.22-590/kernel/user + +#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 + #include + #include ++#include + + /* + * 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); @@ -153987,7 +161093,7 @@ diff -Nurb linux-2.6.22-570/kernel/utsname.c linux-2.6.22-590/kernel/utsname.c return ns; } -@@ -39,7 +40,7 @@ +@@ -39,7 +41,7 @@ * utsname of this process won't be seen by parent, and vice * versa. */ @@ -153998,7 +161104,7 @@ diff -Nurb linux-2.6.22-570/kernel/utsname.c linux-2.6.22-590/kernel/utsname.c 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) { @@ -154012,8 +161118,8 @@ diff -Nurb linux-2.6.22-570/kernel/utsname_sysctl.c linux-2.6.22-590/kernel/utsn 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); @@ -154027,7 +161133,7 @@ diff -Nurb linux-2.6.22-570/kernel/workqueue.c linux-2.6.22-590/kernel/workqueue 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. @@ -154071,7 +161177,7 @@ diff -Nurb linux-2.6.22-570/lib/Kconfig.debug linux-2.6.22-590/lib/Kconfig.debug +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 @@ -154330,7 +161436,7 @@ diff -Nurb linux-2.6.22-570/lib/Kconfig.kgdb linux-2.6.22-590/lib/Kconfig.kgdb + 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 \ @@ -154346,7 +161452,7 @@ diff -Nurb linux-2.6.22-570/lib/Makefile linux-2.6.22-590/lib/Makefile 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. @@ -154509,7 +161615,7 @@ diff -Nurb linux-2.6.22-570/lib/argv_split.c linux-2.6.22-590/lib/argv_split.c +#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 +#include @@ -154537,50 +161643,465 @@ diff -Nurb linux-2.6.22-570/lib/check_signature.c linux-2.6.22-590/lib/check_sig + 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 ++ */ ++ ++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; @@ -154590,9 +162111,21 @@ diff -Nurb linux-2.6.22-570/lib/kobject_uevent.c linux-2.6.22-590/lib/kobject_ue } 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 +#include @@ -154708,7 +162241,7 @@ diff -Nurb linux-2.6.22-570/lib/pagewalk.c linux-2.6.22-590/lib/pagewalk.c +} 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); @@ -154731,7 +162264,7 @@ diff -Nurb linux-2.6.22-570/lib/radix-tree.c linux-2.6.22-590/lib/radix-tree.c 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) @@ -154989,8 +162522,8 @@ diff -Nurb linux-2.6.22-570/mm/filemap.c linux-2.6.22-590/mm/filemap.c } 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 @@ } @@ -155092,8 +162625,8 @@ diff -Nurb linux-2.6.22-570/mm/filemap_xip.c linux-2.6.22-590/mm/filemap_xip.c } 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; } @@ -155186,8 +162719,8 @@ diff -Nurb linux-2.6.22-570/mm/fremap.c linux-2.6.22-590/mm/fremap.c 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]; @@ -155247,8 +162780,8 @@ diff -Nurb linux-2.6.22-570/mm/hugetlb.c linux-2.6.22-590/mm/hugetlb.c 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; @@ -155632,7 +163165,7 @@ diff -Nurb linux-2.6.22-570/mm/memory.c linux-2.6.22-590/mm/memory.c 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) @@ -155686,7 +163219,7 @@ diff -Nurb linux-2.6.22-570/mm/mempolicy.c linux-2.6.22-590/mm/mempolicy.c - 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; @@ -155698,8 +163231,8 @@ diff -Nurb linux-2.6.22-570/mm/migrate.c linux-2.6.22-590/mm/migrate.c /* 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 @@ } @@ -155743,8 +163276,8 @@ diff -Nurb linux-2.6.22-570/mm/mmap.c linux-2.6.22-590/mm/mmap.c 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; @@ -155772,8 +163305,8 @@ diff -Nurb linux-2.6.22-570/mm/mremap.c linux-2.6.22-590/mm/mremap.c } 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 @@ } @@ -155794,8 +163327,8 @@ diff -Nurb linux-2.6.22-570/mm/nommu.c linux-2.6.22-590/mm/nommu.c 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 @@ -156359,7 +163892,7 @@ diff -Nurb linux-2.6.22-570/mm/page_alloc.c linux-2.6.22-590/mm/page_alloc.c +} 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) { @@ -156369,8 +163902,8 @@ diff -Nurb linux-2.6.22-570/mm/pdflush.c linux-2.6.22-590/mm/pdflush.c 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); @@ -156384,8 +163917,8 @@ diff -Nurb linux-2.6.22-570/mm/rmap.c linux-2.6.22-590/mm/rmap.c 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 */ @@ -156551,9 +164084,2632 @@ diff -Nurb linux-2.6.22-570/mm/shmem.c linux-2.6.22-590/mm/shmem.c + 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 +- * Copyright (c) 2004 Red Hat, Inc., James Morris +- * +- * 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 +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +- +-/* 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//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 @@ -156564,8 +166720,8 @@ diff -Nurb linux-2.6.22-570/mm/slab.c linux-2.6.22-590/mm/slab.c 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; @@ -156586,7 +166742,7 @@ diff -Nurb linux-2.6.22-570/mm/slub.c linux-2.6.22-590/mm/slub.c 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. */ @@ -156599,7 +166755,7 @@ diff -Nurb linux-2.6.22-570/mm/swap_state.c linux-2.6.22-590/mm/swap_state.c } 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 @@ -156652,7 +166808,7 @@ diff -Nurb linux-2.6.22-570/mm/truncate.c linux-2.6.22-590/mm/truncate.c 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); @@ -156707,7 +166863,7 @@ diff -Nurb linux-2.6.22-570/mm/util.c linux-2.6.22-590/mm/util.c */ 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); } @@ -156740,7 +166896,7 @@ diff -Nurb linux-2.6.22-570/mm/vmalloc.c linux-2.6.22-590/mm/vmalloc.c 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; } @@ -156802,9 +166958,38 @@ diff -Nurb linux-2.6.22-570/mm/vmscan.c linux-2.6.22-590/mm/vmscan.c } 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 + #include + #include ++#include + + 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 @@ -156816,8 +167001,25 @@ diff -Nurb linux-2.6.22-570/net/8021q/Makefile linux-2.6.22-590/net/8021q/Makefi 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 + #include + #include ++#include + + #include + #include "vlan.h" +@@ -50,7 +51,7 @@ + static char vlan_buggyright[] = "David S. Miller "; + + 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); @@ -156846,7 +167048,16 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan.c linux-2.6.22-590/net/8021q/vlan.c } /* 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; @@ -156854,7 +167065,7 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan.c linux-2.6.22-590/net/8021q/vlan.c vlan_ioctl_set(NULL); /* Un-register us from receiving netdevice events */ -@@ -197,6 +205,34 @@ +@@ -197,6 +206,34 @@ kfree(grp); } @@ -156889,7 +167100,7 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan.c linux-2.6.22-590/net/8021q/vlan.c 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; } @@ -156979,7 +167190,7 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan.c linux-2.6.22-590/net/8021q/vlan.c { 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; @@ -156987,7 +167198,7 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan.c linux-2.6.22-590/net/8021q/vlan.c 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 @@ } } @@ -157142,7 +167353,7 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan.c linux-2.6.22-590/net/8021q/vlan.c /* 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) @@ -157200,13 +167411,13 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan.c linux-2.6.22-590/net/8021q/vlan.c 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); @@ -157293,9 +167504,22 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan.c linux-2.6.22-590/net/8021q/vlan.c } 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; @@ -157305,14 +167529,14 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan.c linux-2.6.22-590/net/8021q/vlan.c 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: @@ -157320,7 +167544,7 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan.c linux-2.6.22-590/net/8021q/vlan.c + 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; + @@ -157330,8 +167554,8 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan.c linux-2.6.22-590/net/8021q/vlan.c + 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; @@ -157374,7 +167598,7 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan.c linux-2.6.22-590/net/8021q/vlan.c vlan_name_type = args.u.name_type; err = 0; } else { -@@ -745,26 +759,17 @@ +@@ -745,26 +763,17 @@ break; case ADD_VLAN_CMD: @@ -157407,7 +167631,7 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan.c linux-2.6.22-590/net/8021q/vlan.c break; case GET_VLAN_INGRESS_PRIORITY_CMD: -@@ -788,9 +793,7 @@ +@@ -788,9 +797,7 @@ err = -EINVAL; break; case GET_VLAN_REALDEV_NAME_CMD: @@ -157418,7 +167642,7 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan.c linux-2.6.22-590/net/8021q/vlan.c 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: @@ -157429,7 +167653,7 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan.c linux-2.6.22-590/net/8021q/vlan.c 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); @@ -157444,7 +167668,7 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan.c linux-2.6.22-590/net/8021q/vlan.c 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); @@ -157476,8 +167700,8 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan.h linux-2.6.22-590/net/8021q/vlan.h + #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) @@ -157487,7 +167711,19 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan_dev.c linux-2.6.22-590/net/8021q/vlan 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. */ @@ -157497,7 +167733,7 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan_dev.c linux-2.6.22-590/net/8021q/vlan if (build_vlan_header) { vhdr = (struct vlan_hdr *) skb_push(skb, VLAN_HLEN); -@@ -544,136 +545,83 @@ +@@ -544,136 +550,83 @@ return 0; } @@ -157669,10 +167905,19 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan_dev.c linux-2.6.22-590/net/8021q/vlan 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 + * @@ -157686,6 +167931,7 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan_netlink.c linux-2.6.22-590/net/8021q/ +#include +#include +#include ++#include +#include +#include +#include "vlan.h" @@ -157780,7 +168026,7 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan_netlink.c linux-2.6.22-590/net/8021q/ + + 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; + @@ -157911,8 +168157,55 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlan_netlink.c linux-2.6.22-590/net/8021q/ +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 + #include + #include ++#include + #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, @@ -157921,7 +168214,7 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlanproc.c linux-2.6.22-590/net/8021q/vlan 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) { @@ -157930,47 +168223,640 @@ diff -Nurb linux-2.6.22-570/net/8021q/vlanproc.c linux-2.6.22-590/net/8021q/vlan 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 - #include - #include -+#include - #include - #include - #include -@@ -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 - #include - #include -+#include - #include - #include - #include -@@ -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 + #include + #include ++#include + + + 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 /* 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 + #include + #include /* for __init */ ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + + + +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 #include @@ -157987,9 +168873,74 @@ diff -Nurb linux-2.6.22-570/net/bluetooth/hidp/core.c linux-2.6.22-590/net/bluet 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 #include @@ -158006,9 +168957,376 @@ diff -Nurb linux-2.6.22-570/net/bluetooth/rfcomm/core.c linux-2.6.22-590/net/blu 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 + #include + #include ++#include + #include + #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 + #include ++#include ++#include + #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 + #include ++#include + + #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 + #include + #include ++#include + #include + #include + #include +@@ -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 }; @@ -158020,7 +169338,7 @@ diff -Nurb linux-2.6.22-570/net/bridge/br_stp_if.c linux-2.6.22-590/net/bridge/b 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. @@ -158045,7 +169363,7 @@ diff -Nurb linux-2.6.22-570/net/bridge/br_sysfs_br.c linux-2.6.22-590/net/bridge 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 = { \ @@ -158056,10 +169374,115 @@ diff -Nurb linux-2.6.22-570/net/bridge/br_sysfs_if.c linux-2.6.22-590/net/bridge .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 + #include + #include ++#include + /* 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 + #include + #include ++#include + #include + #include + +@@ -152,9 +153,22 @@ static struct list_head ptype_all __read_mostly; /* Taps */ #ifdef CONFIG_NET_DMA @@ -158085,9 +169508,304 @@ diff -Nurb linux-2.6.22-570/net/core/dev.c linux-2.6.22-590/net/core/dev.c #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<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<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 { @@ -158099,7 +169817,68 @@ diff -Nurb linux-2.6.22-570/net/core/dev.c linux-2.6.22-590/net/core/dev.c 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)); @@ -158114,7 +169893,7 @@ diff -Nurb linux-2.6.22-570/net/core/dev.c linux-2.6.22-590/net/core/dev.c 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 */ @@ -158133,7 +169912,326 @@ diff -Nurb linux-2.6.22-570/net/core/dev.c linux-2.6.22-590/net/core/dev.c } #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 @@ } } @@ -158156,7 +170254,165 @@ diff -Nurb linux-2.6.22-570/net/core/dev.c linux-2.6.22-590/net/core/dev.c /* 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. */ @@ -158173,7 +170429,7 @@ diff -Nurb linux-2.6.22-570/net/core/dev.c linux-2.6.22-590/net/core/dev.c 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); @@ -158190,7 +170446,7 @@ diff -Nurb linux-2.6.22-570/net/core/dev.c linux-2.6.22-590/net/core/dev.c while(n) { per_cpu(softnet_data, cpu).net_dma = chan; -@@ -3595,7 +3634,6 @@ +@@ -3595,7 +3840,6 @@ } i++; } @@ -158198,7 +170454,7 @@ diff -Nurb linux-2.6.22-570/net/core/dev.c linux-2.6.22-590/net/core/dev.c } /** -@@ -3604,23 +3642,53 @@ +@@ -3604,23 +3848,53 @@ * @chan: DMA channel for the event * @event: event type */ @@ -158263,7 +170519,7 @@ diff -Nurb linux-2.6.22-570/net/core/dev.c linux-2.6.22-590/net/core/dev.c } /** -@@ -3628,12 +3696,10 @@ +@@ -3628,12 +3902,10 @@ */ static int __init netdev_dma_register(void) { @@ -158280,349 +170536,2093 @@ diff -Nurb linux-2.6.22-570/net/core/dev.c linux-2.6.22-590/net/core/dev.c 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 + #include + #include ++#include + + + /* +@@ -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 + #include + #include ++#include + ++#include + #include + + /* 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 + #include + #include ++#include ++#include + #include --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 + #include + #include ++#include + + #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 + #include + #include ++#include + #include ++#include + #include + #include + #include +@@ -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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * 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 + #include + #include ++#include + #include + #include + #include +@@ -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) @@ -158631,7 +172631,7 @@ diff -Nurb linux-2.6.22-570/net/core/rtnetlink.c linux-2.6.22-590/net/core/rtnet 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) @@ -158640,7 +172640,7 @@ diff -Nurb linux-2.6.22-570/net/core/rtnetlink.c linux-2.6.22-590/net/core/rtnet modified = 1; } -@@ -686,7 +816,6 @@ +@@ -686,7 +830,6 @@ send_addr_notify = 1; } @@ -158648,7 +172648,7 @@ diff -Nurb linux-2.6.22-570/net/core/rtnetlink.c linux-2.6.22-590/net/core/rtnet if (ifm->ifi_flags || ifm->ifi_change) { unsigned int flags = ifm->ifi_flags; -@@ -714,7 +843,7 @@ +@@ -714,7 +857,7 @@ err = 0; @@ -158657,21 +172657,22 @@ diff -Nurb linux-2.6.22-570/net/core/rtnetlink.c linux-2.6.22-590/net/core/rtnet 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; @@ -158684,9 +172685,9 @@ diff -Nurb linux-2.6.22-570/net/core/rtnetlink.c linux-2.6.22-590/net/core/rtnet + 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; + @@ -158712,6 +172713,7 @@ diff -Nurb linux-2.6.22-570/net/core/rtnetlink.c linux-2.6.22-590/net/core/rtnet +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; @@ -158728,9 +172730,9 @@ diff -Nurb linux-2.6.22-570/net/core/rtnetlink.c linux-2.6.22-590/net/core/rtnet + + 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; + @@ -158747,6 +172749,7 @@ diff -Nurb linux-2.6.22-570/net/core/rtnetlink.c linux-2.6.22-590/net/core/rtnet + +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; @@ -158768,9 +172771,9 @@ diff -Nurb linux-2.6.22-570/net/core/rtnetlink.c linux-2.6.22-590/net/core/rtnet + + 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; + @@ -158888,8 +172891,18 @@ diff -Nurb linux-2.6.22-570/net/core/rtnetlink.c linux-2.6.22-590/net/core/rtnet + 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; @@ -158898,7 +172911,23 @@ diff -Nurb linux-2.6.22-570/net/core/rtnetlink.c linux-2.6.22-590/net/core/rtnet 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; @@ -158907,7 +172936,103 @@ diff -Nurb linux-2.6.22-570/net/core/rtnetlink.c linux-2.6.22-590/net/core/rtnet 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); @@ -158916,7 +173041,7 @@ diff -Nurb linux-2.6.22-570/net/core/rtnetlink.c linux-2.6.22-590/net/core/rtnet 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); @@ -158925,8 +173050,8 @@ diff -Nurb linux-2.6.22-570/net/core/rtnetlink.c linux-2.6.22-590/net/core/rtnet 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); @@ -158959,9 +173084,205 @@ diff -Nurb linux-2.6.22-570/net/core/skbuff.c linux-2.6.22-590/net/core/skbuff.c 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 + #include + #include ++#include + + #include + #include +@@ -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 + #include + #include ++#include ++#include + #include + +-#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 @@ -159288,7 +173609,7 @@ diff -Nurb linux-2.6.22-570/net/dccp/ccids/ccid3.c linux-2.6.22-590/net/dccp/cci 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_ @@ -159312,7 +173633,7 @@ diff -Nurb linux-2.6.22-570/net/dccp/ccids/ccid3.h linux-2.6.22-590/net/dccp/cci 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 @@ -159603,7 +173924,7 @@ diff -Nurb linux-2.6.22-570/net/dccp/ccids/lib/loss_interval.c linux-2.6.22-590/ +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 @@ -159669,7 +173990,7 @@ diff -Nurb linux-2.6.22-570/net/dccp/ccids/lib/loss_interval.h linux-2.6.22-590/ #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 @@ -159688,1703 +174009,5640 @@ diff -Nurb linux-2.6.22-570/net/dccp/dccp.h linux-2.6.22-590/net/dccp/dccp.h 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, -+ * Florian La Roche, -+ * Alan Cox, -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_IP_MROUTE -+#include -+#endif -+#include -+ -+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 + #include + #include ++#include + + #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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + #include + #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) + #include +@@ -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 + #include + +-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 + #include + #include ++#include + #include + + #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 + #include + +-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 + #include + #include +-#include + #include + #include + +@@ -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 + #include + #include ++#include + #include + #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, ":\n"); + else + seq_puts(seq, "
:\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 + #include + #include ++#include + #include + #ifdef CONFIG_IP_MROUTE + #include +@@ -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 + * . 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 - #include - #include --#include - #include - #include +@@ -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 + #include + +-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 && @@ -161393,14 +179651,636 @@ diff -Nurb linux-2.6.22-570/net/ipv4/ip_output.c linux-2.6.22-590/net/ipv4/ip_ou !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 "); +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 + #include + #include ++#include + + #include + #include +@@ -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 + #include + #include ++#include + #include + + #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;ctdev==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 + #include + #include ++#include + + #include + +@@ -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 + #include + #include ++#include + + #include + +@@ -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 + #include + #include ++#include + + #include + +@@ -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 @@ -162263,54 +181143,1250 @@ diff -Nurb linux-2.6.22-570/net/ipv4/multipath_wrandom.c linux-2.6.22-590/net/ip -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 + #include + #include ++#include - 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 - #include - #include --#include - #include - #include - #ifdef CONFIG_SYSCTL -@@ -495,13 +494,11 @@ + #include + #include +@@ -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 + #include + #include ++#include + + #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 + #include + #include ++#include + + #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 + #include + #include ++#include + + #include + #include +@@ -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 + #include + #include ++#include + + #include + #include +@@ -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 + + /* 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 + #include + #include ++#include + + 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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include +-#include + #include ++#include + #include + #ifdef CONFIG_SYSCTL + #include +@@ -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 @@ -162362,7 +182438,7 @@ diff -Nurb linux-2.6.22-570/net/ipv4/route.c linux-2.6.22-590/net/ipv4/route.c /* 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. */ @@ -162375,17 +182451,18 @@ diff -Nurb linux-2.6.22-570/net/ipv4/route.c linux-2.6.22-590/net/ipv4/route.c - 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; @@ -162395,7 +182472,7 @@ diff -Nurb linux-2.6.22-570/net/ipv4/route.c linux-2.6.22-590/net/ipv4/route.c 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; } @@ -162414,19 +182491,20 @@ diff -Nurb linux-2.6.22-570/net/ipv4/route.c linux-2.6.22-590/net/ipv4/route.c - 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) { @@ -162439,7 +182517,96 @@ diff -Nurb linux-2.6.22-570/net/ipv4/route.c linux-2.6.22-590/net/ipv4/route.c /* 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; @@ -162450,7 +182617,12 @@ diff -Nurb linux-2.6.22-570/net/ipv4/route.c linux-2.6.22-590/net/ipv4/route.c 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; } @@ -162459,7 +182631,7 @@ diff -Nurb linux-2.6.22-570/net/ipv4/route.c linux-2.6.22-590/net/ipv4/route.c 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); } @@ -162523,7 +182695,64 @@ diff -Nurb linux-2.6.22-570/net/ipv4/route.c linux-2.6.22-590/net/ipv4/route.c /* * 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; @@ -162537,7 +182766,13 @@ diff -Nurb linux-2.6.22-570/net/ipv4/route.c linux-2.6.22-590/net/ipv4/route.c 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; } @@ -162546,7 +182781,7 @@ diff -Nurb linux-2.6.22-570/net/ipv4/route.c linux-2.6.22-590/net/ipv4/route.c struct fib_result* res, const struct flowi *fl, const struct flowi *oldflp, -@@ -2295,68 +2135,6 @@ +@@ -2295,68 +2163,6 @@ return err; } @@ -162615,8 +182850,70 @@ diff -Nurb linux-2.6.22-570/net/ipv4/route.c linux-2.6.22-590/net/ipv4/route.c /* * 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))) { - @@ -162633,7 +182930,7 @@ diff -Nurb linux-2.6.22-570/net/ipv4/route.c linux-2.6.22-590/net/ipv4/route.c 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 @@ -162644,10 +182941,730 @@ diff -Nurb linux-2.6.22-570/net/ipv4/route.c linux-2.6.22-590/net/ipv4/route.c 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 + #include + +-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 + #include + #include ++#include + + #include + #include +@@ -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; @@ -162657,9 +183674,21 @@ diff -Nurb linux-2.6.22-570/net/ipv4/tcp_ipv4.c linux-2.6.22-590/net/ipv4/tcp_ip - 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; } @@ -162668,7 +183697,17 @@ diff -Nurb linux-2.6.22-570/net/ipv4/tcp_ipv4.c linux-2.6.22-590/net/ipv4/tcp_ip 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; } @@ -162685,7 +183724,16 @@ diff -Nurb linux-2.6.22-570/net/ipv4/tcp_ipv4.c linux-2.6.22-590/net/ipv4/tcp_ip 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); @@ -162693,7 +183741,7 @@ diff -Nurb linux-2.6.22-570/net/ipv4/tcp_ipv4.c linux-2.6.22-590/net/ipv4/tcp_ip 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); @@ -162701,7 +183749,7 @@ diff -Nurb linux-2.6.22-570/net/ipv4/tcp_ipv4.c linux-2.6.22-590/net/ipv4/tcp_ip 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) @@ -162711,938 +183759,15085 @@ diff -Nurb linux-2.6.22-570/net/ipv4/tcp_ipv4.c linux-2.6.22-590/net/ipv4/tcp_ip 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 - #endif --#ifdef CONFIG_IPV6_MIP6 --#include --#endif - - #include - #include -@@ -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 - #include - #include --#ifdef CONFIG_IPV6_MIP6 -+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) - #include - #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 "); - -- -+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 - #include - #include -+#include - #include - #include - -@@ -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 +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +- +-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 + #include + #include ++#include + #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 + #include + #include ++#include + #include + #include + #include +@@ -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 +- * Alexey Kuznetsov +- * +- * $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 +- * +- * 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 +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#ifdef CONFIG_SYSCTL +-#include +-#endif +-#include +-#include +-#include +-#include +- +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#ifdef CONFIG_IPV6_PRIVACY +-#include +-#endif +- +-#include +-#include +- +-#include +-#include +- +-/* 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; +- +- /* +- * : +- * 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; iidev == 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 + #endif +-#ifdef CONFIG_IPV6_MIP6 +-#include +-#endif + + #include + #include +@@ -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 + #include ++#include + + #include + #include +@@ -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 + #include + #include +-#ifdef CONFIG_IPV6_MIP6 ++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) + #include + #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 + + #include ++#include + + #include + #include +@@ -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 "); + +- ++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 + #include ++#include + + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + + 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 #include #include --#ifdef CONFIG_IPV6_MIP6 -+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) - #include - #endif +-#ifdef CONFIG_IPV6_MIP6 ++#include ++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) + #include + #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 + #include + #include ++#include + + #include + +@@ -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 + #include + #include +-#ifdef CONFIG_IPV6_MIP6 ++#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) + #include + #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 + #include + #include ++#include + #include + #include + +@@ -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 + +-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 + #include + #include ++#include + + #include + #include +@@ -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 + #include + #include ++#include + + #include + +@@ -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 + #include + #include ++#include + #include + + 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 ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + + #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 + #include + #include ++#include + #ifdef CONFIG_SYSCTL + #include + #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 + #include + #include ++#include + + #include + #include +@@ -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 + #include + #include ++#include + + #include + #include +@@ -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 + #include + #include ++#include + + #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 + #include + #include ++#include + #include -@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + + 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 + #include + #include ++#include + #include + #include + #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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + + /* 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 + #include + #include ++#include + + #include + #include +@@ -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, +- * Ross Biro +- * Fred N. van Kempen, +- * +- * 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 +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +- +-#include +- +-#include +-#include +- +-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 - #include - #include --#ifdef CONFIG_IPV6_MIP6 -+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) - #include - #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 @@ -164142,7 +199337,7 @@ diff -Nurb linux-2.6.22-570/net/sunrpc/auth.c linux-2.6.22-590/net/sunrpc/auth.c } 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 #include @@ -164638,7 +199833,7 @@ diff -Nurb linux-2.6.22-570/net/sunrpc/auth_gss/auth_gss.c linux-2.6.22-590/net/ .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); } @@ -164650,7 +199845,7 @@ diff -Nurb linux-2.6.22-570/net/sunrpc/auth_gss/gss_krb5_mech.c linux-2.6.22-590 .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; } @@ -164662,7 +199857,7 @@ diff -Nurb linux-2.6.22-570/net/sunrpc/auth_gss/gss_spkm3_mech.c linux-2.6.22-59 .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) @@ -164704,8 +199899,8 @@ diff -Nurb linux-2.6.22-570/net/sunrpc/auth_null.c linux-2.6.22-590/net/sunrpc/a .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]; }; @@ -164817,7 +200012,15 @@ diff -Nurb linux-2.6.22-570/net/sunrpc/auth_unix.c linux-2.6.22-590/net/sunrpc/a __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) { @@ -164826,7 +200029,7 @@ diff -Nurb linux-2.6.22-570/net/sunrpc/auth_unix.c linux-2.6.22-590/net/sunrpc/a return 0; } -@@ -212,7 +219,12 @@ +@@ -212,7 +218,12 @@ return p; } @@ -164840,7 +200043,7 @@ diff -Nurb linux-2.6.22-570/net/sunrpc/auth_unix.c linux-2.6.22-590/net/sunrpc/a .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 = { @@ -164848,7 +200051,7 @@ diff -Nurb linux-2.6.22-570/net/sunrpc/auth_unix.c linux-2.6.22-590/net/sunrpc/a }; static -@@ -240,7 +251,7 @@ +@@ -240,7 +250,7 @@ }; static @@ -164858,8 +200061,8 @@ diff -Nurb linux-2.6.22-570/net/sunrpc/auth_unix.c linux-2.6.22-590/net/sunrpc/a .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) @@ -165314,7 +200517,7 @@ diff -Nurb linux-2.6.22-570/net/sunrpc/clnt.c linux-2.6.22-590/net/sunrpc/clnt.c +#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 #include @@ -165534,7 +200737,7 @@ diff -Nurb linux-2.6.22-570/net/sunrpc/rpc_pipe.c linux-2.6.22-590/net/sunrpc/rp 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, @@ -165571,7 +200774,7 @@ diff -Nurb linux-2.6.22-570/net/sunrpc/rpcb_clnt.c linux-2.6.22-590/net/sunrpc/r 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 @@ -165914,9 +201117,38 @@ diff -Nurb linux-2.6.22-570/net/sunrpc/sched.c linux-2.6.22-590/net/sunrpc/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 + #include + #include ++#include + + #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); @@ -165960,7 +201192,7 @@ diff -Nurb linux-2.6.22-570/net/sunrpc/sunrpc_syms.c linux-2.6.22-590/net/sunrpc 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(); @@ -165981,7 +201213,7 @@ diff -Nurb linux-2.6.22-570/net/sunrpc/xprt.c linux-2.6.22-590/net/sunrpc/xprt.c 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); @@ -166024,9 +201256,44 @@ diff -Nurb linux-2.6.22-570/net/sunrpc/xprtsock.c linux-2.6.22-590/net/sunrpc/xp } } +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 @@ -166038,7 +201305,15 @@ diff -Nurb linux-2.6.22-570/net/tipc/eth_media.c linux-2.6.22-590/net/tipc/eth_m * All rights reserved. * * Redistribution and use in source and binary forms, with or without -@@ -87,6 +87,9 @@ +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + + #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 * @@ -166048,9 +201323,15 @@ diff -Nurb linux-2.6.22-570/net/tipc/eth_media.c linux-2.6.22-590/net/tipc/eth_m * 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) || @@ -166059,9 +201340,28 @@ diff -Nurb linux-2.6.22-570/net/tipc/eth_media.c linux-2.6.22-590/net/tipc/eth_m 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 @@ -166126,7 +201426,7 @@ diff -Nurb linux-2.6.22-570/net/tipc/link.c linux-2.6.22-590/net/tipc/link.c 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 @@ -166170,7 +201470,7 @@ diff -Nurb linux-2.6.22-570/net/tipc/port.c linux-2.6.22-590/net/tipc/port.c 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 @@ -166200,7 +201500,7 @@ diff -Nurb linux-2.6.22-570/net/tipc/port.h linux-2.6.22-590/net/tipc/port.h 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 @@ -166212,7 +201512,34 @@ diff -Nurb linux-2.6.22-570/net/tipc/socket.c linux-2.6.22-590/net/tipc/socket.c * 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) { @@ -166242,7 +201569,7 @@ diff -Nurb linux-2.6.22-570/net/tipc/socket.c linux-2.6.22-590/net/tipc/socket.c return -EPIPE; else return -ENOTCONN; -@@ -648,17 +649,25 @@ +@@ -648,17 +652,25 @@ my_msg.msg_name = NULL; bytes_sent = 0; @@ -166271,7 +201598,16 @@ diff -Nurb linux-2.6.22-570/net/tipc/socket.c linux-2.6.22-590/net/tipc/socket.c } 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 @@ } /** @@ -166305,7 +201641,7 @@ diff -Nurb linux-2.6.22-570/net/tipc/socket.c linux-2.6.22-590/net/tipc/socket.c * Protocol switches for the various types of TIPC sockets */ -@@ -1636,19 +1618,19 @@ +@@ -1636,19 +1621,19 @@ .release = release, .bind = bind, .connect = connect, @@ -166329,7 +201665,7 @@ diff -Nurb linux-2.6.22-570/net/tipc/socket.c linux-2.6.22-590/net/tipc/socket.c }; static struct proto_ops packet_ops = { -@@ -1657,19 +1639,19 @@ +@@ -1657,19 +1642,19 @@ .release = release, .bind = bind, .connect = connect, @@ -166353,7 +201689,7 @@ diff -Nurb linux-2.6.22-570/net/tipc/socket.c linux-2.6.22-590/net/tipc/socket.c }; static struct proto_ops stream_ops = { -@@ -1678,19 +1660,19 @@ +@@ -1678,19 +1663,19 @@ .release = release, .bind = bind, .connect = connect, @@ -166377,9 +201713,934 @@ diff -Nurb linux-2.6.22-570/net/tipc/socket.c linux-2.6.22-590/net/tipc/socket.c }; 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 + #include + #include ++#include + +-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 + +-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 /* WAN router API definitions */ + #include + #include ++#include + + #include + +@@ -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 + + #include /* Pretty obvious */ ++#include + #include /* New driver API */ + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + +@@ -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 @@ -166409,9 +202670,497 @@ diff -Nurb linux-2.6.22-570/rej linux-2.6.22-590/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_.o from .c +-# o if .tmp_.o doesn't contain a __ksymtab version, i.e. does +-# not export symbols, we just rename .tmp_.o to .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 .o from .tmp_.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: +-# -objs := +-# or +-# -y := +-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 .o file which is the .o files above linked together +-# c) A .mod file in $(MODVERDIR)/, listing the name of the +-# the preliminary .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 .mod.c file pr. module +-# 4) create one Module.symvers file with CRC for all exported symbols +-# 5) compile all .mod.c files +-# 6) final link of the module to a 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 || @@ -166422,8 +203171,8 @@ diff -Nurb linux-2.6.22-570/security/commoncap.c linux-2.6.22-590/security/commo 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) { @@ -166449,7 +203198,7 @@ diff -Nurb linux-2.6.22-570/security/dummy.c linux-2.6.22-590/security/dummy.c 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; @@ -166462,7 +203211,7 @@ diff -Nurb linux-2.6.22-570/security/keys/request_key.c linux-2.6.22-590/securit 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); @@ -166479,7 +203228,7 @@ diff -Nurb linux-2.6.22-570/security/security.c linux-2.6.22-590/security/securi 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 @@ } } @@ -166524,8 +203273,8 @@ diff -Nurb linux-2.6.22-570/security/selinux/avc.c linux-2.6.22-590/security/sel 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; @@ -166565,7 +203314,40 @@ diff -Nurb linux-2.6.22-570/security/selinux/hooks.c linux-2.6.22-590/security/s 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, @@ -166574,7 +203356,7 @@ diff -Nurb linux-2.6.22-570/security/selinux/hooks.c linux-2.6.22-590/security/s 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); @@ -166591,7 +203373,7 @@ diff -Nurb linux-2.6.22-570/security/selinux/hooks.c linux-2.6.22-590/security/s avc_init(); original_ops = secondary_ops = security_ops; -@@ -5060,6 +5078,10 @@ +@@ -5060,6 +5086,10 @@ selinux_disabled = 1; selinux_enabled = 0; @@ -166604,7 +203386,7 @@ diff -Nurb linux-2.6.22-570/security/selinux/hooks.c linux-2.6.22-590/security/s 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") @@ -166612,7 +203394,7 @@ diff -Nurb linux-2.6.22-570/security/selinux/include/av_perm_to_string.h linux-2 + 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 @@ -166620,7 +203402,7 @@ diff -Nurb linux-2.6.22-570/security/selinux/include/av_permissions.h linux-2.6. +#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); @@ -166634,7 +203416,7 @@ diff -Nurb linux-2.6.22-570/security/selinux/include/avc.h linux-2.6.22-590/secu 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) @@ -166642,7 +203424,7 @@ diff -Nurb linux-2.6.22-570/security/selinux/include/class_to_string.h linux-2.6 + 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 @@ -166653,7 +203435,7 @@ diff -Nurb linux-2.6.22-570/security/selinux/include/flask.h linux-2.6.22-590/se * 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); @@ -166672,9 +203454,52 @@ diff -Nurb linux-2.6.22-570/security/selinux/include/security.h linux-2.6.22-590 #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 + #include + #include ++#include + + #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 + #include + #include ++#include + + 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; @@ -167041,7 +203866,7 @@ diff -Nurb linux-2.6.22-570/security/selinux/selinuxfs.c linux-2.6.22-590/securi 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 @@ */ @@ -167098,7 +203923,7 @@ diff -Nurb linux-2.6.22-570/security/selinux/ss/policydb.c linux-2.6.22-590/secu 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) { @@ -167287,9 +204112,64 @@ diff -Nurb linux-2.6.22-570/security/selinux/ss/services.c linux-2.6.22-590/secu 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 diff --git a/linux-2.6-593-egre.patch b/linux-2.6-593-egre.patch index 6b7e2b128..9d02811fc 100644 --- a/linux-2.6-593-egre.patch +++ b/linux-2.6-593-egre.patch @@ -1,17 +1,6 @@ -diff -Nurb linux-2.6.22-592/drivers/net/Makefile linux-2.6.22-593/drivers/net/Makefile ---- linux-2.6.22-592/drivers/net/Makefile 2008-03-15 10:50:00.000000000 -0400 -+++ linux-2.6.22-593/drivers/net/Makefile 2008-03-15 10:51:27.000000000 -0400 -@@ -2,6 +2,7 @@ - # Makefile for the Linux network (ethercard) device drivers. - # - -+obj-m +=gre.o - obj-y +=ztun.o shortbridge.o - obj-$(CONFIG_E1000) += e1000/ - obj-$(CONFIG_E1000E) += e1000e/ -diff -Nurb linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c +diff -Nurp linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c --- linux-2.6.22-592/drivers/net/gre.c 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-593/drivers/net/gre.c 2008-03-15 10:51:27.000000000 -0400 ++++ linux-2.6.22-593/drivers/net/gre.c 2008-02-28 13:51:50.000000000 -0500 @@ -0,0 +1,1632 @@ +/* + * Linux NET3: GRE over IP protocol decoder. @@ -1645,9 +1634,20 @@ diff -Nurb linux-2.6.22-592/drivers/net/gre.c linux-2.6.22-593/drivers/net/gre.c +module_init(ipgre_init); +module_exit(ipgre_fini); +MODULE_LICENSE("GPL"); -diff -Nurb linux-2.6.22-592/include/linux/if_ether.h linux-2.6.22-593/include/linux/if_ether.h +diff -Nurp linux-2.6.22-592/drivers/net/Makefile linux-2.6.22-593/drivers/net/Makefile +--- linux-2.6.22-592/drivers/net/Makefile 2008-02-28 13:51:47.000000000 -0500 ++++ linux-2.6.22-593/drivers/net/Makefile 2008-02-28 13:51:50.000000000 -0500 +@@ -2,6 +2,7 @@ + # Makefile for the Linux network (ethercard) device drivers. + # + ++obj-m +=gre.o + obj-y +=ztun.o shortbridge.o + obj-$(CONFIG_E1000) += e1000/ + obj-$(CONFIG_E1000E) += e1000e/ +diff -Nurp linux-2.6.22-592/include/linux/if_ether.h linux-2.6.22-593/include/linux/if_ether.h --- linux-2.6.22-592/include/linux/if_ether.h 2007-07-08 19:32:17.000000000 -0400 -+++ linux-2.6.22-593/include/linux/if_ether.h 2008-03-15 10:51:27.000000000 -0400 ++++ linux-2.6.22-593/include/linux/if_ether.h 2008-02-28 13:51:50.000000000 -0500 @@ -56,6 +56,7 @@ #define ETH_P_DIAG 0x6005 /* DEC Diagnostics */ #define ETH_P_CUST 0x6006 /* DEC Customer use */ @@ -1656,10 +1656,10 @@ diff -Nurb linux-2.6.22-592/include/linux/if_ether.h linux-2.6.22-593/include/li #define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */ #define ETH_P_ATALK 0x809B /* Appletalk DDP */ #define ETH_P_AARP 0x80F3 /* Appletalk AARP */ -diff -Nurb linux-2.6.22-592/include/linux/if_tunnel.h linux-2.6.22-593/include/linux/if_tunnel.h +diff -Nurp linux-2.6.22-592/include/linux/if_tunnel.h linux-2.6.22-593/include/linux/if_tunnel.h --- linux-2.6.22-592/include/linux/if_tunnel.h 2007-07-08 19:32:17.000000000 -0400 -+++ linux-2.6.22-593/include/linux/if_tunnel.h 2008-03-15 10:51:27.000000000 -0400 -@@ -25,6 +25,7 @@ ++++ linux-2.6.22-593/include/linux/if_tunnel.h 2008-02-28 13:51:50.000000000 -0500 +@@ -25,6 +25,7 @@ struct ip_tunnel_parm __be16 o_flags; __be32 i_key; __be32 o_key; @@ -1667,9 +1667,9 @@ diff -Nurb linux-2.6.22-592/include/linux/if_tunnel.h linux-2.6.22-593/include/l struct iphdr iph; }; -diff -Nurb linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c ---- linux-2.6.22-592/net/ipv4/ip_gre.c 2007-07-08 19:32:17.000000000 -0400 -+++ linux-2.6.22-593/net/ipv4/ip_gre.c 2008-03-15 10:51:27.000000000 -0400 +diff -Nurp linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c +--- linux-2.6.22-592/net/ipv4/ip_gre.c 2008-02-29 16:37:50.000000000 -0500 ++++ linux-2.6.22-593/net/ipv4/ip_gre.c 2008-02-29 17:22:06.000000000 -0500 @@ -25,6 +25,7 @@ #include #include @@ -1697,7 +1697,7 @@ diff -Nurb linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c /* Fallback tunnel: no source, no destination, no key, no options */ -@@ -243,6 +247,7 @@ +@@ -243,6 +247,7 @@ static struct ip_tunnel * ipgre_tunnel_l __be32 remote = parms->iph.daddr; __be32 local = parms->iph.saddr; __be32 key = parms->i_key; @@ -1705,7 +1705,7 @@ diff -Nurb linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c struct ip_tunnel *t, **tp, *nt; struct net_device *dev; char name[IFNAMSIZ]; -@@ -256,6 +261,8 @@ +@@ -256,6 +261,8 @@ static struct ip_tunnel * ipgre_tunnel_l if (!create) return NULL; @@ -1714,11 +1714,11 @@ diff -Nurb linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c if (parms->name[0]) strlcpy(name, parms->name, IFNAMSIZ); else { -@@ -269,7 +276,20 @@ +@@ -268,8 +275,21 @@ static struct ip_tunnel * ipgre_tunnel_l + if (i==100) goto failed; } - -- dev = alloc_netdev(sizeof(*t), name, ipgre_tunnel_setup); ++ + /* Tunnel creation: check payload type and call appropriate + * function */ + switch (proto) @@ -1732,19 +1732,20 @@ diff -Nurb linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c + default: + return NULL; + } -+ + +- dev = alloc_netdev(sizeof(*t), name, ipgre_tunnel_setup); if (!dev) return NULL; -@@ -558,6 +578,7 @@ +@@ -562,6 +582,7 @@ static int ipgre_rcv(struct sk_buff *skb u32 seqno = 0; struct ip_tunnel *tunnel; int offset = 4; + __be16 proto; - if (!pskb_may_pull(skb, 16)) - goto drop_nolock; -@@ -566,6 +587,11 @@ + if (skb->dev->nd_net != &init_net) { + kfree_skb(skb); +@@ -574,6 +595,11 @@ static int ipgre_rcv(struct sk_buff *skb h = skb->data; flags = *(__be16*)h; @@ -1756,10 +1757,11 @@ diff -Nurb linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c if (flags&(GRE_CSUM|GRE_KEY|GRE_ROUTING|GRE_SEQ|GRE_VERSION)) { /* - Version must be 0. - We do not support routing headers. -@@ -617,6 +643,27 @@ +@@ -625,7 +651,28 @@ static int ipgre_rcv(struct sk_buff *skb __pskb_pull(skb, offset); skb_reset_network_header(skb); skb_postpull_rcsum(skb, skb_transport_header(skb), offset); +- skb->pkt_type = PACKET_HOST; + if(proto == ETH_P_ETH) + { +#ifdef GRE_DEBUG @@ -1781,10 +1783,11 @@ diff -Nurb linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); + } + else - skb->pkt_type = PACKET_HOST; ++ skb->pkt_type = PACKET_HOST; #ifdef CONFIG_NET_IPGRE_BROADCAST if (MULTICAST(iph->daddr)) { -@@ -663,7 +710,7 @@ + /* Looped back packet, drop it! */ +@@ -671,7 +718,7 @@ drop_nolock: return(0); } @@ -1793,7 +1796,7 @@ diff -Nurb linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c { struct ip_tunnel *tunnel = netdev_priv(dev); struct net_device_stats *stats = &tunnel->stat; -@@ -895,6 +942,228 @@ +@@ -904,6 +951,228 @@ tx_error: return 0; } @@ -2022,7 +2025,7 @@ diff -Nurb linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c static int ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) { -@@ -902,6 +1171,8 @@ +@@ -911,6 +1183,8 @@ ipgre_tunnel_ioctl (struct net_device *d struct ip_tunnel_parm p; struct ip_tunnel *t; @@ -2031,7 +2034,7 @@ diff -Nurb linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c switch (cmd) { case SIOCGETTUNNEL: t = NULL; -@@ -943,7 +1214,7 @@ +@@ -952,7 +1226,7 @@ ipgre_tunnel_ioctl (struct net_device *d p.o_key = 0; t = ipgre_tunnel_locate(&p, cmd == SIOCADDTUNNEL); @@ -2040,33 +2043,35 @@ diff -Nurb linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c if (dev != ipgre_fb_tunnel_dev && cmd == SIOCCHGTUNNEL) { if (t != NULL) { if (t->dev != dev) { -@@ -960,6 +1231,12 @@ +@@ -968,6 +1242,12 @@ ipgre_tunnel_ioctl (struct net_device *d + nflags = IFF_BROADCAST; else if (p.iph.daddr) nflags = IFF_POINTOPOINT; - ++ + /* XXX:Set back IFF_BROADCAST if + * transporting ethernet */ + printk(KERN_ALERT "1193 GRE: proto %s %d\n", p.name, p.proto_type); + if (p.proto_type == ETH_P_ETH) + nflags = IFF_BROADCAST; -+ + if ((dev->flags^nflags)&(IFF_POINTOPOINT|IFF_BROADCAST)) { err = -EINVAL; - break; -@@ -969,8 +1246,12 @@ +@@ -978,8 +1258,12 @@ ipgre_tunnel_ioctl (struct net_device *d t->parms.iph.daddr = p.iph.daddr; t->parms.i_key = p.i_key; t->parms.o_key = p.o_key; +- memcpy(dev->dev_addr, &p.iph.saddr, 4); +- memcpy(dev->broadcast, &p.iph.daddr, 4); + /* XXX:Copy in the protocol field */ + t->parms.proto_type = p.proto_type; + if (t->parms.proto_type != ETH_P_ETH) { - memcpy(dev->dev_addr, &p.iph.saddr, 4); - memcpy(dev->broadcast, &p.iph.daddr, 4); ++ memcpy(dev->dev_addr, &p.iph.saddr, 4); ++ memcpy(dev->broadcast, &p.iph.daddr, 4); + } ipgre_tunnel_link(t); netdev_state_change(dev); } -@@ -1129,12 +1410,12 @@ +@@ -1139,12 +1423,12 @@ static int ipgre_close(struct net_device #endif @@ -2081,7 +2086,7 @@ diff -Nurb linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c dev->get_stats = ipgre_tunnel_get_stats; dev->do_ioctl = ipgre_tunnel_ioctl; dev->change_mtu = ipgre_tunnel_change_mtu; -@@ -1147,6 +1428,35 @@ +@@ -1157,6 +1441,35 @@ static void ipgre_tunnel_setup(struct ne dev->addr_len = 4; } @@ -2117,35 +2122,38 @@ diff -Nurb linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c static int ipgre_tunnel_init(struct net_device *dev) { struct net_device *tdev = NULL; -@@ -1162,8 +1472,12 @@ +@@ -1172,8 +1486,12 @@ static int ipgre_tunnel_init(struct net_ tunnel->dev = dev; strcpy(tunnel->parms.name, dev->name); +- memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4); +- memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); + if (tunnel->parms.proto_type != ETH_P_ETH) { - memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4); - memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); ++ memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4); ++ memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); + } else { + addend += ETH_HLEN; + } /* Guess output device to choose reasonable mtu and hard_header_len */ -@@ -1180,7 +1494,14 @@ +@@ -1191,7 +1507,14 @@ static int ipgre_tunnel_init(struct net_ ip_rt_put(rt); } +- dev->flags |= IFF_POINTOPOINT; + if (tunnel->parms.proto_type == ETH_P_ETH) + { + dev->flags |= IFF_BROADCAST; + } + else + { - dev->flags |= IFF_POINTOPOINT; ++ dev->flags |= IFF_POINTOPOINT; + } #ifdef CONFIG_NET_IPGRE_BROADCAST if (MULTICAST(iph->daddr)) { -@@ -1259,7 +1580,7 @@ +@@ -1270,7 +1593,7 @@ static int __init ipgre_init(void) } ipgre_fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "gre0", @@ -2154,1314 +2162,3 @@ diff -Nurb linux-2.6.22-592/net/ipv4/ip_gre.c linux-2.6.22-593/net/ipv4/ip_gre.c if (!ipgre_fb_tunnel_dev) { err = -ENOMEM; goto err1; -diff -Nurb linux-2.6.22-592/net/ipv4/ip_gre.c.orig linux-2.6.22-593/net/ipv4/ip_gre.c.orig ---- linux-2.6.22-592/net/ipv4/ip_gre.c.orig 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-593/net/ipv4/ip_gre.c.orig 2007-07-08 19:32:17.000000000 -0400 -@@ -0,0 +1,1307 @@ -+/* -+ * Linux NET3: GRE over IP protocol decoder. -+ * -+ * Authors: Alexey Kuznetsov (kuznet@ms2.inr.ac.ru) -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_IPV6 -+#include -+#include -+#include -+#endif -+ -+/* -+ Problems & solutions -+ -------------------- -+ -+ 1. The most important issue is detecting local dead loops. -+ They would cause complete host lockup in transmit, which -+ would be "resolved" by stack overflow or, if queueing is enabled, -+ with infinite looping in net_bh. -+ -+ We cannot track such dead loops during route installation, -+ it is infeasible task. The most general solutions would be -+ to keep skb->encapsulation counter (sort of local ttl), -+ and silently drop packet when it expires. It is the best -+ solution, but it supposes maintaing new variable in ALL -+ skb, even if no tunneling is used. -+ -+ Current solution: t->recursion lock breaks dead loops. It looks -+ like dev->tbusy flag, but I preferred new variable, because -+ the semantics is different. One day, when hard_start_xmit -+ will be multithreaded we will have to use skb->encapsulation. -+ -+ -+ -+ 2. Networking dead loops would not kill routers, but would really -+ kill network. IP hop limit plays role of "t->recursion" in this case, -+ if we copy it from packet being encapsulated to upper header. -+ It is very good solution, but it introduces two problems: -+ -+ - Routing protocols, using packets with ttl=1 (OSPF, RIP2), -+ do not work over tunnels. -+ - traceroute does not work. I planned to relay ICMP from tunnel, -+ so that this problem would be solved and traceroute output -+ would even more informative. This idea appeared to be wrong: -+ only Linux complies to rfc1812 now (yes, guys, Linux is the only -+ true router now :-)), all routers (at least, in neighbourhood of mine) -+ return only 8 bytes of payload. It is the end. -+ -+ Hence, if we want that OSPF worked or traceroute said something reasonable, -+ we should search for another solution. -+ -+ One of them is to parse packet trying to detect inner encapsulation -+ made by our node. It is difficult or even impossible, especially, -+ taking into account fragmentation. TO be short, tt is not solution at all. -+ -+ Current solution: The solution was UNEXPECTEDLY SIMPLE. -+ We force DF flag on tunnels with preconfigured hop limit, -+ that is ALL. :-) Well, it does not remove the problem completely, -+ but exponential growth of network traffic is changed to linear -+ (branches, that exceed pmtu are pruned) and tunnel mtu -+ fastly degrades to value <68, where looping stops. -+ Yes, it is not good if there exists a router in the loop, -+ which does not force DF, even when encapsulating packets have DF set. -+ But it is not our problem! Nobody could accuse us, we made -+ all that we could make. Even if it is your gated who injected -+ fatal route to network, even if it were you who configured -+ fatal static route: you are innocent. :-) -+ -+ -+ -+ 3. Really, ipv4/ipip.c, ipv4/ip_gre.c and ipv6/sit.c contain -+ practically identical code. It would be good to glue them -+ together, but it is not very evident, how to make them modular. -+ sit is integral part of IPv6, ipip and gre are naturally modular. -+ We could extract common parts (hash table, ioctl etc) -+ to a separate module (ip_tunnel.c). -+ -+ Alexey Kuznetsov. -+ */ -+ -+static int ipgre_tunnel_init(struct net_device *dev); -+static void ipgre_tunnel_setup(struct net_device *dev); -+ -+/* Fallback tunnel: no source, no destination, no key, no options */ -+ -+static int ipgre_fb_tunnel_init(struct net_device *dev); -+ -+static struct net_device *ipgre_fb_tunnel_dev; -+ -+/* Tunnel hash table */ -+ -+/* -+ 4 hash tables: -+ -+ 3: (remote,local) -+ 2: (remote,*) -+ 1: (*,local) -+ 0: (*,*) -+ -+ We require exact key match i.e. if a key is present in packet -+ it will match only tunnel with the same key; if it is not present, -+ it will match only keyless tunnel. -+ -+ All keysless packets, if not matched configured keyless tunnels -+ will match fallback tunnel. -+ */ -+ -+#define HASH_SIZE 16 -+#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF) -+ -+static struct ip_tunnel *tunnels[4][HASH_SIZE]; -+ -+#define tunnels_r_l (tunnels[3]) -+#define tunnels_r (tunnels[2]) -+#define tunnels_l (tunnels[1]) -+#define tunnels_wc (tunnels[0]) -+ -+static DEFINE_RWLOCK(ipgre_lock); -+ -+/* Given src, dst and key, find appropriate for input tunnel. */ -+ -+static struct ip_tunnel * ipgre_tunnel_lookup(__be32 remote, __be32 local, __be32 key) -+{ -+ unsigned h0 = HASH(remote); -+ unsigned h1 = HASH(key); -+ struct ip_tunnel *t; -+ -+ for (t = tunnels_r_l[h0^h1]; t; t = t->next) { -+ if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) { -+ if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) -+ return t; -+ } -+ } -+ for (t = tunnels_r[h0^h1]; t; t = t->next) { -+ if (remote == t->parms.iph.daddr) { -+ if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) -+ return t; -+ } -+ } -+ for (t = tunnels_l[h1]; t; t = t->next) { -+ if (local == t->parms.iph.saddr || -+ (local == t->parms.iph.daddr && MULTICAST(local))) { -+ if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) -+ return t; -+ } -+ } -+ for (t = tunnels_wc[h1]; t; t = t->next) { -+ if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) -+ return t; -+ } -+ -+ if (ipgre_fb_tunnel_dev->flags&IFF_UP) -+ return netdev_priv(ipgre_fb_tunnel_dev); -+ return NULL; -+} -+ -+static struct ip_tunnel **__ipgre_bucket(struct ip_tunnel_parm *parms) -+{ -+ __be32 remote = parms->iph.daddr; -+ __be32 local = parms->iph.saddr; -+ __be32 key = parms->i_key; -+ unsigned h = HASH(key); -+ int prio = 0; -+ -+ if (local) -+ prio |= 1; -+ if (remote && !MULTICAST(remote)) { -+ prio |= 2; -+ h ^= HASH(remote); -+ } -+ -+ return &tunnels[prio][h]; -+} -+ -+static inline struct ip_tunnel **ipgre_bucket(struct ip_tunnel *t) -+{ -+ return __ipgre_bucket(&t->parms); -+} -+ -+static void ipgre_tunnel_link(struct ip_tunnel *t) -+{ -+ struct ip_tunnel **tp = ipgre_bucket(t); -+ -+ t->next = *tp; -+ write_lock_bh(&ipgre_lock); -+ *tp = t; -+ write_unlock_bh(&ipgre_lock); -+} -+ -+static void ipgre_tunnel_unlink(struct ip_tunnel *t) -+{ -+ struct ip_tunnel **tp; -+ -+ for (tp = ipgre_bucket(t); *tp; tp = &(*tp)->next) { -+ if (t == *tp) { -+ write_lock_bh(&ipgre_lock); -+ *tp = t->next; -+ write_unlock_bh(&ipgre_lock); -+ break; -+ } -+ } -+} -+ -+static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int create) -+{ -+ __be32 remote = parms->iph.daddr; -+ __be32 local = parms->iph.saddr; -+ __be32 key = parms->i_key; -+ struct ip_tunnel *t, **tp, *nt; -+ struct net_device *dev; -+ char name[IFNAMSIZ]; -+ -+ for (tp = __ipgre_bucket(parms); (t = *tp) != NULL; tp = &t->next) { -+ if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) { -+ if (key == t->parms.i_key) -+ return t; -+ } -+ } -+ if (!create) -+ return NULL; -+ -+ if (parms->name[0]) -+ strlcpy(name, parms->name, IFNAMSIZ); -+ else { -+ int i; -+ for (i=1; i<100; i++) { -+ sprintf(name, "gre%d", i); -+ if (__dev_get_by_name(name) == NULL) -+ break; -+ } -+ if (i==100) -+ goto failed; -+ } -+ -+ dev = alloc_netdev(sizeof(*t), name, ipgre_tunnel_setup); -+ if (!dev) -+ return NULL; -+ -+ dev->init = ipgre_tunnel_init; -+ nt = netdev_priv(dev); -+ nt->parms = *parms; -+ -+ if (register_netdevice(dev) < 0) { -+ free_netdev(dev); -+ goto failed; -+ } -+ -+ dev_hold(dev); -+ ipgre_tunnel_link(nt); -+ return nt; -+ -+failed: -+ return NULL; -+} -+ -+static void ipgre_tunnel_uninit(struct net_device *dev) -+{ -+ ipgre_tunnel_unlink(netdev_priv(dev)); -+ dev_put(dev); -+} -+ -+ -+static void ipgre_err(struct sk_buff *skb, u32 info) -+{ -+#ifndef I_WISH_WORLD_WERE_PERFECT -+ -+/* It is not :-( All the routers (except for Linux) return only -+ 8 bytes of packet payload. It means, that precise relaying of -+ ICMP in the real Internet is absolutely infeasible. -+ -+ Moreover, Cisco "wise men" put GRE key to the third word -+ in GRE header. It makes impossible maintaining even soft state for keyed -+ GRE tunnels with enabled checksum. Tell them "thank you". -+ -+ Well, I wonder, rfc1812 was written by Cisco employee, -+ what the hell these idiots break standrads established -+ by themself??? -+ */ -+ -+ struct iphdr *iph = (struct iphdr*)skb->data; -+ __be16 *p = (__be16*)(skb->data+(iph->ihl<<2)); -+ int grehlen = (iph->ihl<<2) + 4; -+ const int type = icmp_hdr(skb)->type; -+ const int code = icmp_hdr(skb)->code; -+ struct ip_tunnel *t; -+ __be16 flags; -+ -+ flags = p[0]; -+ if (flags&(GRE_CSUM|GRE_KEY|GRE_SEQ|GRE_ROUTING|GRE_VERSION)) { -+ if (flags&(GRE_VERSION|GRE_ROUTING)) -+ return; -+ if (flags&GRE_KEY) { -+ grehlen += 4; -+ if (flags&GRE_CSUM) -+ grehlen += 4; -+ } -+ } -+ -+ /* If only 8 bytes returned, keyed message will be dropped here */ -+ if (skb_headlen(skb) < grehlen) -+ return; -+ -+ switch (type) { -+ default: -+ case ICMP_PARAMETERPROB: -+ return; -+ -+ case ICMP_DEST_UNREACH: -+ switch (code) { -+ case ICMP_SR_FAILED: -+ case ICMP_PORT_UNREACH: -+ /* Impossible event. */ -+ return; -+ case ICMP_FRAG_NEEDED: -+ /* Soft state for pmtu is maintained by IP core. */ -+ return; -+ default: -+ /* All others are translated to HOST_UNREACH. -+ rfc2003 contains "deep thoughts" about NET_UNREACH, -+ I believe they are just ether pollution. --ANK -+ */ -+ break; -+ } -+ break; -+ case ICMP_TIME_EXCEEDED: -+ if (code != ICMP_EXC_TTL) -+ return; -+ break; -+ } -+ -+ read_lock(&ipgre_lock); -+ t = ipgre_tunnel_lookup(iph->daddr, iph->saddr, (flags&GRE_KEY) ? *(((__be32*)p) + (grehlen>>2) - 1) : 0); -+ if (t == NULL || t->parms.iph.daddr == 0 || MULTICAST(t->parms.iph.daddr)) -+ goto out; -+ -+ if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED) -+ goto out; -+ -+ if (jiffies - t->err_time < IPTUNNEL_ERR_TIMEO) -+ t->err_count++; -+ else -+ t->err_count = 1; -+ t->err_time = jiffies; -+out: -+ read_unlock(&ipgre_lock); -+ return; -+#else -+ struct iphdr *iph = (struct iphdr*)dp; -+ struct iphdr *eiph; -+ __be16 *p = (__be16*)(dp+(iph->ihl<<2)); -+ const int type = icmp_hdr(skb)->type; -+ const int code = icmp_hdr(skb)->code; -+ int rel_type = 0; -+ int rel_code = 0; -+ __be32 rel_info = 0; -+ __u32 n = 0; -+ __be16 flags; -+ int grehlen = (iph->ihl<<2) + 4; -+ struct sk_buff *skb2; -+ struct flowi fl; -+ struct rtable *rt; -+ -+ if (p[1] != htons(ETH_P_IP)) -+ return; -+ -+ flags = p[0]; -+ if (flags&(GRE_CSUM|GRE_KEY|GRE_SEQ|GRE_ROUTING|GRE_VERSION)) { -+ if (flags&(GRE_VERSION|GRE_ROUTING)) -+ return; -+ if (flags&GRE_CSUM) -+ grehlen += 4; -+ if (flags&GRE_KEY) -+ grehlen += 4; -+ if (flags&GRE_SEQ) -+ grehlen += 4; -+ } -+ if (len < grehlen + sizeof(struct iphdr)) -+ return; -+ eiph = (struct iphdr*)(dp + grehlen); -+ -+ switch (type) { -+ default: -+ return; -+ case ICMP_PARAMETERPROB: -+ n = ntohl(icmp_hdr(skb)->un.gateway) >> 24; -+ if (n < (iph->ihl<<2)) -+ return; -+ -+ /* So... This guy found something strange INSIDE encapsulated -+ packet. Well, he is fool, but what can we do ? -+ */ -+ rel_type = ICMP_PARAMETERPROB; -+ n -= grehlen; -+ rel_info = htonl(n << 24); -+ break; -+ -+ case ICMP_DEST_UNREACH: -+ switch (code) { -+ case ICMP_SR_FAILED: -+ case ICMP_PORT_UNREACH: -+ /* Impossible event. */ -+ return; -+ case ICMP_FRAG_NEEDED: -+ /* And it is the only really necessary thing :-) */ -+ n = ntohs(icmp_hdr(skb)->un.frag.mtu); -+ if (n < grehlen+68) -+ return; -+ n -= grehlen; -+ /* BSD 4.2 MORE DOES NOT EXIST IN NATURE. */ -+ if (n > ntohs(eiph->tot_len)) -+ return; -+ rel_info = htonl(n); -+ break; -+ default: -+ /* All others are translated to HOST_UNREACH. -+ rfc2003 contains "deep thoughts" about NET_UNREACH, -+ I believe, it is just ether pollution. --ANK -+ */ -+ rel_type = ICMP_DEST_UNREACH; -+ rel_code = ICMP_HOST_UNREACH; -+ break; -+ } -+ break; -+ case ICMP_TIME_EXCEEDED: -+ if (code != ICMP_EXC_TTL) -+ return; -+ break; -+ } -+ -+ /* Prepare fake skb to feed it to icmp_send */ -+ skb2 = skb_clone(skb, GFP_ATOMIC); -+ if (skb2 == NULL) -+ return; -+ dst_release(skb2->dst); -+ skb2->dst = NULL; -+ skb_pull(skb2, skb->data - (u8*)eiph); -+ skb_reset_network_header(skb2); -+ -+ /* Try to guess incoming interface */ -+ memset(&fl, 0, sizeof(fl)); -+ fl.fl4_dst = eiph->saddr; -+ fl.fl4_tos = RT_TOS(eiph->tos); -+ fl.proto = IPPROTO_GRE; -+ if (ip_route_output_key(&rt, &fl)) { -+ kfree_skb(skb2); -+ return; -+ } -+ skb2->dev = rt->u.dst.dev; -+ -+ /* route "incoming" packet */ -+ if (rt->rt_flags&RTCF_LOCAL) { -+ ip_rt_put(rt); -+ rt = NULL; -+ fl.fl4_dst = eiph->daddr; -+ fl.fl4_src = eiph->saddr; -+ fl.fl4_tos = eiph->tos; -+ if (ip_route_output_key(&rt, &fl) || -+ rt->u.dst.dev->type != ARPHRD_IPGRE) { -+ ip_rt_put(rt); -+ kfree_skb(skb2); -+ return; -+ } -+ } else { -+ ip_rt_put(rt); -+ if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, skb2->dev) || -+ skb2->dst->dev->type != ARPHRD_IPGRE) { -+ kfree_skb(skb2); -+ return; -+ } -+ } -+ -+ /* change mtu on this route */ -+ if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { -+ if (n > dst_mtu(skb2->dst)) { -+ kfree_skb(skb2); -+ return; -+ } -+ skb2->dst->ops->update_pmtu(skb2->dst, n); -+ } else if (type == ICMP_TIME_EXCEEDED) { -+ struct ip_tunnel *t = netdev_priv(skb2->dev); -+ if (t->parms.iph.ttl) { -+ rel_type = ICMP_DEST_UNREACH; -+ rel_code = ICMP_HOST_UNREACH; -+ } -+ } -+ -+ icmp_send(skb2, rel_type, rel_code, rel_info); -+ kfree_skb(skb2); -+#endif -+} -+ -+static inline void ipgre_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb) -+{ -+ if (INET_ECN_is_ce(iph->tos)) { -+ if (skb->protocol == htons(ETH_P_IP)) { -+ IP_ECN_set_ce(ip_hdr(skb)); -+ } else if (skb->protocol == htons(ETH_P_IPV6)) { -+ IP6_ECN_set_ce(ipv6_hdr(skb)); -+ } -+ } -+} -+ -+static inline u8 -+ipgre_ecn_encapsulate(u8 tos, struct iphdr *old_iph, struct sk_buff *skb) -+{ -+ u8 inner = 0; -+ if (skb->protocol == htons(ETH_P_IP)) -+ inner = old_iph->tos; -+ else if (skb->protocol == htons(ETH_P_IPV6)) -+ inner = ipv6_get_dsfield((struct ipv6hdr *)old_iph); -+ return INET_ECN_encapsulate(tos, inner); -+} -+ -+static int ipgre_rcv(struct sk_buff *skb) -+{ -+ struct iphdr *iph; -+ u8 *h; -+ __be16 flags; -+ __sum16 csum = 0; -+ __be32 key = 0; -+ u32 seqno = 0; -+ struct ip_tunnel *tunnel; -+ int offset = 4; -+ -+ if (!pskb_may_pull(skb, 16)) -+ goto drop_nolock; -+ -+ iph = ip_hdr(skb); -+ h = skb->data; -+ flags = *(__be16*)h; -+ -+ if (flags&(GRE_CSUM|GRE_KEY|GRE_ROUTING|GRE_SEQ|GRE_VERSION)) { -+ /* - Version must be 0. -+ - We do not support routing headers. -+ */ -+ if (flags&(GRE_VERSION|GRE_ROUTING)) -+ goto drop_nolock; -+ -+ if (flags&GRE_CSUM) { -+ switch (skb->ip_summed) { -+ case CHECKSUM_COMPLETE: -+ csum = csum_fold(skb->csum); -+ if (!csum) -+ break; -+ /* fall through */ -+ case CHECKSUM_NONE: -+ skb->csum = 0; -+ csum = __skb_checksum_complete(skb); -+ skb->ip_summed = CHECKSUM_COMPLETE; -+ } -+ offset += 4; -+ } -+ if (flags&GRE_KEY) { -+ key = *(__be32*)(h + offset); -+ offset += 4; -+ } -+ if (flags&GRE_SEQ) { -+ seqno = ntohl(*(__be32*)(h + offset)); -+ offset += 4; -+ } -+ } -+ -+ read_lock(&ipgre_lock); -+ if ((tunnel = ipgre_tunnel_lookup(iph->saddr, iph->daddr, key)) != NULL) { -+ secpath_reset(skb); -+ -+ skb->protocol = *(__be16*)(h + 2); -+ /* WCCP version 1 and 2 protocol decoding. -+ * - Change protocol to IP -+ * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header -+ */ -+ if (flags == 0 && -+ skb->protocol == htons(ETH_P_WCCP)) { -+ skb->protocol = htons(ETH_P_IP); -+ if ((*(h + offset) & 0xF0) != 0x40) -+ offset += 4; -+ } -+ -+ skb_reset_mac_header(skb); -+ __pskb_pull(skb, offset); -+ skb_reset_network_header(skb); -+ skb_postpull_rcsum(skb, skb_transport_header(skb), offset); -+ skb->pkt_type = PACKET_HOST; -+#ifdef CONFIG_NET_IPGRE_BROADCAST -+ if (MULTICAST(iph->daddr)) { -+ /* Looped back packet, drop it! */ -+ if (((struct rtable*)skb->dst)->fl.iif == 0) -+ goto drop; -+ tunnel->stat.multicast++; -+ skb->pkt_type = PACKET_BROADCAST; -+ } -+#endif -+ -+ if (((flags&GRE_CSUM) && csum) || -+ (!(flags&GRE_CSUM) && tunnel->parms.i_flags&GRE_CSUM)) { -+ tunnel->stat.rx_crc_errors++; -+ tunnel->stat.rx_errors++; -+ goto drop; -+ } -+ if (tunnel->parms.i_flags&GRE_SEQ) { -+ if (!(flags&GRE_SEQ) || -+ (tunnel->i_seqno && (s32)(seqno - tunnel->i_seqno) < 0)) { -+ tunnel->stat.rx_fifo_errors++; -+ tunnel->stat.rx_errors++; -+ goto drop; -+ } -+ tunnel->i_seqno = seqno + 1; -+ } -+ tunnel->stat.rx_packets++; -+ tunnel->stat.rx_bytes += skb->len; -+ skb->dev = tunnel->dev; -+ dst_release(skb->dst); -+ skb->dst = NULL; -+ nf_reset(skb); -+ ipgre_ecn_decapsulate(iph, skb); -+ netif_rx(skb); -+ read_unlock(&ipgre_lock); -+ return(0); -+ } -+ icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); -+ -+drop: -+ read_unlock(&ipgre_lock); -+drop_nolock: -+ kfree_skb(skb); -+ return(0); -+} -+ -+static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ struct ip_tunnel *tunnel = netdev_priv(dev); -+ struct net_device_stats *stats = &tunnel->stat; -+ struct iphdr *old_iph = ip_hdr(skb); -+ struct iphdr *tiph; -+ u8 tos; -+ __be16 df; -+ struct rtable *rt; /* Route to the other host */ -+ struct net_device *tdev; /* Device to other host */ -+ struct iphdr *iph; /* Our new IP header */ -+ int max_headroom; /* The extra header space needed */ -+ int gre_hlen; -+ __be32 dst; -+ int mtu; -+ -+ if (tunnel->recursion++) { -+ tunnel->stat.collisions++; -+ goto tx_error; -+ } -+ -+ if (dev->hard_header) { -+ gre_hlen = 0; -+ tiph = (struct iphdr*)skb->data; -+ } else { -+ gre_hlen = tunnel->hlen; -+ tiph = &tunnel->parms.iph; -+ } -+ -+ if ((dst = tiph->daddr) == 0) { -+ /* NBMA tunnel */ -+ -+ if (skb->dst == NULL) { -+ tunnel->stat.tx_fifo_errors++; -+ goto tx_error; -+ } -+ -+ if (skb->protocol == htons(ETH_P_IP)) { -+ rt = (struct rtable*)skb->dst; -+ if ((dst = rt->rt_gateway) == 0) -+ goto tx_error_icmp; -+ } -+#ifdef CONFIG_IPV6 -+ else if (skb->protocol == htons(ETH_P_IPV6)) { -+ struct in6_addr *addr6; -+ int addr_type; -+ struct neighbour *neigh = skb->dst->neighbour; -+ -+ if (neigh == NULL) -+ goto tx_error; -+ -+ addr6 = (struct in6_addr*)&neigh->primary_key; -+ addr_type = ipv6_addr_type(addr6); -+ -+ if (addr_type == IPV6_ADDR_ANY) { -+ addr6 = &ipv6_hdr(skb)->daddr; -+ addr_type = ipv6_addr_type(addr6); -+ } -+ -+ if ((addr_type & IPV6_ADDR_COMPATv4) == 0) -+ goto tx_error_icmp; -+ -+ dst = addr6->s6_addr32[3]; -+ } -+#endif -+ else -+ goto tx_error; -+ } -+ -+ tos = tiph->tos; -+ if (tos&1) { -+ if (skb->protocol == htons(ETH_P_IP)) -+ tos = old_iph->tos; -+ tos &= ~1; -+ } -+ -+ { -+ struct flowi fl = { .oif = tunnel->parms.link, -+ .nl_u = { .ip4_u = -+ { .daddr = dst, -+ .saddr = tiph->saddr, -+ .tos = RT_TOS(tos) } }, -+ .proto = IPPROTO_GRE }; -+ if (ip_route_output_key(&rt, &fl)) { -+ tunnel->stat.tx_carrier_errors++; -+ goto tx_error; -+ } -+ } -+ tdev = rt->u.dst.dev; -+ -+ if (tdev == dev) { -+ ip_rt_put(rt); -+ tunnel->stat.collisions++; -+ goto tx_error; -+ } -+ -+ df = tiph->frag_off; -+ if (df) -+ mtu = dst_mtu(&rt->u.dst) - tunnel->hlen; -+ else -+ mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu; -+ -+ if (skb->dst) -+ skb->dst->ops->update_pmtu(skb->dst, mtu); -+ -+ if (skb->protocol == htons(ETH_P_IP)) { -+ df |= (old_iph->frag_off&htons(IP_DF)); -+ -+ if ((old_iph->frag_off&htons(IP_DF)) && -+ mtu < ntohs(old_iph->tot_len)) { -+ icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); -+ ip_rt_put(rt); -+ goto tx_error; -+ } -+ } -+#ifdef CONFIG_IPV6 -+ else if (skb->protocol == htons(ETH_P_IPV6)) { -+ struct rt6_info *rt6 = (struct rt6_info*)skb->dst; -+ -+ if (rt6 && mtu < dst_mtu(skb->dst) && mtu >= IPV6_MIN_MTU) { -+ if ((tunnel->parms.iph.daddr && !MULTICAST(tunnel->parms.iph.daddr)) || -+ rt6->rt6i_dst.plen == 128) { -+ rt6->rt6i_flags |= RTF_MODIFIED; -+ skb->dst->metrics[RTAX_MTU-1] = mtu; -+ } -+ } -+ -+ if (mtu >= IPV6_MIN_MTU && mtu < skb->len - tunnel->hlen + gre_hlen) { -+ icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev); -+ ip_rt_put(rt); -+ goto tx_error; -+ } -+ } -+#endif -+ -+ if (tunnel->err_count > 0) { -+ if (jiffies - tunnel->err_time < IPTUNNEL_ERR_TIMEO) { -+ tunnel->err_count--; -+ -+ dst_link_failure(skb); -+ } else -+ tunnel->err_count = 0; -+ } -+ -+ max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen; -+ -+ if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) { -+ struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); -+ if (!new_skb) { -+ ip_rt_put(rt); -+ stats->tx_dropped++; -+ dev_kfree_skb(skb); -+ tunnel->recursion--; -+ return 0; -+ } -+ if (skb->sk) -+ skb_set_owner_w(new_skb, skb->sk); -+ dev_kfree_skb(skb); -+ skb = new_skb; -+ old_iph = ip_hdr(skb); -+ } -+ -+ skb->transport_header = skb->network_header; -+ skb_push(skb, gre_hlen); -+ skb_reset_network_header(skb); -+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); -+ IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | -+ IPSKB_REROUTED); -+ dst_release(skb->dst); -+ skb->dst = &rt->u.dst; -+ -+ /* -+ * Push down and install the IPIP header. -+ */ -+ -+ iph = ip_hdr(skb); -+ iph->version = 4; -+ iph->ihl = sizeof(struct iphdr) >> 2; -+ iph->frag_off = df; -+ iph->protocol = IPPROTO_GRE; -+ iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb); -+ iph->daddr = rt->rt_dst; -+ iph->saddr = rt->rt_src; -+ -+ if ((iph->ttl = tiph->ttl) == 0) { -+ if (skb->protocol == htons(ETH_P_IP)) -+ iph->ttl = old_iph->ttl; -+#ifdef CONFIG_IPV6 -+ else if (skb->protocol == htons(ETH_P_IPV6)) -+ iph->ttl = ((struct ipv6hdr*)old_iph)->hop_limit; -+#endif -+ else -+ iph->ttl = dst_metric(&rt->u.dst, RTAX_HOPLIMIT); -+ } -+ -+ ((__be16*)(iph+1))[0] = tunnel->parms.o_flags; -+ ((__be16*)(iph+1))[1] = skb->protocol; -+ -+ if (tunnel->parms.o_flags&(GRE_KEY|GRE_CSUM|GRE_SEQ)) { -+ __be32 *ptr = (__be32*)(((u8*)iph) + tunnel->hlen - 4); -+ -+ if (tunnel->parms.o_flags&GRE_SEQ) { -+ ++tunnel->o_seqno; -+ *ptr = htonl(tunnel->o_seqno); -+ ptr--; -+ } -+ if (tunnel->parms.o_flags&GRE_KEY) { -+ *ptr = tunnel->parms.o_key; -+ ptr--; -+ } -+ if (tunnel->parms.o_flags&GRE_CSUM) { -+ *ptr = 0; -+ *(__sum16*)ptr = ip_compute_csum((void*)(iph+1), skb->len - sizeof(struct iphdr)); -+ } -+ } -+ -+ nf_reset(skb); -+ -+ IPTUNNEL_XMIT(); -+ tunnel->recursion--; -+ return 0; -+ -+tx_error_icmp: -+ dst_link_failure(skb); -+ -+tx_error: -+ stats->tx_errors++; -+ dev_kfree_skb(skb); -+ tunnel->recursion--; -+ return 0; -+} -+ -+static int -+ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) -+{ -+ int err = 0; -+ struct ip_tunnel_parm p; -+ struct ip_tunnel *t; -+ -+ switch (cmd) { -+ case SIOCGETTUNNEL: -+ t = NULL; -+ if (dev == ipgre_fb_tunnel_dev) { -+ if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) { -+ err = -EFAULT; -+ break; -+ } -+ t = ipgre_tunnel_locate(&p, 0); -+ } -+ if (t == NULL) -+ t = netdev_priv(dev); -+ memcpy(&p, &t->parms, sizeof(p)); -+ if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) -+ err = -EFAULT; -+ break; -+ -+ case SIOCADDTUNNEL: -+ case SIOCCHGTUNNEL: -+ err = -EPERM; -+ if (!capable(CAP_NET_ADMIN)) -+ goto done; -+ -+ err = -EFAULT; -+ if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) -+ goto done; -+ -+ err = -EINVAL; -+ if (p.iph.version != 4 || p.iph.protocol != IPPROTO_GRE || -+ p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF)) || -+ ((p.i_flags|p.o_flags)&(GRE_VERSION|GRE_ROUTING))) -+ goto done; -+ if (p.iph.ttl) -+ p.iph.frag_off |= htons(IP_DF); -+ -+ if (!(p.i_flags&GRE_KEY)) -+ p.i_key = 0; -+ if (!(p.o_flags&GRE_KEY)) -+ p.o_key = 0; -+ -+ t = ipgre_tunnel_locate(&p, cmd == SIOCADDTUNNEL); -+ -+ if (dev != ipgre_fb_tunnel_dev && cmd == SIOCCHGTUNNEL) { -+ if (t != NULL) { -+ if (t->dev != dev) { -+ err = -EEXIST; -+ break; -+ } -+ } else { -+ unsigned nflags=0; -+ -+ t = netdev_priv(dev); -+ -+ if (MULTICAST(p.iph.daddr)) -+ nflags = IFF_BROADCAST; -+ else if (p.iph.daddr) -+ nflags = IFF_POINTOPOINT; -+ -+ if ((dev->flags^nflags)&(IFF_POINTOPOINT|IFF_BROADCAST)) { -+ err = -EINVAL; -+ break; -+ } -+ ipgre_tunnel_unlink(t); -+ t->parms.iph.saddr = p.iph.saddr; -+ t->parms.iph.daddr = p.iph.daddr; -+ t->parms.i_key = p.i_key; -+ t->parms.o_key = p.o_key; -+ memcpy(dev->dev_addr, &p.iph.saddr, 4); -+ memcpy(dev->broadcast, &p.iph.daddr, 4); -+ ipgre_tunnel_link(t); -+ netdev_state_change(dev); -+ } -+ } -+ -+ if (t) { -+ err = 0; -+ if (cmd == SIOCCHGTUNNEL) { -+ t->parms.iph.ttl = p.iph.ttl; -+ t->parms.iph.tos = p.iph.tos; -+ t->parms.iph.frag_off = p.iph.frag_off; -+ } -+ if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p))) -+ err = -EFAULT; -+ } else -+ err = (cmd == SIOCADDTUNNEL ? -ENOBUFS : -ENOENT); -+ break; -+ -+ case SIOCDELTUNNEL: -+ err = -EPERM; -+ if (!capable(CAP_NET_ADMIN)) -+ goto done; -+ -+ if (dev == ipgre_fb_tunnel_dev) { -+ err = -EFAULT; -+ if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) -+ goto done; -+ err = -ENOENT; -+ if ((t = ipgre_tunnel_locate(&p, 0)) == NULL) -+ goto done; -+ err = -EPERM; -+ if (t == netdev_priv(ipgre_fb_tunnel_dev)) -+ goto done; -+ dev = t->dev; -+ } -+ unregister_netdevice(dev); -+ err = 0; -+ break; -+ -+ default: -+ err = -EINVAL; -+ } -+ -+done: -+ return err; -+} -+ -+static struct net_device_stats *ipgre_tunnel_get_stats(struct net_device *dev) -+{ -+ return &(((struct ip_tunnel*)netdev_priv(dev))->stat); -+} -+ -+static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu) -+{ -+ struct ip_tunnel *tunnel = netdev_priv(dev); -+ if (new_mtu < 68 || new_mtu > 0xFFF8 - tunnel->hlen) -+ return -EINVAL; -+ dev->mtu = new_mtu; -+ return 0; -+} -+ -+#ifdef CONFIG_NET_IPGRE_BROADCAST -+/* Nice toy. Unfortunately, useless in real life :-) -+ It allows to construct virtual multiprotocol broadcast "LAN" -+ over the Internet, provided multicast routing is tuned. -+ -+ -+ I have no idea was this bicycle invented before me, -+ so that I had to set ARPHRD_IPGRE to a random value. -+ I have an impression, that Cisco could make something similar, -+ but this feature is apparently missing in IOS<=11.2(8). -+ -+ I set up 10.66.66/24 and fec0:6666:6666::0/96 as virtual networks -+ with broadcast 224.66.66.66. If you have access to mbone, play with me :-) -+ -+ ping -t 255 224.66.66.66 -+ -+ If nobody answers, mbone does not work. -+ -+ ip tunnel add Universe mode gre remote 224.66.66.66 local ttl 255 -+ ip addr add 10.66.66./24 dev Universe -+ ifconfig Universe up -+ ifconfig Universe add fe80::/10 -+ ifconfig Universe add fec0:6666:6666::/96 -+ ftp 10.66.66.66 -+ ... -+ ftp fec0:6666:6666::193.233.7.65 -+ ... -+ -+ */ -+ -+static int ipgre_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, -+ void *daddr, void *saddr, unsigned len) -+{ -+ struct ip_tunnel *t = netdev_priv(dev); -+ struct iphdr *iph = (struct iphdr *)skb_push(skb, t->hlen); -+ __be16 *p = (__be16*)(iph+1); -+ -+ memcpy(iph, &t->parms.iph, sizeof(struct iphdr)); -+ p[0] = t->parms.o_flags; -+ p[1] = htons(type); -+ -+ /* -+ * Set the source hardware address. -+ */ -+ -+ if (saddr) -+ memcpy(&iph->saddr, saddr, 4); -+ -+ if (daddr) { -+ memcpy(&iph->daddr, daddr, 4); -+ return t->hlen; -+ } -+ if (iph->daddr && !MULTICAST(iph->daddr)) -+ return t->hlen; -+ -+ return -t->hlen; -+} -+ -+static int ipgre_open(struct net_device *dev) -+{ -+ struct ip_tunnel *t = netdev_priv(dev); -+ -+ if (MULTICAST(t->parms.iph.daddr)) { -+ struct flowi fl = { .oif = t->parms.link, -+ .nl_u = { .ip4_u = -+ { .daddr = t->parms.iph.daddr, -+ .saddr = t->parms.iph.saddr, -+ .tos = RT_TOS(t->parms.iph.tos) } }, -+ .proto = IPPROTO_GRE }; -+ struct rtable *rt; -+ if (ip_route_output_key(&rt, &fl)) -+ return -EADDRNOTAVAIL; -+ dev = rt->u.dst.dev; -+ ip_rt_put(rt); -+ if (__in_dev_get_rtnl(dev) == NULL) -+ return -EADDRNOTAVAIL; -+ t->mlink = dev->ifindex; -+ ip_mc_inc_group(__in_dev_get_rtnl(dev), t->parms.iph.daddr); -+ } -+ return 0; -+} -+ -+static int ipgre_close(struct net_device *dev) -+{ -+ 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); -+ if (in_dev) { -+ ip_mc_dec_group(in_dev, t->parms.iph.daddr); -+ in_dev_put(in_dev); -+ } -+ } -+ return 0; -+} -+ -+#endif -+ -+static void ipgre_tunnel_setup(struct net_device *dev) -+{ -+ SET_MODULE_OWNER(dev); -+ dev->uninit = ipgre_tunnel_uninit; -+ dev->destructor = free_netdev; -+ dev->hard_start_xmit = ipgre_tunnel_xmit; -+ dev->get_stats = ipgre_tunnel_get_stats; -+ dev->do_ioctl = ipgre_tunnel_ioctl; -+ dev->change_mtu = ipgre_tunnel_change_mtu; -+ -+ dev->type = ARPHRD_IPGRE; -+ dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr) + 4; -+ dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 4; -+ dev->flags = IFF_NOARP; -+ dev->iflink = 0; -+ dev->addr_len = 4; -+} -+ -+static int ipgre_tunnel_init(struct net_device *dev) -+{ -+ struct net_device *tdev = NULL; -+ struct ip_tunnel *tunnel; -+ struct iphdr *iph; -+ int hlen = LL_MAX_HEADER; -+ int mtu = ETH_DATA_LEN; -+ int addend = sizeof(struct iphdr) + 4; -+ -+ tunnel = netdev_priv(dev); -+ iph = &tunnel->parms.iph; -+ -+ tunnel->dev = dev; -+ strcpy(tunnel->parms.name, dev->name); -+ -+ memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4); -+ memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); -+ -+ /* Guess output device to choose reasonable mtu and hard_header_len */ -+ -+ if (iph->daddr) { -+ struct flowi fl = { .oif = tunnel->parms.link, -+ .nl_u = { .ip4_u = -+ { .daddr = iph->daddr, -+ .saddr = iph->saddr, -+ .tos = RT_TOS(iph->tos) } }, -+ .proto = IPPROTO_GRE }; -+ struct rtable *rt; -+ if (!ip_route_output_key(&rt, &fl)) { -+ tdev = rt->u.dst.dev; -+ ip_rt_put(rt); -+ } -+ -+ dev->flags |= IFF_POINTOPOINT; -+ -+#ifdef CONFIG_NET_IPGRE_BROADCAST -+ if (MULTICAST(iph->daddr)) { -+ if (!iph->saddr) -+ return -EINVAL; -+ dev->flags = IFF_BROADCAST; -+ dev->hard_header = ipgre_header; -+ dev->open = ipgre_open; -+ dev->stop = ipgre_close; -+ } -+#endif -+ } -+ -+ if (!tdev && tunnel->parms.link) -+ tdev = __dev_get_by_index(tunnel->parms.link); -+ -+ if (tdev) { -+ hlen = tdev->hard_header_len; -+ mtu = tdev->mtu; -+ } -+ dev->iflink = tunnel->parms.link; -+ -+ /* Precalculate GRE options length */ -+ if (tunnel->parms.o_flags&(GRE_CSUM|GRE_KEY|GRE_SEQ)) { -+ if (tunnel->parms.o_flags&GRE_CSUM) -+ addend += 4; -+ if (tunnel->parms.o_flags&GRE_KEY) -+ addend += 4; -+ if (tunnel->parms.o_flags&GRE_SEQ) -+ addend += 4; -+ } -+ dev->hard_header_len = hlen + addend; -+ dev->mtu = mtu - addend; -+ tunnel->hlen = addend; -+ return 0; -+} -+ -+static int __init ipgre_fb_tunnel_init(struct net_device *dev) -+{ -+ struct ip_tunnel *tunnel = netdev_priv(dev); -+ struct iphdr *iph = &tunnel->parms.iph; -+ -+ tunnel->dev = dev; -+ strcpy(tunnel->parms.name, dev->name); -+ -+ iph->version = 4; -+ iph->protocol = IPPROTO_GRE; -+ iph->ihl = 5; -+ tunnel->hlen = sizeof(struct iphdr) + 4; -+ -+ dev_hold(dev); -+ tunnels_wc[0] = tunnel; -+ return 0; -+} -+ -+ -+static struct net_protocol ipgre_protocol = { -+ .handler = ipgre_rcv, -+ .err_handler = ipgre_err, -+}; -+ -+ -+/* -+ * And now the modules code and kernel interface. -+ */ -+ -+static int __init ipgre_init(void) -+{ -+ int err; -+ -+ printk(KERN_INFO "GRE over IPv4 tunneling driver\n"); -+ -+ if (inet_add_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) { -+ printk(KERN_INFO "ipgre init: can't add protocol\n"); -+ return -EAGAIN; -+ } -+ -+ ipgre_fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "gre0", -+ ipgre_tunnel_setup); -+ if (!ipgre_fb_tunnel_dev) { -+ err = -ENOMEM; -+ goto err1; -+ } -+ -+ ipgre_fb_tunnel_dev->init = ipgre_fb_tunnel_init; -+ -+ if ((err = register_netdev(ipgre_fb_tunnel_dev))) -+ goto err2; -+out: -+ return err; -+err2: -+ free_netdev(ipgre_fb_tunnel_dev); -+err1: -+ inet_del_protocol(&ipgre_protocol, IPPROTO_GRE); -+ goto out; -+} -+ -+static void __exit ipgre_destroy_tunnels(void) -+{ -+ int prio; -+ -+ for (prio = 0; prio < 4; prio++) { -+ int h; -+ for (h = 0; h < HASH_SIZE; h++) { -+ struct ip_tunnel *t; -+ while ((t = tunnels[prio][h]) != NULL) -+ unregister_netdevice(t->dev); -+ } -+ } -+} -+ -+static void __exit ipgre_fini(void) -+{ -+ if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) -+ printk(KERN_INFO "ipgre close: can't remove protocol\n"); -+ -+ rtnl_lock(); -+ ipgre_destroy_tunnels(); -+ rtnl_unlock(); -+} -+ -+module_init(ipgre_init); -+module_exit(ipgre_fini); -+MODULE_LICENSE("GPL");