aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorJames Bottomley <jejb@titanic.(none)>2005-05-20 15:27:44 -0500
committerJames Bottomley <jejb@titanic.(none)>2005-05-20 15:27:44 -0500
commitad34ea2cc3845ef4dcd7d12fb0fa8484734bd672 (patch)
treead434400f5ecaa33b433c8f830e40792d8d6c05c /net
parent90356ac3194bf91a441a5f9c3067af386ef62462 (diff)
parent88d7bd8cb9eb8d64bf7997600b0d64f7834047c5 (diff)
merge by hand - fix up rejections in Documentation/DocBook/Makefile
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 f9a31a9f70f..ebcf4830d6f 100644
--- a/net/802/fddi.c
+++ b/net/802/fddi.c
@@ -10,7 +10,7 @@
* Authors: Lawrence V. Stefani, <stefani@lkg.dec.com>
*
* fddi.c is based on previous eth.c and tr.c work by
- * Ross Biro, <bir7@leland.Stanford.Edu>
+ * Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Mark Evans, <evansmp@uhura.aston.ac.uk>
* Florian La Roche, <rzsfl@rz.uni-sb.de>
diff --git a/net/802/hippi.c b/net/802/hippi.c
index 4eb135c0afb..051e8af56a7 100644
--- a/net/802/hippi.c
+++ b/net/802/hippi.c
@@ -7,7 +7,7 @@
*
* Version: @(#)hippi.c 1.0.0 05/29/97
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Mark Evans, <evansmp@uhura.aston.ac.uk>
* Florian La Roche, <rzsfl@rz.uni-sb.de>
diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c
index c32d27af0a3..7b214cffc95 100644
--- a/net/8021q/vlanproc.c
+++ b/net/8021q/vlanproc.c
@@ -23,7 +23,7 @@
#include <linux/errno.h> /* return codes */
#include <linux/kernel.h>
#include <linux/slab.h> /* kmalloc(), kfree() */
-#include <linux/mm.h> /* verify_area(), etc. */
+#include <linux/mm.h>
#include <linux/string.h> /* inline mem*, str* functions */
#include <linux/init.h> /* __initfunc et al. */
#include <asm/byteorder.h> /* htons(), etc. */
diff --git a/net/appletalk/dev.c b/net/appletalk/dev.c
index 76598445d84..1237e208e24 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)
return -EINVAL;
}
-void ltalk_setup(struct net_device *dev)
+static void ltalk_setup(struct net_device *dev)
{
/* Fill in the fields of the device structure with localtalk-generic values. */
@@ -40,4 +40,22 @@ void ltalk_setup(struct net_device *dev)
dev->flags = IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP;
}
-EXPORT_SYMBOL(ltalk_setup);
+
+/**
+ * alloc_ltalkdev - Allocates and sets up an localtalk device
+ * @sizeof_priv: Size of additional driver-private structure to be allocated
+ * for this localtalk device
+ *
+ * Fill in the fields of the device structure with localtalk-generic
+ * values. Basically does everything except registering the device.
+ *
+ * Constructs a new net device, complete with a private data area of
+ * size @sizeof_priv. A 32-byte (not bit) alignment is enforced for
+ * this private data area.
+ */
+
+struct net_device *alloc_ltalkdev(int sizeof_priv)
+{
+ return alloc_netdev(sizeof_priv, "lt%d", ltalk_setup);
+}
+EXPORT_SYMBOL(alloc_ltalkdev);
diff --git a/net/atm/common.c b/net/atm/common.c
index 6d16be334ea..e93e838069e 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -12,7 +12,7 @@
#include <linux/socket.h> /* SOL_SOCKET */
#include <linux/errno.h> /* error codes */
#include <linux/capability.h>
-#include <linux/mm.h> /* verify_area */
+#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/time.h> /* struct timeval */
#include <linux/skbuff.h>
@@ -540,7 +540,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
error = -EMSGSIZE;
goto out;
}
- /* verify_area is done by net/socket.c */
+
eff = (size+3) & ~3; /* align to word boundary */
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
error = 0;
diff --git a/net/atm/resources.c b/net/atm/resources.c
index 33f1685dbb7..a57a9268bd2 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)
return dev;
}
-static void __free_atm_dev(struct atm_dev *dev)
-{
- kfree(dev);
-}
-
static struct atm_dev *__atm_dev_lookup(int number)
{
struct atm_dev *dev;
@@ -90,7 +85,7 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
if ((inuse = __atm_dev_lookup(number))) {
atm_dev_put(inuse);
spin_unlock(&atm_dev_lock);
- __free_atm_dev(dev);
+ kfree(dev);
return NULL;
}
dev->number = number;
@@ -119,7 +114,7 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
spin_lock(&atm_dev_lock);
list_del(&dev->dev_list);
spin_unlock(&atm_dev_lock);
- __free_atm_dev(dev);
+ kfree(dev);
return NULL;
}
@@ -148,7 +143,7 @@ void atm_dev_deregister(struct atm_dev *dev)
}
}
- __free_atm_dev(dev);
+ kfree(dev);
}
void shutdown_atm_dev(struct atm_dev *dev)
diff --git a/net/atm/signaling.c b/net/atm/signaling.c
index 6ff803154c0..f7c449ac180 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)
break;
case as_indicate:
vcc = *(struct atm_vcc **) &msg->listen_vcc;
+ sk = sk_atm(vcc);
DPRINTK("as_indicate!!!\n");
lock_sock(sk);
if (sk_acceptq_is_full(sk)) {
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 33b1a376302..707097deac3 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,
*asmptr = AX25_UI;
/* Datagram frames go straight out of the door as UI */
- skb->dev = ax25->ax25_dev->dev;
-
- ax25_queue_xmit(skb);
+ ax25_queue_xmit(skb, ax25->ax25_dev->dev);
err = len;
diff --git a/net/ax25/ax25_ds_subr.c b/net/ax25/ax25_ds_subr.c
index 10ffd2beba3..1d4ab641f82 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
*p++ = cmd;
*p++ = param;
- skb->dev = ax25_dev->dev;
- skb->protocol = htons(ETH_P_AX25);
+ skb->protocol = ax25_type_trans(skb, ax25_dev->dev);
dev_queue_xmit(skb);
}
diff --git a/net/ax25/ax25_ip.c b/net/ax25/ax25_ip.c
index 04d711344d5..bba0173e2d6 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)
skb = ourskb;
}
- skb->dev = dev;
-
- ax25_queue_xmit(skb);
+ ax25_queue_xmit(skb, dev);
put:
ax25_put_route(route);
diff --git a/net/ax25/ax25_out.c b/net/ax25/ax25_out.c
index 3475a3ac934..5fc048dcd39 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)
ax25_addr_build(ptr, &ax25->source_addr, &ax25->dest_addr, ax25->digipeat, type, ax25->modulus);
- skb->dev = ax25->ax25_dev->dev;
-
- ax25_queue_xmit(skb);
+ ax25_queue_xmit(skb, ax25->ax25_dev->dev);
}
/*
* A small shim to dev_queue_xmit to add the KISS control byte, and do
* any packet forwarding in operation.
*/
-void ax25_queue_xmit(struct sk_buff *skb)
+void ax25_queue_xmit(struct sk_buff *skb, struct net_device *dev)
{
unsigned char *ptr;
- skb->protocol = htons(ETH_P_AX25);
- skb->dev = ax25_fwd_dev(skb->dev);
+ skb->protocol = ax25_type_trans(skb, ax25_fwd_dev(dev));
ptr = skb_push(skb, 1);
*ptr = 0x00; /* KISS */
diff --git a/net/ax25/ax25_subr.c b/net/ax25/ax25_subr.c
index 8cf72707af8..99694b57f6f 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
dptr = skb_push(skb, ax25_addr_size(digi));
dptr += ax25_addr_build(dptr, dest, src, &retdigi, AX25_RESPONSE, AX25_MODULUS);
- skb->dev = dev;
-
- ax25_queue_xmit(skb);
+ ax25_queue_xmit(skb, dev);
}
/*
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 1650c6bf699..12b43345b54 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -31,7 +31,6 @@
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/skbuff.h>
diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c
index 9a8d99a39b6..9778c6acd53 100644
--- a/net/bluetooth/bnep/sock.c
+++ b/net/bluetooth/bnep/sock.c
@@ -34,7 +34,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/poll.h>
diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c
index 1e5c030b72a..b2e7e38531c 100644
--- a/net/bluetooth/cmtp/capi.c
+++ b/net/bluetooth/cmtp/capi.c
@@ -26,7 +26,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/poll.h>
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c
index 20ce04f2be8..2e341de3e76 100644
--- a/net/bluetooth/cmtp/core.c
+++ b/net/bluetooth/cmtp/core.c
@@ -26,7 +26,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/poll.h>
diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c
index 4c7f9e20dad..beb045bf571 100644
--- a/net/bluetooth/cmtp/sock.c
+++ b/net/bluetooth/cmtp/sock.c
@@ -26,7 +26,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/poll.h>
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 71762d7e997..a31244e5888 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -30,7 +30,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/poll.h>
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 860dba7bdd8..fb5524365bc 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -31,7 +31,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/poll.h>
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 8ccba8ee997..c4b592b4ef1 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -30,7 +30,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/poll.h>
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index c9792ba7512..ebdcce5e7ca 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -30,7 +30,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/poll.h>
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 2cf98ceabcc..affbc55462e 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -26,7 +26,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/poll.h>
diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c
index fabb36d4666..f8986f88143 100644
--- a/net/bluetooth/hidp/sock.c
+++ b/net/bluetooth/hidp/sock.c
@@ -26,7 +26,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/poll.h>
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index c12babcf0b3..32fccfb5bfa 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -30,7 +30,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/poll.h>
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 640028a2183..f3f6355a278 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -33,7 +33,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/poll.h>
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 3e750ef09e6..746c11fc017 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -30,7 +30,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/poll.h>
diff --git a/net/core/datagram.c b/net/core/datagram.c
index d1bfd279cc1..fcee054b6f7 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -115,10 +115,10 @@ out_noerr:
/**
* skb_recv_datagram - Receive a datagram skbuff
- * @sk - socket
- * @flags - MSG_ flags
- * @noblock - blocking operation?
- * @err - error code returned
+ * @sk: socket
+ * @flags: MSG_ flags
+ * @noblock: blocking operation?
+ * @err: error code returned
*
* Get a datagram skbuff, understands the peeking, nonblocking wakeups
* 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)
/**
* skb_copy_datagram_iovec - Copy a datagram to an iovec.
- * @skb - buffer to copy
- * @offset - offset in the buffer to start copying from
- * @iovec - io vector to copy to
- * @len - amount of data to copy from buffer to iovec
+ * @skb: buffer to copy
+ * @offset: offset in the buffer to start copying from
+ * @to: io vector to copy to
+ * @len: amount of data to copy from buffer to iovec
*
* Note: the iovec is modified during the copy.
*/
@@ -377,9 +377,9 @@ fault:
/**
* skb_copy_and_csum_datagram_iovec - Copy and checkum skb to user iovec.
- * @skb - skbuff
- * @hlen - hardware length
- * @iovec - io vector
+ * @skb: skbuff
+ * @hlen: hardware length
+ * @iov: io vector
*
* Caller _must_ check that skb will fit to this iovec.
*
@@ -425,9 +425,9 @@ fault:
/**
* datagram_poll - generic datagram poll
- * @file - file struct
- * @sock - socket
- * @wait - poll table
+ * @file: file struct
+ * @sock: socket
+ * @wait: poll table
*
* Datagram poll: Again totally generic. This also handles
* sequenced packet sockets providing the socket receive queue
diff --git a/net/core/dev.c b/net/core/dev.c
index 42344d90369..d4d9e2680ad 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -7,7 +7,7 @@
* 2 of the License, or (at your option) any later version.
*
* Derived from the non IP parts of dev.c 1.0.19
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Mark Evans, <evansmp@uhura.aston.ac.uk>
*
@@ -1214,6 +1214,19 @@ int __skb_linearize(struct sk_buff *skb, int gfp_mask)
* A negative errno code is returned on a failure. A success does not
* guarantee the frame will be transmitted as it may be dropped due
* to congestion or traffic shaping.
+ *
+ * -----------------------------------------------------------------------------------
+ * I notice this method can also return errors from the queue disciplines,
+ * including NET_XMIT_DROP, which is a positive value. So, errors can also
+ * be positive.
+ *
+ * Regardless of the return value, the skb is consumed, so it is currently
+ * difficult to retry a send to this method. (You can bump the ref count
+ * before sending to hold a reference for retry if you are careful.)
+ *
+ * When calling this method, interrupts MUST be enabled. This is because
+ * the BH enable code must have IRQs enabled so that it will not deadlock.
+ * --BLG
*/
int dev_queue_xmit(struct sk_buff *skb)
@@ -3078,7 +3091,7 @@ void free_netdev(struct net_device *dev)
void synchronize_net(void)
{
might_sleep();
- synchronize_kernel();
+ synchronize_rcu();
}
/**
diff --git a/net/core/iovec.c b/net/core/iovec.c
index d57ace949ab..65e4b56fbc7 100644
--- a/net/core/iovec.c
+++ b/net/core/iovec.c
@@ -33,7 +33,7 @@
* Verify iovec. The caller must ensure that the iovec is big enough
* to hold the message iovec.
*
- * Save time not doing verify_area. copy_*_user will make this work
+ * Save time not doing access_ok. copy_*_user will make this work
* in any case.
*/
diff --git a/net/core/link_watch.c b/net/core/link_watch.c
index 4859b7446c6..d43d1201275 100644
--- a/net/core/link_watch.c
+++ b/net/core/link_watch.c
@@ -16,6 +16,7 @@
#include <linux/netdevice.h>
#include <linux/if.h>
#include <net/sock.h>
+#include <net/pkt_sched.h>
#include <linux/rtnetlink.h>
#include <linux/jiffies.h>
#include <linux/spinlock.h>
@@ -74,6 +75,12 @@ void linkwatch_run_queue(void)
clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state);
if (dev->flags & IFF_UP) {
+ if (netif_carrier_ok(dev)) {
+ WARN_ON(dev->qdisc_sleeping == &noop_qdisc);
+ dev_activate(dev);
+ } else
+ dev_deactivate(dev);
+
netdev_state_change(dev);
}
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 0a2f67bbef2..43bdc521e20 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)
struct neigh_statistics *st = v;
if (v == SEQ_START_TOKEN) {
- 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");
+ 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");
return 0;
}
diff --git a/net/core/netfilter.c b/net/core/netfilter.c
index e51cfa46950..22a8f127c4a 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)
* NF_IP_RAW_INPUT and NF_IP_PRE_ROUTING. */
if (!skb->dev) {
printk("ip_local_deliver: skb->dev is NULL.\n");
- }
- else if (strcmp(skb->dev->name, "lo") == 0) {
- if (skb->nf_debug != ((1 << NF_IP_LOCAL_OUT)
- | (1 << NF_IP_POST_ROUTING)
- | (1 << NF_IP_PRE_ROUTING)
- | (1 << NF_IP_LOCAL_IN))) {
- printk("ip_local_deliver: bad loopback skb: ");
- debug_print_hooks_ip(skb->nf_debug);
- nf_dump_skb(PF_INET, skb);
- }
- }
- else {
+ } else {
if (skb->nf_debug != ((1<<NF_IP_PRE_ROUTING)
| (1<<NF_IP_LOCAL_IN))) {
- printk("ip_local_deliver: bad non-lo skb: ");
+ printk("ip_local_deliver: bad skb: ");
debug_print_hooks_ip(skb->nf_debug);
nf_dump_skb(PF_INET, skb);
}
@@ -247,8 +236,6 @@ void nf_debug_ip_loopback_xmit(struct sk_buff *newskb)
debug_print_hooks_ip(newskb->nf_debug);
nf_dump_skb(PF_INET, newskb);
}
- /* Clear to avoid confusing input check */
- newskb->nf_debug = 0;
}
void nf_debug_ip_finish_output2(struct sk_buff *skb)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 44dfaf8f04a..00caf4b318b 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -22,7 +22,6 @@
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/string.h>
@@ -87,30 +86,33 @@ struct sock *rtnl;
struct rtnetlink_link * rtnetlink_links[NPROTO];
-static const int rtm_min[(RTM_MAX+1-RTM_BASE)/4] =
+static const int rtm_min[RTM_NR_FAMILIES] =
{
- NLMSG_LENGTH(sizeof(struct ifinfomsg)),
- NLMSG_LENGTH(sizeof(struct ifaddrmsg)),
- NLMSG_LENGTH(sizeof(struct rtmsg)),
- NLMSG_LENGTH(sizeof(struct ndmsg)),
- NLMSG_LENGTH(sizeof(struct rtmsg)),
- NLMSG_LENGTH(sizeof(struct tcmsg)),
- NLMSG_LENGTH(sizeof(struct tcmsg)),
- NLMSG_LENGTH(sizeof(struct tcmsg)),
- NLMSG_LENGTH(sizeof(struct tcamsg))
+ [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
+ [RTM_FAM(RTM_NEWADDR)] = NLMSG_LENGTH(sizeof(struct ifaddrmsg)),
+ [RTM_FAM(RTM_NEWROUTE)] = NLMSG_LENGTH(sizeof(struct rtmsg)),
+ [RTM_FAM(RTM_NEWNEIGH)] = NLMSG_LENGTH(sizeof(struct ndmsg)),
+ [RTM_FAM(RTM_NEWRULE)] = NLMSG_LENGTH(sizeof(struct rtmsg)),
+ [RTM_FAM(RTM_NEWQDISC)] = NLMSG_LENGTH(sizeof(struct tcmsg)),
+ [RTM_FAM(RTM_NEWTCLASS)] = NLMSG_LENGTH(sizeof(struct tcmsg)),
+ [RTM_FAM(RTM_NEWTFILTER)] = NLMSG_LENGTH(sizeof(struct tcmsg)),
+ [RTM_FAM(RTM_NEWACTION)] = NLMSG_LENGTH(sizeof(struct tcamsg)),
+ [RTM_FAM(RTM_NEWPREFIX)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
+ [RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
+ [RTM_FAM(RTM_GETANYCAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
};
-static const int rta_max[(RTM_MAX+1-RTM_BASE)/4] =
+static const int rta_max[RTM_NR_FAMILIES] =
{
- IFLA_MAX,
- IFA_MAX,
- RTA_MAX,
- NDA_MAX,
- RTA_MAX,
- TCA_MAX,
- TCA_MAX,
- TCA_MAX,
- TCAA_MAX
+ [RTM_FAM(RTM_NEWLINK)] = IFLA_MAX,
+ [RTM_FAM(RTM_NEWADDR)] = IFA_MAX,
+ [RTM_FAM(RTM_NEWROUTE)] = RTA_MAX,
+ [RTM_FAM(RTM_NEWNEIGH)] = NDA_MAX,
+ [RTM_FAM(RTM_NEWRULE)] = RTA_MAX,
+ [RTM_FAM(RTM_NEWQDISC)] = TCA_MAX,
+ [RTM_FAM(RTM_NEWTCLASS)] = TCA_MAX,
+ [RTM_FAM(RTM_NEWTFILTER)] = TCA_MAX,
+ [RTM_FAM(RTM_NEWACTION)] = TCAA_MAX,
};
void __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)
/*
* rtnetlink input queue processing routine:
- * - try to acquire shared lock. If it is failed, defer processing.
+ * - process as much as there was in the queue upon entry.
* - feed skbs to rtnetlink_rcv_skb, until it refuse a message,
- * that will occur, when a dump started and/or acquisition of
- * exclusive lock failed.
+ * that will occur, when a dump started.
*/
static void rtnetlink_rcv(struct sock *sk, int len)
{
+ unsigned int qlen = skb_queue_len(&sk->sk_receive_queue);
+
do {
struct sk_buff *skb;
- if (rtnl_shlock_nowait())
- return;
+ rtnl_lock();
+
+ if (qlen > skb_queue_len(&sk->sk_receive_queue))
+ qlen = skb_queue_len(&sk->sk_receive_queue);
- while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
+ for (; qlen; qlen--) {
+ skb = skb_dequeue(&sk->sk_receive_queue);
if (rtnetlink_rcv_skb(skb)) {
if (skb->len)
skb_queue_head(&sk->sk_receive_queue,
skb);
- else
+ else {
kfree_skb(skb);
+ qlen--;
+ }
break;
}
kfree_skb(skb);
@@ -636,10 +644,10 @@ static void rtnetlink_rcv(struct sock *sk, int len)
up(&rtnl_sem);
netdev_run_todo();
- } while (rtnl && rtnl->sk_receive_queue.qlen);
+ } while (qlen);
}
-static struct rtnetlink_link link_rtnetlink_table[RTM_MAX-RTM_BASE+1] =
+static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] =
{
[RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo },
[RTM_SETLINK - RTM_BASE] = { .doit = do_setlink },
diff --git a/net/core/scm.c b/net/core/scm.c
index a2ebf30f6aa..e887d19be50 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -15,7 +15,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/stat.h>
#include <linux/socket.h>
#include <linux/file.h>
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 1b64817d7de..f65b3de590a 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -86,8 +86,10 @@ static kmem_cache_t *skbuff_head_cache;
*/
void skb_over_panic(struct sk_buff *skb, int sz, void *here)
{
- printk(KERN_INFO "skput:over: %p:%d put:%d dev:%s",
- here, skb->len, sz, skb->dev ? skb->dev->name : "<NULL>");
+ printk(KERN_EMERG "skb_over_panic: text:%p len:%d put:%d head:%p "
+ "data:%p tail:%p end:%p dev:%s\n",
+ here, skb->len, sz, skb->head, skb->data, skb->tail, skb->end,
+ skb->dev ? skb->dev->name : "<NULL>");
BUG();
}
@@ -102,8 +104,10 @@ void skb_over_panic(struct sk_buff *skb, int sz, void *here)
void skb_under_panic(struct sk_buff *skb, int sz, void *here)
{
- printk(KERN_INFO "skput:under: %p:%d put:%d dev:%s",
- here, skb->len, sz, skb->dev ? skb->dev->name : "<NULL>");
+ printk(KERN_EMERG "skb_under_panic: text:%p len:%d put:%d head:%p "
+ "data:%p tail:%p end:%p dev:%s\n",
+ here, skb->len, sz, skb->head, skb->data, skb->tail, skb->end,
+ skb->dev ? skb->dev->name : "<NULL>");
BUG();
}
diff --git a/net/core/sock.c b/net/core/sock.c
index 4df4fa3c5de..96e00b08698 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -9,7 +9,7 @@
*
* Version: $Id: sock.c,v 1.117 2002/02/01 22:01:03 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Florian La Roche, <flla@stud.uni-sb.de>
* Alan Cox, <A.Cox@swansea.ac.uk>
@@ -97,7 +97,6 @@
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
@@ -617,10 +616,10 @@ lenout:
/**
* sk_alloc - All socket objects are allocated here
- * @family - protocol family
- * @priority - for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc)
- * @prot - struct proto associated with this new sock instance
- * @zero_it - if we should zero the newly allocated sock
+ * @family: protocol family
+ * @priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc)
+ * @prot: struct proto associated with this new sock instance
+ * @zero_it: if we should zero the newly allocated sock
*/
struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it)
{
@@ -636,7 +635,11 @@ struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it)
if (zero_it) {
memset(sk, 0, prot->obj_size);
sk->sk_family = family;
- sk->sk_prot = prot;
+ /*
+ * See comment in struct sock definition to understand
+ * why we need sk_prot_creator -acme
+ */
+ sk->sk_prot = sk->sk_prot_creator = prot;
sock_lock_init(sk);
}
@@ -655,7 +658,7 @@ struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it)
void sk_free(struct sock *sk)
{
struct sk_filter *filter;
- struct module *owner = sk->sk_prot->owner;
+ struct module *owner = sk->sk_prot_creator->owner;
if (sk->sk_destruct)
sk->sk_destruct(sk);
@@ -673,8 +676,8 @@ void sk_free(struct sock *sk)
__FUNCTION__, atomic_read(&sk->sk_omem_alloc));
security_sk_free(sk);
- if (sk->sk_prot->slab != NULL)
- kmem_cache_free(sk->sk_prot->slab, sk);
+ if (sk->sk_prot_creator->slab != NULL)
+ kmem_cache_free(sk->sk_prot_creator->slab, sk);
else
kfree(sk);
module_put(owner);
@@ -971,8 +974,8 @@ static void __release_sock(struct sock *sk)
/**
* sk_wait_data - wait for data to arrive at sk_receive_queue
- * sk - sock to wait on
- * timeo - for how long
+ * @sk: sock to wait on
+ * @timeo: for how long
*
* Now socket state including sk->sk_err is changed only under lock,
* hence we may omit checks after joining wait queue.
diff --git a/net/core/stream.c b/net/core/stream.c
index 1e27a57b5a9..ac9edfdf874 100644
--- a/net/core/stream.c
+++ b/net/core/stream.c
@@ -21,7 +21,7 @@
/**
* sk_stream_write_space - stream socket write_space callback.
- * sk - socket
+ * @sk: socket
*
* FIXME: write proper description
*/
@@ -43,8 +43,8 @@ EXPORT_SYMBOL(sk_stream_write_space);
/**
* sk_stream_wait_connect - Wait for a socket to get into the connected state
- * @sk - sock to wait on
- * @timeo_p - for how long to wait
+ * @sk: sock to wait on
+ * @timeo_p: for how long to wait
*
* Must be called with the socket locked.
*/
@@ -79,7 +79,7 @@ EXPORT_SYMBOL(sk_stream_wait_connect);
/**
* sk_stream_closing - Return 1 if we still have things to send in our buffers.
- * @sk - socket to verify
+ * @sk: socket to verify
*/
static inline int sk_stream_closing(struct sock *sk)
{
@@ -107,8 +107,8 @@ EXPORT_SYMBOL(sk_stream_wait_close);
/**
* sk_stream_wait_memory - Wait for more memory for a socket
- * @sk - socket to wait for memory
- * @timeo_p - for how long
+ * @sk: socket to wait for memory
+ * @timeo_p: for how long
*/
int sk_stream_wait_memory(struct sock *sk, long *timeo_p)
{
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index c2a0346f423..ee7bf46eb78 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 = {
#endif /* CONFIG_PROC_FS */
-static struct rtnetlink_link dnet_rtnetlink_table[RTM_MAX-RTM_BASE+1] =
+static struct rtnetlink_link dnet_rtnetlink_table[RTM_NR_MSGTYPES] =
{
- [4] = { .doit = dn_dev_rtm_newaddr, },
- [5] = { .doit = dn_dev_rtm_deladdr, },
- [6] = { .dumpit = dn_dev_dump_ifaddr, },
-
+ [RTM_NEWADDR - RTM_BASE] = { .doit = dn_dev_rtm_newaddr, },
+ [RTM_DELADDR - RTM_BASE] = { .doit = dn_dev_rtm_deladdr, },
+ [RTM_GETADDR - RTM_BASE] = { .dumpit = dn_dev_dump_ifaddr, },
#ifdef CONFIG_DECNET_ROUTER
- [8] = { .doit = dn_fib_rtm_newroute, },
- [9] = { .doit = dn_fib_rtm_delroute, },
- [10] = { .doit = dn_cache_getroute, .dumpit = dn_fib_dump, },
- [16] = { .doit = dn_fib_rtm_newrule, },
- [17] = { .doit = dn_fib_rtm_delrule, },
- [18] = { .dumpit = dn_fib_dump_rules, },
+ [RTM_NEWROUTE - RTM_BASE] = { .doit = dn_fib_rtm_newroute, },
+ [RTM_DELROUTE - RTM_BASE] = { .doit = dn_fib_rtm_delroute, },
+ [RTM_GETROUTE - RTM_BASE] = { .doit = dn_cache_getroute,
+ .dumpit = dn_fib_dump, },
+ [RTM_NEWRULE - RTM_BASE] = { .doit = dn_fib_rtm_newrule, },
+ [RTM_DELRULE - RTM_BASE] = { .doit = dn_fib_rtm_delrule, },
+ [RTM_GETRULE - RTM_BASE] = { .dumpit = dn_fib_dump_rules, },
#else
- [10] = { .doit = dn_cache_getroute, .dumpit = dn_cache_dump, },
+ [RTM_GETROUTE - RTM_BASE] = { .doit = dn_cache_getroute,
+ .dumpit = dn_cache_dump, },
#endif
};
diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c
index f86a6259fd1..284a9998e53 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)
static void dnrmg_receive_user_sk(struct sock *sk, int len)
{
struct sk_buff *skb;
+ unsigned int qlen = skb_queue_len(&sk->sk_receive_queue);
- while((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
+ for (; qlen && (skb = skb_dequeue(&sk->sk_receive_queue)); qlen--) {
dnrmg_receive_user_skb(skb);
kfree_skb(skb);
}
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 16c4234cbe1..6617ea47d36 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -7,7 +7,7 @@
*
* Version: @(#)eth.c 1.0.7 05/25/93
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Mark Evans, <evansmp@uhura.aston.ac.uk>
* Florian La Roche, <rzsfl@rz.uni-sb.de>
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index c34dab67e46..b3cb49ce5fa 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -7,7 +7,7 @@
*
* Version: $Id: af_inet.c,v 1.137 2002/02/01 22:01:03 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Florian La Roche, <flla@stud.uni-sb.de>
* Alan Cox, <A.Cox@swansea.ac.uk>
@@ -73,7 +73,6 @@
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/timer.h>
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index eea7ef01077..3cc96730c4e 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -9,7 +9,7 @@
* 2 of the License, or (at your option) any later version.
*
* Derived from the IP parts of dev.c 1.0.19
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Mark Evans, <evansmp@uhura.aston.ac.uk>
*
@@ -1107,17 +1107,18 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa)
}
}
-static struct rtnetlink_link inet_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = {
- [4] = { .doit = inet_rtm_newaddr, },
- [5] = { .doit = inet_rtm_deladdr, },
- [6] = { .dumpit = inet_dump_ifaddr, },
- [8] = { .doit = inet_rtm_newroute, },
- [9] = { .doit = inet_rtm_delroute, },
- [10] = { .doit = inet_rtm_getroute, .dumpit = inet_dump_fib, },
+static struct rtnetlink_link inet_rtnetlink_table[RTM_NR_MSGTYPES] = {
+ [RTM_NEWADDR - RTM_BASE] = { .doit = inet_rtm_newaddr, },
+ [RTM_DELADDR - RTM_BASE] = { .doit = inet_rtm_deladdr, },
+ [RTM_GETADDR - RTM_BASE] = { .dumpit = inet_dump_ifaddr, },
+ [RTM_NEWROUTE - RTM_BASE] = { .doit = inet_rtm_newroute, },
+ [RTM_DELROUTE - RTM_BASE] = { .doit = inet_rtm_delroute, },
+ [RTM_GETROUTE - RTM_BASE] = { .doit = inet_rtm_getroute,
+ .dumpit = inet_dump_fib, },
#ifdef CONFIG_IP_MULTIPLE_TABLES
- [16] = { .doit = inet_rtm_newrule, },
- [17] = { .doit = inet_rtm_delrule, },
- [18] = { .dumpit = inet_dump_rules, },
+ [RTM_NEWRULE - RTM_BASE] = { .doit = inet_rtm_newrule, },
+ [RTM_DELRULE - RTM_BASE] = { .doit = inet_rtm_delrule, },
+ [RTM_GETRULE - RTM_BASE] = { .dumpit = inet_dump_rules, },
#endif
};
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index a0d0833034b..4e47a2658c7 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -7,7 +7,7 @@
*
* Version: $Id: ip_input.c,v 1.55 2002/01/12 07:39:45 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Donald Becker, <becker@super.org>
* Alan Cox, <Alan.Cox@linux.org>
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 30ab7b6ab76..daebd93fd8a 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -7,7 +7,7 @@
*
* Version: $Id: ip_output.c,v 1.100 2002/02/01 22:01:03 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Donald Becker, <becker@super.org>
* Alan Cox, <Alan.Cox@linux.org>
@@ -111,6 +111,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb)
#ifdef CONFIG_NETFILTER_DEBUG
nf_debug_ip_loopback_xmit(newskb);
#endif
+ nf_reset(newskb);
netif_rx(newskb);
return 0;
}
@@ -195,6 +196,8 @@ static inline int ip_finish_output2(struct sk_buff *skb)
nf_debug_ip_finish_output2(skb);
#endif /*CONFIG_NETFILTER_DEBUG*/
+ nf_reset(skb);
+
if (hh) {
int hh_alen;
diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c
index 10b23e1bece..c3d2ca1a678 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,
multipath_comparekeys(&rt->fl, flp)) {
struct multipath_candidate* mpc =
(struct multipath_candidate*)
- kmalloc(size_mpc, GFP_KERNEL);
+ kmalloc(size_mpc, GFP_ATOMIC);
if (!mpc)
return;
@@ -244,7 +244,7 @@ static void wrandom_set_nhinfo(__u32 network,
if (!target_route) {
const size_t size_rt = sizeof(struct multipath_route);
target_route = (struct multipath_route *)
- kmalloc(size_rt, GFP_KERNEL);
+ kmalloc(size_rt, GFP_ATOMIC);
target_route->gw = nh->nh_gw;
target_route->oif = nh->nh_oif;
@@ -265,7 +265,7 @@ static void wrandom_set_nhinfo(__u32 network,
if (!target_dest) {
const size_t size_dst = sizeof(struct multipath_dest);
target_dest = (struct multipath_dest*)
- kmalloc(size_dst, GFP_KERNEL);
+ kmalloc(size_dst, GFP_ATOMIC);
target_dest->nh_info = nh;
target_dest->network = network;
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c
index 12b88cbb11d..dd86503aa78 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,
}
/* Look up to see if we're just after a \n. */
-static int find_nl_seq(u16 seq, const struct ip_ct_ftp_master *info, int dir)
+static int find_nl_seq(u32 seq, const struct ip_ct_ftp_master *info, int dir)
{
unsigned int i;
@@ -263,7 +263,7 @@ static int find_nl_seq(u16 seq, const struct ip_ct_ftp_master *info, int dir)
}
/* We don't update if it's older than what we have. */
-static void update_nl_seq(u16 nl_seq, struct ip_ct_ftp_master *info, int dir)
+static void update_nl_seq(u32 nl_seq, struct ip_ct_ftp_master *info, int dir)
{
unsigned int i, oldest = NUM_SEQ_TO_REMEMBER;
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index e800b16fc92..721ddbf522b 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] =
{
[TH_SYN] = 1,
[TH_SYN|TH_ACK] = 1,
+ [TH_SYN|TH_ACK|TH_PUSH] = 1,
[TH_RST] = 1,
[TH_RST|TH_ACK] = 1,
[TH_RST|TH_ACK|TH_PUSH] = 1,
@@ -818,6 +819,7 @@ static int tcp_error(struct sk_buff *skb,
*/
/* FIXME: Source route IP option packets --RR */
if (hooknum == NF_IP_PRE_ROUTING
+ && skb->ip_summed != CHECKSUM_UNNECESSARY
&& csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP,
skb->ip_summed == CHECKSUM_HW ? skb->csum
: 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 80a7bde2a57..46ca45f74d8 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,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
+ /* We've seen it coming out the other side: confirm it */
+ return ip_conntrack_confirm(pskb);
+}
+
+static unsigned int ip_conntrack_help(unsigned int hooknum,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo;
@@ -412,9 +422,7 @@ static unsigned int ip_confirm(unsigned int hooknum,
if (ret != NF_ACCEPT)
return ret;
}
-
- /* We've seen it coming out the other side: confirm it */
- return ip_conntrack_confirm(pskb);
+ return NF_ACCEPT;
}
static unsigned int ip_conntrack_defrag(unsigned int hooknum,
@@ -423,13 +431,6 @@ static unsigned int ip_conntrack_defrag(unsigned int hooknum,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
-#if !defined(CONFIG_IP_NF_NAT) && !defined(CONFIG_IP_NF_NAT_MODULE)
- /* Previously seen (loopback)? Ignore. Do this before
- fragment check. */
- if ((*pskb)->nfct)
- return NF_ACCEPT;
-#endif
-
/* Gather fragments. */
if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
*pskb = ip_ct_gather_frags(*pskb,
@@ -516,13 +517,30 @@ static struct nf_hook_ops ip_conntrack_local_out_ops = {
.priority = NF_IP_PRI_CONNTRACK,
};
+/* helpers */
+static struct nf_hook_ops ip_conntrack_helper_out_ops = {
+ .hook = ip_conntrack_help,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_IP_POST_ROUTING,
+ .priority = NF_IP_PRI_CONNTRACK_HELPER,
+};
+
+static struct nf_hook_ops ip_conntrack_helper_in_ops = {
+ .hook = ip_conntrack_help,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_IP_LOCAL_IN,
+ .priority = NF_IP_PRI_CONNTRACK_HELPER,
+};
+
/* Refragmenter; last chance. */
static struct nf_hook_ops ip_conntrack_out_ops = {
.hook = ip_refrag,
.owner = THIS_MODULE,
.pf = PF_INET,
.hooknum = NF_IP_POST_ROUTING,
- .priority = NF_IP_PRI_LAST,
+ .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
};
static struct nf_hook_ops ip_conntrack_local_in_ops = {
@@ -530,7 +548,7 @@ static struct nf_hook_ops ip_conntrack_local_in_ops = {
.owner = THIS_MODULE,
.pf = PF_INET,
.hooknum = NF_IP_LOCAL_IN,
- .priority = NF_IP_PRI_LAST-1,
+ .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
};
/* Sysctl support */
@@ -831,10 +849,20 @@ static int init_or_cleanup(int init)
printk("ip_conntrack: can't register local out hook.\n");
goto cleanup_inops;
}
+ ret = nf_register_hook(&ip_conntrack_helper_in_ops);
+ if (ret < 0) {
+ printk("ip_conntrack: can't register local in helper hook.\n");
+ goto cleanup_inandlocalops;
+ }
+ ret = nf_register_hook(&ip_conntrack_helper_out_ops);
+ if (ret < 0) {
+ printk("ip_conntrack: can't register postrouting helper hook.\n");
+ goto cleanup_helperinops;
+ }
ret = nf_register_hook(&ip_conntrack_out_ops);
if (ret < 0) {
printk("ip_conntrack: can't register post-routing hook.\n");
- goto cleanup_inandlocalops;
+ goto cleanup_helperoutops;
}
ret = nf_register_hook(&ip_conntrack_local_in_ops);
if (ret < 0) {
@@ -860,6 +888,10 @@ static int init_or_cleanup(int init)
nf_unregister_hook(&ip_conntrack_local_in_ops);
cleanup_inoutandlocalops:
nf_unregister_hook(&ip_conntrack_out_ops);
+ cleanup_helperoutops:
+ nf_unregister_hook(&ip_conntrack_helper_out_ops);
+ cleanup_helperinops:
+ nf_unregister_hook(&ip_conntrack_helper_in_ops);
cleanup_inandlocalops:
nf_unregister_hook(&ip_conntrack_local_out_ops);
cleanup_inops:
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index 162ceacfc29..9fc6f93af0d 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,
unsigned long statusbit;
enum ip_nat_manip_type mtype = HOOK2MANIP(hooknum);
- if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)
- && (hooknum == NF_IP_POST_ROUTING || hooknum == NF_IP_LOCAL_IN)) {
- DEBUGP("ip_nat_core: adjusting sequence number\n");
- /* future: put this in a l4-proto specific function,
- * and call this function here. */
- if (!ip_nat_seq_adjust(pskb, ct, ctinfo))
- return NF_DROP;
- }
-
if (mtype == IP_NAT_MANIP_SRC)
statusbit = IPS_SRC_NAT;
else
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index dec4a74212c..79f56f662b3 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,
return ret;
}
+static unsigned int
+ip_nat_adjust(unsigned int hooknum,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ struct ip_conntrack *ct;
+ enum ip_conntrack_info ctinfo;
+
+ ct = ip_conntrack_get(*pskb, &ctinfo);
+ if (ct && test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
+ DEBUGP("ip_nat_standalone: adjusting sequence number\n");
+ if (!ip_nat_seq_adjust(pskb, ct, ctinfo))
+ return NF_DROP;
+ }
+ return NF_ACCEPT;
+}
+
/* We must be after connection tracking and before packet filtering. */
/* Before packet filtering, change destination */
@@ -250,6 +269,15 @@ static struct nf_hook_ops ip_nat_out_ops = {
.priority = NF_IP_PRI_NAT_SRC,
};
+/* After conntrack, adjust sequence number */
+static struct nf_hook_ops ip_nat_adjust_out_ops = {
+ .hook = ip_nat_adjust,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_IP_POST_ROUTING,
+ .priority = NF_IP_PRI_NAT_SEQ_ADJUST,
+};
+
/* Before packet filtering, change destination */
static struct nf_hook_ops ip_nat_local_out_ops = {
.hook = ip_nat_local_fn,
@@ -268,6 +296,16 @@ static struct nf_hook_ops ip_nat_local_in_ops = {
.priority = NF_IP_PRI_NAT_SRC,
};
+/* After conntrack, adjust sequence number */
+static struct nf_hook_ops ip_nat_adjust_in_ops = {
+ .hook = ip_nat_adjust,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_IP_LOCAL_IN,
+ .priority = NF_IP_PRI_NAT_SEQ_ADJUST,
+};
+
+
static int init_or_cleanup(int init)
{
int ret = 0;
@@ -296,10 +334,20 @@ static int init_or_cleanup(int init)
printk("ip_nat_init: can't register out hook.\n");
goto cleanup_inops;
}
+ ret = nf_register_hook(&ip_nat_adjust_in_ops);
+ if (ret < 0) {
+ printk("ip_nat_init: can't register adjust in hook.\n");
+ goto cleanup_outops;
+ }
+ ret = nf_register_hook(&ip_nat_adjust_out_ops);
+ if (ret < 0) {
+ printk("ip_nat_init: can't register adjust out hook.\n");
+ goto cleanup_adjustin_ops;
+ }
ret = nf_register_hook(&ip_nat_local_out_ops);
if (ret < 0) {
printk("ip_nat_init: can't register local out hook.\n");
- goto cleanup_outops;
+ goto cleanup_adjustout_ops;;
}
ret = nf_register_hook(&ip_nat_local_in_ops);
if (ret < 0) {
@@ -312,6 +360,10 @@ static int init_or_cleanup(int init)
nf_unregister_hook(&ip_nat_local_in_ops);
cleanup_localoutops:
nf_unregister_hook(&ip_nat_local_out_ops);
+ cleanup_adjustout_ops:
+ nf_unregister_hook(&ip_nat_adjust_out_ops);
+ cleanup_adjustin_ops:
+ nf_unregister_hook(&ip_nat_adjust_in_ops);
cleanup_outops:
nf_unregister_hook(&ip_nat_out_ops);
cleanup_inops:
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 9e40dffc204..e5746b67441 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)
static void
ipq_rcv_sk(struct sock *sk, int len)
{
- do {
- struct sk_buff *skb;
+ struct sk_buff *skb;
+ unsigned int qlen;
- if (down_trylock(&ipqnl_sem))
- return;
+ down(&ipqnl_sem);
- while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
- ipq_rcv_skb(skb);
- kfree_skb(skb);
- }
+ for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) {
+ skb = skb_dequeue(&sk->sk_receive_queue);
+ ipq_rcv_skb(skb);
+ kfree_skb(skb);
+ }
- up(&ipqnl_sem);
-
- } while (ipqnl && ipqnl->sk_receive_queue.qlen);
+ up(&ipqnl_sem);
}
static int
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
index 01b4a3c814d..47449ba83eb 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[] = {
.hook = ipt_hook,
.pf = PF_INET,
.hooknum = NF_IP_PRE_ROUTING,
- .priority = NF_IP_PRI_RAW
+ .priority = NF_IP_PRI_RAW,
+ .owner = THIS_MODULE,
},
{
.hook = ipt_hook,
.pf = PF_INET,
.hooknum = NF_IP_LOCAL_OUT,
- .priority = NF_IP_PRI_RAW
+ .priority = NF_IP_PRI_RAW,
+ .owner = THIS_MODULE,
},
};
diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c
index 90a587cacaa..0db405a869f 100644
--- a/net/ipv4/protocol.c
+++ b/net/ipv4/protocol.c
@@ -7,7 +7,7 @@
*
* Version: $Id: protocol.c,v 1.14 2001/05/18 02:25:49 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
*
* Fixes:
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 93624a32eb9..5b1ec586bae 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -7,7 +7,7 @@
*
* Version: $Id: raw.c,v 1.64 2002/02/01 22:01:04 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
*
* Fixes:
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index bb90a0c3a91..a682d28e247 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -7,7 +7,7 @@
*
* Version: $Id: route.c,v 1.103 2002/01/12 07:44:09 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Alan Cox, <gw4pts@gw4pts.ampr.org>
* Linus Torvalds, <Linus.Torvalds@helsinki.fi>
@@ -397,7 +397,7 @@ static int rt_cpu_seq_show(struct seq_file *seq, void *v)
struct rt_cache_stat *st = v;
if (v == SEQ_START_TOKEN) {
- 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");
+ 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");
return 0;
}
@@ -2843,7 +2843,7 @@ ctl_table ipv4_route_table[] = {
.procname = "flush",
.data = &flush_delay,
.maxlen = sizeof(int),
- .mode = 0644,
+ .mode = 0200,
.proc_handler = &ipv4_sysctl_rtcache_flush,
.strategy = &ipv4_sysctl_rtcache_flush_strategy,
},
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 5cff56af785..a037bafcba3 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -7,7 +7,7 @@
*
* Version: $Id: tcp.c,v 1.216 2002/02/01 22:01:04 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Mark Evans, <evansmp@uhura.aston.ac.uk>
* Corey Minyard <wf-rch!minyard@relay.EU.net>
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c
index 313c1408da3..8faa8948f75 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)
static void tcpdiag_rcv(struct sock *sk, int len)
{
struct sk_buff *skb;
+ unsigned int qlen = skb_queue_len(&sk->sk_receive_queue);
- while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
+ while (qlen-- && (skb = skb_dequeue(&sk->sk_receive_queue))) {
tcpdiag_rcv_skb(skb);
kfree_skb(skb);
}
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 25049273590..79835a67a27 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -7,7 +7,7 @@
*
* Version: $Id: tcp_input.c,v 1.243 2002/02/01 22:01:04 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Mark Evans, <evansmp@uhura.aston.ac.uk>
* Corey Minyard <wf-rch!minyard@relay.EU.net>
@@ -3517,7 +3517,6 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq)
goto drop;
- th = skb->h.th;
__skb_pull(skb, th->doff*4);
TCP_ECN_accept_cwr(tp, skb);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 3ac6659869c..dad98e4a504 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)
int rover;
spin_lock(&tcp_portalloc_lock);
- rover = tcp_port_rover;
+ if (tcp_port_rover < low)
+ rover = low;
+ else
+ rover = tcp_port_rover;
do {
rover++;
- if (rover < low || rover > high)
+ if (rover > high)
rover = low;
head = &tcp_bhash[tcp_bhashfn(rover)];
spin_lock(&head->lock);
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index fd70509f0d5..eea1a17a9ac 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -7,7 +7,7 @@
*
* Version: $Id: tcp_minisocks.c,v 1.15 2002/02/01 22:01:04 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Mark Evans, <evansmp@uhura.aston.ac.uk>
* Corey Minyard <wf-rch!minyard@relay.EU.net>
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 13c14cb6dee..fa24e7ae1f4 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -7,7 +7,7 @@
*
* Version: $Id: tcp_output.c,v 1.146 2002/02/01 22:01:04 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Mark Evans, <evansmp@uhura.aston.ac.uk>
* Corey Minyard <wf-rch!minyard@relay.EU.net>
@@ -427,7 +427,7 @@ void tcp_push_one(struct sock *sk, unsigned cur_mss)
struct tcp_sock *tp = tcp_sk(sk);
struct sk_buff *skb = sk->sk_send_head;
- if (tcp_snd_test(tp, skb, cur_mss, TCP_NAGLE_PUSH)) {
+ if (tcp_snd_test(sk, skb, cur_mss, TCP_NAGLE_PUSH)) {
/* Send it out now. */
TCP_SKB_CB(skb)->when = tcp_time_stamp;
tcp_tso_set_push(skb);
@@ -440,9 +440,12 @@ void tcp_push_one(struct sock *sk, unsigned cur_mss)
}
}
-void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_std)
+void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb)
{
- if (skb->len <= mss_std) {
+ struct tcp_sock *tp = tcp_sk(sk);
+
+ if (skb->len <= tp->mss_cache_std ||
+ !(sk->sk_route_caps & NETIF_F_TSO)) {
/* Avoid the costly divide in the normal
* non-TSO case.
*/
@@ -451,10 +454,10 @@ void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_std)
} else {
unsigned int factor;
- factor = skb->len + (mss_std - 1);
- factor /= mss_std;
+ factor = skb->len + (tp->mss_cache_std - 1);
+ factor /= tp->mss_cache_std;
skb_shinfo(skb)->tso_segs = factor;
- skb_shinfo(skb)->tso_size = mss_std;
+ skb_shinfo(skb)->tso_size = tp->mss_cache_std;
}
}
@@ -525,8 +528,8 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len)
}
/* Fix up tso_factor for both original and new SKB. */
- tcp_set_skb_tso_segs(skb, tp->mss_cache_std);
- tcp_set_skb_tso_segs(buff, tp->mss_cache_std);
+ tcp_set_skb_tso_segs(sk, skb);
+ tcp_set_skb_tso_segs(sk, buff);
if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) {
tp->lost_out += tcp_skb_pcount(skb);
@@ -601,7 +604,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
* factor and mss.
*/
if (tcp_skb_pcount(skb) > 1)
- tcp_set_skb_tso_segs(skb, tcp_skb_mss(skb));
+ tcp_set_skb_tso_segs(sk, skb);
return 0;
}
@@ -752,7 +755,7 @@ int tcp_write_xmit(struct sock *sk, int nonagle)
mss_now = tcp_current_mss(sk, 1);
while ((skb = sk->sk_send_head) &&
- tcp_snd_test(tp, skb, mss_now,
+ tcp_snd_test(sk, skb, mss_now,
tcp_skb_is_last(sk, skb) ? nonagle :
TCP_NAGLE_PUSH)) {
if (skb->len > mss_now) {
@@ -1676,7 +1679,7 @@ int tcp_write_wakeup(struct sock *sk)
tp->mss_cache = tp->mss_cache_std;
}
} else if (!tcp_skb_pcount(skb))
- tcp_set_skb_tso_segs(skb, tp->mss_cache_std);
+ tcp_set_skb_tso_segs(sk, skb);
TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
TCP_SKB_CB(skb)->when = tcp_time_stamp;
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 85b279f1e93..799ebe061e2 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -7,7 +7,7 @@
*
* Version: $Id: tcp_timer.c,v 1.88 2002/02/01 22:01:04 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Mark Evans, <evansmp@uhura.aston.ac.uk>
* Corey Minyard <wf-rch!minyard@relay.EU.net>
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 8a213238f28..4a6952e3fee 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -7,7 +7,7 @@
*
* Version: $Id: udp.c,v 1.102 2002/02/01 22:01:04 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Arnt Gulbrandsen, <agulbra@nvg.unit.no>
* Alan Cox, <Alan.Cox@linux.org>
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 7fe2afd2e66..b2b60f3e9cd 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -8,7 +8,10 @@
*
*/
+#include <asm/bug.h>
+#include <linux/compiler.h>
#include <linux/config.h>
+#include <linux/inetdevice.h>
#include <net/xfrm.h>
#include <net/ip.h>
@@ -152,6 +155,8 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
x->u.rt.rt_dst = rt0->rt_dst;
x->u.rt.rt_gateway = rt->rt_gateway;
x->u.rt.rt_spec_dst = rt0->rt_spec_dst;
+ x->u.rt.idev = rt0->idev;
+ in_dev_hold(rt0->idev);
header_len -= x->u.dst.xfrm->props.header_len;
trailer_len -= x->u.dst.xfrm->props.trailer_len;
}
@@ -243,11 +248,48 @@ static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu)
path->ops->update_pmtu(path, mtu);
}
+static void xfrm4_dst_destroy(struct dst_entry *dst)
+{
+ struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
+
+ if (likely(xdst->u.rt.idev))
+ in_dev_put(xdst->u.rt.idev);
+ xfrm_dst_destroy(xdst);
+}
+
+static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
+ int unregister)
+{
+ struct xfrm_dst *xdst;
+
+ if (!unregister)
+ return;
+
+ xdst = (struct xfrm_dst *)dst;
+ if (xdst->u.rt.idev->dev == dev) {
+ struct in_device *loopback_idev = in_dev_get(&loopback_dev);
+ BUG_ON(!loopback_idev);
+
+ do {
+ in_dev_put(xdst->u.rt.idev);
+ xdst->u.rt.idev = loopback_idev;
+ in_dev_hold(loopback_idev);
+ xdst = (struct xfrm_dst *)xdst->u.dst.child;
+ } while (xdst->u.dst.xfrm);
+
+ __in_dev_put(loopback_idev);
+ }
+
+ xfrm_dst_ifdown(dst, dev);
+}
+
static struct dst_ops xfrm4_dst_ops = {
.family = AF_INET,
.protocol = __constant_htons(ETH_P_IP),
.gc = xfrm4_garbage_collect,
.update_pmtu = xfrm4_update_pmtu,
+ .destroy = xfrm4_dst_destroy,
+ .ifdown = xfrm4_dst_ifdown,
.gc_thresh = 1024,
.entry_size = sizeof(struct xfrm_dst),
};
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 7196ac2f2d1..7744a259269 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,
netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_PREFIX, GFP_ATOMIC);
}
-static struct rtnetlink_link inet6_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = {
+static struct rtnetlink_link inet6_rtnetlink_table[RTM_NR_MSGTYPES] = {
[RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, },
[RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, },
[RTM_DELADDR - RTM_BASE] = { .doit = inet6_rtm_deladdr, },
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 768b11703da..2b193e3df49 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -28,7 +28,6 @@
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/string.h>
@@ -88,6 +87,7 @@ int sysctl_ipv6_bindv6only;
#ifdef INET_REFCNT_DEBUG
atomic_t inet6_sock_nr;
+EXPORT_SYMBOL(inet6_sock_nr);
#endif
/* 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 6dda815c013..315bc1fbec3 100644
--- a/net/ipv6/exthdrs_core.c
+++ b/net/ipv6/exthdrs_core.c
@@ -41,8 +41,8 @@ int ipv6_ext_hdr(u8 nexthdr)
* when Linux implements ESP (and maybe AUTH) headers.
* --AK
*
- * This function parses (probably truncated) exthdr set "hdr"
- * of length "len". "nexthdrp" initially points to some place,
+ * This function parses (probably truncated) exthdr set "hdr".
+ * "nexthdrp" initially points to some place,
* where type of the first header can be found.
*
* It skips all well-known exthdrs, and returns pointer to the start
@@ -63,7 +63,7 @@ int ipv6_ext_hdr(u8 nexthdr)
* --ANK (980726)
*/
-int ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp, int len)
+int ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp)
{
u8 nexthdr = *nexthdrp;
@@ -71,13 +71,11 @@ int ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp, int len
struct ipv6_opt_hdr _hdr, *hp;
int hdrlen;
- if (len < (int)sizeof(struct ipv6_opt_hdr))
- return -1;
if (nexthdr == NEXTHDR_NONE)
return -1;
hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
if (hp == NULL)
- BUG();
+ return -1;
if (nexthdr == NEXTHDR_FRAGMENT) {
unsigned short _frag_off, *fp;
fp = skb_header_pointer(skb,
@@ -97,7 +95,6 @@ int ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp, int len
hdrlen = ipv6_optlen(hp);
nexthdr = hp->nexthdr;
- len -= hdrlen;
start += hdrlen;
}
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 87b9082ceab..8e0f569b883 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -135,7 +135,7 @@ static int is_ineligible(struct sk_buff *skb)
if (len < 0)
return 1;
- ptr = ipv6_skip_exthdr(skb, ptr, &nexthdr, len);
+ ptr = ipv6_skip_exthdr(skb, ptr, &nexthdr);
if (ptr < 0)
return 0;
if (nexthdr == IPPROTO_ICMPV6) {
@@ -514,7 +514,7 @@ static void icmpv6_notify(struct sk_buff *skb, int type, int code, u32 info)
nexthdr = ((struct ipv6hdr *)skb->data)->nexthdr;
if (ipv6_ext_hdr(nexthdr)) {
/* now skip over extension headers */
- inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr, skb->len - sizeof(struct ipv6hdr));
+ inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr);
if (inner_offset<0)
return;
} else {
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index c54830b8959..750943e2d34 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)
static void
ipq_rcv_sk(struct sock *sk, int len)
{
- do {
- struct sk_buff *skb;
+ struct sk_buff *skb;
+ unsigned int qlen;
- if (down_trylock(&ipqnl_sem))
- return;
+ down(&ipqnl_sem);
- while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
- ipq_rcv_skb(skb);
- kfree_skb(skb);
- }
+ for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) {
+ skb = skb_dequeue(&sk->sk_receive_queue);
+ ipq_rcv_skb(skb);
+ kfree_skb(skb);
+ }
- up(&ipqnl_sem);
-
- } while (ipqnl && ipqnl->sk_receive_queue.qlen);
+ up(&ipqnl_sem);
}
static int
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 1352c1d9bf4..617645bc5ed 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -455,11 +455,11 @@ csum_copy_err:
static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
struct raw6_sock *rp)
{
- struct inet_sock *inet = inet_sk(sk);
struct sk_buff *skb;
int err = 0;
int offset;
int len;
+ int total_len;
u32 tmp_csum;
u16 csum;
@@ -470,7 +470,8 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
goto out;
offset = rp->offset;
- if (offset >= inet->cork.length - 1) {
+ total_len = inet_sk(sk)->cork.length - (skb->nh.raw - skb->data);
+ if (offset >= total_len - 1) {
err = -EINVAL;
ip6_flush_pending_frames(sk);
goto out;
@@ -514,7 +515,7 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
tmp_csum = csum_ipv6_magic(&fl->fl6_src,
&fl->fl6_dst,
- inet->cork.length, fl->proto, tmp_csum);
+ total_len, fl->proto, tmp_csum);
if (tmp_csum == 0)
tmp_csum = -1;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 183802902c0..3bf8a0254f8 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2005,7 +2005,7 @@ ctl_table ipv6_route_table[] = {
.procname = "flush",
.data = &flush_delay,
.maxlen = sizeof(int),
- .mode = 0644,
+ .mode = 0200,
.proc_handler = &ipv6_sysctl_rtcache_flush
},
{
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 4760c85e19d..0f69e800a0a 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)
int rover;
spin_lock(&tcp_portalloc_lock);
- rover = tcp_port_rover;
+ if (tcp_port_rover < low)
+ rover = low;
+ else
+ rover = tcp_port_rover;
do { rover++;
- if ((rover < low) || (rover > high))
+ if (rover > high)
rover = low;
head = &tcp_bhash[tcp_bhashfn(rover)];
spin_lock(&head->lock);
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 8a4f37de4d2..4429b1a1fe5 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -11,7 +11,11 @@
*
*/
+#include <asm/bug.h>
+#include <linux/compiler.h>
#include <linux/config.h>
+#include <linux/netdevice.h>
+#include <net/addrconf.h>
#include <net/xfrm.h>
#include <net/ip.h>
#include <net/ipv6.h>
@@ -166,6 +170,8 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
memcpy(&x->u.rt6.rt6i_gateway, &rt0->rt6i_gateway, sizeof(x->u.rt6.rt6i_gateway));
x->u.rt6.rt6i_dst = rt0->rt6i_dst;
x->u.rt6.rt6i_src = rt0->rt6i_src;
+ x->u.rt6.rt6i_idev = rt0->rt6i_idev;
+ in6_dev_hold(rt0->rt6i_idev);
header_len -= x->u.dst.xfrm->props.header_len;
trailer_len -= x->u.dst.xfrm->props.trailer_len;
}
@@ -251,11 +257,48 @@ static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu)
path->ops->update_pmtu(path, mtu);
}
+static void xfrm6_dst_destroy(struct dst_entry *dst)
+{
+ struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
+
+ if (likely(xdst->u.rt6.rt6i_idev))
+ in6_dev_put(xdst->u.rt6.rt6i_idev);
+ xfrm_dst_destroy(xdst);
+}
+
+static void xfrm6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
+ int unregister)
+{
+ struct xfrm_dst *xdst;
+
+ if (!unregister)
+ return;
+
+ xdst = (struct xfrm_dst *)dst;
+ if (xdst->u.rt6.rt6i_idev->dev == dev) {
+ struct inet6_dev *loopback_idev = in6_dev_get(&loopback_dev);
+ BUG_ON(!loopback_idev);
+
+ do {
+ in6_dev_put(xdst->u.rt6.rt6i_idev);
+ xdst->u.rt6.rt6i_idev = loopback_idev;
+ in6_dev_hold(loopback_idev);
+ xdst = (struct xfrm_dst *)xdst->u.dst.child;
+ } while (xdst->u.dst.xfrm);
+
+ __in6_dev_put(loopback_idev);
+ }
+
+ xfrm_dst_ifdown(dst, dev);
+}
+
static struct dst_ops xfrm6_dst_ops = {
.family = AF_INET6,
.protocol = __constant_htons(ETH_P_IPV6),
.gc = xfrm6_garbage_collect,
.update_pmtu = xfrm6_update_pmtu,
+ .destroy = xfrm6_dst_destroy,
+ .ifdown = xfrm6_dst_ifdown,
.gc_thresh = 1024,
.entry_size = sizeof(struct xfrm_dst),
};
diff --git a/net/irda/irda_device.c b/net/irda/irda_device.c
index d6ccd3239dc..70543d89438 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)
}
EXPORT_SYMBOL(irda_device_unregister_dongle);
+#ifdef CONFIG_ISA_DMA_API
/*
* Function setup_dma (idev, buffer, count, mode)
*
@@ -492,3 +493,4 @@ void irda_setup_dma(int channel, dma_addr_t buffer, int count, int mode)
release_dma_lock(flags);
}
EXPORT_SYMBOL(irda_setup_dma);
+#endif
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 1d5905c90cd..733bf52cef3 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -21,7 +21,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/major.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/errno.h>
@@ -50,6 +49,8 @@
#include <linux/bitops.h>
#include <linux/mm.h>
#include <linux/types.h>
+#include <linux/audit.h>
+
#include <net/sock.h>
#include <net/scm.h>
@@ -374,7 +375,6 @@ static int netlink_release(struct socket *sock)
nlk->cb->done(nlk->cb);
netlink_destroy_callback(nlk->cb);
nlk->cb = NULL;
- __sock_put(sk);
}
spin_unlock(&nlk->cb_lock);
@@ -906,6 +906,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
NETLINK_CB(skb).groups = nlk->groups;
NETLINK_CB(skb).dst_pid = dst_pid;
NETLINK_CB(skb).dst_groups = dst_groups;
+ NETLINK_CB(skb).loginuid = audit_get_loginuid(current->audit_context);
memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
/* What can I do? Netlink is asynchronous, so that
@@ -1100,7 +1101,6 @@ static int netlink_dump(struct sock *sk)
spin_unlock(&nlk->cb_lock);
netlink_destroy_callback(cb);
- __sock_put(sk);
return 0;
}
@@ -1139,7 +1139,6 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
return -EBUSY;
}
nlk->cb = cb;
- sock_hold(sk);
spin_unlock(&nlk->cb_lock);
netlink_dump(sk);
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 64acea0adaa..0269616e75a 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -7,7 +7,7 @@
*
* Version: $Id: af_packet.c,v 1.61 2002/02/08 03:57:19 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Alan Cox, <gw4pts@gw4pts.ampr.org>
*
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 3d1d902dd1a..b0941186f86 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -185,7 +185,7 @@ config NET_SCH_GRED
depends on NET_SCHED
help
Say Y here if you want to use the Generic Random Early Detection
- (RED) packet scheduling algorithm for some of your network devices
+ (GRED) packet scheduling algorithm for some of your network devices
(see the top of <file:net/sched/sch_red.c> for details and
references about the algorithm).
@@ -506,3 +506,13 @@ config NET_CLS_POLICE
Say Y to support traffic policing (bandwidth limits). Needed for
ingress and egress rate limiting.
+config NET_ACT_SIMP
+ tristate "Simple action"
+ depends on NET_CLS_ACT
+ ---help---
+ You must have new iproute2 to use this feature.
+ This adds a very simple action for demonstration purposes
+ The idea is to give action authors a basic example to look at.
+ All this action will do is print on the console the configured
+ policy string followed by _ then packet count.
+
diff --git a/net/sched/Makefile b/net/sched/Makefile
index 431e55786ef..eb3fe583eba 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -6,13 +6,14 @@ obj-y := sch_generic.o
obj-$(CONFIG_NET_SCHED) += sch_api.o sch_fifo.o
obj-$(CONFIG_NET_CLS) += cls_api.o
-obj-$(CONFIG_NET_CLS_ACT) += act_api.o
+obj-$(CONFIG_NET_CLS_ACT) += act_api.o
obj-$(CONFIG_NET_ACT_POLICE) += police.o
obj-$(CONFIG_NET_CLS_POLICE) += police.o
-obj-$(CONFIG_NET_ACT_GACT) += gact.o
-obj-$(CONFIG_NET_ACT_MIRRED) += mirred.o
-obj-$(CONFIG_NET_ACT_IPT) += ipt.o
-obj-$(CONFIG_NET_ACT_PEDIT) += pedit.o
+obj-$(CONFIG_NET_ACT_GACT) += gact.o
+obj-$(CONFIG_NET_ACT_MIRRED) += mirred.o
+obj-$(CONFIG_NET_ACT_IPT) += ipt.o
+obj-$(CONFIG_NET_ACT_PEDIT) += pedit.o
+obj-$(CONFIG_NET_ACT_SIMP) += simple.o
obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o
obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o
obj-$(CONFIG_NET_SCH_HPFQ) += sch_hpfq.o
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 5e6cc371b39..cafcb084098 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -171,10 +171,10 @@ repeat:
skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
skb->tc_verd = CLR_TC_MUNGED(skb->tc_verd);
}
- if (ret != TC_ACT_PIPE)
- goto exec_done;
if (ret == TC_ACT_REPEAT)
goto repeat; /* we need a ttl - JHS */
+ if (ret != TC_ACT_PIPE)
+ goto exec_done;
}
act = a->next;
}
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index fdfc83af3d1..29d8b9a4d16 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -46,9 +46,11 @@
#include <net/act_api.h>
#include <net/pkt_cls.h>
+#define HTSIZE (PAGE_SIZE/sizeof(struct fw_filter *))
+
struct fw_head
{
- struct fw_filter *ht[256];
+ struct fw_filter *ht[HTSIZE];
};
struct fw_filter
@@ -69,7 +71,28 @@ static struct tcf_ext_map fw_ext_map = {
static __inline__ int fw_hash(u32 handle)
{
- return handle&0xFF;
+ if (HTSIZE == 4096)
+ return ((handle >> 24) & 0xFFF) ^
+ ((handle >> 12) & 0xFFF) ^
+ (handle & 0xFFF);
+ else if (HTSIZE == 2048)
+ return ((handle >> 22) & 0x7FF) ^
+ ((handle >> 11) & 0x7FF) ^
+ (handle & 0x7FF);
+ else if (HTSIZE == 1024)
+ return ((handle >> 20) & 0x3FF) ^
+ ((handle >> 10) & 0x3FF) ^
+ (handle & 0x3FF);
+ else if (HTSIZE == 512)
+ return (handle >> 27) ^
+ ((handle >> 18) & 0x1FF) ^
+ ((handle >> 9) & 0x1FF) ^
+ (handle & 0x1FF);
+ else if (HTSIZE == 256) {
+ u8 *t = (u8 *) &handle;
+ return t[0] ^ t[1] ^ t[2] ^ t[3];
+ } else
+ return handle & (HTSIZE - 1);
}
static int fw_classify(struct sk_buff *skb, struct tcf_proto *tp,
@@ -152,7 +175,7 @@ static void fw_destroy(struct tcf_proto *tp)
if (head == NULL)
return;
- for (h=0; h<256; h++) {
+ for (h=0; h<HTSIZE; h++) {
while ((f=head->ht[h]) != NULL) {
head->ht[h] = f->next;
fw_delete_filter(tp, f);
@@ -291,7 +314,7 @@ static void fw_walk(struct tcf_proto *tp, struct tcf_walker *arg)
if (arg->stop)
return;
- for (h = 0; h < 256; h++) {
+ for (h = 0; h < HTSIZE; h++) {
struct fw_filter *f;
for (f = head->ht[h]; f; f = f->next) {
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 4323a74eea3..07977f8f267 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1289,6 +1289,7 @@ static int __init pktsched_init(void)
subsys_initcall(pktsched_init);
+EXPORT_SYMBOL(qdisc_lookup);
EXPORT_SYMBOL(qdisc_get_rtab);
EXPORT_SYMBOL(qdisc_put_rtab);
EXPORT_SYMBOL(register_qdisc);
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 8c01e023f02..87e48a4e105 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -179,6 +179,7 @@ requeue:
netif_schedule(dev);
return 1;
}
+ BUG_ON((int) q->q.qlen < 0);
return q->q.qlen;
}
@@ -539,6 +540,10 @@ void dev_activate(struct net_device *dev)
write_unlock_bh(&qdisc_tree_lock);
}
+ if (!netif_carrier_ok(dev))
+ /* Delay activation until next carrier-on event */
+ return;
+
spin_lock_bh(&dev->queue_lock);
rcu_assign_pointer(dev->qdisc, dev->qdisc_sleeping);
if (dev->qdisc != &noqueue_qdisc) {
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index a85935e7d53..558cc087e60 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)
if (q->direct_queue.qlen < q->direct_qlen) {
__skb_queue_tail(&q->direct_queue, skb);
q->direct_pkts++;
+ } else {
+ kfree_skb(skb);
+ sch->qstats.drops++;
+ return NET_XMIT_DROP;
}
#ifdef CONFIG_NET_CLS_ACT
} else if (!cl) {
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 31c29deb139..e0c9fbe73b1 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,
}
/* Put skb in the private delayed queue. */
-static int delay_skb(struct Qdisc *sch, struct sk_buff *skb)
+static int netem_delay(struct Qdisc *sch, struct sk_buff *skb)
{
struct netem_sched_data *q = qdisc_priv(sch);
- struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb;
psched_tdiff_t td;
psched_time_t now;
PSCHED_GET_TIME(now);
td = tabledist(q->latency, q->jitter, &q->delay_cor, q->delay_dist);
- PSCHED_TADD2(now, td, cb->time_to_send);
/* Always queue at tail to keep packets in order */
if (likely(q->delayed.qlen < q->limit)) {
+ struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb;
+
+ PSCHED_TADD2(now, td, cb->time_to_send);
+
+ pr_debug("netem_delay: skb=%p now=%llu tosend=%llu\n", skb,
+ now, cb->time_to_send);
+
__skb_queue_tail(&q->delayed, skb);
- if (!timer_pending(&q->timer)) {
- q->timer.expires = jiffies + PSCHED_US2JIFFIE(td);
- add_timer(&q->timer);
- }
return NET_XMIT_SUCCESS;
}
+ pr_debug("netem_delay: queue over limit %d\n", q->limit);
+ sch->qstats.overlimits++;
kfree_skb(skb);
return NET_XMIT_DROP;
}
+/*
+ * Move a packet that is ready to send from the delay holding
+ * list to the underlying qdisc.
+ */
+static int netem_run(struct Qdisc *sch)
+{
+ struct netem_sched_data *q = qdisc_priv(sch);
+ struct sk_buff *skb;
+ psched_time_t now;
+
+ PSCHED_GET_TIME(now);
+
+ skb = skb_peek(&q->delayed);
+ if (skb) {
+ const struct netem_skb_cb *cb
+ = (const struct netem_skb_cb *)skb->cb;
+ long delay
+ = PSCHED_US2JIFFIE(PSCHED_TDIFF(cb->time_to_send, now));
+ pr_debug("netem_run: skb=%p delay=%ld\n", skb, delay);
+
+ /* if more time remaining? */
+ if (delay > 0) {
+ mod_timer(&q->timer, jiffies + delay);
+ return 1;
+ }
+
+ __skb_unlink(skb, &q->delayed);
+
+ if (q->qdisc->enqueue(skb, q->qdisc)) {
+ sch->q.qlen--;
+ sch->qstats.drops++;
+ }
+ }
+
+ return 0;
+}
+
static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
{
struct netem_sched_data *q = qdisc_priv(sch);
- struct sk_buff *skb2;
int ret;
- pr_debug("netem_enqueue skb=%p @%lu\n", skb, jiffies);
+ pr_debug("netem_enqueue skb=%p\n", skb);
/* Random packet drop 0 => none, ~0 => all */
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)
}
/* Random duplication */
- if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor)
- && (skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) {
- pr_debug("netem_enqueue: dup %p\n", skb2);
+ if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor)) {
+ struct sk_buff *skb2;
+
+ skb2 = skb_clone(skb, GFP_ATOMIC);
+ if (skb2 && netem_delay(sch, skb2) == NET_XMIT_SUCCESS) {
+ struct Qdisc *qp;
+
+ /* Since one packet can generate two packets in the
+ * queue, the parent's qlen accounting gets confused,
+ * so fix it.
+ */
+ qp = qdisc_lookup(sch->dev, TC_H_MAJ(sch->parent));
+ if (qp)
+ qp->q.qlen++;
- if (delay_skb(sch, skb2)) {
sch->q.qlen++;
sch->bstats.bytes += skb2->len;
sch->bstats.packets++;
@@ -202,7 +251,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
ret = q->qdisc->enqueue(skb, q->qdisc);
} else {
q->counter = 0;
- ret = delay_skb(sch, skb);
+ ret = netem_delay(sch, skb);
+ netem_run(sch);
}
if (likely(ret == NET_XMIT_SUCCESS)) {
@@ -212,6 +262,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
} else
sch->qstats.drops++;
+ pr_debug("netem: enqueue ret %d\n", ret);
return ret;
}
@@ -241,56 +292,35 @@ static unsigned int netem_drop(struct Qdisc* sch)
return len;
}
-/* Dequeue packet.
- * Move all packets that are ready to send from the delay holding
- * list to the underlying qdisc, then just call dequeue
- */
static struct sk_buff *netem_dequeue(struct Qdisc *sch)
{
struct netem_sched_data *q = qdisc_priv(sch);
struct sk_buff *skb;
+ int pending;
+
+ pending = netem_run(sch);
skb = q->qdisc->dequeue(q->qdisc);
- if (skb)
+ if (skb) {
+ pr_debug("netem_dequeue: return skb=%p\n", skb);
sch->q.qlen--;
+ sch->flags &= ~TCQ_F_THROTTLED;
+ }
+ else if (pending) {
+ pr_debug("netem_dequeue: throttling\n");
+ sch->flags |= TCQ_F_THROTTLED;
+ }
+
return skb;
}
static void netem_watchdog(unsigned long arg)
{
struct Qdisc *sch = (struct Qdisc *)arg;
- struct netem_sched_data *q = qdisc_priv(sch);
- struct net_device *dev = sch->dev;
- struct sk_buff *skb;
- psched_time_t now;
-
- pr_debug("netem_watchdog: fired @%lu\n", jiffies);
-
- spin_lock_bh(&dev->queue_lock);
- PSCHED_GET_TIME(now);
-
- while ((skb = skb_peek(&q->delayed)) != NULL) {
- const struct netem_skb_cb *cb
- = (const struct netem_skb_cb *)skb->cb;
- long delay
- = PSCHED_US2JIFFIE(PSCHED_TDIFF(cb->time_to_send, now));
- pr_debug("netem_watchdog: skb %p@%lu %ld\n",
- skb, jiffies, delay);
- /* if more time remaining? */
- if (delay > 0) {
- mod_timer(&q->timer, jiffies + delay);
- break;
- }
- __skb_unlink(skb, &q->delayed);
-
- if (q->qdisc->enqueue(skb, q->qdisc)) {
- sch->q.qlen--;
- sch->qstats.drops++;
- }
- }
- qdisc_run(dev);
- spin_unlock_bh(&dev->queue_lock);
+ pr_debug("netem_watchdog qlen=%d\n", sch->q.qlen);
+ sch->flags &= ~TCQ_F_THROTTLED;
+ netif_schedule(sch->dev);
}
static void netem_reset(struct Qdisc *sch)
@@ -301,6 +331,7 @@ static void netem_reset(struct Qdisc *sch)
skb_queue_purge(&q->delayed);
sch->q.qlen = 0;
+ sch->flags &= ~TCQ_F_THROTTLED;
del_timer_sync(&q->timer);
}
diff --git a/net/sched/simple.c b/net/sched/simple.c
new file mode 100644
index 00000000000..3ab4c675ab5
--- /dev/null
+++ b/net/sched/simple.c
@@ -0,0 +1,93 @@
+/*
+ * net/sched/simp.c Simple example of an action
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Authors: Jamal Hadi Salim (2005)
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/rtnetlink.h>
+#include <net/pkt_sched.h>
+
+#define TCA_ACT_SIMP 22
+
+/* XXX: Hide all these common elements under some macro
+ * probably
+*/
+#include <linux/tc_act/tc_defact.h>
+#include <net/tc_act/tc_defact.h>
+
+/* use generic hash table with 8 buckets */
+#define MY_TAB_SIZE 8
+#define MY_TAB_MASK (MY_TAB_SIZE - 1)
+static u32 idx_gen;
+static struct tcf_defact *tcf_simp_ht[MY_TAB_SIZE];
+static DEFINE_RWLOCK(simp_lock);
+
+/* override the defaults */
+#define tcf_st tcf_defact
+#define tc_st tc_defact
+#define tcf_t_lock simp_lock
+#define tcf_ht tcf_simp_ht
+
+#define CONFIG_NET_ACT_INIT 1
+#include <net/pkt_act.h>
+#include <net/act_generic.h>
+
+static int tcf_simp(struct sk_buff **pskb, struct tc_action *a)
+{
+ struct sk_buff *skb = *pskb;
+ struct tcf_defact *p = PRIV(a, defact);
+
+ spin_lock(&p->lock);
+ p->tm.lastuse = jiffies;
+ p->bstats.bytes += skb->len;
+ p->bstats.packets++;
+
+ /* print policy string followed by _ then packet count
+ * Example if this was the 3rd packet and the string was "hello"
+ * then it would look like "hello_3" (without quotes)
+ **/
+ printk("simple: %s_%d\n", (char *)p->defdata, p->bstats.packets);
+ spin_unlock(&p->lock);
+ return p->action;
+}
+
+static struct tc_action_ops act_simp_ops = {
+ .kind = "simple",
+ .type = TCA_ACT_SIMP,
+ .capab = TCA_CAP_NONE,
+ .owner = THIS_MODULE,
+ .act = tcf_simp,
+ tca_use_default_ops
+};
+
+MODULE_AUTHOR("Jamal Hadi Salim(2005)");
+MODULE_DESCRIPTION("Simple example action");
+MODULE_LICENSE("GPL");
+
+static int __init simp_init_module(void)
+{
+ int ret = tcf_register_action(&act_simp_ops);
+ if (!ret)
+ printk("Simple TC action Loaded\n");
+ return ret;
+}
+
+static void __exit simp_cleanup_module(void)
+{
+ tcf_unregister_action(&act_simp_ops);
+}
+
+module_init(simp_init_module);
+module_exit(simp_cleanup_module);
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 544b75077db..334f61773e6 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,
sp->autoclose * HZ;
/* Use SCTP specific send buffer space queues. */
+ ep->sndbuf_policy = sctp_sndbuf_policy;
sk->sk_write_space = sctp_write_space;
sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index e42c74e3ec1..c9d9ea06473 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)
/* Is this a wildcard address? */
static int sctp_v6_is_any(const union sctp_addr *addr)
{
- int type;
- type = ipv6_addr_type((struct in6_addr *)&addr->v6.sin6_addr);
- return IPV6_ADDR_ANY == type;
+ return ipv6_addr_any(&addr->v6.sin6_addr);
}
/* Should this be available for binding? */
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 9013f64f521..84b5b370b09 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -313,12 +313,12 @@ int sctp_packet_transmit(struct sctp_packet *packet)
sk = chunk->skb->sk;
/* Allocate the new skb. */
- nskb = dev_alloc_skb(packet->size);
+ nskb = alloc_skb(packet->size + LL_MAX_HEADER, GFP_ATOMIC);
if (!nskb)
goto nomem;
/* Make sure the outbound skb has enough header room reserved. */
- skb_reserve(nskb, packet->overhead);
+ skb_reserve(nskb, packet->overhead + LL_MAX_HEADER);
/* Set the owning socket so that we know where to get the
* destination IP address.
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index b9813cf3d91..2e1f9c3556f 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1043,6 +1043,9 @@ SCTP_STATIC __init int sctp_init(void)
sctp_max_retrans_path = 5;
sctp_max_retrans_init = 8;
+ /* Sendbuffer growth - do per-socket accounting */
+ sctp_sndbuf_policy = 0;
+
/* HB.interval - 30 seconds */
sctp_hb_interval = 30 * HZ;
@@ -1159,8 +1162,6 @@ SCTP_STATIC __init int sctp_init(void)
status = 0;
out:
return status;
-err_add_protocol:
- proto_unregister(&sctp_prot);
err_ctl_sock_init:
sctp_v6_exit();
err_v6_init:
@@ -1188,6 +1189,8 @@ err_bucket_cachep:
inet_del_protocol(&sctp_protocol, IPPROTO_SCTP);
inet_unregister_protosw(&sctp_seqpacket_protosw);
inet_unregister_protosw(&sctp_stream_protosw);
+err_add_protocol:
+ proto_unregister(&sctp_prot);
goto out;
}
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 1db12cc18cf..33ac8bf47b0 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(
struct sctp_chunk *retval;
__u8 flags = 0;
- /* Maybe set the T-bit if we have no association. */
+ /* Set the T-bit if we have no association (vtag will be
+ * reflected)
+ */
flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T;
retval = sctp_make_chunk(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags, 0);
@@ -732,7 +734,7 @@ struct sctp_chunk *sctp_make_shutdown_complete(
}
/* Create an ABORT. Note that we set the T bit if we have no
- * association.
+ * association, except when responding to an INIT (sctpimpguide 2.41).
*/
struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc,
const struct sctp_chunk *chunk,
@@ -741,8 +743,16 @@ struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc,
struct sctp_chunk *retval;
__u8 flags = 0;
- /* Maybe set the T-bit if we have no association. */
- flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T;
+ /* Set the T-bit if we have no association and 'chunk' is not
+ * an INIT (vtag will be reflected).
+ */
+ if (!asoc) {
+ if (chunk && chunk->chunk_hdr &&
+ chunk->chunk_hdr->type == SCTP_CID_INIT)
+ flags = 0;
+ else
+ flags = SCTP_CHUNK_FLAG_T;
+ }
retval = sctp_make_chunk(asoc, SCTP_CID_ABORT, flags, hint);
@@ -2744,7 +2754,6 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
hint = (nstreams + 1) * sizeof(__u32);
- /* Maybe set the T-bit if we have no association. */
retval = sctp_make_chunk(asoc, SCTP_CID_FWD_TSN, 0, hint);
if (!retval)
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 278c56a2d07..8e01b8f09ac 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,
* should stop the T2-shutdown timer and remove all knowledge of the
* association (and thus the association enters the CLOSED state).
*
- * Verification Tag: 8.5.1(C)
+ * Verification Tag: 8.5.1(C), sctpimpguide 2.41.
* C) Rules for packet carrying SHUTDOWN COMPLETE:
* ...
- * - The receiver of a SHUTDOWN COMPLETE shall accept the packet if the
- * Verification Tag field of the packet matches its own tag OR it is
- * set to its peer's tag and the T bit is set in the Chunk Flags.
- * Otherwise, the receiver MUST silently discard the packet and take
- * no further action. An endpoint MUST ignore the SHUTDOWN COMPLETE if
- * it is not in the SHUTDOWN-ACK-SENT state.
+ * - The receiver of a SHUTDOWN COMPLETE shall accept the packet
+ * if the Verification Tag field of the packet matches its own tag and
+ * the T bit is not set
+ * OR
+ * it is set to its peer's tag and the T bit is set in the Chunk
+ * Flags.
+ * Otherwise, the receiver MUST silently discard the packet
+ * and take no further action. An endpoint MUST ignore the
+ * SHUTDOWN COMPLETE if it is not in the SHUTDOWN-ACK-SENT state.
*
* Inputs
* (endpoint, asoc, chunk)
@@ -2858,16 +2861,16 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep,
/*
* Generate an ABORT in response to a packet.
*
- * Section: 8.4 Handle "Out of the blue" Packets
+ * Section: 8.4 Handle "Out of the blue" Packets, sctpimpguide 2.41
*
- * 8) The receiver should respond to the sender of the OOTB packet
- * with an ABORT. When sending the ABORT, the receiver of the
- * OOTB packet MUST fill in the Verification Tag field of the
- * outbound packet with the value found in the Verification Tag
- * field of the OOTB packet and set the T-bit in the Chunk Flags
- * to indicate that no TCB was found. After sending this ABORT,
- * the receiver of the OOTB packet shall discard the OOTB packet
- * and take no further action.
+ * 8) The receiver should respond to the sender of the OOTB packet with
+ * an ABORT. When sending the ABORT, the receiver of the OOTB packet
+ * MUST fill in the Verification Tag field of the outbound packet
+ * with the value found in the Verification Tag field of the OOTB
+ * packet and set the T-bit in the Chunk Flags to indicate that the
+ * Verification Tag is reflected. After sending this ABORT, the
+ * receiver of the OOTB packet shall discard the OOTB packet and take
+ * no further action.
*
* Verification Tag:
*
@@ -2895,6 +2898,10 @@ sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
return SCTP_DISPOSITION_NOMEM;
}
+ /* Reflect vtag if T-Bit is set */
+ if (sctp_test_T_bit(abort))
+ packet->vtag = ntohl(chunk->sctp_hdr->vtag);
+
/* Set the skb to the belonging sock for accounting. */
abort->skb->sk = ep->base.sk;
@@ -3026,22 +3033,24 @@ nomem:
}
/*
- * RFC 2960, 8.4 - Handle "Out of the blue" Packets
+ * RFC 2960, 8.4 - Handle "Out of the blue" Packets, sctpimpguide 2.41.
+ *
* 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should
* respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE.
* When sending the SHUTDOWN COMPLETE, the receiver of the OOTB
* packet must fill in the Verification Tag field of the outbound
* packet with the Verification Tag received in the SHUTDOWN ACK and
- * set the T-bit in the Chunk Flags to indicate that no TCB was
- * found. Otherwise,
+ * set the T-bit in the Chunk Flags to indicate that the Verification
+ * Tag is reflected.
*
* 8) The receiver should respond to the sender of the OOTB packet with
* an ABORT. When sending the ABORT, the receiver of the OOTB packet
* MUST fill in the Verification Tag field of the outbound packet
* with the value found in the Verification Tag field of the OOTB
- * packet and set the T-bit in the Chunk Flags to indicate that no
- * TCB was found. After sending this ABORT, the receiver of the OOTB
- * packet shall discard the OOTB packet and take no further action.
+ * packet and set the T-bit in the Chunk Flags to indicate that the
+ * Verification Tag is reflected. After sending this ABORT, the
+ * receiver of the OOTB packet shall discard the OOTB packet and take
+ * no further action.
*/
sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
@@ -3090,13 +3099,15 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
/*
* Handle an "Out of the blue" SHUTDOWN ACK.
*
- * Section: 8.4 5)
+ * Section: 8.4 5, sctpimpguide 2.41.
+ *
* 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should
- * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE.
- * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB packet
- * must fill in the Verification Tag field of the outbound packet with
- * the Verification Tag received in the SHUTDOWN ACK and set the
- * T-bit in the Chunk Flags to indicate that no TCB was found.
+ * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE.
+ * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB
+ * packet must fill in the Verification Tag field of the outbound
+ * packet with the Verification Tag received in the SHUTDOWN ACK and
+ * set the T-bit in the Chunk Flags to indicate that the Verification
+ * Tag is reflected.
*
* Inputs
* (endpoint, asoc, type, arg, commands)
@@ -3128,6 +3139,10 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
return SCTP_DISPOSITION_NOMEM;
}
+ /* Reflect vtag if T-Bit is set */
+ if (sctp_test_T_bit(shut))
+ packet->vtag = ntohl(chunk->sctp_hdr->vtag);
+
/* Set the skb to the belonging sock for accounting. */
shut->skb->sk = ep->base.sk;
@@ -3591,7 +3606,6 @@ sctp_disposition_t sctp_sf_discard_chunk(const struct sctp_endpoint *ep,
*
* 2) If the OOTB packet contains an ABORT chunk, the receiver MUST
* silently discard the OOTB packet and take no further action.
- * Otherwise,
*
* Verification Tag: No verification necessary
*
@@ -4961,6 +4975,11 @@ static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
sctp_ootb_pkt_free(packet);
return NULL;
}
+
+ /* Reflect vtag if T-Bit is set */
+ if (sctp_test_T_bit(abort))
+ packet->vtag = ntohl(chunk->sctp_hdr->vtag);
+
/* Add specified error causes, i.e., payload, to the
* end of the chunk.
*/
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index e8c21018257..0b338eca6dc 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -115,9 +115,17 @@ static inline int sctp_wspace(struct sctp_association *asoc)
struct sock *sk = asoc->base.sk;
int amt = 0;
- amt = sk->sk_sndbuf - asoc->sndbuf_used;
+ if (asoc->ep->sndbuf_policy) {
+ /* make sure that no association uses more than sk_sndbuf */
+ amt = sk->sk_sndbuf - asoc->sndbuf_used;
+ } else {
+ /* do socket level accounting */
+ amt = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
+ }
+
if (amt < 0)
amt = 0;
+
return amt;
}
@@ -138,12 +146,21 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk)
/* The sndbuf space is tracked per association. */
sctp_association_hold(asoc);
+ skb_set_owner_w(chunk->skb, sk);
+
chunk->skb->destructor = sctp_wfree;
/* Save the chunk pointer in skb for sctp_wfree to use later. */
*((struct sctp_chunk **)(chunk->skb->cb)) = chunk;
- asoc->sndbuf_used += SCTP_DATA_SNDSIZE(chunk);
- sk->sk_wmem_queued += SCTP_DATA_SNDSIZE(chunk);
+ asoc->sndbuf_used += SCTP_DATA_SNDSIZE(chunk) +
+ sizeof(struct sk_buff) +
+ sizeof(struct sctp_chunk);
+
+ sk->sk_wmem_queued += SCTP_DATA_SNDSIZE(chunk) +
+ sizeof(struct sk_buff) +
+ sizeof(struct sctp_chunk);
+
+ atomic_add(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc);
}
/* Verify that this is a valid address. */
@@ -3473,7 +3490,7 @@ static int sctp_getsockopt_associnfo(struct sock *sk, int len,
return -EINVAL;
/* Values correspoinding to the specific association */
- if (assocparams.sasoc_assoc_id != 0) {
+ if (asoc) {
assocparams.sasoc_asocmaxrxt = asoc->max_retrans;
assocparams.sasoc_peer_rwnd = asoc->peer.rwnd;
assocparams.sasoc_local_rwnd = asoc->a_rwnd;
@@ -4422,8 +4439,17 @@ static void sctp_wfree(struct sk_buff *skb)
chunk = *((struct sctp_chunk **)(skb->cb));
asoc = chunk->asoc;
sk = asoc->base.sk;
- asoc->sndbuf_used -= SCTP_DATA_SNDSIZE(chunk);
- sk->sk_wmem_queued -= SCTP_DATA_SNDSIZE(chunk);
+ asoc->sndbuf_used -= SCTP_DATA_SNDSIZE(chunk) +
+ sizeof(struct sk_buff) +
+ sizeof(struct sctp_chunk);
+
+ sk->sk_wmem_queued -= SCTP_DATA_SNDSIZE(chunk) +
+ sizeof(struct sk_buff) +
+ sizeof(struct sctp_chunk);
+
+ atomic_sub(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc);
+
+ sock_wfree(skb);
__sctp_write_space(asoc);
sctp_association_put(asoc);
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index 89fa20c73a5..7fc31849312 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -110,6 +110,14 @@ static ctl_table sctp_table[] = {
.proc_handler = &proc_dointvec
},
{
+ .ctl_name = NET_SCTP_SNDBUF_POLICY,
+ .procname = "sndbuf_policy",
+ .data = &sctp_sndbuf_policy,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec
+ },
+ {
.ctl_name = NET_SCTP_PATH_MAX_RETRANS,
.procname = "path_max_retrans",
.data = &sctp_max_retrans_path,
diff --git a/net/socket.c b/net/socket.c
index 2cd44990d8d..cec0cb38b9c 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -4,7 +4,7 @@
* Version: @(#)socket.c 1.1.93 18/02/95
*
* Authors: Orest Zborowski, <obz@Kodak.COM>
- * Ross Biro, <bir7@leland.Stanford.Edu>
+ * Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
*
* Fixes:
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 4484931018e..67b9f035ba8 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -46,9 +46,9 @@ xdr_decode_netobj(u32 *p, struct xdr_netobj *obj)
/**
* xdr_encode_opaque_fixed - Encode fixed length opaque data
- * @p - pointer to current position in XDR buffer.
- * @ptr - pointer to data to encode (or NULL)
- * @nbytes - size of data.
+ * @p: pointer to current position in XDR buffer.
+ * @ptr: pointer to data to encode (or NULL)
+ * @nbytes: size of data.
*
* Copy the array of data of length nbytes at ptr to the XDR buffer
* at position p, then align to the next 32-bit boundary by padding
@@ -76,9 +76,9 @@ EXPORT_SYMBOL(xdr_encode_opaque_fixed);
/**
* xdr_encode_opaque - Encode variable length opaque data
- * @p - pointer to current position in XDR buffer.
- * @ptr - pointer to data to encode (or NULL)
- * @nbytes - size of data.
+ * @p: pointer to current position in XDR buffer.
+ * @ptr: pointer to data to encode (or NULL)
+ * @nbytes: size of data.
*
* Returns the updated current XDR buffer position
*/
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index acc73fe6869..c478fc8db77 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -85,7 +85,6 @@
#include <linux/module.h>
#include <linux/config.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/errno.h>
diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c
index 956c17f6c54..d6844ac226f 100644
--- a/net/wanrouter/wanmain.c
+++ b/net/wanrouter/wanmain.c
@@ -48,8 +48,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h> /* support for loadable modules */
-#include <linux/slab.h> /* kmalloc(), kfree() */
-#include <linux/mm.h> /* verify_area(), etc. */
+#include <linux/slab.h> /* kmalloc(), kfree() */
+#include <linux/mm.h>
#include <linux/string.h> /* inline mem*, str* functions */
#include <asm/byteorder.h> /* htons(), etc. */
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 80828078733..55ed979db14 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)
return !xfrm_bundle_ok((struct xfrm_dst *)dst, NULL, AF_UNSPEC);
}
-static void xfrm_dst_destroy(struct dst_entry *dst)
+void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev)
{
- struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
-
- dst_release(xdst->route);
-
- if (!dst->xfrm)
- return;
- xfrm_state_put(dst->xfrm);
- dst->xfrm = NULL;
-}
-
-static void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
- int unregister)
-{
- if (!unregister)
- return;
-
while ((dst = dst->child) && dst->xfrm && dst->dev == dev) {
dst->dev = &loopback_dev;
dev_hold(&loopback_dev);
dev_put(dev);
}
}
+EXPORT_SYMBOL(xfrm_dst_ifdown);
static void xfrm_link_failure(struct sk_buff *skb)
{
@@ -1262,10 +1247,6 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
dst_ops->kmem_cachep = xfrm_dst_cache;
if (likely(dst_ops->check == NULL))
dst_ops->check = xfrm_dst_check;
- if (likely(dst_ops->destroy == NULL))
- dst_ops->destroy = xfrm_dst_destroy;
- if (likely(dst_ops->ifdown == NULL))
- dst_ops->ifdown = xfrm_dst_ifdown;
if (likely(dst_ops->negative_advice == NULL))
dst_ops->negative_advice = xfrm_negative_advice;
if (likely(dst_ops->link_failure == NULL))
@@ -1297,8 +1278,6 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo)
xfrm_policy_afinfo[afinfo->family] = NULL;
dst_ops->kmem_cachep = NULL;
dst_ops->check = NULL;
- dst_ops->destroy = NULL;
- dst_ops->ifdown = NULL;
dst_ops->negative_advice = NULL;
dst_ops->link_failure = NULL;
dst_ops->get_mss = NULL;
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 1db59f11f37..d11747c2a76 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,
x = best;
if (!x && !error && !acquire_in_progress) {
- x0 = afinfo->state_lookup(&tmpl->id.daddr, tmpl->id.spi, tmpl->id.proto);
- if (x0 != NULL) {
+ if (tmpl->id.spi &&
+ (x0 = afinfo->state_lookup(daddr, tmpl->id.spi,
+ tmpl->id.proto)) != NULL) {
xfrm_state_put(x0);
error = -EEXIST;
goto out;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 63661b0fd73..5ddda2c98af 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
return 0;
}
-static const int xfrm_msg_min[(XFRM_MSG_MAX + 1 - XFRM_MSG_BASE)] = {
- NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)), /* NEW SA */
- NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)), /* DEL SA */
- NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)), /* GET SA */
- NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)),/* NEW POLICY */
- NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)), /* DEL POLICY */
- NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)), /* GET POLICY */
- NLMSG_LENGTH(sizeof(struct xfrm_userspi_info)), /* ALLOC SPI */
- NLMSG_LENGTH(sizeof(struct xfrm_user_acquire)), /* ACQUIRE */
- NLMSG_LENGTH(sizeof(struct xfrm_user_expire)), /* EXPIRE */
- NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)),/* UPD POLICY */
- NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)), /* UPD SA */
- NLMSG_LENGTH(sizeof(struct xfrm_user_polexpire)), /* POLEXPIRE */
- NLMSG_LENGTH(sizeof(struct xfrm_usersa_flush)), /* FLUSH SA */
- NLMSG_LENGTH(0), /* FLUSH POLICY */
+#define XMSGSIZE(type) NLMSG_LENGTH(sizeof(struct type))
+
+static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = {
+ [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info),
+ [XFRM_MSG_DELSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id),
+ [XFRM_MSG_GETSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id),
+ [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info),
+ [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id),
+ [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id),
+ [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userspi_info),
+ [XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_acquire),
+ [XFRM_MSG_EXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_expire),
+ [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info),
+ [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info),
+ [XFRM_MSG_POLEXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_polexpire),
+ [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush),
+ [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = NLMSG_LENGTH(0),
};
+#undef XMSGSIZE
+
static struct xfrm_link {
int (*doit)(struct sk_buff *, struct nlmsghdr *, void **);
int (*dump)(struct sk_buff *, struct netlink_callback *);
-} xfrm_dispatch[] = {
- { .doit = xfrm_add_sa, },
- { .doit = xfrm_del_sa, },
- {
- .doit = xfrm_get_sa,
- .dump = xfrm_dump_sa,
- },
- { .doit = xfrm_add_policy },
- { .doit = xfrm_get_policy },
- {
- .doit = xfrm_get_policy,
- .dump = xfrm_dump_policy,
- },
- { .doit = xfrm_alloc_userspi },
- {},
- {},
- { .doit = xfrm_add_policy },
- { .doit = xfrm_add_sa, },
- {},
- { .doit = xfrm_flush_sa },
- { .doit = xfrm_flush_policy },
+} xfrm_dispatch[XFRM_NR_MSGTYPES] = {
+ [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa },
+ [XFRM_MSG_DELSA - XFRM_MSG_BASE] = { .doit = xfrm_del_sa },
+ [XFRM_MSG_GETSA - XFRM_MSG_BASE] = { .doit = xfrm_get_sa,
+ .dump = xfrm_dump_sa },
+ [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy },
+ [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy },
+ [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy,
+ .dump = xfrm_dump_policy },
+ [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi },
+ [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy },
+ [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa },
+ [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = { .doit = xfrm_flush_sa },
+ [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_flush_policy },
};
static 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
return -1;
}
- if ((type == 2 || type == 5) && (nlh->nlmsg_flags & NLM_F_DUMP)) {
+ if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) ||
+ type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) &&
+ (nlh->nlmsg_flags & NLM_F_DUMP)) {
u32 rlen;
if (link->dump == NULL)
@@ -1009,18 +1008,26 @@ static int xfrm_user_rcv_skb(struct sk_buff *skb)
static void xfrm_netlink_rcv(struct sock *sk, int len)
{
+ unsigned int qlen = skb_queue_len(&sk->sk_receive_queue);
+
do {
struct sk_buff *skb;
down(&xfrm_cfg_sem);
- while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
+ if (qlen > skb_queue_len(&sk->sk_receive_queue))
+ qlen = skb_queue_len(&sk->sk_receive_queue);
+
+ for (; qlen; qlen--) {
+ skb = skb_dequeue(&sk->sk_receive_queue);
if (xfrm_user_rcv_skb(skb)) {
if (skb->len)
skb_queue_head(&sk->sk_receive_queue,
skb);
- else
+ else {
kfree_skb(skb);
+ qlen--;
+ }
break;
}
kfree_skb(skb);
@@ -1028,7 +1035,7 @@ static void xfrm_netlink_rcv(struct sock *sk, int len)
up(&xfrm_cfg_sem);
- } while (xfrm_nl && xfrm_nl->sk_receive_queue.qlen);
+ } while (qlen);
}
static int build_expire(struct sk_buff *skb, struct xfrm_state *x, int hard)