aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/802/fddi.c2
-rw-r--r--net/802/hippi.c2
-rw-r--r--net/8021q/vlanproc.c2
-rw-r--r--net/appletalk/dev.c22
-rw-r--r--net/atm/common.c4
-rw-r--r--net/atm/resources.c11
-rw-r--r--net/atm/signaling.c1
-rw-r--r--net/ax25/af_ax25.c4
-rw-r--r--net/ax25/ax25_ds_subr.c3
-rw-r--r--net/ax25/ax25_ip.c4
-rw-r--r--net/ax25/ax25_out.c9
-rw-r--r--net/ax25/ax25_subr.c4
-rw-r--r--net/bluetooth/af_bluetooth.c1
-rw-r--r--net/bluetooth/bnep/sock.c1
-rw-r--r--net/bluetooth/cmtp/capi.c1
-rw-r--r--net/bluetooth/cmtp/core.c1
-rw-r--r--net/bluetooth/cmtp/sock.c1
-rw-r--r--net/bluetooth/hci_conn.c1
-rw-r--r--net/bluetooth/hci_core.c1
-rw-r--r--net/bluetooth/hci_event.c1
-rw-r--r--net/bluetooth/hci_sock.c1
-rw-r--r--net/bluetooth/hidp/core.c1
-rw-r--r--net/bluetooth/hidp/sock.c1
-rw-r--r--net/bluetooth/l2cap.c1
-rw-r--r--net/bluetooth/rfcomm/sock.c1
-rw-r--r--net/bluetooth/sco.c1
-rw-r--r--net/core/datagram.c28
-rw-r--r--net/core/dev.c17
-rw-r--r--net/core/iovec.c2
-rw-r--r--net/core/link_watch.c7
-rw-r--r--net/core/neighbour.c2
-rw-r--r--net/core/netfilter.c17
-rw-r--r--net/core/rtnetlink.c68
-rw-r--r--net/core/scm.c1
-rw-r--r--net/core/skbuff.c12
-rw-r--r--net/core/sock.c27
-rw-r--r--net/core/stream.c12
-rw-r--r--net/decnet/dn_dev.c25
-rw-r--r--net/decnet/netfilter/dn_rtmsg.c3
-rw-r--r--net/ethernet/eth.c2
-rw-r--r--net/ipv4/af_inet.c3
-rw-r--r--net/ipv4/devinet.c23
-rw-r--r--net/ipv4/ip_input.c2
-rw-r--r--net/ipv4/ip_output.c5
-rw-r--r--net/ipv4/multipath_wrandom.c6
-rw-r--r--net/ipv4/netfilter/ip_conntrack_ftp.c4
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_standalone.c58
-rw-r--r--net/ipv4/netfilter/ip_nat_core.c9
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c54
-rw-r--r--net/ipv4/netfilter/ip_queue.c20
-rw-r--r--net/ipv4/netfilter/iptable_raw.c6
-rw-r--r--net/ipv4/protocol.c2
-rw-r--r--net/ipv4/raw.c2
-rw-r--r--net/ipv4/route.c6
-rw-r--r--net/ipv4/tcp.c2
-rw-r--r--net/ipv4/tcp_diag.c3
-rw-r--r--net/ipv4/tcp_input.c3
-rw-r--r--net/ipv4/tcp_ipv4.c7
-rw-r--r--net/ipv4/tcp_minisocks.c2
-rw-r--r--net/ipv4/tcp_output.c27
-rw-r--r--net/ipv4/tcp_timer.c2
-rw-r--r--net/ipv4/udp.c2
-rw-r--r--net/ipv4/xfrm4_policy.c42
-rw-r--r--net/ipv6/addrconf.c2
-rw-r--r--net/ipv6/af_inet6.c2
-rw-r--r--net/ipv6/exthdrs_core.c11
-rw-r--r--net/ipv6/icmp.c4
-rw-r--r--net/ipv6/netfilter/ip6_queue.c20
-rw-r--r--net/ipv6/raw.c7
-rw-r--r--net/ipv6/route.c2
-rw-r--r--net/ipv6/tcp_ipv6.c7
-rw-r--r--net/ipv6/xfrm6_policy.c43
-rw-r--r--net/irda/irda_device.c2
-rw-r--r--net/netlink/af_netlink.c7
-rw-r--r--net/packet/af_packet.c2
-rw-r--r--net/sched/Kconfig12
-rw-r--r--net/sched/Makefile11
-rw-r--r--net/sched/act_api.c4
-rw-r--r--net/sched/cls_fw.c31
-rw-r--r--net/sched/sch_api.c1
-rw-r--r--net/sched/sch_generic.c5
-rw-r--r--net/sched/sch_htb.c4
-rw-r--r--net/sched/sch_netem.c131
-rw-r--r--net/sched/simple.c93
-rw-r--r--net/sctp/endpointola.c1
-rw-r--r--net/sctp/ipv6.c4
-rw-r--r--net/sctp/output.c4
-rw-r--r--net/sctp/protocol.c7
-rw-r--r--net/sctp/sm_make_chunk.c19
-rw-r--r--net/sctp/sm_statefuns.c77
-rw-r--r--net/sctp/socket.c38
-rw-r--r--net/sctp/sysctl.c8
-rw-r--r--net/socket.c2
-rw-r--r--net/sunrpc/xdr.c12
-rw-r--r--net/unix/af_unix.c1
-rw-r--r--net/wanrouter/wanmain.c4
-rw-r--r--net/xfrm/xfrm_policy.c25
-rw-r--r--net/xfrm/xfrm_state.c5
-rw-r--r--net/xfrm/xfrm_user.c87
100 files changed, 847 insertions, 445 deletions
diff --git a/net/802/fddi.c b/net/802/fddi.c
index f9a31a9f70f1..ebcf4830d6f1 100644
--- a/net/802/fddi.c
+++ b/net/802/fddi.c
@@ -10,7 +10,7 @@
10 * Authors: Lawrence V. Stefani, <stefani@lkg.dec.com> 10 * Authors: Lawrence V. Stefani, <stefani@lkg.dec.com>
11 * 11 *
12 * fddi.c is based on previous eth.c and tr.c work by 12 * fddi.c is based on previous eth.c and tr.c work by
13 * Ross Biro, <bir7@leland.Stanford.Edu> 13 * Ross Biro
14 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 14 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
15 * Mark Evans, <evansmp@uhura.aston.ac.uk> 15 * Mark Evans, <evansmp@uhura.aston.ac.uk>
16 * Florian La Roche, <rzsfl@rz.uni-sb.de> 16 * Florian La Roche, <rzsfl@rz.uni-sb.de>
diff --git a/net/802/hippi.c b/net/802/hippi.c
index 4eb135c0afbb..051e8af56a77 100644
--- a/net/802/hippi.c
+++ b/net/802/hippi.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * Version: @(#)hippi.c 1.0.0 05/29/97 8 * Version: @(#)hippi.c 1.0.0 05/29/97
9 * 9 *
10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 10 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Mark Evans, <evansmp@uhura.aston.ac.uk> 12 * Mark Evans, <evansmp@uhura.aston.ac.uk>
13 * Florian La Roche, <rzsfl@rz.uni-sb.de> 13 * Florian La Roche, <rzsfl@rz.uni-sb.de>
diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c
index c32d27af0a3f..7b214cffc956 100644
--- a/net/8021q/vlanproc.c
+++ b/net/8021q/vlanproc.c
@@ -23,7 +23,7 @@
23#include <linux/errno.h> /* return codes */ 23#include <linux/errno.h> /* return codes */
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/slab.h> /* kmalloc(), kfree() */ 25#include <linux/slab.h> /* kmalloc(), kfree() */
26#include <linux/mm.h> /* verify_area(), etc. */ 26#include <linux/mm.h>
27#include <linux/string.h> /* inline mem*, str* functions */ 27#include <linux/string.h> /* inline mem*, str* functions */
28#include <linux/init.h> /* __initfunc et al. */ 28#include <linux/init.h> /* __initfunc et al. */
29#include <asm/byteorder.h> /* htons(), etc. */ 29#include <asm/byteorder.h> /* htons(), etc. */
diff --git a/net/appletalk/dev.c b/net/appletalk/dev.c
index 76598445d84b..1237e208e246 100644
--- a/net/appletalk/dev.c
+++ b/net/appletalk/dev.c
@@ -19,7 +19,7 @@ static int ltalk_mac_addr(struct net_device *dev, void *addr)
19 return -EINVAL; 19 return -EINVAL;
20} 20}
21 21
22void ltalk_setup(struct net_device *dev) 22static void ltalk_setup(struct net_device *dev)
23{ 23{
24 /* Fill in the fields of the device structure with localtalk-generic values. */ 24 /* Fill in the fields of the device structure with localtalk-generic values. */
25 25
@@ -40,4 +40,22 @@ void ltalk_setup(struct net_device *dev)
40 40
41 dev->flags = IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP; 41 dev->flags = IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP;
42} 42}
43EXPORT_SYMBOL(ltalk_setup); 43
44/**
45 * alloc_ltalkdev - Allocates and sets up an localtalk device
46 * @sizeof_priv: Size of additional driver-private structure to be allocated
47 * for this localtalk device
48 *
49 * Fill in the fields of the device structure with localtalk-generic
50 * values. Basically does everything except registering the device.
51 *
52 * Constructs a new net device, complete with a private data area of
53 * size @sizeof_priv. A 32-byte (not bit) alignment is enforced for
54 * this private data area.
55 */
56
57struct net_device *alloc_ltalkdev(int sizeof_priv)
58{
59 return alloc_netdev(sizeof_priv, "lt%d", ltalk_setup);
60}
61EXPORT_SYMBOL(alloc_ltalkdev);
diff --git a/net/atm/common.c b/net/atm/common.c
index 6d16be334ea0..e93e838069e8 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -12,7 +12,7 @@
12#include <linux/socket.h> /* SOL_SOCKET */ 12#include <linux/socket.h> /* SOL_SOCKET */
13#include <linux/errno.h> /* error codes */ 13#include <linux/errno.h> /* error codes */
14#include <linux/capability.h> 14#include <linux/capability.h>
15#include <linux/mm.h> /* verify_area */ 15#include <linux/mm.h>
16#include <linux/sched.h> 16#include <linux/sched.h>
17#include <linux/time.h> /* struct timeval */ 17#include <linux/time.h> /* struct timeval */
18#include <linux/skbuff.h> 18#include <linux/skbuff.h>
@@ -540,7 +540,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
540 error = -EMSGSIZE; 540 error = -EMSGSIZE;
541 goto out; 541 goto out;
542 } 542 }
543 /* verify_area is done by net/socket.c */ 543
544 eff = (size+3) & ~3; /* align to word boundary */ 544 eff = (size+3) & ~3; /* align to word boundary */
545 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); 545 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
546 error = 0; 546 error = 0;
diff --git a/net/atm/resources.c b/net/atm/resources.c
index 33f1685dbb77..a57a9268bd24 100644
--- a/net/atm/resources.c
+++ b/net/atm/resources.c
@@ -44,11 +44,6 @@ static struct atm_dev *__alloc_atm_dev(const char *type)
44 return dev; 44 return dev;
45} 45}
46 46
47static void __free_atm_dev(struct atm_dev *dev)
48{
49 kfree(dev);
50}
51
52static struct atm_dev *__atm_dev_lookup(int number) 47static struct atm_dev *__atm_dev_lookup(int number)
53{ 48{
54 struct atm_dev *dev; 49 struct atm_dev *dev;
@@ -90,7 +85,7 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
90 if ((inuse = __atm_dev_lookup(number))) { 85 if ((inuse = __atm_dev_lookup(number))) {
91 atm_dev_put(inuse); 86 atm_dev_put(inuse);
92 spin_unlock(&atm_dev_lock); 87 spin_unlock(&atm_dev_lock);
93 __free_atm_dev(dev); 88 kfree(dev);
94 return NULL; 89 return NULL;
95 } 90 }
96 dev->number = number; 91 dev->number = number;
@@ -119,7 +114,7 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
119 spin_lock(&atm_dev_lock); 114 spin_lock(&atm_dev_lock);
120 list_del(&dev->dev_list); 115 list_del(&dev->dev_list);
121 spin_unlock(&atm_dev_lock); 116 spin_unlock(&atm_dev_lock);
122 __free_atm_dev(dev); 117 kfree(dev);
123 return NULL; 118 return NULL;
124 } 119 }
125 120
@@ -148,7 +143,7 @@ void atm_dev_deregister(struct atm_dev *dev)
148 } 143 }
149 } 144 }
150 145
151 __free_atm_dev(dev); 146 kfree(dev);
152} 147}
153 148
154void shutdown_atm_dev(struct atm_dev *dev) 149void shutdown_atm_dev(struct atm_dev *dev)
diff --git a/net/atm/signaling.c b/net/atm/signaling.c
index 6ff803154c04..f7c449ac1800 100644
--- a/net/atm/signaling.c
+++ b/net/atm/signaling.c
@@ -134,6 +134,7 @@ static int sigd_send(struct atm_vcc *vcc,struct sk_buff *skb)
134 break; 134 break;
135 case as_indicate: 135 case as_indicate:
136 vcc = *(struct atm_vcc **) &msg->listen_vcc; 136 vcc = *(struct atm_vcc **) &msg->listen_vcc;
137 sk = sk_atm(vcc);
137 DPRINTK("as_indicate!!!\n"); 138 DPRINTK("as_indicate!!!\n");
138 lock_sock(sk); 139 lock_sock(sk);
139 if (sk_acceptq_is_full(sk)) { 140 if (sk_acceptq_is_full(sk)) {
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 33b1a3763027..707097deac3d 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1587,9 +1587,7 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock,
1587 *asmptr = AX25_UI; 1587 *asmptr = AX25_UI;
1588 1588
1589 /* Datagram frames go straight out of the door as UI */ 1589 /* Datagram frames go straight out of the door as UI */
1590 skb->dev = ax25->ax25_dev->dev; 1590 ax25_queue_xmit(skb, ax25->ax25_dev->dev);
1591
1592 ax25_queue_xmit(skb);
1593 1591
1594 err = len; 1592 err = len;
1595 1593
diff --git a/net/ax25/ax25_ds_subr.c b/net/ax25/ax25_ds_subr.c
index 10ffd2beba3f..1d4ab641f82b 100644
--- a/net/ax25/ax25_ds_subr.c
+++ b/net/ax25/ax25_ds_subr.c
@@ -143,8 +143,7 @@ static void ax25_kiss_cmd(ax25_dev *ax25_dev, unsigned char cmd, unsigned char p
143 *p++ = cmd; 143 *p++ = cmd;
144 *p++ = param; 144 *p++ = param;
145 145
146 skb->dev = ax25_dev->dev; 146 skb->protocol = ax25_type_trans(skb, ax25_dev->dev);
147 skb->protocol = htons(ETH_P_AX25);
148 147
149 dev_queue_xmit(skb); 148 dev_queue_xmit(skb);
150} 149}
diff --git a/net/ax25/ax25_ip.c b/net/ax25/ax25_ip.c
index 04d711344d55..bba0173e2d65 100644
--- a/net/ax25/ax25_ip.c
+++ b/net/ax25/ax25_ip.c
@@ -199,9 +199,7 @@ int ax25_rebuild_header(struct sk_buff *skb)
199 skb = ourskb; 199 skb = ourskb;
200 } 200 }
201 201
202 skb->dev = dev; 202 ax25_queue_xmit(skb, dev);
203
204 ax25_queue_xmit(skb);
205 203
206put: 204put:
207 ax25_put_route(route); 205 ax25_put_route(route);
diff --git a/net/ax25/ax25_out.c b/net/ax25/ax25_out.c
index 3475a3ac9343..5fc048dcd39a 100644
--- a/net/ax25/ax25_out.c
+++ b/net/ax25/ax25_out.c
@@ -340,21 +340,18 @@ void ax25_transmit_buffer(ax25_cb *ax25, struct sk_buff *skb, int type)
340 340
341 ax25_addr_build(ptr, &ax25->source_addr, &ax25->dest_addr, ax25->digipeat, type, ax25->modulus); 341 ax25_addr_build(ptr, &ax25->source_addr, &ax25->dest_addr, ax25->digipeat, type, ax25->modulus);
342 342
343 skb->dev = ax25->ax25_dev->dev; 343 ax25_queue_xmit(skb, ax25->ax25_dev->dev);
344
345 ax25_queue_xmit(skb);
346} 344}
347 345
348/* 346/*
349 * A small shim to dev_queue_xmit to add the KISS control byte, and do 347 * A small shim to dev_queue_xmit to add the KISS control byte, and do
350 * any packet forwarding in operation. 348 * any packet forwarding in operation.
351 */ 349 */
352void ax25_queue_xmit(struct sk_buff *skb) 350void ax25_queue_xmit(struct sk_buff *skb, struct net_device *dev)
353{ 351{
354 unsigned char *ptr; 352 unsigned char *ptr;
355 353
356 skb->protocol = htons(ETH_P_AX25); 354 skb->protocol = ax25_type_trans(skb, ax25_fwd_dev(dev));
357 skb->dev = ax25_fwd_dev(skb->dev);
358 355
359 ptr = skb_push(skb, 1); 356 ptr = skb_push(skb, 1);
360 *ptr = 0x00; /* KISS */ 357 *ptr = 0x00; /* KISS */
diff --git a/net/ax25/ax25_subr.c b/net/ax25/ax25_subr.c
index 8cf72707af8b..99694b57f6f5 100644
--- a/net/ax25/ax25_subr.c
+++ b/net/ax25/ax25_subr.c
@@ -220,9 +220,7 @@ void ax25_return_dm(struct net_device *dev, ax25_address *src, ax25_address *des
220 dptr = skb_push(skb, ax25_addr_size(digi)); 220 dptr = skb_push(skb, ax25_addr_size(digi));
221 dptr += ax25_addr_build(dptr, dest, src, &retdigi, AX25_RESPONSE, AX25_MODULUS); 221 dptr += ax25_addr_build(dptr, dest, src, &retdigi, AX25_RESPONSE, AX25_MODULUS);
222 222
223 skb->dev = dev; 223 ax25_queue_xmit(skb, dev);
224
225 ax25_queue_xmit(skb);
226} 224}
227 225
228/* 226/*
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 1650c6bf6997..12b43345b54f 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -31,7 +31,6 @@
31#include <linux/list.h> 31#include <linux/list.h>
32#include <linux/errno.h> 32#include <linux/errno.h>
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/major.h>
35#include <linux/sched.h> 34#include <linux/sched.h>
36#include <linux/slab.h> 35#include <linux/slab.h>
37#include <linux/skbuff.h> 36#include <linux/skbuff.h>
diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c
index 9a8d99a39b6d..9778c6acd53b 100644
--- a/net/bluetooth/bnep/sock.c
+++ b/net/bluetooth/bnep/sock.c
@@ -34,7 +34,6 @@
34#include <linux/types.h> 34#include <linux/types.h>
35#include <linux/errno.h> 35#include <linux/errno.h>
36#include <linux/kernel.h> 36#include <linux/kernel.h>
37#include <linux/major.h>
38#include <linux/sched.h> 37#include <linux/sched.h>
39#include <linux/slab.h> 38#include <linux/slab.h>
40#include <linux/poll.h> 39#include <linux/poll.h>
diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c
index 1e5c030b72ad..b2e7e38531c6 100644
--- a/net/bluetooth/cmtp/capi.c
+++ b/net/bluetooth/cmtp/capi.c
@@ -26,7 +26,6 @@
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/errno.h> 27#include <linux/errno.h>
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/major.h>
30#include <linux/sched.h> 29#include <linux/sched.h>
31#include <linux/slab.h> 30#include <linux/slab.h>
32#include <linux/poll.h> 31#include <linux/poll.h>
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c
index 20ce04f2be8b..2e341de3e763 100644
--- a/net/bluetooth/cmtp/core.c
+++ b/net/bluetooth/cmtp/core.c
@@ -26,7 +26,6 @@
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/errno.h> 27#include <linux/errno.h>
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/major.h>
30#include <linux/sched.h> 29#include <linux/sched.h>
31#include <linux/slab.h> 30#include <linux/slab.h>
32#include <linux/poll.h> 31#include <linux/poll.h>
diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c
index 4c7f9e20dade..beb045bf5714 100644
--- a/net/bluetooth/cmtp/sock.c
+++ b/net/bluetooth/cmtp/sock.c
@@ -26,7 +26,6 @@
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/errno.h> 27#include <linux/errno.h>
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/major.h>
30#include <linux/sched.h> 29#include <linux/sched.h>
31#include <linux/slab.h> 30#include <linux/slab.h>
32#include <linux/poll.h> 31#include <linux/poll.h>
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 71762d7e9970..a31244e58888 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -30,7 +30,6 @@
30#include <linux/types.h> 30#include <linux/types.h>
31#include <linux/errno.h> 31#include <linux/errno.h>
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/major.h>
34#include <linux/sched.h> 33#include <linux/sched.h>
35#include <linux/slab.h> 34#include <linux/slab.h>
36#include <linux/poll.h> 35#include <linux/poll.h>
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 860dba7bdd89..fb5524365bc2 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -31,7 +31,6 @@
31#include <linux/types.h> 31#include <linux/types.h>
32#include <linux/errno.h> 32#include <linux/errno.h>
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/major.h>
35#include <linux/sched.h> 34#include <linux/sched.h>
36#include <linux/slab.h> 35#include <linux/slab.h>
37#include <linux/poll.h> 36#include <linux/poll.h>
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 8ccba8ee9979..c4b592b4ef10 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -30,7 +30,6 @@
30#include <linux/types.h> 30#include <linux/types.h>
31#include <linux/errno.h> 31#include <linux/errno.h>
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/major.h>
34#include <linux/sched.h> 33#include <linux/sched.h>
35#include <linux/slab.h> 34#include <linux/slab.h>
36#include <linux/poll.h> 35#include <linux/poll.h>
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index c9792ba75122..ebdcce5e7ca0 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -30,7 +30,6 @@
30#include <linux/types.h> 30#include <linux/types.h>
31#include <linux/errno.h> 31#include <linux/errno.h>
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/major.h>
34#include <linux/sched.h> 33#include <linux/sched.h>
35#include <linux/slab.h> 34#include <linux/slab.h>
36#include <linux/poll.h> 35#include <linux/poll.h>
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 2cf98ceabcc7..affbc55462e8 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -26,7 +26,6 @@
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/errno.h> 27#include <linux/errno.h>
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/major.h>
30#include <linux/sched.h> 29#include <linux/sched.h>
31#include <linux/slab.h> 30#include <linux/slab.h>
32#include <linux/poll.h> 31#include <linux/poll.h>
diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c
index fabb36d4666b..f8986f881431 100644
--- a/net/bluetooth/hidp/sock.c
+++ b/net/bluetooth/hidp/sock.c
@@ -26,7 +26,6 @@
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/errno.h> 27#include <linux/errno.h>
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/major.h>
30#include <linux/sched.h> 29#include <linux/sched.h>
31#include <linux/slab.h> 30#include <linux/slab.h>
32#include <linux/poll.h> 31#include <linux/poll.h>
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index c12babcf0b3c..32fccfb5bfa5 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -30,7 +30,6 @@
30#include <linux/types.h> 30#include <linux/types.h>
31#include <linux/errno.h> 31#include <linux/errno.h>
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/major.h>
34#include <linux/sched.h> 33#include <linux/sched.h>
35#include <linux/slab.h> 34#include <linux/slab.h>
36#include <linux/poll.h> 35#include <linux/poll.h>
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 640028a2183c..f3f6355a2786 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -33,7 +33,6 @@
33#include <linux/types.h> 33#include <linux/types.h>
34#include <linux/errno.h> 34#include <linux/errno.h>
35#include <linux/kernel.h> 35#include <linux/kernel.h>
36#include <linux/major.h>
37#include <linux/sched.h> 36#include <linux/sched.h>
38#include <linux/slab.h> 37#include <linux/slab.h>
39#include <linux/poll.h> 38#include <linux/poll.h>
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 3e750ef09e60..746c11fc017e 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -30,7 +30,6 @@
30#include <linux/types.h> 30#include <linux/types.h>
31#include <linux/errno.h> 31#include <linux/errno.h>
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/major.h>
34#include <linux/sched.h> 33#include <linux/sched.h>
35#include <linux/slab.h> 34#include <linux/slab.h>
36#include <linux/poll.h> 35#include <linux/poll.h>
diff --git a/net/core/datagram.c b/net/core/datagram.c
index d1bfd279cc1a..fcee054b6f75 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -115,10 +115,10 @@ out_noerr:
115 115
116/** 116/**
117 * skb_recv_datagram - Receive a datagram skbuff 117 * skb_recv_datagram - Receive a datagram skbuff
118 * @sk - socket 118 * @sk: socket
119 * @flags - MSG_ flags 119 * @flags: MSG_ flags
120 * @noblock - blocking operation? 120 * @noblock: blocking operation?
121 * @err - error code returned 121 * @err: error code returned
122 * 122 *
123 * Get a datagram skbuff, understands the peeking, nonblocking wakeups 123 * Get a datagram skbuff, understands the peeking, nonblocking wakeups
124 * and possible races. This replaces identical code in packet, raw and 124 * and possible races. This replaces identical code in packet, raw and
@@ -201,10 +201,10 @@ void skb_free_datagram(struct sock *sk, struct sk_buff *skb)
201 201
202/** 202/**
203 * skb_copy_datagram_iovec - Copy a datagram to an iovec. 203 * skb_copy_datagram_iovec - Copy a datagram to an iovec.
204 * @skb - buffer to copy 204 * @skb: buffer to copy
205 * @offset - offset in the buffer to start copying from 205 * @offset: offset in the buffer to start copying from
206 * @iovec - io vector to copy to 206 * @to: io vector to copy to
207 * @len - amount of data to copy from buffer to iovec 207 * @len: amount of data to copy from buffer to iovec
208 * 208 *
209 * Note: the iovec is modified during the copy. 209 * Note: the iovec is modified during the copy.
210 */ 210 */
@@ -377,9 +377,9 @@ fault:
377 377
378/** 378/**
379 * skb_copy_and_csum_datagram_iovec - Copy and checkum skb to user iovec. 379 * skb_copy_and_csum_datagram_iovec - Copy and checkum skb to user iovec.
380 * @skb - skbuff 380 * @skb: skbuff
381 * @hlen - hardware length 381 * @hlen: hardware length
382 * @iovec - io vector 382 * @iov: io vector
383 * 383 *
384 * Caller _must_ check that skb will fit to this iovec. 384 * Caller _must_ check that skb will fit to this iovec.
385 * 385 *
@@ -425,9 +425,9 @@ fault:
425 425
426/** 426/**
427 * datagram_poll - generic datagram poll 427 * datagram_poll - generic datagram poll
428 * @file - file struct 428 * @file: file struct
429 * @sock - socket 429 * @sock: socket
430 * @wait - poll table 430 * @wait: poll table
431 * 431 *
432 * Datagram poll: Again totally generic. This also handles 432 * Datagram poll: Again totally generic. This also handles
433 * sequenced packet sockets providing the socket receive queue 433 * sequenced packet sockets providing the socket receive queue
diff --git a/net/core/dev.c b/net/core/dev.c
index 42344d903692..d4d9e2680adb 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -7,7 +7,7 @@
7 * 2 of the License, or (at your option) any later version. 7 * 2 of the License, or (at your option) any later version.
8 * 8 *
9 * Derived from the non IP parts of dev.c 1.0.19 9 * Derived from the non IP parts of dev.c 1.0.19
10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 10 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Mark Evans, <evansmp@uhura.aston.ac.uk> 12 * Mark Evans, <evansmp@uhura.aston.ac.uk>
13 * 13 *
@@ -1214,6 +1214,19 @@ int __skb_linearize(struct sk_buff *skb, int gfp_mask)
1214 * A negative errno code is returned on a failure. A success does not 1214 * A negative errno code is returned on a failure. A success does not
1215 * guarantee the frame will be transmitted as it may be dropped due 1215 * guarantee the frame will be transmitted as it may be dropped due
1216 * to congestion or traffic shaping. 1216 * to congestion or traffic shaping.
1217 *
1218 * -----------------------------------------------------------------------------------
1219 * I notice this method can also return errors from the queue disciplines,
1220 * including NET_XMIT_DROP, which is a positive value. So, errors can also
1221 * be positive.
1222 *
1223 * Regardless of the return value, the skb is consumed, so it is currently
1224 * difficult to retry a send to this method. (You can bump the ref count
1225 * before sending to hold a reference for retry if you are careful.)
1226 *
1227 * When calling this method, interrupts MUST be enabled. This is because
1228 * the BH enable code must have IRQs enabled so that it will not deadlock.
1229 * --BLG
1217 */ 1230 */
1218 1231
1219int dev_queue_xmit(struct sk_buff *skb) 1232int dev_queue_xmit(struct sk_buff *skb)
@@ -3078,7 +3091,7 @@ void free_netdev(struct net_device *dev)
3078void synchronize_net(void) 3091void synchronize_net(void)
3079{ 3092{
3080 might_sleep(); 3093 might_sleep();
3081 synchronize_kernel(); 3094 synchronize_rcu();
3082} 3095}
3083 3096
3084/** 3097/**
diff --git a/net/core/iovec.c b/net/core/iovec.c
index d57ace949ab8..65e4b56fbc77 100644
--- a/net/core/iovec.c
+++ b/net/core/iovec.c
@@ -33,7 +33,7 @@
33 * Verify iovec. The caller must ensure that the iovec is big enough 33 * Verify iovec. The caller must ensure that the iovec is big enough
34 * to hold the message iovec. 34 * to hold the message iovec.
35 * 35 *
36 * Save time not doing verify_area. copy_*_user will make this work 36 * Save time not doing access_ok. copy_*_user will make this work
37 * in any case. 37 * in any case.
38 */ 38 */
39 39
diff --git a/net/core/link_watch.c b/net/core/link_watch.c
index 4859b7446c6f..d43d1201275c 100644
--- a/net/core/link_watch.c
+++ b/net/core/link_watch.c
@@ -16,6 +16,7 @@
16#include <linux/netdevice.h> 16#include <linux/netdevice.h>
17#include <linux/if.h> 17#include <linux/if.h>
18#include <net/sock.h> 18#include <net/sock.h>
19#include <net/pkt_sched.h>
19#include <linux/rtnetlink.h> 20#include <linux/rtnetlink.h>
20#include <linux/jiffies.h> 21#include <linux/jiffies.h>
21#include <linux/spinlock.h> 22#include <linux/spinlock.h>
@@ -74,6 +75,12 @@ void linkwatch_run_queue(void)
74 clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state); 75 clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state);
75 76
76 if (dev->flags & IFF_UP) { 77 if (dev->flags & IFF_UP) {
78 if (netif_carrier_ok(dev)) {
79 WARN_ON(dev->qdisc_sleeping == &noop_qdisc);
80 dev_activate(dev);
81 } else
82 dev_deactivate(dev);
83
77 netdev_state_change(dev); 84 netdev_state_change(dev);
78 } 85 }
79 86
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 0a2f67bbef2e..43bdc521e20d 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1953,7 +1953,7 @@ static int neigh_stat_seq_show(struct seq_file *seq, void *v)
1953 struct neigh_statistics *st = v; 1953 struct neigh_statistics *st = v;
1954 1954
1955 if (v == SEQ_START_TOKEN) { 1955 if (v == SEQ_START_TOKEN) {
1956 seq_printf(seq, "entries allocs destroys hash_grows lookups hits res_failed rcv_probes_mcast rcv_probes_ucast periodic_gc_runs forced_gc_runs forced_gc_goal_miss\n"); 1956 seq_printf(seq, "entries allocs destroys hash_grows lookups hits res_failed rcv_probes_mcast rcv_probes_ucast periodic_gc_runs forced_gc_runs\n");
1957 return 0; 1957 return 0;
1958 } 1958 }
1959 1959
diff --git a/net/core/netfilter.c b/net/core/netfilter.c
index e51cfa46950c..22a8f127c4aa 100644
--- a/net/core/netfilter.c
+++ b/net/core/netfilter.c
@@ -217,21 +217,10 @@ void nf_debug_ip_local_deliver(struct sk_buff *skb)
217 * NF_IP_RAW_INPUT and NF_IP_PRE_ROUTING. */ 217 * NF_IP_RAW_INPUT and NF_IP_PRE_ROUTING. */
218 if (!skb->dev) { 218 if (!skb->dev) {
219 printk("ip_local_deliver: skb->dev is NULL.\n"); 219 printk("ip_local_deliver: skb->dev is NULL.\n");
220 } 220 } else {
221 else if (strcmp(skb->dev->name, "lo") == 0) {
222 if (skb->nf_debug != ((1 << NF_IP_LOCAL_OUT)
223 | (1 << NF_IP_POST_ROUTING)
224 | (1 << NF_IP_PRE_ROUTING)
225 | (1 << NF_IP_LOCAL_IN))) {
226 printk("ip_local_deliver: bad loopback skb: ");
227 debug_print_hooks_ip(skb->nf_debug);
228 nf_dump_skb(PF_INET, skb);
229 }
230 }
231 else {
232 if (skb->nf_debug != ((1<<NF_IP_PRE_ROUTING) 221 if (skb->nf_debug != ((1<<NF_IP_PRE_ROUTING)
233 | (1<<NF_IP_LOCAL_IN))) { 222 | (1<<NF_IP_LOCAL_IN))) {
234 printk("ip_local_deliver: bad non-lo skb: "); 223 printk("ip_local_deliver: bad skb: ");
235 debug_print_hooks_ip(skb->nf_debug); 224 debug_print_hooks_ip(skb->nf_debug);
236 nf_dump_skb(PF_INET, skb); 225 nf_dump_skb(PF_INET, skb);
237 } 226 }
@@ -247,8 +236,6 @@ void nf_debug_ip_loopback_xmit(struct sk_buff *newskb)
247 debug_print_hooks_ip(newskb->nf_debug); 236 debug_print_hooks_ip(newskb->nf_debug);
248 nf_dump_skb(PF_INET, newskb); 237 nf_dump_skb(PF_INET, newskb);
249 } 238 }
250 /* Clear to avoid confusing input check */
251 newskb->nf_debug = 0;
252} 239}
253 240
254void nf_debug_ip_finish_output2(struct sk_buff *skb) 241void nf_debug_ip_finish_output2(struct sk_buff *skb)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 44dfaf8f04af..00caf4b318b2 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -22,7 +22,6 @@
22#include <linux/types.h> 22#include <linux/types.h>
23#include <linux/socket.h> 23#include <linux/socket.h>
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/major.h>
26#include <linux/sched.h> 25#include <linux/sched.h>
27#include <linux/timer.h> 26#include <linux/timer.h>
28#include <linux/string.h> 27#include <linux/string.h>
@@ -87,30 +86,33 @@ struct sock *rtnl;
87 86
88struct rtnetlink_link * rtnetlink_links[NPROTO]; 87struct rtnetlink_link * rtnetlink_links[NPROTO];
89 88
90static const int rtm_min[(RTM_MAX+1-RTM_BASE)/4] = 89static const int rtm_min[RTM_NR_FAMILIES] =
91{ 90{
92 NLMSG_LENGTH(sizeof(struct ifinfomsg)), 91 [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
93 NLMSG_LENGTH(sizeof(struct ifaddrmsg)), 92 [RTM_FAM(RTM_NEWADDR)] = NLMSG_LENGTH(sizeof(struct ifaddrmsg)),
94 NLMSG_LENGTH(sizeof(struct rtmsg)), 93 [RTM_FAM(RTM_NEWROUTE)] = NLMSG_LENGTH(sizeof(struct rtmsg)),
95 NLMSG_LENGTH(sizeof(struct ndmsg)), 94 [RTM_FAM(RTM_NEWNEIGH)] = NLMSG_LENGTH(sizeof(struct ndmsg)),
96 NLMSG_LENGTH(sizeof(struct rtmsg)), 95 [RTM_FAM(RTM_NEWRULE)] = NLMSG_LENGTH(sizeof(struct rtmsg)),
97 NLMSG_LENGTH(sizeof(struct tcmsg)), 96 [RTM_FAM(RTM_NEWQDISC)] = NLMSG_LENGTH(sizeof(struct tcmsg)),
98 NLMSG_LENGTH(sizeof(struct tcmsg)), 97 [RTM_FAM(RTM_NEWTCLASS)] = NLMSG_LENGTH(sizeof(struct tcmsg)),
99 NLMSG_LENGTH(sizeof(struct tcmsg)), 98 [RTM_FAM(RTM_NEWTFILTER)] = NLMSG_LENGTH(sizeof(struct tcmsg)),
100 NLMSG_LENGTH(sizeof(struct tcamsg)) 99 [RTM_FAM(RTM_NEWACTION)] = NLMSG_LENGTH(sizeof(struct tcamsg)),
100 [RTM_FAM(RTM_NEWPREFIX)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
101 [RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
102 [RTM_FAM(RTM_GETANYCAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
101}; 103};
102 104
103static const int rta_max[(RTM_MAX+1-RTM_BASE)/4] = 105static const int rta_max[RTM_NR_FAMILIES] =
104{ 106{
105 IFLA_MAX, 107 [RTM_FAM(RTM_NEWLINK)] = IFLA_MAX,
106 IFA_MAX, 108 [RTM_FAM(RTM_NEWADDR)] = IFA_MAX,
107 RTA_MAX, 109 [RTM_FAM(RTM_NEWROUTE)] = RTA_MAX,
108 NDA_MAX, 110 [RTM_FAM(RTM_NEWNEIGH)] = NDA_MAX,
109 RTA_MAX, 111 [RTM_FAM(RTM_NEWRULE)] = RTA_MAX,
110 TCA_MAX, 112 [RTM_FAM(RTM_NEWQDISC)] = TCA_MAX,
111 TCA_MAX, 113 [RTM_FAM(RTM_NEWTCLASS)] = TCA_MAX,
112 TCA_MAX, 114 [RTM_FAM(RTM_NEWTFILTER)] = TCA_MAX,
113 TCAA_MAX 115 [RTM_FAM(RTM_NEWACTION)] = TCAA_MAX,
114}; 116};
115 117
116void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data) 118void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data)
@@ -607,27 +609,33 @@ static inline int rtnetlink_rcv_skb(struct sk_buff *skb)
607 609
608/* 610/*
609 * rtnetlink input queue processing routine: 611 * rtnetlink input queue processing routine:
610 * - try to acquire shared lock. If it is failed, defer processing. 612 * - process as much as there was in the queue upon entry.
611 * - feed skbs to rtnetlink_rcv_skb, until it refuse a message, 613 * - feed skbs to rtnetlink_rcv_skb, until it refuse a message,
612 * that will occur, when a dump started and/or acquisition of 614 * that will occur, when a dump started.
613 * exclusive lock failed.
614 */ 615 */
615 616
616static void rtnetlink_rcv(struct sock *sk, int len) 617static void rtnetlink_rcv(struct sock *sk, int len)
617{ 618{
619 unsigned int qlen = skb_queue_len(&sk->sk_receive_queue);
620
618 do { 621 do {
619 struct sk_buff *skb; 622 struct sk_buff *skb;
620 623
621 if (rtnl_shlock_nowait()) 624 rtnl_lock();
622 return; 625
626 if (qlen > skb_queue_len(&sk->sk_receive_queue))
627 qlen = skb_queue_len(&sk->sk_receive_queue);
623 628
624 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { 629 for (; qlen; qlen--) {
630 skb = skb_dequeue(&sk->sk_receive_queue);
625 if (rtnetlink_rcv_skb(skb)) { 631 if (rtnetlink_rcv_skb(skb)) {
626 if (skb->len) 632 if (skb->len)
627 skb_queue_head(&sk->sk_receive_queue, 633 skb_queue_head(&sk->sk_receive_queue,
628 skb); 634 skb);
629 else 635 else {
630 kfree_skb(skb); 636 kfree_skb(skb);
637 qlen--;
638 }
631 break; 639 break;
632 } 640 }
633 kfree_skb(skb); 641 kfree_skb(skb);
@@ -636,10 +644,10 @@ static void rtnetlink_rcv(struct sock *sk, int len)
636 up(&rtnl_sem); 644 up(&rtnl_sem);
637 645
638 netdev_run_todo(); 646 netdev_run_todo();
639 } while (rtnl && rtnl->sk_receive_queue.qlen); 647 } while (qlen);
640} 648}
641 649
642static struct rtnetlink_link link_rtnetlink_table[RTM_MAX-RTM_BASE+1] = 650static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] =
643{ 651{
644 [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo }, 652 [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo },
645 [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink }, 653 [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink },
diff --git a/net/core/scm.c b/net/core/scm.c
index a2ebf30f6aa8..e887d19be506 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -15,7 +15,6 @@
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/mm.h> 16#include <linux/mm.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/major.h>
19#include <linux/stat.h> 18#include <linux/stat.h>
20#include <linux/socket.h> 19#include <linux/socket.h>
21#include <linux/file.h> 20#include <linux/file.h>
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 1b64817d7de6..f65b3de590a9 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -86,8 +86,10 @@ static kmem_cache_t *skbuff_head_cache;
86 */ 86 */
87void skb_over_panic(struct sk_buff *skb, int sz, void *here) 87void skb_over_panic(struct sk_buff *skb, int sz, void *here)
88{ 88{
89 printk(KERN_INFO "skput:over: %p:%d put:%d dev:%s", 89 printk(KERN_EMERG "skb_over_panic: text:%p len:%d put:%d head:%p "
90 here, skb->len, sz, skb->dev ? skb->dev->name : "<NULL>"); 90 "data:%p tail:%p end:%p dev:%s\n",
91 here, skb->len, sz, skb->head, skb->data, skb->tail, skb->end,
92 skb->dev ? skb->dev->name : "<NULL>");
91 BUG(); 93 BUG();
92} 94}
93 95
@@ -102,8 +104,10 @@ void skb_over_panic(struct sk_buff *skb, int sz, void *here)
102 104
103void skb_under_panic(struct sk_buff *skb, int sz, void *here) 105void skb_under_panic(struct sk_buff *skb, int sz, void *here)
104{ 106{
105 printk(KERN_INFO "skput:under: %p:%d put:%d dev:%s", 107 printk(KERN_EMERG "skb_under_panic: text:%p len:%d put:%d head:%p "
106 here, skb->len, sz, skb->dev ? skb->dev->name : "<NULL>"); 108 "data:%p tail:%p end:%p dev:%s\n",
109 here, skb->len, sz, skb->head, skb->data, skb->tail, skb->end,
110 skb->dev ? skb->dev->name : "<NULL>");
107 BUG(); 111 BUG();
108} 112}
109 113
diff --git a/net/core/sock.c b/net/core/sock.c
index 4df4fa3c5de0..96e00b08698f 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -9,7 +9,7 @@
9 * 9 *
10 * Version: $Id: sock.c,v 1.117 2002/02/01 22:01:03 davem Exp $ 10 * Version: $Id: sock.c,v 1.117 2002/02/01 22:01:03 davem Exp $
11 * 11 *
12 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 12 * Authors: Ross Biro
13 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 13 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
14 * Florian La Roche, <flla@stud.uni-sb.de> 14 * Florian La Roche, <flla@stud.uni-sb.de>
15 * Alan Cox, <A.Cox@swansea.ac.uk> 15 * Alan Cox, <A.Cox@swansea.ac.uk>
@@ -97,7 +97,6 @@
97#include <linux/socket.h> 97#include <linux/socket.h>
98#include <linux/in.h> 98#include <linux/in.h>
99#include <linux/kernel.h> 99#include <linux/kernel.h>
100#include <linux/major.h>
101#include <linux/module.h> 100#include <linux/module.h>
102#include <linux/proc_fs.h> 101#include <linux/proc_fs.h>
103#include <linux/seq_file.h> 102#include <linux/seq_file.h>
@@ -617,10 +616,10 @@ lenout:
617 616
618/** 617/**
619 * sk_alloc - All socket objects are allocated here 618 * sk_alloc - All socket objects are allocated here
620 * @family - protocol family 619 * @family: protocol family
621 * @priority - for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc) 620 * @priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc)
622 * @prot - struct proto associated with this new sock instance 621 * @prot: struct proto associated with this new sock instance
623 * @zero_it - if we should zero the newly allocated sock 622 * @zero_it: if we should zero the newly allocated sock
624 */ 623 */
625struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it) 624struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it)
626{ 625{
@@ -636,7 +635,11 @@ struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it)
636 if (zero_it) { 635 if (zero_it) {
637 memset(sk, 0, prot->obj_size); 636 memset(sk, 0, prot->obj_size);
638 sk->sk_family = family; 637 sk->sk_family = family;
639 sk->sk_prot = prot; 638 /*
639 * See comment in struct sock definition to understand
640 * why we need sk_prot_creator -acme
641 */
642 sk->sk_prot = sk->sk_prot_creator = prot;
640 sock_lock_init(sk); 643 sock_lock_init(sk);
641 } 644 }
642 645
@@ -655,7 +658,7 @@ struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it)
655void sk_free(struct sock *sk) 658void sk_free(struct sock *sk)
656{ 659{
657 struct sk_filter *filter; 660 struct sk_filter *filter;
658 struct module *owner = sk->sk_prot->owner; 661 struct module *owner = sk->sk_prot_creator->owner;
659 662
660 if (sk->sk_destruct) 663 if (sk->sk_destruct)
661 sk->sk_destruct(sk); 664 sk->sk_destruct(sk);
@@ -673,8 +676,8 @@ void sk_free(struct sock *sk)
673 __FUNCTION__, atomic_read(&sk->sk_omem_alloc)); 676 __FUNCTION__, atomic_read(&sk->sk_omem_alloc));
674 677
675 security_sk_free(sk); 678 security_sk_free(sk);
676 if (sk->sk_prot->slab != NULL) 679 if (sk->sk_prot_creator->slab != NULL)
677 kmem_cache_free(sk->sk_prot->slab, sk); 680 kmem_cache_free(sk->sk_prot_creator->slab, sk);
678 else 681 else
679 kfree(sk); 682 kfree(sk);
680 module_put(owner); 683 module_put(owner);
@@ -971,8 +974,8 @@ static void __release_sock(struct sock *sk)
971 974
972/** 975/**
973 * sk_wait_data - wait for data to arrive at sk_receive_queue 976 * sk_wait_data - wait for data to arrive at sk_receive_queue
974 * sk - sock to wait on 977 * @sk: sock to wait on
975 * timeo - for how long 978 * @timeo: for how long
976 * 979 *
977 * Now socket state including sk->sk_err is changed only under lock, 980 * Now socket state including sk->sk_err is changed only under lock,
978 * hence we may omit checks after joining wait queue. 981 * hence we may omit checks after joining wait queue.
diff --git a/net/core/stream.c b/net/core/stream.c
index 1e27a57b5a97..ac9edfdf8742 100644
--- a/net/core/stream.c
+++ b/net/core/stream.c
@@ -21,7 +21,7 @@
21 21
22/** 22/**
23 * sk_stream_write_space - stream socket write_space callback. 23 * sk_stream_write_space - stream socket write_space callback.
24 * sk - socket 24 * @sk: socket
25 * 25 *
26 * FIXME: write proper description 26 * FIXME: write proper description
27 */ 27 */
@@ -43,8 +43,8 @@ EXPORT_SYMBOL(sk_stream_write_space);
43 43
44/** 44/**
45 * sk_stream_wait_connect - Wait for a socket to get into the connected state 45 * sk_stream_wait_connect - Wait for a socket to get into the connected state
46 * @sk - sock to wait on 46 * @sk: sock to wait on
47 * @timeo_p - for how long to wait 47 * @timeo_p: for how long to wait
48 * 48 *
49 * Must be called with the socket locked. 49 * Must be called with the socket locked.
50 */ 50 */
@@ -79,7 +79,7 @@ EXPORT_SYMBOL(sk_stream_wait_connect);
79 79
80/** 80/**
81 * sk_stream_closing - Return 1 if we still have things to send in our buffers. 81 * sk_stream_closing - Return 1 if we still have things to send in our buffers.
82 * @sk - socket to verify 82 * @sk: socket to verify
83 */ 83 */
84static inline int sk_stream_closing(struct sock *sk) 84static inline int sk_stream_closing(struct sock *sk)
85{ 85{
@@ -107,8 +107,8 @@ EXPORT_SYMBOL(sk_stream_wait_close);
107 107
108/** 108/**
109 * sk_stream_wait_memory - Wait for more memory for a socket 109 * sk_stream_wait_memory - Wait for more memory for a socket
110 * @sk - socket to wait for memory 110 * @sk: socket to wait for memory
111 * @timeo_p - for how long 111 * @timeo_p: for how long
112 */ 112 */
113int sk_stream_wait_memory(struct sock *sk, long *timeo_p) 113int sk_stream_wait_memory(struct sock *sk, long *timeo_p)
114{ 114{
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index c2a0346f423b..ee7bf46eb78a 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -1411,21 +1411,22 @@ static struct file_operations dn_dev_seq_fops = {
1411 1411
1412#endif /* CONFIG_PROC_FS */ 1412#endif /* CONFIG_PROC_FS */
1413 1413
1414static struct rtnetlink_link dnet_rtnetlink_table[RTM_MAX-RTM_BASE+1] = 1414static struct rtnetlink_link dnet_rtnetlink_table[RTM_NR_MSGTYPES] =
1415{ 1415{
1416 [4] = { .doit = dn_dev_rtm_newaddr, }, 1416 [RTM_NEWADDR - RTM_BASE] = { .doit = dn_dev_rtm_newaddr, },
1417 [5] = { .doit = dn_dev_rtm_deladdr, }, 1417 [RTM_DELADDR - RTM_BASE] = { .doit = dn_dev_rtm_deladdr, },
1418 [6] = { .dumpit = dn_dev_dump_ifaddr, }, 1418 [RTM_GETADDR - RTM_BASE] = { .dumpit = dn_dev_dump_ifaddr, },
1419
1420#ifdef CONFIG_DECNET_ROUTER 1419#ifdef CONFIG_DECNET_ROUTER
1421 [8] = { .doit = dn_fib_rtm_newroute, }, 1420 [RTM_NEWROUTE - RTM_BASE] = { .doit = dn_fib_rtm_newroute, },
1422 [9] = { .doit = dn_fib_rtm_delroute, }, 1421 [RTM_DELROUTE - RTM_BASE] = { .doit = dn_fib_rtm_delroute, },
1423 [10] = { .doit = dn_cache_getroute, .dumpit = dn_fib_dump, }, 1422 [RTM_GETROUTE - RTM_BASE] = { .doit = dn_cache_getroute,
1424 [16] = { .doit = dn_fib_rtm_newrule, }, 1423 .dumpit = dn_fib_dump, },
1425 [17] = { .doit = dn_fib_rtm_delrule, }, 1424 [RTM_NEWRULE - RTM_BASE] = { .doit = dn_fib_rtm_newrule, },
1426 [18] = { .dumpit = dn_fib_dump_rules, }, 1425 [RTM_DELRULE - RTM_BASE] = { .doit = dn_fib_rtm_delrule, },
1426 [RTM_GETRULE - RTM_BASE] = { .dumpit = dn_fib_dump_rules, },
1427#else 1427#else
1428 [10] = { .doit = dn_cache_getroute, .dumpit = dn_cache_dump, }, 1428 [RTM_GETROUTE - RTM_BASE] = { .doit = dn_cache_getroute,
1429 .dumpit = dn_cache_dump, },
1429#endif 1430#endif
1430 1431
1431}; 1432};
diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c
index f86a6259fd12..284a9998e53d 100644
--- a/net/decnet/netfilter/dn_rtmsg.c
+++ b/net/decnet/netfilter/dn_rtmsg.c
@@ -119,8 +119,9 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb)
119static void dnrmg_receive_user_sk(struct sock *sk, int len) 119static void dnrmg_receive_user_sk(struct sock *sk, int len)
120{ 120{
121 struct sk_buff *skb; 121 struct sk_buff *skb;
122 unsigned int qlen = skb_queue_len(&sk->sk_receive_queue);
122 123
123 while((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { 124 for (; qlen && (skb = skb_dequeue(&sk->sk_receive_queue)); qlen--) {
124 dnrmg_receive_user_skb(skb); 125 dnrmg_receive_user_skb(skb);
125 kfree_skb(skb); 126 kfree_skb(skb);
126 } 127 }
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 16c4234cbe12..6617ea47d365 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * Version: @(#)eth.c 1.0.7 05/25/93 8 * Version: @(#)eth.c 1.0.7 05/25/93
9 * 9 *
10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 10 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Mark Evans, <evansmp@uhura.aston.ac.uk> 12 * Mark Evans, <evansmp@uhura.aston.ac.uk>
13 * Florian La Roche, <rzsfl@rz.uni-sb.de> 13 * Florian La Roche, <rzsfl@rz.uni-sb.de>
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index c34dab67e461..b3cb49ce5fad 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * Version: $Id: af_inet.c,v 1.137 2002/02/01 22:01:03 davem Exp $ 8 * Version: $Id: af_inet.c,v 1.137 2002/02/01 22:01:03 davem Exp $
9 * 9 *
10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 10 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Florian La Roche, <flla@stud.uni-sb.de> 12 * Florian La Roche, <flla@stud.uni-sb.de>
13 * Alan Cox, <A.Cox@swansea.ac.uk> 13 * Alan Cox, <A.Cox@swansea.ac.uk>
@@ -73,7 +73,6 @@
73#include <linux/socket.h> 73#include <linux/socket.h>
74#include <linux/in.h> 74#include <linux/in.h>
75#include <linux/kernel.h> 75#include <linux/kernel.h>
76#include <linux/major.h>
77#include <linux/module.h> 76#include <linux/module.h>
78#include <linux/sched.h> 77#include <linux/sched.h>
79#include <linux/timer.h> 78#include <linux/timer.h>
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index eea7ef010776..3cc96730c4ed 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -9,7 +9,7 @@
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 * 10 *
11 * Derived from the IP parts of dev.c 1.0.19 11 * Derived from the IP parts of dev.c 1.0.19
12 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 12 * Authors: Ross Biro
13 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 13 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
14 * Mark Evans, <evansmp@uhura.aston.ac.uk> 14 * Mark Evans, <evansmp@uhura.aston.ac.uk>
15 * 15 *
@@ -1107,17 +1107,18 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa)
1107 } 1107 }
1108} 1108}
1109 1109
1110static struct rtnetlink_link inet_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = { 1110static struct rtnetlink_link inet_rtnetlink_table[RTM_NR_MSGTYPES] = {
1111 [4] = { .doit = inet_rtm_newaddr, }, 1111 [RTM_NEWADDR - RTM_BASE] = { .doit = inet_rtm_newaddr, },
1112 [5] = { .doit = inet_rtm_deladdr, }, 1112 [RTM_DELADDR - RTM_BASE] = { .doit = inet_rtm_deladdr, },
1113 [6] = { .dumpit = inet_dump_ifaddr, }, 1113 [RTM_GETADDR - RTM_BASE] = { .dumpit = inet_dump_ifaddr, },
1114 [8] = { .doit = inet_rtm_newroute, }, 1114 [RTM_NEWROUTE - RTM_BASE] = { .doit = inet_rtm_newroute, },
1115 [9] = { .doit = inet_rtm_delroute, }, 1115 [RTM_DELROUTE - RTM_BASE] = { .doit = inet_rtm_delroute, },
1116 [10] = { .doit = inet_rtm_getroute, .dumpit = inet_dump_fib, }, 1116 [RTM_GETROUTE - RTM_BASE] = { .doit = inet_rtm_getroute,
1117 .dumpit = inet_dump_fib, },
1117#ifdef CONFIG_IP_MULTIPLE_TABLES 1118#ifdef CONFIG_IP_MULTIPLE_TABLES
1118 [16] = { .doit = inet_rtm_newrule, }, 1119 [RTM_NEWRULE - RTM_BASE] = { .doit = inet_rtm_newrule, },
1119 [17] = { .doit = inet_rtm_delrule, }, 1120 [RTM_DELRULE - RTM_BASE] = { .doit = inet_rtm_delrule, },
1120 [18] = { .dumpit = inet_dump_rules, }, 1121 [RTM_GETRULE - RTM_BASE] = { .dumpit = inet_dump_rules, },
1121#endif 1122#endif
1122}; 1123};
1123 1124
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index a0d0833034be..4e47a2658c7c 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * Version: $Id: ip_input.c,v 1.55 2002/01/12 07:39:45 davem Exp $ 8 * Version: $Id: ip_input.c,v 1.55 2002/01/12 07:39:45 davem Exp $
9 * 9 *
10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 10 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Donald Becker, <becker@super.org> 12 * Donald Becker, <becker@super.org>
13 * Alan Cox, <Alan.Cox@linux.org> 13 * Alan Cox, <Alan.Cox@linux.org>
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 30ab7b6ab761..daebd93fd8a0 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * Version: $Id: ip_output.c,v 1.100 2002/02/01 22:01:03 davem Exp $ 8 * Version: $Id: ip_output.c,v 1.100 2002/02/01 22:01:03 davem Exp $
9 * 9 *
10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 10 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Donald Becker, <becker@super.org> 12 * Donald Becker, <becker@super.org>
13 * Alan Cox, <Alan.Cox@linux.org> 13 * Alan Cox, <Alan.Cox@linux.org>
@@ -111,6 +111,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb)
111#ifdef CONFIG_NETFILTER_DEBUG 111#ifdef CONFIG_NETFILTER_DEBUG
112 nf_debug_ip_loopback_xmit(newskb); 112 nf_debug_ip_loopback_xmit(newskb);
113#endif 113#endif
114 nf_reset(newskb);
114 netif_rx(newskb); 115 netif_rx(newskb);
115 return 0; 116 return 0;
116} 117}
@@ -195,6 +196,8 @@ static inline int ip_finish_output2(struct sk_buff *skb)
195 nf_debug_ip_finish_output2(skb); 196 nf_debug_ip_finish_output2(skb);
196#endif /*CONFIG_NETFILTER_DEBUG*/ 197#endif /*CONFIG_NETFILTER_DEBUG*/
197 198
199 nf_reset(skb);
200
198 if (hh) { 201 if (hh) {
199 int hh_alen; 202 int hh_alen;
200 203
diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c
index 10b23e1bece6..c3d2ca1a6781 100644
--- a/net/ipv4/multipath_wrandom.c
+++ b/net/ipv4/multipath_wrandom.c
@@ -172,7 +172,7 @@ static void wrandom_select_route(const struct flowi *flp,
172 multipath_comparekeys(&rt->fl, flp)) { 172 multipath_comparekeys(&rt->fl, flp)) {
173 struct multipath_candidate* mpc = 173 struct multipath_candidate* mpc =
174 (struct multipath_candidate*) 174 (struct multipath_candidate*)
175 kmalloc(size_mpc, GFP_KERNEL); 175 kmalloc(size_mpc, GFP_ATOMIC);
176 176
177 if (!mpc) 177 if (!mpc)
178 return; 178 return;
@@ -244,7 +244,7 @@ static void wrandom_set_nhinfo(__u32 network,
244 if (!target_route) { 244 if (!target_route) {
245 const size_t size_rt = sizeof(struct multipath_route); 245 const size_t size_rt = sizeof(struct multipath_route);
246 target_route = (struct multipath_route *) 246 target_route = (struct multipath_route *)
247 kmalloc(size_rt, GFP_KERNEL); 247 kmalloc(size_rt, GFP_ATOMIC);
248 248
249 target_route->gw = nh->nh_gw; 249 target_route->gw = nh->nh_gw;
250 target_route->oif = nh->nh_oif; 250 target_route->oif = nh->nh_oif;
@@ -265,7 +265,7 @@ static void wrandom_set_nhinfo(__u32 network,
265 if (!target_dest) { 265 if (!target_dest) {
266 const size_t size_dst = sizeof(struct multipath_dest); 266 const size_t size_dst = sizeof(struct multipath_dest);
267 target_dest = (struct multipath_dest*) 267 target_dest = (struct multipath_dest*)
268 kmalloc(size_dst, GFP_KERNEL); 268 kmalloc(size_dst, GFP_ATOMIC);
269 269
270 target_dest->nh_info = nh; 270 target_dest->nh_info = nh;
271 target_dest->network = network; 271 target_dest->network = network;
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c
index 12b88cbb11db..dd86503aa788 100644
--- a/net/ipv4/netfilter/ip_conntrack_ftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_ftp.c
@@ -252,7 +252,7 @@ static int find_pattern(const char *data, size_t dlen,
252} 252}
253 253
254/* Look up to see if we're just after a \n. */ 254/* Look up to see if we're just after a \n. */
255static int find_nl_seq(u16 seq, const struct ip_ct_ftp_master *info, int dir) 255static int find_nl_seq(u32 seq, const struct ip_ct_ftp_master *info, int dir)
256{ 256{
257 unsigned int i; 257 unsigned int i;
258 258
@@ -263,7 +263,7 @@ static int find_nl_seq(u16 seq, const struct ip_ct_ftp_master *info, int dir)
263} 263}
264 264
265/* We don't update if it's older than what we have. */ 265/* We don't update if it's older than what we have. */
266static void update_nl_seq(u16 nl_seq, struct ip_ct_ftp_master *info, int dir) 266static void update_nl_seq(u32 nl_seq, struct ip_ct_ftp_master *info, int dir)
267{ 267{
268 unsigned int i, oldest = NUM_SEQ_TO_REMEMBER; 268 unsigned int i, oldest = NUM_SEQ_TO_REMEMBER;
269 269
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index e800b16fc920..721ddbf522b4 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -770,6 +770,7 @@ static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
770{ 770{
771 [TH_SYN] = 1, 771 [TH_SYN] = 1,
772 [TH_SYN|TH_ACK] = 1, 772 [TH_SYN|TH_ACK] = 1,
773 [TH_SYN|TH_ACK|TH_PUSH] = 1,
773 [TH_RST] = 1, 774 [TH_RST] = 1,
774 [TH_RST|TH_ACK] = 1, 775 [TH_RST|TH_ACK] = 1,
775 [TH_RST|TH_ACK|TH_PUSH] = 1, 776 [TH_RST|TH_ACK|TH_PUSH] = 1,
@@ -818,6 +819,7 @@ static int tcp_error(struct sk_buff *skb,
818 */ 819 */
819 /* FIXME: Source route IP option packets --RR */ 820 /* FIXME: Source route IP option packets --RR */
820 if (hooknum == NF_IP_PRE_ROUTING 821 if (hooknum == NF_IP_PRE_ROUTING
822 && skb->ip_summed != CHECKSUM_UNNECESSARY
821 && csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP, 823 && csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP,
822 skb->ip_summed == CHECKSUM_HW ? skb->csum 824 skb->ip_summed == CHECKSUM_HW ? skb->csum
823 : skb_checksum(skb, iph->ihl*4, tcplen, 0))) { 825 : skb_checksum(skb, iph->ihl*4, tcplen, 0))) {
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index 80a7bde2a57a..46ca45f74d85 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -401,6 +401,16 @@ static unsigned int ip_confirm(unsigned int hooknum,
401 const struct net_device *out, 401 const struct net_device *out,
402 int (*okfn)(struct sk_buff *)) 402 int (*okfn)(struct sk_buff *))
403{ 403{
404 /* We've seen it coming out the other side: confirm it */
405 return ip_conntrack_confirm(pskb);
406}
407
408static unsigned int ip_conntrack_help(unsigned int hooknum,
409 struct sk_buff **pskb,
410 const struct net_device *in,
411 const struct net_device *out,
412 int (*okfn)(struct sk_buff *))
413{
404 struct ip_conntrack *ct; 414 struct ip_conntrack *ct;
405 enum ip_conntrack_info ctinfo; 415 enum ip_conntrack_info ctinfo;
406 416
@@ -412,9 +422,7 @@ static unsigned int ip_confirm(unsigned int hooknum,
412 if (ret != NF_ACCEPT) 422 if (ret != NF_ACCEPT)
413 return ret; 423 return ret;
414 } 424 }
415 425 return NF_ACCEPT;
416 /* We've seen it coming out the other side: confirm it */
417 return ip_conntrack_confirm(pskb);
418} 426}
419 427
420static unsigned int ip_conntrack_defrag(unsigned int hooknum, 428static unsigned int ip_conntrack_defrag(unsigned int hooknum,
@@ -423,13 +431,6 @@ static unsigned int ip_conntrack_defrag(unsigned int hooknum,
423 const struct net_device *out, 431 const struct net_device *out,
424 int (*okfn)(struct sk_buff *)) 432 int (*okfn)(struct sk_buff *))
425{ 433{
426#if !defined(CONFIG_IP_NF_NAT) && !defined(CONFIG_IP_NF_NAT_MODULE)
427 /* Previously seen (loopback)? Ignore. Do this before
428 fragment check. */
429 if ((*pskb)->nfct)
430 return NF_ACCEPT;
431#endif
432
433 /* Gather fragments. */ 434 /* Gather fragments. */
434 if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { 435 if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
435 *pskb = ip_ct_gather_frags(*pskb, 436 *pskb = ip_ct_gather_frags(*pskb,
@@ -516,13 +517,30 @@ static struct nf_hook_ops ip_conntrack_local_out_ops = {
516 .priority = NF_IP_PRI_CONNTRACK, 517 .priority = NF_IP_PRI_CONNTRACK,
517}; 518};
518 519
520/* helpers */
521static struct nf_hook_ops ip_conntrack_helper_out_ops = {
522 .hook = ip_conntrack_help,
523 .owner = THIS_MODULE,
524 .pf = PF_INET,
525 .hooknum = NF_IP_POST_ROUTING,
526 .priority = NF_IP_PRI_CONNTRACK_HELPER,
527};
528
529static struct nf_hook_ops ip_conntrack_helper_in_ops = {
530 .hook = ip_conntrack_help,
531 .owner = THIS_MODULE,
532 .pf = PF_INET,
533 .hooknum = NF_IP_LOCAL_IN,
534 .priority = NF_IP_PRI_CONNTRACK_HELPER,
535};
536
519/* Refragmenter; last chance. */ 537/* Refragmenter; last chance. */
520static struct nf_hook_ops ip_conntrack_out_ops = { 538static struct nf_hook_ops ip_conntrack_out_ops = {
521 .hook = ip_refrag, 539 .hook = ip_refrag,
522 .owner = THIS_MODULE, 540 .owner = THIS_MODULE,
523 .pf = PF_INET, 541 .pf = PF_INET,
524 .hooknum = NF_IP_POST_ROUTING, 542 .hooknum = NF_IP_POST_ROUTING,
525 .priority = NF_IP_PRI_LAST, 543 .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
526}; 544};
527 545
528static struct nf_hook_ops ip_conntrack_local_in_ops = { 546static struct nf_hook_ops ip_conntrack_local_in_ops = {
@@ -530,7 +548,7 @@ static struct nf_hook_ops ip_conntrack_local_in_ops = {
530 .owner = THIS_MODULE, 548 .owner = THIS_MODULE,
531 .pf = PF_INET, 549 .pf = PF_INET,
532 .hooknum = NF_IP_LOCAL_IN, 550 .hooknum = NF_IP_LOCAL_IN,
533 .priority = NF_IP_PRI_LAST-1, 551 .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
534}; 552};
535 553
536/* Sysctl support */ 554/* Sysctl support */
@@ -831,10 +849,20 @@ static int init_or_cleanup(int init)
831 printk("ip_conntrack: can't register local out hook.\n"); 849 printk("ip_conntrack: can't register local out hook.\n");
832 goto cleanup_inops; 850 goto cleanup_inops;
833 } 851 }
852 ret = nf_register_hook(&ip_conntrack_helper_in_ops);
853 if (ret < 0) {
854 printk("ip_conntrack: can't register local in helper hook.\n");
855 goto cleanup_inandlocalops;
856 }
857 ret = nf_register_hook(&ip_conntrack_helper_out_ops);
858 if (ret < 0) {
859 printk("ip_conntrack: can't register postrouting helper hook.\n");
860 goto cleanup_helperinops;
861 }
834 ret = nf_register_hook(&ip_conntrack_out_ops); 862 ret = nf_register_hook(&ip_conntrack_out_ops);
835 if (ret < 0) { 863 if (ret < 0) {
836 printk("ip_conntrack: can't register post-routing hook.\n"); 864 printk("ip_conntrack: can't register post-routing hook.\n");
837 goto cleanup_inandlocalops; 865 goto cleanup_helperoutops;
838 } 866 }
839 ret = nf_register_hook(&ip_conntrack_local_in_ops); 867 ret = nf_register_hook(&ip_conntrack_local_in_ops);
840 if (ret < 0) { 868 if (ret < 0) {
@@ -860,6 +888,10 @@ static int init_or_cleanup(int init)
860 nf_unregister_hook(&ip_conntrack_local_in_ops); 888 nf_unregister_hook(&ip_conntrack_local_in_ops);
861 cleanup_inoutandlocalops: 889 cleanup_inoutandlocalops:
862 nf_unregister_hook(&ip_conntrack_out_ops); 890 nf_unregister_hook(&ip_conntrack_out_ops);
891 cleanup_helperoutops:
892 nf_unregister_hook(&ip_conntrack_helper_out_ops);
893 cleanup_helperinops:
894 nf_unregister_hook(&ip_conntrack_helper_in_ops);
863 cleanup_inandlocalops: 895 cleanup_inandlocalops:
864 nf_unregister_hook(&ip_conntrack_local_out_ops); 896 nf_unregister_hook(&ip_conntrack_local_out_ops);
865 cleanup_inops: 897 cleanup_inops:
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index 162ceacfc29a..9fc6f93af0dd 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -356,15 +356,6 @@ unsigned int nat_packet(struct ip_conntrack *ct,
356 unsigned long statusbit; 356 unsigned long statusbit;
357 enum ip_nat_manip_type mtype = HOOK2MANIP(hooknum); 357 enum ip_nat_manip_type mtype = HOOK2MANIP(hooknum);
358 358
359 if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)
360 && (hooknum == NF_IP_POST_ROUTING || hooknum == NF_IP_LOCAL_IN)) {
361 DEBUGP("ip_nat_core: adjusting sequence number\n");
362 /* future: put this in a l4-proto specific function,
363 * and call this function here. */
364 if (!ip_nat_seq_adjust(pskb, ct, ctinfo))
365 return NF_DROP;
366 }
367
368 if (mtype == IP_NAT_MANIP_SRC) 359 if (mtype == IP_NAT_MANIP_SRC)
369 statusbit = IPS_SRC_NAT; 360 statusbit = IPS_SRC_NAT;
370 else 361 else
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index dec4a74212cd..79f56f662b33 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -230,6 +230,25 @@ ip_nat_local_fn(unsigned int hooknum,
230 return ret; 230 return ret;
231} 231}
232 232
233static unsigned int
234ip_nat_adjust(unsigned int hooknum,
235 struct sk_buff **pskb,
236 const struct net_device *in,
237 const struct net_device *out,
238 int (*okfn)(struct sk_buff *))
239{
240 struct ip_conntrack *ct;
241 enum ip_conntrack_info ctinfo;
242
243 ct = ip_conntrack_get(*pskb, &ctinfo);
244 if (ct && test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
245 DEBUGP("ip_nat_standalone: adjusting sequence number\n");
246 if (!ip_nat_seq_adjust(pskb, ct, ctinfo))
247 return NF_DROP;
248 }
249 return NF_ACCEPT;
250}
251
233/* We must be after connection tracking and before packet filtering. */ 252/* We must be after connection tracking and before packet filtering. */
234 253
235/* Before packet filtering, change destination */ 254/* Before packet filtering, change destination */
@@ -250,6 +269,15 @@ static struct nf_hook_ops ip_nat_out_ops = {
250 .priority = NF_IP_PRI_NAT_SRC, 269 .priority = NF_IP_PRI_NAT_SRC,
251}; 270};
252 271
272/* After conntrack, adjust sequence number */
273static struct nf_hook_ops ip_nat_adjust_out_ops = {
274 .hook = ip_nat_adjust,
275 .owner = THIS_MODULE,
276 .pf = PF_INET,
277 .hooknum = NF_IP_POST_ROUTING,
278 .priority = NF_IP_PRI_NAT_SEQ_ADJUST,
279};
280
253/* Before packet filtering, change destination */ 281/* Before packet filtering, change destination */
254static struct nf_hook_ops ip_nat_local_out_ops = { 282static struct nf_hook_ops ip_nat_local_out_ops = {
255 .hook = ip_nat_local_fn, 283 .hook = ip_nat_local_fn,
@@ -268,6 +296,16 @@ static struct nf_hook_ops ip_nat_local_in_ops = {
268 .priority = NF_IP_PRI_NAT_SRC, 296 .priority = NF_IP_PRI_NAT_SRC,
269}; 297};
270 298
299/* After conntrack, adjust sequence number */
300static struct nf_hook_ops ip_nat_adjust_in_ops = {
301 .hook = ip_nat_adjust,
302 .owner = THIS_MODULE,
303 .pf = PF_INET,
304 .hooknum = NF_IP_LOCAL_IN,
305 .priority = NF_IP_PRI_NAT_SEQ_ADJUST,
306};
307
308
271static int init_or_cleanup(int init) 309static int init_or_cleanup(int init)
272{ 310{
273 int ret = 0; 311 int ret = 0;
@@ -296,10 +334,20 @@ static int init_or_cleanup(int init)
296 printk("ip_nat_init: can't register out hook.\n"); 334 printk("ip_nat_init: can't register out hook.\n");
297 goto cleanup_inops; 335 goto cleanup_inops;
298 } 336 }
337 ret = nf_register_hook(&ip_nat_adjust_in_ops);
338 if (ret < 0) {
339 printk("ip_nat_init: can't register adjust in hook.\n");
340 goto cleanup_outops;
341 }
342 ret = nf_register_hook(&ip_nat_adjust_out_ops);
343 if (ret < 0) {
344 printk("ip_nat_init: can't register adjust out hook.\n");
345 goto cleanup_adjustin_ops;
346 }
299 ret = nf_register_hook(&ip_nat_local_out_ops); 347 ret = nf_register_hook(&ip_nat_local_out_ops);
300 if (ret < 0) { 348 if (ret < 0) {
301 printk("ip_nat_init: can't register local out hook.\n"); 349 printk("ip_nat_init: can't register local out hook.\n");
302 goto cleanup_outops; 350 goto cleanup_adjustout_ops;;
303 } 351 }
304 ret = nf_register_hook(&ip_nat_local_in_ops); 352 ret = nf_register_hook(&ip_nat_local_in_ops);
305 if (ret < 0) { 353 if (ret < 0) {
@@ -312,6 +360,10 @@ static int init_or_cleanup(int init)
312 nf_unregister_hook(&ip_nat_local_in_ops); 360 nf_unregister_hook(&ip_nat_local_in_ops);
313 cleanup_localoutops: 361 cleanup_localoutops:
314 nf_unregister_hook(&ip_nat_local_out_ops); 362 nf_unregister_hook(&ip_nat_local_out_ops);
363 cleanup_adjustout_ops:
364 nf_unregister_hook(&ip_nat_adjust_out_ops);
365 cleanup_adjustin_ops:
366 nf_unregister_hook(&ip_nat_adjust_in_ops);
315 cleanup_outops: 367 cleanup_outops:
316 nf_unregister_hook(&ip_nat_out_ops); 368 nf_unregister_hook(&ip_nat_out_ops);
317 cleanup_inops: 369 cleanup_inops:
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 9e40dffc204f..e5746b674413 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -546,20 +546,18 @@ ipq_rcv_skb(struct sk_buff *skb)
546static void 546static void
547ipq_rcv_sk(struct sock *sk, int len) 547ipq_rcv_sk(struct sock *sk, int len)
548{ 548{
549 do { 549 struct sk_buff *skb;
550 struct sk_buff *skb; 550 unsigned int qlen;
551 551
552 if (down_trylock(&ipqnl_sem)) 552 down(&ipqnl_sem);
553 return;
554 553
555 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { 554 for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) {
556 ipq_rcv_skb(skb); 555 skb = skb_dequeue(&sk->sk_receive_queue);
557 kfree_skb(skb); 556 ipq_rcv_skb(skb);
558 } 557 kfree_skb(skb);
558 }
559 559
560 up(&ipqnl_sem); 560 up(&ipqnl_sem);
561
562 } while (ipqnl && ipqnl->sk_receive_queue.qlen);
563} 561}
564 562
565static int 563static int
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
index 01b4a3c814d3..47449ba83eb9 100644
--- a/net/ipv4/netfilter/iptable_raw.c
+++ b/net/ipv4/netfilter/iptable_raw.c
@@ -103,13 +103,15 @@ static struct nf_hook_ops ipt_ops[] = {
103 .hook = ipt_hook, 103 .hook = ipt_hook,
104 .pf = PF_INET, 104 .pf = PF_INET,
105 .hooknum = NF_IP_PRE_ROUTING, 105 .hooknum = NF_IP_PRE_ROUTING,
106 .priority = NF_IP_PRI_RAW 106 .priority = NF_IP_PRI_RAW,
107 .owner = THIS_MODULE,
107 }, 108 },
108 { 109 {
109 .hook = ipt_hook, 110 .hook = ipt_hook,
110 .pf = PF_INET, 111 .pf = PF_INET,
111 .hooknum = NF_IP_LOCAL_OUT, 112 .hooknum = NF_IP_LOCAL_OUT,
112 .priority = NF_IP_PRI_RAW 113 .priority = NF_IP_PRI_RAW,
114 .owner = THIS_MODULE,
113 }, 115 },
114}; 116};
115 117
diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c
index 90a587cacaa4..0db405a869f2 100644
--- a/net/ipv4/protocol.c
+++ b/net/ipv4/protocol.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * Version: $Id: protocol.c,v 1.14 2001/05/18 02:25:49 davem Exp $ 8 * Version: $Id: protocol.c,v 1.14 2001/05/18 02:25:49 davem Exp $
9 * 9 *
10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 10 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * 12 *
13 * Fixes: 13 * Fixes:
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 93624a32eb9a..5b1ec586bae6 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * Version: $Id: raw.c,v 1.64 2002/02/01 22:01:04 davem Exp $ 8 * Version: $Id: raw.c,v 1.64 2002/02/01 22:01:04 davem Exp $
9 * 9 *
10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 10 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * 12 *
13 * Fixes: 13 * Fixes:
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index bb90a0c3a91e..a682d28e247b 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * Version: $Id: route.c,v 1.103 2002/01/12 07:44:09 davem Exp $ 8 * Version: $Id: route.c,v 1.103 2002/01/12 07:44:09 davem Exp $
9 * 9 *
10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 10 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Alan Cox, <gw4pts@gw4pts.ampr.org> 12 * Alan Cox, <gw4pts@gw4pts.ampr.org>
13 * Linus Torvalds, <Linus.Torvalds@helsinki.fi> 13 * Linus Torvalds, <Linus.Torvalds@helsinki.fi>
@@ -397,7 +397,7 @@ static int rt_cpu_seq_show(struct seq_file *seq, void *v)
397 struct rt_cache_stat *st = v; 397 struct rt_cache_stat *st = v;
398 398
399 if (v == SEQ_START_TOKEN) { 399 if (v == SEQ_START_TOKEN) {
400 seq_printf(seq, "entries in_hit in_slow_tot in_no_route in_brd in_martian_dst in_martian_src out_hit out_slow_tot out_slow_mc gc_total gc_ignored gc_goal_miss gc_dst_overflow in_hlist_search out_hlist_search\n"); 400 seq_printf(seq, "entries in_hit in_slow_tot in_slow_mc in_no_route in_brd in_martian_dst in_martian_src out_hit out_slow_tot out_slow_mc gc_total gc_ignored gc_goal_miss gc_dst_overflow in_hlist_search out_hlist_search\n");
401 return 0; 401 return 0;
402 } 402 }
403 403
@@ -2843,7 +2843,7 @@ ctl_table ipv4_route_table[] = {
2843 .procname = "flush", 2843 .procname = "flush",
2844 .data = &flush_delay, 2844 .data = &flush_delay,
2845 .maxlen = sizeof(int), 2845 .maxlen = sizeof(int),
2846 .mode = 0644, 2846 .mode = 0200,
2847 .proc_handler = &ipv4_sysctl_rtcache_flush, 2847 .proc_handler = &ipv4_sysctl_rtcache_flush,
2848 .strategy = &ipv4_sysctl_rtcache_flush_strategy, 2848 .strategy = &ipv4_sysctl_rtcache_flush_strategy,
2849 }, 2849 },
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 5cff56af7855..a037bafcba3c 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * Version: $Id: tcp.c,v 1.216 2002/02/01 22:01:04 davem Exp $ 8 * Version: $Id: tcp.c,v 1.216 2002/02/01 22:01:04 davem Exp $
9 * 9 *
10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 10 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Mark Evans, <evansmp@uhura.aston.ac.uk> 12 * Mark Evans, <evansmp@uhura.aston.ac.uk>
13 * Corey Minyard <wf-rch!minyard@relay.EU.net> 13 * Corey Minyard <wf-rch!minyard@relay.EU.net>
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c
index 313c1408da33..8faa8948f75c 100644
--- a/net/ipv4/tcp_diag.c
+++ b/net/ipv4/tcp_diag.c
@@ -777,8 +777,9 @@ static inline void tcpdiag_rcv_skb(struct sk_buff *skb)
777static void tcpdiag_rcv(struct sock *sk, int len) 777static void tcpdiag_rcv(struct sock *sk, int len)
778{ 778{
779 struct sk_buff *skb; 779 struct sk_buff *skb;
780 unsigned int qlen = skb_queue_len(&sk->sk_receive_queue);
780 781
781 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { 782 while (qlen-- && (skb = skb_dequeue(&sk->sk_receive_queue))) {
782 tcpdiag_rcv_skb(skb); 783 tcpdiag_rcv_skb(skb);
783 kfree_skb(skb); 784 kfree_skb(skb);
784 } 785 }
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 250492735902..79835a67a274 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * Version: $Id: tcp_input.c,v 1.243 2002/02/01 22:01:04 davem Exp $ 8 * Version: $Id: tcp_input.c,v 1.243 2002/02/01 22:01:04 davem Exp $
9 * 9 *
10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 10 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Mark Evans, <evansmp@uhura.aston.ac.uk> 12 * Mark Evans, <evansmp@uhura.aston.ac.uk>
13 * Corey Minyard <wf-rch!minyard@relay.EU.net> 13 * Corey Minyard <wf-rch!minyard@relay.EU.net>
@@ -3517,7 +3517,6 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
3517 if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) 3517 if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq)
3518 goto drop; 3518 goto drop;
3519 3519
3520 th = skb->h.th;
3521 __skb_pull(skb, th->doff*4); 3520 __skb_pull(skb, th->doff*4);
3522 3521
3523 TCP_ECN_accept_cwr(tp, skb); 3522 TCP_ECN_accept_cwr(tp, skb);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 3ac6659869c4..dad98e4a5043 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -222,10 +222,13 @@ static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
222 int rover; 222 int rover;
223 223
224 spin_lock(&tcp_portalloc_lock); 224 spin_lock(&tcp_portalloc_lock);
225 rover = tcp_port_rover; 225 if (tcp_port_rover < low)
226 rover = low;
227 else
228 rover = tcp_port_rover;
226 do { 229 do {
227 rover++; 230 rover++;
228 if (rover < low || rover > high) 231 if (rover > high)
229 rover = low; 232 rover = low;
230 head = &tcp_bhash[tcp_bhashfn(rover)]; 233 head = &tcp_bhash[tcp_bhashfn(rover)];
231 spin_lock(&head->lock); 234 spin_lock(&head->lock);
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index fd70509f0d53..eea1a17a9ac2 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * Version: $Id: tcp_minisocks.c,v 1.15 2002/02/01 22:01:04 davem Exp $ 8 * Version: $Id: tcp_minisocks.c,v 1.15 2002/02/01 22:01:04 davem Exp $
9 * 9 *
10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 10 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Mark Evans, <evansmp@uhura.aston.ac.uk> 12 * Mark Evans, <evansmp@uhura.aston.ac.uk>
13 * Corey Minyard <wf-rch!minyard@relay.EU.net> 13 * Corey Minyard <wf-rch!minyard@relay.EU.net>
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 13c14cb6dee4..fa24e7ae1f40 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * Version: $Id: tcp_output.c,v 1.146 2002/02/01 22:01:04 davem Exp $ 8 * Version: $Id: tcp_output.c,v 1.146 2002/02/01 22:01:04 davem Exp $
9 * 9 *
10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 10 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Mark Evans, <evansmp@uhura.aston.ac.uk> 12 * Mark Evans, <evansmp@uhura.aston.ac.uk>
13 * Corey Minyard <wf-rch!minyard@relay.EU.net> 13 * Corey Minyard <wf-rch!minyard@relay.EU.net>
@@ -427,7 +427,7 @@ void tcp_push_one(struct sock *sk, unsigned cur_mss)
427 struct tcp_sock *tp = tcp_sk(sk); 427 struct tcp_sock *tp = tcp_sk(sk);
428 struct sk_buff *skb = sk->sk_send_head; 428 struct sk_buff *skb = sk->sk_send_head;
429 429
430 if (tcp_snd_test(tp, skb, cur_mss, TCP_NAGLE_PUSH)) { 430 if (tcp_snd_test(sk, skb, cur_mss, TCP_NAGLE_PUSH)) {
431 /* Send it out now. */ 431 /* Send it out now. */
432 TCP_SKB_CB(skb)->when = tcp_time_stamp; 432 TCP_SKB_CB(skb)->when = tcp_time_stamp;
433 tcp_tso_set_push(skb); 433 tcp_tso_set_push(skb);
@@ -440,9 +440,12 @@ void tcp_push_one(struct sock *sk, unsigned cur_mss)
440 } 440 }
441} 441}
442 442
443void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_std) 443void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb)
444{ 444{
445 if (skb->len <= mss_std) { 445 struct tcp_sock *tp = tcp_sk(sk);
446
447 if (skb->len <= tp->mss_cache_std ||
448 !(sk->sk_route_caps & NETIF_F_TSO)) {
446 /* Avoid the costly divide in the normal 449 /* Avoid the costly divide in the normal
447 * non-TSO case. 450 * non-TSO case.
448 */ 451 */
@@ -451,10 +454,10 @@ void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_std)
451 } else { 454 } else {
452 unsigned int factor; 455 unsigned int factor;
453 456
454 factor = skb->len + (mss_std - 1); 457 factor = skb->len + (tp->mss_cache_std - 1);
455 factor /= mss_std; 458 factor /= tp->mss_cache_std;
456 skb_shinfo(skb)->tso_segs = factor; 459 skb_shinfo(skb)->tso_segs = factor;
457 skb_shinfo(skb)->tso_size = mss_std; 460 skb_shinfo(skb)->tso_size = tp->mss_cache_std;
458 } 461 }
459} 462}
460 463
@@ -525,8 +528,8 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len)
525 } 528 }
526 529
527 /* Fix up tso_factor for both original and new SKB. */ 530 /* Fix up tso_factor for both original and new SKB. */
528 tcp_set_skb_tso_segs(skb, tp->mss_cache_std); 531 tcp_set_skb_tso_segs(sk, skb);
529 tcp_set_skb_tso_segs(buff, tp->mss_cache_std); 532 tcp_set_skb_tso_segs(sk, buff);
530 533
531 if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) { 534 if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) {
532 tp->lost_out += tcp_skb_pcount(skb); 535 tp->lost_out += tcp_skb_pcount(skb);
@@ -601,7 +604,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
601 * factor and mss. 604 * factor and mss.
602 */ 605 */
603 if (tcp_skb_pcount(skb) > 1) 606 if (tcp_skb_pcount(skb) > 1)
604 tcp_set_skb_tso_segs(skb, tcp_skb_mss(skb)); 607 tcp_set_skb_tso_segs(sk, skb);
605 608
606 return 0; 609 return 0;
607} 610}
@@ -752,7 +755,7 @@ int tcp_write_xmit(struct sock *sk, int nonagle)
752 mss_now = tcp_current_mss(sk, 1); 755 mss_now = tcp_current_mss(sk, 1);
753 756
754 while ((skb = sk->sk_send_head) && 757 while ((skb = sk->sk_send_head) &&
755 tcp_snd_test(tp, skb, mss_now, 758 tcp_snd_test(sk, skb, mss_now,
756 tcp_skb_is_last(sk, skb) ? nonagle : 759 tcp_skb_is_last(sk, skb) ? nonagle :
757 TCP_NAGLE_PUSH)) { 760 TCP_NAGLE_PUSH)) {
758 if (skb->len > mss_now) { 761 if (skb->len > mss_now) {
@@ -1676,7 +1679,7 @@ int tcp_write_wakeup(struct sock *sk)
1676 tp->mss_cache = tp->mss_cache_std; 1679 tp->mss_cache = tp->mss_cache_std;
1677 } 1680 }
1678 } else if (!tcp_skb_pcount(skb)) 1681 } else if (!tcp_skb_pcount(skb))
1679 tcp_set_skb_tso_segs(skb, tp->mss_cache_std); 1682 tcp_set_skb_tso_segs(sk, skb);
1680 1683
1681 TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH; 1684 TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
1682 TCP_SKB_CB(skb)->when = tcp_time_stamp; 1685 TCP_SKB_CB(skb)->when = tcp_time_stamp;
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 85b279f1e935..799ebe061e2c 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * Version: $Id: tcp_timer.c,v 1.88 2002/02/01 22:01:04 davem Exp $ 8 * Version: $Id: tcp_timer.c,v 1.88 2002/02/01 22:01:04 davem Exp $
9 * 9 *
10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 10 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Mark Evans, <evansmp@uhura.aston.ac.uk> 12 * Mark Evans, <evansmp@uhura.aston.ac.uk>
13 * Corey Minyard <wf-rch!minyard@relay.EU.net> 13 * Corey Minyard <wf-rch!minyard@relay.EU.net>
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 8a213238f287..4a6952e3fee9 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * Version: $Id: udp.c,v 1.102 2002/02/01 22:01:04 davem Exp $ 8 * Version: $Id: udp.c,v 1.102 2002/02/01 22:01:04 davem Exp $
9 * 9 *
10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 10 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Arnt Gulbrandsen, <agulbra@nvg.unit.no> 12 * Arnt Gulbrandsen, <agulbra@nvg.unit.no>
13 * Alan Cox, <Alan.Cox@linux.org> 13 * Alan Cox, <Alan.Cox@linux.org>
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 7fe2afd2e669..b2b60f3e9cdd 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -8,7 +8,10 @@
8 * 8 *
9 */ 9 */
10 10
11#include <asm/bug.h>
12#include <linux/compiler.h>
11#include <linux/config.h> 13#include <linux/config.h>
14#include <linux/inetdevice.h>
12#include <net/xfrm.h> 15#include <net/xfrm.h>
13#include <net/ip.h> 16#include <net/ip.h>
14 17
@@ -152,6 +155,8 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
152 x->u.rt.rt_dst = rt0->rt_dst; 155 x->u.rt.rt_dst = rt0->rt_dst;
153 x->u.rt.rt_gateway = rt->rt_gateway; 156 x->u.rt.rt_gateway = rt->rt_gateway;
154 x->u.rt.rt_spec_dst = rt0->rt_spec_dst; 157 x->u.rt.rt_spec_dst = rt0->rt_spec_dst;
158 x->u.rt.idev = rt0->idev;
159 in_dev_hold(rt0->idev);
155 header_len -= x->u.dst.xfrm->props.header_len; 160 header_len -= x->u.dst.xfrm->props.header_len;
156 trailer_len -= x->u.dst.xfrm->props.trailer_len; 161 trailer_len -= x->u.dst.xfrm->props.trailer_len;
157 } 162 }
@@ -243,11 +248,48 @@ static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu)
243 path->ops->update_pmtu(path, mtu); 248 path->ops->update_pmtu(path, mtu);
244} 249}
245 250
251static void xfrm4_dst_destroy(struct dst_entry *dst)
252{
253 struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
254
255 if (likely(xdst->u.rt.idev))
256 in_dev_put(xdst->u.rt.idev);
257 xfrm_dst_destroy(xdst);
258}
259
260static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
261 int unregister)
262{
263 struct xfrm_dst *xdst;
264
265 if (!unregister)
266 return;
267
268 xdst = (struct xfrm_dst *)dst;
269 if (xdst->u.rt.idev->dev == dev) {
270 struct in_device *loopback_idev = in_dev_get(&loopback_dev);
271 BUG_ON(!loopback_idev);
272
273 do {
274 in_dev_put(xdst->u.rt.idev);
275 xdst->u.rt.idev = loopback_idev;
276 in_dev_hold(loopback_idev);
277 xdst = (struct xfrm_dst *)xdst->u.dst.child;
278 } while (xdst->u.dst.xfrm);
279
280 __in_dev_put(loopback_idev);
281 }
282
283 xfrm_dst_ifdown(dst, dev);
284}
285
246static struct dst_ops xfrm4_dst_ops = { 286static struct dst_ops xfrm4_dst_ops = {
247 .family = AF_INET, 287 .family = AF_INET,
248 .protocol = __constant_htons(ETH_P_IP), 288 .protocol = __constant_htons(ETH_P_IP),
249 .gc = xfrm4_garbage_collect, 289 .gc = xfrm4_garbage_collect,
250 .update_pmtu = xfrm4_update_pmtu, 290 .update_pmtu = xfrm4_update_pmtu,
291 .destroy = xfrm4_dst_destroy,
292 .ifdown = xfrm4_dst_ifdown,
251 .gc_thresh = 1024, 293 .gc_thresh = 1024,
252 .entry_size = sizeof(struct xfrm_dst), 294 .entry_size = sizeof(struct xfrm_dst),
253}; 295};
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 7196ac2f2d16..7744a2592693 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3076,7 +3076,7 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev,
3076 netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_PREFIX, GFP_ATOMIC); 3076 netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_PREFIX, GFP_ATOMIC);
3077} 3077}
3078 3078
3079static struct rtnetlink_link inet6_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = { 3079static struct rtnetlink_link inet6_rtnetlink_table[RTM_NR_MSGTYPES] = {
3080 [RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, }, 3080 [RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, },
3081 [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, }, 3081 [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, },
3082 [RTM_DELADDR - RTM_BASE] = { .doit = inet6_rtm_deladdr, }, 3082 [RTM_DELADDR - RTM_BASE] = { .doit = inet6_rtm_deladdr, },
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 768b11703daf..2b193e3df49a 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -28,7 +28,6 @@
28#include <linux/socket.h> 28#include <linux/socket.h>
29#include <linux/in.h> 29#include <linux/in.h>
30#include <linux/kernel.h> 30#include <linux/kernel.h>
31#include <linux/major.h>
32#include <linux/sched.h> 31#include <linux/sched.h>
33#include <linux/timer.h> 32#include <linux/timer.h>
34#include <linux/string.h> 33#include <linux/string.h>
@@ -88,6 +87,7 @@ int sysctl_ipv6_bindv6only;
88 87
89#ifdef INET_REFCNT_DEBUG 88#ifdef INET_REFCNT_DEBUG
90atomic_t inet6_sock_nr; 89atomic_t inet6_sock_nr;
90EXPORT_SYMBOL(inet6_sock_nr);
91#endif 91#endif
92 92
93/* The inetsw table contains everything that inet_create needs to 93/* The inetsw table contains everything that inet_create needs to
diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c
index 6dda815c013f..315bc1fbec3f 100644
--- a/net/ipv6/exthdrs_core.c
+++ b/net/ipv6/exthdrs_core.c
@@ -41,8 +41,8 @@ int ipv6_ext_hdr(u8 nexthdr)
41 * when Linux implements ESP (and maybe AUTH) headers. 41 * when Linux implements ESP (and maybe AUTH) headers.
42 * --AK 42 * --AK
43 * 43 *
44 * This function parses (probably truncated) exthdr set "hdr" 44 * This function parses (probably truncated) exthdr set "hdr".
45 * of length "len". "nexthdrp" initially points to some place, 45 * "nexthdrp" initially points to some place,
46 * where type of the first header can be found. 46 * where type of the first header can be found.
47 * 47 *
48 * It skips all well-known exthdrs, and returns pointer to the start 48 * It skips all well-known exthdrs, and returns pointer to the start
@@ -63,7 +63,7 @@ int ipv6_ext_hdr(u8 nexthdr)
63 * --ANK (980726) 63 * --ANK (980726)
64 */ 64 */
65 65
66int ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp, int len) 66int ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp)
67{ 67{
68 u8 nexthdr = *nexthdrp; 68 u8 nexthdr = *nexthdrp;
69 69
@@ -71,13 +71,11 @@ int ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp, int len
71 struct ipv6_opt_hdr _hdr, *hp; 71 struct ipv6_opt_hdr _hdr, *hp;
72 int hdrlen; 72 int hdrlen;
73 73
74 if (len < (int)sizeof(struct ipv6_opt_hdr))
75 return -1;
76 if (nexthdr == NEXTHDR_NONE) 74 if (nexthdr == NEXTHDR_NONE)
77 return -1; 75 return -1;
78 hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr); 76 hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
79 if (hp == NULL) 77 if (hp == NULL)
80 BUG(); 78 return -1;
81 if (nexthdr == NEXTHDR_FRAGMENT) { 79 if (nexthdr == NEXTHDR_FRAGMENT) {
82 unsigned short _frag_off, *fp; 80 unsigned short _frag_off, *fp;
83 fp = skb_header_pointer(skb, 81 fp = skb_header_pointer(skb,
@@ -97,7 +95,6 @@ int ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp, int len
97 hdrlen = ipv6_optlen(hp); 95 hdrlen = ipv6_optlen(hp);
98 96
99 nexthdr = hp->nexthdr; 97 nexthdr = hp->nexthdr;
100 len -= hdrlen;
101 start += hdrlen; 98 start += hdrlen;
102 } 99 }
103 100
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 87b9082ceab2..8e0f569b883e 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -135,7 +135,7 @@ static int is_ineligible(struct sk_buff *skb)
135 if (len < 0) 135 if (len < 0)
136 return 1; 136 return 1;
137 137
138 ptr = ipv6_skip_exthdr(skb, ptr, &nexthdr, len); 138 ptr = ipv6_skip_exthdr(skb, ptr, &nexthdr);
139 if (ptr < 0) 139 if (ptr < 0)
140 return 0; 140 return 0;
141 if (nexthdr == IPPROTO_ICMPV6) { 141 if (nexthdr == IPPROTO_ICMPV6) {
@@ -514,7 +514,7 @@ static void icmpv6_notify(struct sk_buff *skb, int type, int code, u32 info)
514 nexthdr = ((struct ipv6hdr *)skb->data)->nexthdr; 514 nexthdr = ((struct ipv6hdr *)skb->data)->nexthdr;
515 if (ipv6_ext_hdr(nexthdr)) { 515 if (ipv6_ext_hdr(nexthdr)) {
516 /* now skip over extension headers */ 516 /* now skip over extension headers */
517 inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr, skb->len - sizeof(struct ipv6hdr)); 517 inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr);
518 if (inner_offset<0) 518 if (inner_offset<0)
519 return; 519 return;
520 } else { 520 } else {
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index c54830b89593..750943e2d34e 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -549,20 +549,18 @@ ipq_rcv_skb(struct sk_buff *skb)
549static void 549static void
550ipq_rcv_sk(struct sock *sk, int len) 550ipq_rcv_sk(struct sock *sk, int len)
551{ 551{
552 do { 552 struct sk_buff *skb;
553 struct sk_buff *skb; 553 unsigned int qlen;
554 554
555 if (down_trylock(&ipqnl_sem)) 555 down(&ipqnl_sem);
556 return;
557 556
558 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { 557 for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) {
559 ipq_rcv_skb(skb); 558 skb = skb_dequeue(&sk->sk_receive_queue);
560 kfree_skb(skb); 559 ipq_rcv_skb(skb);
561 } 560 kfree_skb(skb);
561 }
562 562
563 up(&ipqnl_sem); 563 up(&ipqnl_sem);
564
565 } while (ipqnl && ipqnl->sk_receive_queue.qlen);
566} 564}
567 565
568static int 566static int
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 1352c1d9bf4d..617645bc5ed6 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -455,11 +455,11 @@ csum_copy_err:
455static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, 455static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
456 struct raw6_sock *rp) 456 struct raw6_sock *rp)
457{ 457{
458 struct inet_sock *inet = inet_sk(sk);
459 struct sk_buff *skb; 458 struct sk_buff *skb;
460 int err = 0; 459 int err = 0;
461 int offset; 460 int offset;
462 int len; 461 int len;
462 int total_len;
463 u32 tmp_csum; 463 u32 tmp_csum;
464 u16 csum; 464 u16 csum;
465 465
@@ -470,7 +470,8 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
470 goto out; 470 goto out;
471 471
472 offset = rp->offset; 472 offset = rp->offset;
473 if (offset >= inet->cork.length - 1) { 473 total_len = inet_sk(sk)->cork.length - (skb->nh.raw - skb->data);
474 if (offset >= total_len - 1) {
474 err = -EINVAL; 475 err = -EINVAL;
475 ip6_flush_pending_frames(sk); 476 ip6_flush_pending_frames(sk);
476 goto out; 477 goto out;
@@ -514,7 +515,7 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
514 515
515 tmp_csum = csum_ipv6_magic(&fl->fl6_src, 516 tmp_csum = csum_ipv6_magic(&fl->fl6_src,
516 &fl->fl6_dst, 517 &fl->fl6_dst,
517 inet->cork.length, fl->proto, tmp_csum); 518 total_len, fl->proto, tmp_csum);
518 519
519 if (tmp_csum == 0) 520 if (tmp_csum == 0)
520 tmp_csum = -1; 521 tmp_csum = -1;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 183802902c02..3bf8a0254f81 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2005,7 +2005,7 @@ ctl_table ipv6_route_table[] = {
2005 .procname = "flush", 2005 .procname = "flush",
2006 .data = &flush_delay, 2006 .data = &flush_delay,
2007 .maxlen = sizeof(int), 2007 .maxlen = sizeof(int),
2008 .mode = 0644, 2008 .mode = 0200,
2009 .proc_handler = &ipv6_sysctl_rtcache_flush 2009 .proc_handler = &ipv6_sysctl_rtcache_flush
2010 }, 2010 },
2011 { 2011 {
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 4760c85e19db..0f69e800a0ad 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -139,9 +139,12 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
139 int rover; 139 int rover;
140 140
141 spin_lock(&tcp_portalloc_lock); 141 spin_lock(&tcp_portalloc_lock);
142 rover = tcp_port_rover; 142 if (tcp_port_rover < low)
143 rover = low;
144 else
145 rover = tcp_port_rover;
143 do { rover++; 146 do { rover++;
144 if ((rover < low) || (rover > high)) 147 if (rover > high)
145 rover = low; 148 rover = low;
146 head = &tcp_bhash[tcp_bhashfn(rover)]; 149 head = &tcp_bhash[tcp_bhashfn(rover)];
147 spin_lock(&head->lock); 150 spin_lock(&head->lock);
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 8a4f37de4d2d..4429b1a1fe5f 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -11,7 +11,11 @@
11 * 11 *
12 */ 12 */
13 13
14#include <asm/bug.h>
15#include <linux/compiler.h>
14#include <linux/config.h> 16#include <linux/config.h>
17#include <linux/netdevice.h>
18#include <net/addrconf.h>
15#include <net/xfrm.h> 19#include <net/xfrm.h>
16#include <net/ip.h> 20#include <net/ip.h>
17#include <net/ipv6.h> 21#include <net/ipv6.h>
@@ -166,6 +170,8 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
166 memcpy(&x->u.rt6.rt6i_gateway, &rt0->rt6i_gateway, sizeof(x->u.rt6.rt6i_gateway)); 170 memcpy(&x->u.rt6.rt6i_gateway, &rt0->rt6i_gateway, sizeof(x->u.rt6.rt6i_gateway));
167 x->u.rt6.rt6i_dst = rt0->rt6i_dst; 171 x->u.rt6.rt6i_dst = rt0->rt6i_dst;
168 x->u.rt6.rt6i_src = rt0->rt6i_src; 172 x->u.rt6.rt6i_src = rt0->rt6i_src;
173 x->u.rt6.rt6i_idev = rt0->rt6i_idev;
174 in6_dev_hold(rt0->rt6i_idev);
169 header_len -= x->u.dst.xfrm->props.header_len; 175 header_len -= x->u.dst.xfrm->props.header_len;
170 trailer_len -= x->u.dst.xfrm->props.trailer_len; 176 trailer_len -= x->u.dst.xfrm->props.trailer_len;
171 } 177 }
@@ -251,11 +257,48 @@ static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu)
251 path->ops->update_pmtu(path, mtu); 257 path->ops->update_pmtu(path, mtu);
252} 258}
253 259
260static void xfrm6_dst_destroy(struct dst_entry *dst)
261{
262 struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
263
264 if (likely(xdst->u.rt6.rt6i_idev))
265 in6_dev_put(xdst->u.rt6.rt6i_idev);
266 xfrm_dst_destroy(xdst);
267}
268
269static void xfrm6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
270 int unregister)
271{
272 struct xfrm_dst *xdst;
273
274 if (!unregister)
275 return;
276
277 xdst = (struct xfrm_dst *)dst;
278 if (xdst->u.rt6.rt6i_idev->dev == dev) {
279 struct inet6_dev *loopback_idev = in6_dev_get(&loopback_dev);
280 BUG_ON(!loopback_idev);
281
282 do {
283 in6_dev_put(xdst->u.rt6.rt6i_idev);
284 xdst->u.rt6.rt6i_idev = loopback_idev;
285 in6_dev_hold(loopback_idev);
286 xdst = (struct xfrm_dst *)xdst->u.dst.child;
287 } while (xdst->u.dst.xfrm);
288
289 __in6_dev_put(loopback_idev);
290 }
291
292 xfrm_dst_ifdown(dst, dev);
293}
294
254static struct dst_ops xfrm6_dst_ops = { 295static struct dst_ops xfrm6_dst_ops = {
255 .family = AF_INET6, 296 .family = AF_INET6,
256 .protocol = __constant_htons(ETH_P_IPV6), 297 .protocol = __constant_htons(ETH_P_IPV6),
257 .gc = xfrm6_garbage_collect, 298 .gc = xfrm6_garbage_collect,
258 .update_pmtu = xfrm6_update_pmtu, 299 .update_pmtu = xfrm6_update_pmtu,
300 .destroy = xfrm6_dst_destroy,
301 .ifdown = xfrm6_dst_ifdown,
259 .gc_thresh = 1024, 302 .gc_thresh = 1024,
260 .entry_size = sizeof(struct xfrm_dst), 303 .entry_size = sizeof(struct xfrm_dst),
261}; 304};
diff --git a/net/irda/irda_device.c b/net/irda/irda_device.c
index d6ccd3239dcf..70543d89438b 100644
--- a/net/irda/irda_device.c
+++ b/net/irda/irda_device.c
@@ -470,6 +470,7 @@ void irda_device_unregister_dongle(struct dongle_reg *dongle)
470} 470}
471EXPORT_SYMBOL(irda_device_unregister_dongle); 471EXPORT_SYMBOL(irda_device_unregister_dongle);
472 472
473#ifdef CONFIG_ISA_DMA_API
473/* 474/*
474 * Function setup_dma (idev, buffer, count, mode) 475 * Function setup_dma (idev, buffer, count, mode)
475 * 476 *
@@ -492,3 +493,4 @@ void irda_setup_dma(int channel, dma_addr_t buffer, int count, int mode)
492 release_dma_lock(flags); 493 release_dma_lock(flags);
493} 494}
494EXPORT_SYMBOL(irda_setup_dma); 495EXPORT_SYMBOL(irda_setup_dma);
496#endif
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 1d5905c90cd4..733bf52cef3e 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -21,7 +21,6 @@
21 21
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/major.h>
25#include <linux/signal.h> 24#include <linux/signal.h>
26#include <linux/sched.h> 25#include <linux/sched.h>
27#include <linux/errno.h> 26#include <linux/errno.h>
@@ -50,6 +49,8 @@
50#include <linux/bitops.h> 49#include <linux/bitops.h>
51#include <linux/mm.h> 50#include <linux/mm.h>
52#include <linux/types.h> 51#include <linux/types.h>
52#include <linux/audit.h>
53
53#include <net/sock.h> 54#include <net/sock.h>
54#include <net/scm.h> 55#include <net/scm.h>
55 56
@@ -374,7 +375,6 @@ static int netlink_release(struct socket *sock)
374 nlk->cb->done(nlk->cb); 375 nlk->cb->done(nlk->cb);
375 netlink_destroy_callback(nlk->cb); 376 netlink_destroy_callback(nlk->cb);
376 nlk->cb = NULL; 377 nlk->cb = NULL;
377 __sock_put(sk);
378 } 378 }
379 spin_unlock(&nlk->cb_lock); 379 spin_unlock(&nlk->cb_lock);
380 380
@@ -906,6 +906,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
906 NETLINK_CB(skb).groups = nlk->groups; 906 NETLINK_CB(skb).groups = nlk->groups;
907 NETLINK_CB(skb).dst_pid = dst_pid; 907 NETLINK_CB(skb).dst_pid = dst_pid;
908 NETLINK_CB(skb).dst_groups = dst_groups; 908 NETLINK_CB(skb).dst_groups = dst_groups;
909 NETLINK_CB(skb).loginuid = audit_get_loginuid(current->audit_context);
909 memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); 910 memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
910 911
911 /* What can I do? Netlink is asynchronous, so that 912 /* What can I do? Netlink is asynchronous, so that
@@ -1100,7 +1101,6 @@ static int netlink_dump(struct sock *sk)
1100 spin_unlock(&nlk->cb_lock); 1101 spin_unlock(&nlk->cb_lock);
1101 1102
1102 netlink_destroy_callback(cb); 1103 netlink_destroy_callback(cb);
1103 __sock_put(sk);
1104 return 0; 1104 return 0;
1105} 1105}
1106 1106
@@ -1139,7 +1139,6 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
1139 return -EBUSY; 1139 return -EBUSY;
1140 } 1140 }
1141 nlk->cb = cb; 1141 nlk->cb = cb;
1142 sock_hold(sk);
1143 spin_unlock(&nlk->cb_lock); 1142 spin_unlock(&nlk->cb_lock);
1144 1143
1145 netlink_dump(sk); 1144 netlink_dump(sk);
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 64acea0adaae..0269616e75a1 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * Version: $Id: af_packet.c,v 1.61 2002/02/08 03:57:19 davem Exp $ 8 * Version: $Id: af_packet.c,v 1.61 2002/02/08 03:57:19 davem Exp $
9 * 9 *
10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 10 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Alan Cox, <gw4pts@gw4pts.ampr.org> 12 * Alan Cox, <gw4pts@gw4pts.ampr.org>
13 * 13 *
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 3d1d902dd1a1..b0941186f867 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -185,7 +185,7 @@ config NET_SCH_GRED
185 depends on NET_SCHED 185 depends on NET_SCHED
186 help 186 help
187 Say Y here if you want to use the Generic Random Early Detection 187 Say Y here if you want to use the Generic Random Early Detection
188 (RED) packet scheduling algorithm for some of your network devices 188 (GRED) packet scheduling algorithm for some of your network devices
189 (see the top of <file:net/sched/sch_red.c> for details and 189 (see the top of <file:net/sched/sch_red.c> for details and
190 references about the algorithm). 190 references about the algorithm).
191 191
@@ -506,3 +506,13 @@ config NET_CLS_POLICE
506 Say Y to support traffic policing (bandwidth limits). Needed for 506 Say Y to support traffic policing (bandwidth limits). Needed for
507 ingress and egress rate limiting. 507 ingress and egress rate limiting.
508 508
509config NET_ACT_SIMP
510 tristate "Simple action"
511 depends on NET_CLS_ACT
512 ---help---
513 You must have new iproute2 to use this feature.
514 This adds a very simple action for demonstration purposes
515 The idea is to give action authors a basic example to look at.
516 All this action will do is print on the console the configured
517 policy string followed by _ then packet count.
518
diff --git a/net/sched/Makefile b/net/sched/Makefile
index 431e55786efd..eb3fe583eba8 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -6,13 +6,14 @@ obj-y := sch_generic.o
6 6
7obj-$(CONFIG_NET_SCHED) += sch_api.o sch_fifo.o 7obj-$(CONFIG_NET_SCHED) += sch_api.o sch_fifo.o
8obj-$(CONFIG_NET_CLS) += cls_api.o 8obj-$(CONFIG_NET_CLS) += cls_api.o
9obj-$(CONFIG_NET_CLS_ACT) += act_api.o 9obj-$(CONFIG_NET_CLS_ACT) += act_api.o
10obj-$(CONFIG_NET_ACT_POLICE) += police.o 10obj-$(CONFIG_NET_ACT_POLICE) += police.o
11obj-$(CONFIG_NET_CLS_POLICE) += police.o 11obj-$(CONFIG_NET_CLS_POLICE) += police.o
12obj-$(CONFIG_NET_ACT_GACT) += gact.o 12obj-$(CONFIG_NET_ACT_GACT) += gact.o
13obj-$(CONFIG_NET_ACT_MIRRED) += mirred.o 13obj-$(CONFIG_NET_ACT_MIRRED) += mirred.o
14obj-$(CONFIG_NET_ACT_IPT) += ipt.o 14obj-$(CONFIG_NET_ACT_IPT) += ipt.o
15obj-$(CONFIG_NET_ACT_PEDIT) += pedit.o 15obj-$(CONFIG_NET_ACT_PEDIT) += pedit.o
16obj-$(CONFIG_NET_ACT_SIMP) += simple.o
16obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o 17obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o
17obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o 18obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o
18obj-$(CONFIG_NET_SCH_HPFQ) += sch_hpfq.o 19obj-$(CONFIG_NET_SCH_HPFQ) += sch_hpfq.o
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 5e6cc371b39e..cafcb084098d 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -171,10 +171,10 @@ repeat:
171 skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd); 171 skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
172 skb->tc_verd = CLR_TC_MUNGED(skb->tc_verd); 172 skb->tc_verd = CLR_TC_MUNGED(skb->tc_verd);
173 } 173 }
174 if (ret != TC_ACT_PIPE)
175 goto exec_done;
176 if (ret == TC_ACT_REPEAT) 174 if (ret == TC_ACT_REPEAT)
177 goto repeat; /* we need a ttl - JHS */ 175 goto repeat; /* we need a ttl - JHS */
176 if (ret != TC_ACT_PIPE)
177 goto exec_done;
178 } 178 }
179 act = a->next; 179 act = a->next;
180 } 180 }
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index fdfc83af3d1f..29d8b9a4d162 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -46,9 +46,11 @@
46#include <net/act_api.h> 46#include <net/act_api.h>
47#include <net/pkt_cls.h> 47#include <net/pkt_cls.h>
48 48
49#define HTSIZE (PAGE_SIZE/sizeof(struct fw_filter *))
50
49struct fw_head 51struct fw_head
50{ 52{
51 struct fw_filter *ht[256]; 53 struct fw_filter *ht[HTSIZE];
52}; 54};
53 55
54struct fw_filter 56struct fw_filter
@@ -69,7 +71,28 @@ static struct tcf_ext_map fw_ext_map = {
69 71
70static __inline__ int fw_hash(u32 handle) 72static __inline__ int fw_hash(u32 handle)
71{ 73{
72 return handle&0xFF; 74 if (HTSIZE == 4096)
75 return ((handle >> 24) & 0xFFF) ^
76 ((handle >> 12) & 0xFFF) ^
77 (handle & 0xFFF);
78 else if (HTSIZE == 2048)
79 return ((handle >> 22) & 0x7FF) ^
80 ((handle >> 11) & 0x7FF) ^
81 (handle & 0x7FF);
82 else if (HTSIZE == 1024)
83 return ((handle >> 20) & 0x3FF) ^
84 ((handle >> 10) & 0x3FF) ^
85 (handle & 0x3FF);
86 else if (HTSIZE == 512)
87 return (handle >> 27) ^
88 ((handle >> 18) & 0x1FF) ^
89 ((handle >> 9) & 0x1FF) ^
90 (handle & 0x1FF);
91 else if (HTSIZE == 256) {
92 u8 *t = (u8 *) &handle;
93 return t[0] ^ t[1] ^ t[2] ^ t[3];
94 } else
95 return handle & (HTSIZE - 1);
73} 96}
74 97
75static int fw_classify(struct sk_buff *skb, struct tcf_proto *tp, 98static int fw_classify(struct sk_buff *skb, struct tcf_proto *tp,
@@ -152,7 +175,7 @@ static void fw_destroy(struct tcf_proto *tp)
152 if (head == NULL) 175 if (head == NULL)
153 return; 176 return;
154 177
155 for (h=0; h<256; h++) { 178 for (h=0; h<HTSIZE; h++) {
156 while ((f=head->ht[h]) != NULL) { 179 while ((f=head->ht[h]) != NULL) {
157 head->ht[h] = f->next; 180 head->ht[h] = f->next;
158 fw_delete_filter(tp, f); 181 fw_delete_filter(tp, f);
@@ -291,7 +314,7 @@ static void fw_walk(struct tcf_proto *tp, struct tcf_walker *arg)
291 if (arg->stop) 314 if (arg->stop)
292 return; 315 return;
293 316
294 for (h = 0; h < 256; h++) { 317 for (h = 0; h < HTSIZE; h++) {
295 struct fw_filter *f; 318 struct fw_filter *f;
296 319
297 for (f = head->ht[h]; f; f = f->next) { 320 for (f = head->ht[h]; f; f = f->next) {
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 4323a74eea30..07977f8f2679 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1289,6 +1289,7 @@ static int __init pktsched_init(void)
1289 1289
1290subsys_initcall(pktsched_init); 1290subsys_initcall(pktsched_init);
1291 1291
1292EXPORT_SYMBOL(qdisc_lookup);
1292EXPORT_SYMBOL(qdisc_get_rtab); 1293EXPORT_SYMBOL(qdisc_get_rtab);
1293EXPORT_SYMBOL(qdisc_put_rtab); 1294EXPORT_SYMBOL(qdisc_put_rtab);
1294EXPORT_SYMBOL(register_qdisc); 1295EXPORT_SYMBOL(register_qdisc);
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 8c01e023f02e..87e48a4e1051 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -179,6 +179,7 @@ requeue:
179 netif_schedule(dev); 179 netif_schedule(dev);
180 return 1; 180 return 1;
181 } 181 }
182 BUG_ON((int) q->q.qlen < 0);
182 return q->q.qlen; 183 return q->q.qlen;
183} 184}
184 185
@@ -539,6 +540,10 @@ void dev_activate(struct net_device *dev)
539 write_unlock_bh(&qdisc_tree_lock); 540 write_unlock_bh(&qdisc_tree_lock);
540 } 541 }
541 542
543 if (!netif_carrier_ok(dev))
544 /* Delay activation until next carrier-on event */
545 return;
546
542 spin_lock_bh(&dev->queue_lock); 547 spin_lock_bh(&dev->queue_lock);
543 rcu_assign_pointer(dev->qdisc, dev->qdisc_sleeping); 548 rcu_assign_pointer(dev->qdisc, dev->qdisc_sleeping);
544 if (dev->qdisc != &noqueue_qdisc) { 549 if (dev->qdisc != &noqueue_qdisc) {
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index a85935e7d53d..558cc087e602 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -717,6 +717,10 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
717 if (q->direct_queue.qlen < q->direct_qlen) { 717 if (q->direct_queue.qlen < q->direct_qlen) {
718 __skb_queue_tail(&q->direct_queue, skb); 718 __skb_queue_tail(&q->direct_queue, skb);
719 q->direct_pkts++; 719 q->direct_pkts++;
720 } else {
721 kfree_skb(skb);
722 sch->qstats.drops++;
723 return NET_XMIT_DROP;
720 } 724 }
721#ifdef CONFIG_NET_CLS_ACT 725#ifdef CONFIG_NET_CLS_ACT
722 } else if (!cl) { 726 } else if (!cl) {
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 31c29deb139d..e0c9fbe73b15 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -138,38 +138,77 @@ static long tabledist(unsigned long mu, long sigma,
138} 138}
139 139
140/* Put skb in the private delayed queue. */ 140/* Put skb in the private delayed queue. */
141static int delay_skb(struct Qdisc *sch, struct sk_buff *skb) 141static int netem_delay(struct Qdisc *sch, struct sk_buff *skb)
142{ 142{
143 struct netem_sched_data *q = qdisc_priv(sch); 143 struct netem_sched_data *q = qdisc_priv(sch);
144 struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb;
145 psched_tdiff_t td; 144 psched_tdiff_t td;
146 psched_time_t now; 145 psched_time_t now;
147 146
148 PSCHED_GET_TIME(now); 147 PSCHED_GET_TIME(now);
149 td = tabledist(q->latency, q->jitter, &q->delay_cor, q->delay_dist); 148 td = tabledist(q->latency, q->jitter, &q->delay_cor, q->delay_dist);
150 PSCHED_TADD2(now, td, cb->time_to_send);
151 149
152 /* Always queue at tail to keep packets in order */ 150 /* Always queue at tail to keep packets in order */
153 if (likely(q->delayed.qlen < q->limit)) { 151 if (likely(q->delayed.qlen < q->limit)) {
152 struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb;
153
154 PSCHED_TADD2(now, td, cb->time_to_send);
155
156 pr_debug("netem_delay: skb=%p now=%llu tosend=%llu\n", skb,
157 now, cb->time_to_send);
158
154 __skb_queue_tail(&q->delayed, skb); 159 __skb_queue_tail(&q->delayed, skb);
155 if (!timer_pending(&q->timer)) {
156 q->timer.expires = jiffies + PSCHED_US2JIFFIE(td);
157 add_timer(&q->timer);
158 }
159 return NET_XMIT_SUCCESS; 160 return NET_XMIT_SUCCESS;
160 } 161 }
161 162
163 pr_debug("netem_delay: queue over limit %d\n", q->limit);
164 sch->qstats.overlimits++;
162 kfree_skb(skb); 165 kfree_skb(skb);
163 return NET_XMIT_DROP; 166 return NET_XMIT_DROP;
164} 167}
165 168
169/*
170 * Move a packet that is ready to send from the delay holding
171 * list to the underlying qdisc.
172 */
173static int netem_run(struct Qdisc *sch)
174{
175 struct netem_sched_data *q = qdisc_priv(sch);
176 struct sk_buff *skb;
177 psched_time_t now;
178
179 PSCHED_GET_TIME(now);
180
181 skb = skb_peek(&q->delayed);
182 if (skb) {
183 const struct netem_skb_cb *cb
184 = (const struct netem_skb_cb *)skb->cb;
185 long delay
186 = PSCHED_US2JIFFIE(PSCHED_TDIFF(cb->time_to_send, now));
187 pr_debug("netem_run: skb=%p delay=%ld\n", skb, delay);
188
189 /* if more time remaining? */
190 if (delay > 0) {
191 mod_timer(&q->timer, jiffies + delay);
192 return 1;
193 }
194
195 __skb_unlink(skb, &q->delayed);
196
197 if (q->qdisc->enqueue(skb, q->qdisc)) {
198 sch->q.qlen--;
199 sch->qstats.drops++;
200 }
201 }
202
203 return 0;
204}
205
166static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) 206static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
167{ 207{
168 struct netem_sched_data *q = qdisc_priv(sch); 208 struct netem_sched_data *q = qdisc_priv(sch);
169 struct sk_buff *skb2;
170 int ret; 209 int ret;
171 210
172 pr_debug("netem_enqueue skb=%p @%lu\n", skb, jiffies); 211 pr_debug("netem_enqueue skb=%p\n", skb);
173 212
174 /* Random packet drop 0 => none, ~0 => all */ 213 /* Random packet drop 0 => none, ~0 => all */
175 if (q->loss && q->loss >= get_crandom(&q->loss_cor)) { 214 if (q->loss && q->loss >= get_crandom(&q->loss_cor)) {
@@ -180,11 +219,21 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
180 } 219 }
181 220
182 /* Random duplication */ 221 /* Random duplication */
183 if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor) 222 if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor)) {
184 && (skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) { 223 struct sk_buff *skb2;
185 pr_debug("netem_enqueue: dup %p\n", skb2); 224
225 skb2 = skb_clone(skb, GFP_ATOMIC);
226 if (skb2 && netem_delay(sch, skb2) == NET_XMIT_SUCCESS) {
227 struct Qdisc *qp;
228
229 /* Since one packet can generate two packets in the
230 * queue, the parent's qlen accounting gets confused,
231 * so fix it.
232 */
233 qp = qdisc_lookup(sch->dev, TC_H_MAJ(sch->parent));
234 if (qp)
235 qp->q.qlen++;
186 236
187 if (delay_skb(sch, skb2)) {
188 sch->q.qlen++; 237 sch->q.qlen++;
189 sch->bstats.bytes += skb2->len; 238 sch->bstats.bytes += skb2->len;
190 sch->bstats.packets++; 239 sch->bstats.packets++;
@@ -202,7 +251,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
202 ret = q->qdisc->enqueue(skb, q->qdisc); 251 ret = q->qdisc->enqueue(skb, q->qdisc);
203 } else { 252 } else {
204 q->counter = 0; 253 q->counter = 0;
205 ret = delay_skb(sch, skb); 254 ret = netem_delay(sch, skb);
255 netem_run(sch);
206 } 256 }
207 257
208 if (likely(ret == NET_XMIT_SUCCESS)) { 258 if (likely(ret == NET_XMIT_SUCCESS)) {
@@ -212,6 +262,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
212 } else 262 } else
213 sch->qstats.drops++; 263 sch->qstats.drops++;
214 264
265 pr_debug("netem: enqueue ret %d\n", ret);
215 return ret; 266 return ret;
216} 267}
217 268
@@ -241,56 +292,35 @@ static unsigned int netem_drop(struct Qdisc* sch)
241 return len; 292 return len;
242} 293}
243 294
244/* Dequeue packet.
245 * Move all packets that are ready to send from the delay holding
246 * list to the underlying qdisc, then just call dequeue
247 */
248static struct sk_buff *netem_dequeue(struct Qdisc *sch) 295static struct sk_buff *netem_dequeue(struct Qdisc *sch)
249{ 296{
250 struct netem_sched_data *q = qdisc_priv(sch); 297 struct netem_sched_data *q = qdisc_priv(sch);
251 struct sk_buff *skb; 298 struct sk_buff *skb;
299 int pending;
300
301 pending = netem_run(sch);
252 302
253 skb = q->qdisc->dequeue(q->qdisc); 303 skb = q->qdisc->dequeue(q->qdisc);
254 if (skb) 304 if (skb) {
305 pr_debug("netem_dequeue: return skb=%p\n", skb);
255 sch->q.qlen--; 306 sch->q.qlen--;
307 sch->flags &= ~TCQ_F_THROTTLED;
308 }
309 else if (pending) {
310 pr_debug("netem_dequeue: throttling\n");
311 sch->flags |= TCQ_F_THROTTLED;
312 }
313
256 return skb; 314 return skb;
257} 315}
258 316
259static void netem_watchdog(unsigned long arg) 317static void netem_watchdog(unsigned long arg)
260{ 318{
261 struct Qdisc *sch = (struct Qdisc *)arg; 319 struct Qdisc *sch = (struct Qdisc *)arg;
262 struct netem_sched_data *q = qdisc_priv(sch);
263 struct net_device *dev = sch->dev;
264 struct sk_buff *skb;
265 psched_time_t now;
266
267 pr_debug("netem_watchdog: fired @%lu\n", jiffies);
268
269 spin_lock_bh(&dev->queue_lock);
270 PSCHED_GET_TIME(now);
271
272 while ((skb = skb_peek(&q->delayed)) != NULL) {
273 const struct netem_skb_cb *cb
274 = (const struct netem_skb_cb *)skb->cb;
275 long delay
276 = PSCHED_US2JIFFIE(PSCHED_TDIFF(cb->time_to_send, now));
277 pr_debug("netem_watchdog: skb %p@%lu %ld\n",
278 skb, jiffies, delay);
279 320
280 /* if more time remaining? */ 321 pr_debug("netem_watchdog qlen=%d\n", sch->q.qlen);
281 if (delay > 0) { 322 sch->flags &= ~TCQ_F_THROTTLED;
282 mod_timer(&q->timer, jiffies + delay); 323 netif_schedule(sch->dev);
283 break;
284 }
285 __skb_unlink(skb, &q->delayed);
286
287 if (q->qdisc->enqueue(skb, q->qdisc)) {
288 sch->q.qlen--;
289 sch->qstats.drops++;
290 }
291 }
292 qdisc_run(dev);
293 spin_unlock_bh(&dev->queue_lock);
294} 324}
295 325
296static void netem_reset(struct Qdisc *sch) 326static void netem_reset(struct Qdisc *sch)
@@ -301,6 +331,7 @@ static void netem_reset(struct Qdisc *sch)
301 skb_queue_purge(&q->delayed); 331 skb_queue_purge(&q->delayed);
302 332
303 sch->q.qlen = 0; 333 sch->q.qlen = 0;
334 sch->flags &= ~TCQ_F_THROTTLED;
304 del_timer_sync(&q->timer); 335 del_timer_sync(&q->timer);
305} 336}
306 337
diff --git a/net/sched/simple.c b/net/sched/simple.c
new file mode 100644
index 000000000000..3ab4c675ab5d
--- /dev/null
+++ b/net/sched/simple.c
@@ -0,0 +1,93 @@
1/*
2 * net/sched/simp.c Simple example of an action
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Authors: Jamal Hadi Salim (2005)
10 *
11 */
12
13#include <linux/config.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/kernel.h>
17#include <linux/netdevice.h>
18#include <linux/skbuff.h>
19#include <linux/rtnetlink.h>
20#include <net/pkt_sched.h>
21
22#define TCA_ACT_SIMP 22
23
24/* XXX: Hide all these common elements under some macro
25 * probably
26*/
27#include <linux/tc_act/tc_defact.h>
28#include <net/tc_act/tc_defact.h>
29
30/* use generic hash table with 8 buckets */
31#define MY_TAB_SIZE 8
32#define MY_TAB_MASK (MY_TAB_SIZE - 1)
33static u32 idx_gen;
34static struct tcf_defact *tcf_simp_ht[MY_TAB_SIZE];
35static DEFINE_RWLOCK(simp_lock);
36
37/* override the defaults */
38#define tcf_st tcf_defact
39#define tc_st tc_defact
40#define tcf_t_lock simp_lock
41#define tcf_ht tcf_simp_ht
42
43#define CONFIG_NET_ACT_INIT 1
44#include <net/pkt_act.h>
45#include <net/act_generic.h>
46
47static int tcf_simp(struct sk_buff **pskb, struct tc_action *a)
48{
49 struct sk_buff *skb = *pskb;
50 struct tcf_defact *p = PRIV(a, defact);
51
52 spin_lock(&p->lock);
53 p->tm.lastuse = jiffies;
54 p->bstats.bytes += skb->len;
55 p->bstats.packets++;
56
57 /* print policy string followed by _ then packet count
58 * Example if this was the 3rd packet and the string was "hello"
59 * then it would look like "hello_3" (without quotes)
60 **/
61 printk("simple: %s_%d\n", (char *)p->defdata, p->bstats.packets);
62 spin_unlock(&p->lock);
63 return p->action;
64}
65
66static struct tc_action_ops act_simp_ops = {
67 .kind = "simple",
68 .type = TCA_ACT_SIMP,
69 .capab = TCA_CAP_NONE,
70 .owner = THIS_MODULE,
71 .act = tcf_simp,
72 tca_use_default_ops
73};
74
75MODULE_AUTHOR("Jamal Hadi Salim(2005)");
76MODULE_DESCRIPTION("Simple example action");
77MODULE_LICENSE("GPL");
78
79static int __init simp_init_module(void)
80{
81 int ret = tcf_register_action(&act_simp_ops);
82 if (!ret)
83 printk("Simple TC action Loaded\n");
84 return ret;
85}
86
87static void __exit simp_cleanup_module(void)
88{
89 tcf_unregister_action(&act_simp_ops);
90}
91
92module_init(simp_init_module);
93module_exit(simp_cleanup_module);
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 544b75077dbd..334f61773e6d 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -125,6 +125,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
125 sp->autoclose * HZ; 125 sp->autoclose * HZ;
126 126
127 /* Use SCTP specific send buffer space queues. */ 127 /* Use SCTP specific send buffer space queues. */
128 ep->sndbuf_policy = sctp_sndbuf_policy;
128 sk->sk_write_space = sctp_write_space; 129 sk->sk_write_space = sctp_write_space;
129 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); 130 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
130 131
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index e42c74e3ec1e..c9d9ea064734 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -496,9 +496,7 @@ static void sctp_v6_inaddr_any(union sctp_addr *addr, unsigned short port)
496/* Is this a wildcard address? */ 496/* Is this a wildcard address? */
497static int sctp_v6_is_any(const union sctp_addr *addr) 497static int sctp_v6_is_any(const union sctp_addr *addr)
498{ 498{
499 int type; 499 return ipv6_addr_any(&addr->v6.sin6_addr);
500 type = ipv6_addr_type((struct in6_addr *)&addr->v6.sin6_addr);
501 return IPV6_ADDR_ANY == type;
502} 500}
503 501
504/* Should this be available for binding? */ 502/* Should this be available for binding? */
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 9013f64f5219..84b5b370b09d 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -313,12 +313,12 @@ int sctp_packet_transmit(struct sctp_packet *packet)
313 sk = chunk->skb->sk; 313 sk = chunk->skb->sk;
314 314
315 /* Allocate the new skb. */ 315 /* Allocate the new skb. */
316 nskb = dev_alloc_skb(packet->size); 316 nskb = alloc_skb(packet->size + LL_MAX_HEADER, GFP_ATOMIC);
317 if (!nskb) 317 if (!nskb)
318 goto nomem; 318 goto nomem;
319 319
320 /* Make sure the outbound skb has enough header room reserved. */ 320 /* Make sure the outbound skb has enough header room reserved. */
321 skb_reserve(nskb, packet->overhead); 321 skb_reserve(nskb, packet->overhead + LL_MAX_HEADER);
322 322
323 /* Set the owning socket so that we know where to get the 323 /* Set the owning socket so that we know where to get the
324 * destination IP address. 324 * destination IP address.
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index b9813cf3d91c..2e1f9c3556f5 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1043,6 +1043,9 @@ SCTP_STATIC __init int sctp_init(void)
1043 sctp_max_retrans_path = 5; 1043 sctp_max_retrans_path = 5;
1044 sctp_max_retrans_init = 8; 1044 sctp_max_retrans_init = 8;
1045 1045
1046 /* Sendbuffer growth - do per-socket accounting */
1047 sctp_sndbuf_policy = 0;
1048
1046 /* HB.interval - 30 seconds */ 1049 /* HB.interval - 30 seconds */
1047 sctp_hb_interval = 30 * HZ; 1050 sctp_hb_interval = 30 * HZ;
1048 1051
@@ -1159,8 +1162,6 @@ SCTP_STATIC __init int sctp_init(void)
1159 status = 0; 1162 status = 0;
1160out: 1163out:
1161 return status; 1164 return status;
1162err_add_protocol:
1163 proto_unregister(&sctp_prot);
1164err_ctl_sock_init: 1165err_ctl_sock_init:
1165 sctp_v6_exit(); 1166 sctp_v6_exit();
1166err_v6_init: 1167err_v6_init:
@@ -1188,6 +1189,8 @@ err_bucket_cachep:
1188 inet_del_protocol(&sctp_protocol, IPPROTO_SCTP); 1189 inet_del_protocol(&sctp_protocol, IPPROTO_SCTP);
1189 inet_unregister_protosw(&sctp_seqpacket_protosw); 1190 inet_unregister_protosw(&sctp_seqpacket_protosw);
1190 inet_unregister_protosw(&sctp_stream_protosw); 1191 inet_unregister_protosw(&sctp_stream_protosw);
1192err_add_protocol:
1193 proto_unregister(&sctp_prot);
1191 goto out; 1194 goto out;
1192} 1195}
1193 1196
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 1db12cc18cf7..33ac8bf47b0e 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -710,7 +710,9 @@ struct sctp_chunk *sctp_make_shutdown_complete(
710 struct sctp_chunk *retval; 710 struct sctp_chunk *retval;
711 __u8 flags = 0; 711 __u8 flags = 0;
712 712
713 /* Maybe set the T-bit if we have no association. */ 713 /* Set the T-bit if we have no association (vtag will be
714 * reflected)
715 */
714 flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T; 716 flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T;
715 717
716 retval = sctp_make_chunk(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags, 0); 718 retval = sctp_make_chunk(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags, 0);
@@ -732,7 +734,7 @@ struct sctp_chunk *sctp_make_shutdown_complete(
732} 734}
733 735
734/* Create an ABORT. Note that we set the T bit if we have no 736/* Create an ABORT. Note that we set the T bit if we have no
735 * association. 737 * association, except when responding to an INIT (sctpimpguide 2.41).
736 */ 738 */
737struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc, 739struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc,
738 const struct sctp_chunk *chunk, 740 const struct sctp_chunk *chunk,
@@ -741,8 +743,16 @@ struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc,
741 struct sctp_chunk *retval; 743 struct sctp_chunk *retval;
742 __u8 flags = 0; 744 __u8 flags = 0;
743 745
744 /* Maybe set the T-bit if we have no association. */ 746 /* Set the T-bit if we have no association and 'chunk' is not
745 flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T; 747 * an INIT (vtag will be reflected).
748 */
749 if (!asoc) {
750 if (chunk && chunk->chunk_hdr &&
751 chunk->chunk_hdr->type == SCTP_CID_INIT)
752 flags = 0;
753 else
754 flags = SCTP_CHUNK_FLAG_T;
755 }
746 756
747 retval = sctp_make_chunk(asoc, SCTP_CID_ABORT, flags, hint); 757 retval = sctp_make_chunk(asoc, SCTP_CID_ABORT, flags, hint);
748 758
@@ -2744,7 +2754,6 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
2744 2754
2745 hint = (nstreams + 1) * sizeof(__u32); 2755 hint = (nstreams + 1) * sizeof(__u32);
2746 2756
2747 /* Maybe set the T-bit if we have no association. */
2748 retval = sctp_make_chunk(asoc, SCTP_CID_FWD_TSN, 0, hint); 2757 retval = sctp_make_chunk(asoc, SCTP_CID_FWD_TSN, 0, hint);
2749 2758
2750 if (!retval) 2759 if (!retval)
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 278c56a2d076..8e01b8f09ac2 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -126,15 +126,18 @@ sctp_chunk_length_valid(struct sctp_chunk *chunk,
126 * should stop the T2-shutdown timer and remove all knowledge of the 126 * should stop the T2-shutdown timer and remove all knowledge of the
127 * association (and thus the association enters the CLOSED state). 127 * association (and thus the association enters the CLOSED state).
128 * 128 *
129 * Verification Tag: 8.5.1(C) 129 * Verification Tag: 8.5.1(C), sctpimpguide 2.41.
130 * C) Rules for packet carrying SHUTDOWN COMPLETE: 130 * C) Rules for packet carrying SHUTDOWN COMPLETE:
131 * ... 131 * ...
132 * - The receiver of a SHUTDOWN COMPLETE shall accept the packet if the 132 * - The receiver of a SHUTDOWN COMPLETE shall accept the packet
133 * Verification Tag field of the packet matches its own tag OR it is 133 * if the Verification Tag field of the packet matches its own tag and
134 * set to its peer's tag and the T bit is set in the Chunk Flags. 134 * the T bit is not set
135 * Otherwise, the receiver MUST silently discard the packet and take 135 * OR
136 * no further action. An endpoint MUST ignore the SHUTDOWN COMPLETE if 136 * it is set to its peer's tag and the T bit is set in the Chunk
137 * it is not in the SHUTDOWN-ACK-SENT state. 137 * Flags.
138 * Otherwise, the receiver MUST silently discard the packet
139 * and take no further action. An endpoint MUST ignore the
140 * SHUTDOWN COMPLETE if it is not in the SHUTDOWN-ACK-SENT state.
138 * 141 *
139 * Inputs 142 * Inputs
140 * (endpoint, asoc, chunk) 143 * (endpoint, asoc, chunk)
@@ -2858,16 +2861,16 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep,
2858/* 2861/*
2859 * Generate an ABORT in response to a packet. 2862 * Generate an ABORT in response to a packet.
2860 * 2863 *
2861 * Section: 8.4 Handle "Out of the blue" Packets 2864 * Section: 8.4 Handle "Out of the blue" Packets, sctpimpguide 2.41
2862 * 2865 *
2863 * 8) The receiver should respond to the sender of the OOTB packet 2866 * 8) The receiver should respond to the sender of the OOTB packet with
2864 * with an ABORT. When sending the ABORT, the receiver of the 2867 * an ABORT. When sending the ABORT, the receiver of the OOTB packet
2865 * OOTB packet MUST fill in the Verification Tag field of the 2868 * MUST fill in the Verification Tag field of the outbound packet
2866 * outbound packet with the value found in the Verification Tag 2869 * with the value found in the Verification Tag field of the OOTB
2867 * field of the OOTB packet and set the T-bit in the Chunk Flags 2870 * packet and set the T-bit in the Chunk Flags to indicate that the
2868 * to indicate that no TCB was found. After sending this ABORT, 2871 * Verification Tag is reflected. After sending this ABORT, the
2869 * the receiver of the OOTB packet shall discard the OOTB packet 2872 * receiver of the OOTB packet shall discard the OOTB packet and take
2870 * and take no further action. 2873 * no further action.
2871 * 2874 *
2872 * Verification Tag: 2875 * Verification Tag:
2873 * 2876 *
@@ -2895,6 +2898,10 @@ sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
2895 return SCTP_DISPOSITION_NOMEM; 2898 return SCTP_DISPOSITION_NOMEM;
2896 } 2899 }
2897 2900
2901 /* Reflect vtag if T-Bit is set */
2902 if (sctp_test_T_bit(abort))
2903 packet->vtag = ntohl(chunk->sctp_hdr->vtag);
2904
2898 /* Set the skb to the belonging sock for accounting. */ 2905 /* Set the skb to the belonging sock for accounting. */
2899 abort->skb->sk = ep->base.sk; 2906 abort->skb->sk = ep->base.sk;
2900 2907
@@ -3026,22 +3033,24 @@ nomem:
3026} 3033}
3027 3034
3028/* 3035/*
3029 * RFC 2960, 8.4 - Handle "Out of the blue" Packets 3036 * RFC 2960, 8.4 - Handle "Out of the blue" Packets, sctpimpguide 2.41.
3037 *
3030 * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should 3038 * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should
3031 * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. 3039 * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE.
3032 * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB 3040 * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB
3033 * packet must fill in the Verification Tag field of the outbound 3041 * packet must fill in the Verification Tag field of the outbound
3034 * packet with the Verification Tag received in the SHUTDOWN ACK and 3042 * packet with the Verification Tag received in the SHUTDOWN ACK and
3035 * set the T-bit in the Chunk Flags to indicate that no TCB was 3043 * set the T-bit in the Chunk Flags to indicate that the Verification
3036 * found. Otherwise, 3044 * Tag is reflected.
3037 * 3045 *
3038 * 8) The receiver should respond to the sender of the OOTB packet with 3046 * 8) The receiver should respond to the sender of the OOTB packet with
3039 * an ABORT. When sending the ABORT, the receiver of the OOTB packet 3047 * an ABORT. When sending the ABORT, the receiver of the OOTB packet
3040 * MUST fill in the Verification Tag field of the outbound packet 3048 * MUST fill in the Verification Tag field of the outbound packet
3041 * with the value found in the Verification Tag field of the OOTB 3049 * with the value found in the Verification Tag field of the OOTB
3042 * packet and set the T-bit in the Chunk Flags to indicate that no 3050 * packet and set the T-bit in the Chunk Flags to indicate that the
3043 * TCB was found. After sending this ABORT, the receiver of the OOTB 3051 * Verification Tag is reflected. After sending this ABORT, the
3044 * packet shall discard the OOTB packet and take no further action. 3052 * receiver of the OOTB packet shall discard the OOTB packet and take
3053 * no further action.
3045 */ 3054 */
3046sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, 3055sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
3047 const struct sctp_association *asoc, 3056 const struct sctp_association *asoc,
@@ -3090,13 +3099,15 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
3090/* 3099/*
3091 * Handle an "Out of the blue" SHUTDOWN ACK. 3100 * Handle an "Out of the blue" SHUTDOWN ACK.
3092 * 3101 *
3093 * Section: 8.4 5) 3102 * Section: 8.4 5, sctpimpguide 2.41.
3103 *
3094 * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should 3104 * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should
3095 * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. 3105 * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE.
3096 * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB packet 3106 * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB
3097 * must fill in the Verification Tag field of the outbound packet with 3107 * packet must fill in the Verification Tag field of the outbound
3098 * the Verification Tag received in the SHUTDOWN ACK and set the 3108 * packet with the Verification Tag received in the SHUTDOWN ACK and
3099 * T-bit in the Chunk Flags to indicate that no TCB was found. 3109 * set the T-bit in the Chunk Flags to indicate that the Verification
3110 * Tag is reflected.
3100 * 3111 *
3101 * Inputs 3112 * Inputs
3102 * (endpoint, asoc, type, arg, commands) 3113 * (endpoint, asoc, type, arg, commands)
@@ -3128,6 +3139,10 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
3128 return SCTP_DISPOSITION_NOMEM; 3139 return SCTP_DISPOSITION_NOMEM;
3129 } 3140 }
3130 3141
3142 /* Reflect vtag if T-Bit is set */
3143 if (sctp_test_T_bit(shut))
3144 packet->vtag = ntohl(chunk->sctp_hdr->vtag);
3145
3131 /* Set the skb to the belonging sock for accounting. */ 3146 /* Set the skb to the belonging sock for accounting. */
3132 shut->skb->sk = ep->base.sk; 3147 shut->skb->sk = ep->base.sk;
3133 3148
@@ -3591,7 +3606,6 @@ sctp_disposition_t sctp_sf_discard_chunk(const struct sctp_endpoint *ep,
3591 * 3606 *
3592 * 2) If the OOTB packet contains an ABORT chunk, the receiver MUST 3607 * 2) If the OOTB packet contains an ABORT chunk, the receiver MUST
3593 * silently discard the OOTB packet and take no further action. 3608 * silently discard the OOTB packet and take no further action.
3594 * Otherwise,
3595 * 3609 *
3596 * Verification Tag: No verification necessary 3610 * Verification Tag: No verification necessary
3597 * 3611 *
@@ -4961,6 +4975,11 @@ static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
4961 sctp_ootb_pkt_free(packet); 4975 sctp_ootb_pkt_free(packet);
4962 return NULL; 4976 return NULL;
4963 } 4977 }
4978
4979 /* Reflect vtag if T-Bit is set */
4980 if (sctp_test_T_bit(abort))
4981 packet->vtag = ntohl(chunk->sctp_hdr->vtag);
4982
4964 /* Add specified error causes, i.e., payload, to the 4983 /* Add specified error causes, i.e., payload, to the
4965 * end of the chunk. 4984 * end of the chunk.
4966 */ 4985 */
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index e8c210182571..0b338eca6dc0 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -115,9 +115,17 @@ static inline int sctp_wspace(struct sctp_association *asoc)
115 struct sock *sk = asoc->base.sk; 115 struct sock *sk = asoc->base.sk;
116 int amt = 0; 116 int amt = 0;
117 117
118 amt = sk->sk_sndbuf - asoc->sndbuf_used; 118 if (asoc->ep->sndbuf_policy) {
119 /* make sure that no association uses more than sk_sndbuf */
120 amt = sk->sk_sndbuf - asoc->sndbuf_used;
121 } else {
122 /* do socket level accounting */
123 amt = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
124 }
125
119 if (amt < 0) 126 if (amt < 0)
120 amt = 0; 127 amt = 0;
128
121 return amt; 129 return amt;
122} 130}
123 131
@@ -138,12 +146,21 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk)
138 /* The sndbuf space is tracked per association. */ 146 /* The sndbuf space is tracked per association. */
139 sctp_association_hold(asoc); 147 sctp_association_hold(asoc);
140 148
149 skb_set_owner_w(chunk->skb, sk);
150
141 chunk->skb->destructor = sctp_wfree; 151 chunk->skb->destructor = sctp_wfree;
142 /* Save the chunk pointer in skb for sctp_wfree to use later. */ 152 /* Save the chunk pointer in skb for sctp_wfree to use later. */
143 *((struct sctp_chunk **)(chunk->skb->cb)) = chunk; 153 *((struct sctp_chunk **)(chunk->skb->cb)) = chunk;
144 154
145 asoc->sndbuf_used += SCTP_DATA_SNDSIZE(chunk); 155 asoc->sndbuf_used += SCTP_DATA_SNDSIZE(chunk) +
146 sk->sk_wmem_queued += SCTP_DATA_SNDSIZE(chunk); 156 sizeof(struct sk_buff) +
157 sizeof(struct sctp_chunk);
158
159 sk->sk_wmem_queued += SCTP_DATA_SNDSIZE(chunk) +
160 sizeof(struct sk_buff) +
161 sizeof(struct sctp_chunk);
162
163 atomic_add(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc);
147} 164}
148 165
149/* Verify that this is a valid address. */ 166/* Verify that this is a valid address. */
@@ -3473,7 +3490,7 @@ static int sctp_getsockopt_associnfo(struct sock *sk, int len,
3473 return -EINVAL; 3490 return -EINVAL;
3474 3491
3475 /* Values correspoinding to the specific association */ 3492 /* Values correspoinding to the specific association */
3476 if (assocparams.sasoc_assoc_id != 0) { 3493 if (asoc) {
3477 assocparams.sasoc_asocmaxrxt = asoc->max_retrans; 3494 assocparams.sasoc_asocmaxrxt = asoc->max_retrans;
3478 assocparams.sasoc_peer_rwnd = asoc->peer.rwnd; 3495 assocparams.sasoc_peer_rwnd = asoc->peer.rwnd;
3479 assocparams.sasoc_local_rwnd = asoc->a_rwnd; 3496 assocparams.sasoc_local_rwnd = asoc->a_rwnd;
@@ -4422,8 +4439,17 @@ static void sctp_wfree(struct sk_buff *skb)
4422 chunk = *((struct sctp_chunk **)(skb->cb)); 4439 chunk = *((struct sctp_chunk **)(skb->cb));
4423 asoc = chunk->asoc; 4440 asoc = chunk->asoc;
4424 sk = asoc->base.sk; 4441 sk = asoc->base.sk;
4425 asoc->sndbuf_used -= SCTP_DATA_SNDSIZE(chunk); 4442 asoc->sndbuf_used -= SCTP_DATA_SNDSIZE(chunk) +
4426 sk->sk_wmem_queued -= SCTP_DATA_SNDSIZE(chunk); 4443 sizeof(struct sk_buff) +
4444 sizeof(struct sctp_chunk);
4445
4446 sk->sk_wmem_queued -= SCTP_DATA_SNDSIZE(chunk) +
4447 sizeof(struct sk_buff) +
4448 sizeof(struct sctp_chunk);
4449
4450 atomic_sub(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc);
4451
4452 sock_wfree(skb);
4427 __sctp_write_space(asoc); 4453 __sctp_write_space(asoc);
4428 4454
4429 sctp_association_put(asoc); 4455 sctp_association_put(asoc);
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index 89fa20c73a5c..7fc31849312b 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -110,6 +110,14 @@ static ctl_table sctp_table[] = {
110 .proc_handler = &proc_dointvec 110 .proc_handler = &proc_dointvec
111 }, 111 },
112 { 112 {
113 .ctl_name = NET_SCTP_SNDBUF_POLICY,
114 .procname = "sndbuf_policy",
115 .data = &sctp_sndbuf_policy,
116 .maxlen = sizeof(int),
117 .mode = 0644,
118 .proc_handler = &proc_dointvec
119 },
120 {
113 .ctl_name = NET_SCTP_PATH_MAX_RETRANS, 121 .ctl_name = NET_SCTP_PATH_MAX_RETRANS,
114 .procname = "path_max_retrans", 122 .procname = "path_max_retrans",
115 .data = &sctp_max_retrans_path, 123 .data = &sctp_max_retrans_path,
diff --git a/net/socket.c b/net/socket.c
index 2cd44990d8d3..cec0cb38b9ce 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -4,7 +4,7 @@
4 * Version: @(#)socket.c 1.1.93 18/02/95 4 * Version: @(#)socket.c 1.1.93 18/02/95
5 * 5 *
6 * Authors: Orest Zborowski, <obz@Kodak.COM> 6 * Authors: Orest Zborowski, <obz@Kodak.COM>
7 * Ross Biro, <bir7@leland.Stanford.Edu> 7 * Ross Biro
8 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 8 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
9 * 9 *
10 * Fixes: 10 * Fixes:
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 4484931018eb..67b9f035ba86 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -46,9 +46,9 @@ xdr_decode_netobj(u32 *p, struct xdr_netobj *obj)
46 46
47/** 47/**
48 * xdr_encode_opaque_fixed - Encode fixed length opaque data 48 * xdr_encode_opaque_fixed - Encode fixed length opaque data
49 * @p - pointer to current position in XDR buffer. 49 * @p: pointer to current position in XDR buffer.
50 * @ptr - pointer to data to encode (or NULL) 50 * @ptr: pointer to data to encode (or NULL)
51 * @nbytes - size of data. 51 * @nbytes: size of data.
52 * 52 *
53 * Copy the array of data of length nbytes at ptr to the XDR buffer 53 * Copy the array of data of length nbytes at ptr to the XDR buffer
54 * at position p, then align to the next 32-bit boundary by padding 54 * at position p, then align to the next 32-bit boundary by padding
@@ -76,9 +76,9 @@ EXPORT_SYMBOL(xdr_encode_opaque_fixed);
76 76
77/** 77/**
78 * xdr_encode_opaque - Encode variable length opaque data 78 * xdr_encode_opaque - Encode variable length opaque data
79 * @p - pointer to current position in XDR buffer. 79 * @p: pointer to current position in XDR buffer.
80 * @ptr - pointer to data to encode (or NULL) 80 * @ptr: pointer to data to encode (or NULL)
81 * @nbytes - size of data. 81 * @nbytes: size of data.
82 * 82 *
83 * Returns the updated current XDR buffer position 83 * Returns the updated current XDR buffer position
84 */ 84 */
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index acc73fe68698..c478fc8db776 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -85,7 +85,6 @@
85#include <linux/module.h> 85#include <linux/module.h>
86#include <linux/config.h> 86#include <linux/config.h>
87#include <linux/kernel.h> 87#include <linux/kernel.h>
88#include <linux/major.h>
89#include <linux/signal.h> 88#include <linux/signal.h>
90#include <linux/sched.h> 89#include <linux/sched.h>
91#include <linux/errno.h> 90#include <linux/errno.h>
diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c
index 956c17f6c548..d6844ac226f5 100644
--- a/net/wanrouter/wanmain.c
+++ b/net/wanrouter/wanmain.c
@@ -48,8 +48,8 @@
48#include <linux/kernel.h> 48#include <linux/kernel.h>
49#include <linux/init.h> 49#include <linux/init.h>
50#include <linux/module.h> /* support for loadable modules */ 50#include <linux/module.h> /* support for loadable modules */
51#include <linux/slab.h> /* kmalloc(), kfree() */ 51#include <linux/slab.h> /* kmalloc(), kfree() */
52#include <linux/mm.h> /* verify_area(), etc. */ 52#include <linux/mm.h>
53#include <linux/string.h> /* inline mem*, str* functions */ 53#include <linux/string.h> /* inline mem*, str* functions */
54 54
55#include <asm/byteorder.h> /* htons(), etc. */ 55#include <asm/byteorder.h> /* htons(), etc. */
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 80828078733d..55ed979db144 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1028,30 +1028,15 @@ static int stale_bundle(struct dst_entry *dst)
1028 return !xfrm_bundle_ok((struct xfrm_dst *)dst, NULL, AF_UNSPEC); 1028 return !xfrm_bundle_ok((struct xfrm_dst *)dst, NULL, AF_UNSPEC);
1029} 1029}
1030 1030
1031static void xfrm_dst_destroy(struct dst_entry *dst) 1031void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev)
1032{ 1032{
1033 struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
1034
1035 dst_release(xdst->route);
1036
1037 if (!dst->xfrm)
1038 return;
1039 xfrm_state_put(dst->xfrm);
1040 dst->xfrm = NULL;
1041}
1042
1043static void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
1044 int unregister)
1045{
1046 if (!unregister)
1047 return;
1048
1049 while ((dst = dst->child) && dst->xfrm && dst->dev == dev) { 1033 while ((dst = dst->child) && dst->xfrm && dst->dev == dev) {
1050 dst->dev = &loopback_dev; 1034 dst->dev = &loopback_dev;
1051 dev_hold(&loopback_dev); 1035 dev_hold(&loopback_dev);
1052 dev_put(dev); 1036 dev_put(dev);
1053 } 1037 }
1054} 1038}
1039EXPORT_SYMBOL(xfrm_dst_ifdown);
1055 1040
1056static void xfrm_link_failure(struct sk_buff *skb) 1041static void xfrm_link_failure(struct sk_buff *skb)
1057{ 1042{
@@ -1262,10 +1247,6 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
1262 dst_ops->kmem_cachep = xfrm_dst_cache; 1247 dst_ops->kmem_cachep = xfrm_dst_cache;
1263 if (likely(dst_ops->check == NULL)) 1248 if (likely(dst_ops->check == NULL))
1264 dst_ops->check = xfrm_dst_check; 1249 dst_ops->check = xfrm_dst_check;
1265 if (likely(dst_ops->destroy == NULL))
1266 dst_ops->destroy = xfrm_dst_destroy;
1267 if (likely(dst_ops->ifdown == NULL))
1268 dst_ops->ifdown = xfrm_dst_ifdown;
1269 if (likely(dst_ops->negative_advice == NULL)) 1250 if (likely(dst_ops->negative_advice == NULL))
1270 dst_ops->negative_advice = xfrm_negative_advice; 1251 dst_ops->negative_advice = xfrm_negative_advice;
1271 if (likely(dst_ops->link_failure == NULL)) 1252 if (likely(dst_ops->link_failure == NULL))
@@ -1297,8 +1278,6 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo)
1297 xfrm_policy_afinfo[afinfo->family] = NULL; 1278 xfrm_policy_afinfo[afinfo->family] = NULL;
1298 dst_ops->kmem_cachep = NULL; 1279 dst_ops->kmem_cachep = NULL;
1299 dst_ops->check = NULL; 1280 dst_ops->check = NULL;
1300 dst_ops->destroy = NULL;
1301 dst_ops->ifdown = NULL;
1302 dst_ops->negative_advice = NULL; 1281 dst_ops->negative_advice = NULL;
1303 dst_ops->link_failure = NULL; 1282 dst_ops->link_failure = NULL;
1304 dst_ops->get_mss = NULL; 1283 dst_ops->get_mss = NULL;
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 1db59f11f37d..d11747c2a763 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -357,8 +357,9 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
357 357
358 x = best; 358 x = best;
359 if (!x && !error && !acquire_in_progress) { 359 if (!x && !error && !acquire_in_progress) {
360 x0 = afinfo->state_lookup(&tmpl->id.daddr, tmpl->id.spi, tmpl->id.proto); 360 if (tmpl->id.spi &&
361 if (x0 != NULL) { 361 (x0 = afinfo->state_lookup(daddr, tmpl->id.spi,
362 tmpl->id.proto)) != NULL) {
362 xfrm_state_put(x0); 363 xfrm_state_put(x0);
363 error = -EEXIST; 364 error = -EEXIST;
364 goto out; 365 goto out;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 63661b0fd736..5ddda2c98af9 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -855,47 +855,44 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **x
855 return 0; 855 return 0;
856} 856}
857 857
858static const int xfrm_msg_min[(XFRM_MSG_MAX + 1 - XFRM_MSG_BASE)] = { 858#define XMSGSIZE(type) NLMSG_LENGTH(sizeof(struct type))
859 NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)), /* NEW SA */ 859
860 NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)), /* DEL SA */ 860static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = {
861 NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)), /* GET SA */ 861 [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info),
862 NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)),/* NEW POLICY */ 862 [XFRM_MSG_DELSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id),
863 NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)), /* DEL POLICY */ 863 [XFRM_MSG_GETSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id),
864 NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)), /* GET POLICY */ 864 [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info),
865 NLMSG_LENGTH(sizeof(struct xfrm_userspi_info)), /* ALLOC SPI */ 865 [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id),
866 NLMSG_LENGTH(sizeof(struct xfrm_user_acquire)), /* ACQUIRE */ 866 [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id),
867 NLMSG_LENGTH(sizeof(struct xfrm_user_expire)), /* EXPIRE */ 867 [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userspi_info),
868 NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)),/* UPD POLICY */ 868 [XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_acquire),
869 NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)), /* UPD SA */ 869 [XFRM_MSG_EXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_expire),
870 NLMSG_LENGTH(sizeof(struct xfrm_user_polexpire)), /* POLEXPIRE */ 870 [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info),
871 NLMSG_LENGTH(sizeof(struct xfrm_usersa_flush)), /* FLUSH SA */ 871 [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info),
872 NLMSG_LENGTH(0), /* FLUSH POLICY */ 872 [XFRM_MSG_POLEXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_polexpire),
873 [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush),
874 [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = NLMSG_LENGTH(0),
873}; 875};
874 876
877#undef XMSGSIZE
878
875static struct xfrm_link { 879static struct xfrm_link {
876 int (*doit)(struct sk_buff *, struct nlmsghdr *, void **); 880 int (*doit)(struct sk_buff *, struct nlmsghdr *, void **);
877 int (*dump)(struct sk_buff *, struct netlink_callback *); 881 int (*dump)(struct sk_buff *, struct netlink_callback *);
878} xfrm_dispatch[] = { 882} xfrm_dispatch[XFRM_NR_MSGTYPES] = {
879 { .doit = xfrm_add_sa, }, 883 [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa },
880 { .doit = xfrm_del_sa, }, 884 [XFRM_MSG_DELSA - XFRM_MSG_BASE] = { .doit = xfrm_del_sa },
881 { 885 [XFRM_MSG_GETSA - XFRM_MSG_BASE] = { .doit = xfrm_get_sa,
882 .doit = xfrm_get_sa, 886 .dump = xfrm_dump_sa },
883 .dump = xfrm_dump_sa, 887 [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy },
884 }, 888 [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy },
885 { .doit = xfrm_add_policy }, 889 [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy,
886 { .doit = xfrm_get_policy }, 890 .dump = xfrm_dump_policy },
887 { 891 [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi },
888 .doit = xfrm_get_policy, 892 [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy },
889 .dump = xfrm_dump_policy, 893 [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa },
890 }, 894 [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = { .doit = xfrm_flush_sa },
891 { .doit = xfrm_alloc_userspi }, 895 [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_flush_policy },
892 {},
893 {},
894 { .doit = xfrm_add_policy },
895 { .doit = xfrm_add_sa, },
896 {},
897 { .doit = xfrm_flush_sa },
898 { .doit = xfrm_flush_policy },
899}; 896};
900 897
901static int xfrm_done(struct netlink_callback *cb) 898static int xfrm_done(struct netlink_callback *cb)
@@ -931,7 +928,9 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *err
931 return -1; 928 return -1;
932 } 929 }
933 930
934 if ((type == 2 || type == 5) && (nlh->nlmsg_flags & NLM_F_DUMP)) { 931 if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) ||
932 type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) &&
933 (nlh->nlmsg_flags & NLM_F_DUMP)) {
935 u32 rlen; 934 u32 rlen;
936 935
937 if (link->dump == NULL) 936 if (link->dump == NULL)
@@ -1009,18 +1008,26 @@ static int xfrm_user_rcv_skb(struct sk_buff *skb)
1009 1008
1010static void xfrm_netlink_rcv(struct sock *sk, int len) 1009static void xfrm_netlink_rcv(struct sock *sk, int len)
1011{ 1010{
1011 unsigned int qlen = skb_queue_len(&sk->sk_receive_queue);
1012
1012 do { 1013 do {
1013 struct sk_buff *skb; 1014 struct sk_buff *skb;
1014 1015
1015 down(&xfrm_cfg_sem); 1016 down(&xfrm_cfg_sem);
1016 1017
1017 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { 1018 if (qlen > skb_queue_len(&sk->sk_receive_queue))
1019 qlen = skb_queue_len(&sk->sk_receive_queue);
1020
1021 for (; qlen; qlen--) {
1022 skb = skb_dequeue(&sk->sk_receive_queue);
1018 if (xfrm_user_rcv_skb(skb)) { 1023 if (xfrm_user_rcv_skb(skb)) {
1019 if (skb->len) 1024 if (skb->len)
1020 skb_queue_head(&sk->sk_receive_queue, 1025 skb_queue_head(&sk->sk_receive_queue,
1021 skb); 1026 skb);
1022 else 1027 else {
1023 kfree_skb(skb); 1028 kfree_skb(skb);
1029 qlen--;
1030 }
1024 break; 1031 break;
1025 } 1032 }
1026 kfree_skb(skb); 1033 kfree_skb(skb);
@@ -1028,7 +1035,7 @@ static void xfrm_netlink_rcv(struct sock *sk, int len)
1028 1035
1029 up(&xfrm_cfg_sem); 1036 up(&xfrm_cfg_sem);
1030 1037
1031 } while (xfrm_nl && xfrm_nl->sk_receive_queue.qlen); 1038 } while (qlen);
1032} 1039}
1033 1040
1034static int build_expire(struct sk_buff *skb, struct xfrm_state *x, int hard) 1041static int build_expire(struct sk_buff *skb, struct xfrm_state *x, int hard)