-diff -Nurb linux-2.6.22-524/net/core/dev.c linux-2.6.22-525/net/core/dev.c
---- linux-2.6.22-524/net/core/dev.c 2008-07-21 16:44:33.000000000 -0400
-+++ linux-2.6.22-525/net/core/dev.c 2008-07-27 22:02:10.000000000 -0400
-@@ -97,6 +97,8 @@
+Index: linux-2.6.27.y/include/linux/netdevice.h
+===================================================================
+--- linux-2.6.27.y.orig/include/linux/netdevice.h
++++ linux-2.6.27.y/include/linux/netdevice.h
+@@ -857,6 +857,7 @@ static inline void netif_napi_del(struct
+ struct packet_type {
+ __be16 type; /* This is really htons(ether_type). */
+ struct net_device *dev; /* NULL is wildcarded here */
++ unsigned char sknid_elevator;
+ int (*func) (struct sk_buff *,
+ struct net_device *,
+ struct packet_type *,
+Index: linux-2.6.27.y/net/core/dev.c
+===================================================================
+--- linux-2.6.27.y.orig/net/core/dev.c
++++ linux-2.6.27.y/net/core/dev.c
+@@ -99,6 +99,8 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
#include <linux/if_bridge.h>
+ #include <linux/if_macvlan.h>
#include <net/dst.h>
- #include <net/pkt_sched.h>
-@@ -1131,7 +1133,7 @@
+@@ -1318,7 +1320,7 @@ static void dev_queue_xmit_nit(struct sk
if ((ptype->dev == dev || !ptype->dev) &&
(ptype->af_packet_priv == NULL ||
(struct sock *)ptype->af_packet_priv != skb->sk)) {
if (!skb2)
break;
-@@ -1803,6 +1805,7 @@
- * the ingress scheduler, you just cant add policies on ingress.
- *
- */
-+
- static int ing_filter(struct sk_buff *skb)
- {
- struct Qdisc *q;
-@@ -1832,13 +1835,21 @@
+@@ -2170,6 +2172,10 @@ void netif_nit_deliver(struct sk_buff *s
+ rcu_read_unlock();
}
- #endif
+/* The code already makes the assumption that packet handlers run
+ * sequentially on the same CPU. -Sapan */
+DEFINE_PER_CPU(int, sknid_elevator) = 0;
+
- int netif_receive_skb(struct sk_buff *skb)
- {
- struct packet_type *ptype, *pt_prev;
+ /**
+ * netif_receive_skb - process receive buffer from network
+ * @skb: buffer to process
+@@ -2191,8 +2197,11 @@ int netif_receive_skb(struct sk_buff *sk
struct net_device *orig_dev;
+ struct net_device *null_or_orig;
int ret = NET_RX_DROP;
-+ int *cur_elevator=&__get_cpu_var(sknid_elevator);
-+ struct sk_buff *skb2;
++ int *cur_elevator = &__get_cpu_var(sknid_elevator);
__be16 type;
-+ *cur_elevator = 0;
++ *cur_elevator = 0;
+
- /* if we've gotten here through NAPI, check netpoll */
- if (skb->dev->poll && netpoll_rx(skb))
- return NET_RX_DROP;
-@@ -1871,10 +1882,12 @@
- }
- #endif
+ if (skb->vlan_tci && vlan_hwaccel_do_receive(skb))
+ return NET_RX_SUCCESS;
-+ skb2 = skb_clone(skb, GFP_ATOMIC);
- list_for_each_entry_rcu(ptype, &ptype_all, list) {
- if (!ptype->dev || ptype->dev == skb->dev) {
-- if (pt_prev)
-+ if (pt_prev) {
- ret = deliver_skb(skb, pt_prev, orig_dev);
-+ }
- pt_prev = ptype;
- }
- }
-@@ -1891,6 +1904,7 @@
-
- if (ret == TC_ACT_SHOT || (ret == TC_ACT_STOLEN)) {
- kfree_skb(skb);
-+ kfree_skb(skb2);
- goto out;
+@@ -2272,7 +2281,27 @@ ncls:
}
-@@ -1899,8 +1913,17 @@
- #endif
-
- skb = handle_bridge(skb, &pt_prev, &ret, orig_dev);
-- if (!skb)
-+ if (!skb) {
-+ kfree_skb(skb2);
- goto out;
-+ }
-+
-+ /* We don't want the packet handlers to throw the packet away
-+ * if we want the taps to treat it again - Sapan */
-+ if (!skb2) {
-+ *cur_elevator = 0;
-+ }
-+
-
- type = skb->protocol;
- list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type)&15], list) {
-@@ -1914,6 +1937,7 @@
-
if (pt_prev) {
- ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
-+
- } else {
- kfree_skb(skb);
- /* Jamal, now you will not able to escape explaining
-@@ -1922,6 +1946,29 @@
- ret = NET_RX_DROP;
- }
-
-+ if ((*cur_elevator)>0) {
-+ skb2->skb_tag = *cur_elevator;
-+ list_for_each_entry_rcu(ptype, &ptype_all, list) {
-+ if ((!ptype->dev || ptype->dev == skb2->dev) && (ptype->sknid_elevator)) {
-+ ret = deliver_skb(skb2, ptype, orig_dev);
-+ }
++ /* At this point, cur_elevator may be -2 or a positive value, in
++ * case a previous protocol handler marked it */
++ if (*cur_elevator) {
++ atomic_inc(&skb->users);
+ }
-+ type = skb2->protocol;
-+ list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type)&15], list) {
-+ if (ptype->type == type &&
-+ (!ptype->dev || ptype->dev == skb2->dev) && (ptype->sknid_elevator)) {
-+ ret = deliver_skb(skb2, ptype, orig_dev);
++
+ ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
++
++ if ((*cur_elevator)>0) {
++ skb->skb_tag = *cur_elevator;
++ list_for_each_entry_rcu(ptype, &ptype_all, list) {
++ if ((!ptype->dev || ptype->dev == skb->dev) && (ptype->sknid_elevator)) {
++ ret = deliver_skb(skb, ptype, orig_dev);
++ }
+ }
+ }
-+ }
+
-+ if (skb2) {
-+ /* We have a packet */
-+ kfree_skb(skb2);
-+ }
-+
-+ *cur_elevator=0;
-+
- out:
- rcu_read_unlock();
- return ret;
-@@ -3780,6 +3827,7 @@
++ if (*cur_elevator) {
++ /* We have a packet */
++ kfree_skb(skb);
++ }
+ } else {
+ kfree_skb(skb);
+ /* Jamal, now you will not able to escape explaining
+@@ -4895,6 +4924,7 @@ EXPORT_SYMBOL(unregister_netdevice_notif
EXPORT_SYMBOL(net_enable_timestamp);
EXPORT_SYMBOL(net_disable_timestamp);
EXPORT_SYMBOL(dev_get_flags);
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
EXPORT_SYMBOL(br_handle_frame_hook);
-diff -Nurb linux-2.6.22-524/net/packet/af_packet.c linux-2.6.22-525/net/packet/af_packet.c
---- linux-2.6.22-524/net/packet/af_packet.c 2007-07-08 19:32:17.000000000 -0400
-+++ linux-2.6.22-525/net/packet/af_packet.c 2008-07-27 22:02:22.000000000 -0400
-@@ -78,6 +78,7 @@
+Index: linux-2.6.27.y/net/packet/af_packet.c
+===================================================================
+--- linux-2.6.27.y.orig/net/packet/af_packet.c
++++ linux-2.6.27.y/net/packet/af_packet.c
+@@ -77,6 +77,7 @@
#include <linux/poll.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/vs_network.h>
+ #include <linux/mutex.h>
#ifdef CONFIG_INET
- #include <net/inet_common.h>
-@@ -246,10 +247,53 @@
+@@ -278,10 +279,53 @@ static const struct proto_ops packet_ops
static const struct proto_ops packet_ops_spkt;
/*
* When we registered the protocol we saved the socket in the data
-@@ -269,6 +313,16 @@
+@@ -301,6 +345,16 @@ static int packet_rcv_spkt(struct sk_buf
* so that this procedure is noop.
*/
if (skb->pkt_type == PACKET_LOOPBACK)
goto out;
-@@ -324,6 +378,9 @@
+@@ -359,6 +413,9 @@ static int packet_sendmsg_spkt(struct ki
__be16 proto=0;
int err;
/*
* Get and verify the address.
*/
-@@ -416,11 +473,16 @@
+@@ -451,11 +508,16 @@ out_unlock:
return err;
}
rcu_read_lock_bh();
filter = rcu_dereference(sk->sk_filter);
if (filter != NULL)
-@@ -711,6 +773,9 @@
+@@ -775,6 +837,9 @@ static int packet_sendmsg(struct kiocb *
unsigned char *addr;
int ifindex, err, reserve = 0;
/*
* Get and verify the address.
*/
-@@ -880,6 +945,7 @@
+@@ -941,6 +1006,7 @@ static int packet_do_bind(struct sock *s
po->num = protocol;
po->prot_hook.type = protocol;
po->prot_hook.dev = dev;
po->ifindex = dev ? dev->ifindex : 0;
-@@ -984,8 +1050,9 @@
+@@ -1039,8 +1105,9 @@ static int packet_create(struct net *net
__be16 proto = (__force __be16)protocol; /* weird, but documented */
int err;
if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW &&
sock->type != SOCK_PACKET)
return -ESOCKTNOSUPPORT;
-@@ -1016,6 +1083,7 @@
-
+@@ -1072,6 +1139,7 @@ static int packet_create(struct net *net
spin_lock_init(&po->bind_lock);
+ mutex_init(&po->pg_vec_lock);
po->prot_hook.func = packet_rcv;
-+ po->prot_hook.sknid_elevator = 1;
++ po->prot_hook.sknid_elevator = 1;
if (sock->type == SOCK_PACKET)
po->prot_hook.func = packet_rcv_spkt;