+diff -Nurb linux-2.6.22-510/net/core/dev.c linux-2.6.22-520/net/core/dev.c
+--- linux-2.6.22-510/net/core/dev.c 2008-06-06 17:07:48.000000000 -0400
++++ linux-2.6.22-520/net/core/dev.c 2008-06-06 17:07:56.000000000 -0400
+@@ -1803,6 +1803,7 @@
+ * the ingress scheduler, you just cant add policies on ingress.
+ *
+ */
++
+ static int ing_filter(struct sk_buff *skb)
+ {
+ struct Qdisc *q;
+@@ -1832,13 +1833,20 @@
+ }
+ #endif
+
++/* The code already makes the assumption that packet handlers run
++ * sequentially on the same CPU. -Sapan */
++DEFINE_PER_CPU(int, sknid_elevator);
++
+ int netif_receive_skb(struct sk_buff *skb)
+ {
+ struct packet_type *ptype, *pt_prev;
+ struct net_device *orig_dev;
+ int ret = NET_RX_DROP;
++ int *cur_elevator=&__get_cpu_var(sknid_elevator);
+ __be16 type;
+
++ *cur_elevator = 0;
++
+ /* if we've gotten here through NAPI, check netpoll */
+ if (skb->dev->poll && netpoll_rx(skb))
+ return NET_RX_DROP;
+@@ -1873,8 +1881,9 @@
+
+ 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;
+ }
+ }
+@@ -1912,8 +1921,22 @@
+ }
+ }
+
++ /* We don't want the packet handlers to throw the packet away
++ * if we want the taps to treat it again - Sapan */
++ if (*cur_elevator) {
++ atomic_inc(&skb->users);
++ }
++
+ if (pt_prev) {
+ 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) {
++ ret = deliver_skb(skb, ptype, orig_dev);
++ }
++ }
++ }
+ } else {
+ kfree_skb(skb);
+ /* Jamal, now you will not able to escape explaining
+@@ -1922,6 +1945,13 @@
+ ret = NET_RX_DROP;
+ }
+
++ if (*cur_elevator) {
++ /* We have a packet */
++ kfree_skb(skb);
++ }
++
++ *cur_elevator=0;
++
+ out:
+ rcu_read_unlock();
+ return ret;
+@@ -3780,6 +3810,7 @@
+ EXPORT_SYMBOL(net_enable_timestamp);
+ EXPORT_SYMBOL(net_disable_timestamp);
+ EXPORT_SYMBOL(dev_get_flags);
++EXPORT_PER_CPU_SYMBOL(sknid_elevator);
+
+ #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
+ EXPORT_SYMBOL(br_handle_frame_hook);