hi all. i have noticed that in list_for_each_entry_rcu the checks (!ptype->dev || ptype->dev == skb->dev) are made on the current packet but the function (delived_skb) is called on the previous one. i can't understand why this make sense.. anyone can explain me? Moreover i created a patch that removes pt_prev and uses only ptype and all seems to work fine.. against test8 --- linux/net/core/dev.old.c 2003-11-22 15:18:26.000000000 +0100 +++ linux/net/core/dev.c 2003-11-23 13:24:58.626540048 +0100 @@ -1530,7 +1530,7 @@ int netif_receive_skb(struct sk_buff *skb) { - struct packet_type *ptype, *pt_prev; + struct packet_type *ptype; int ret = NET_RX_DROP; unsigned short type = skb->protocol; @@ -1550,39 +1550,28 @@ skb->h.raw = skb->nh.raw = skb->data; - pt_prev = NULL; rcu_read_lock(); list_for_each_entry_rcu(ptype, &ptype_all, list) { if (!ptype->dev || ptype->dev == skb->dev) { - if (pt_prev) - ret = deliver_skb(skb, pt_prev, 0); - pt_prev = ptype; + if (ptype) + ret = deliver_skb(skb, ptype, 0); } } handle_diverter(skb); - if (__handle_bridge(skb, &pt_prev, &ret)) + if (__handle_bridge(skb, &ptype, &ret)) goto out; list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type)&15], list) { if (ptype->type == type && (!ptype->dev || ptype->dev == skb->dev)) { - if (pt_prev) - ret = deliver_skb(skb, pt_prev, 0); - pt_prev = ptype; + if (ptype) + ret = deliver_skb(skb, ptype, 0); } } - - if (pt_prev) { - ret = pt_prev->func(skb, skb->dev, pt_prev); - } else { - kfree_skb(skb); - /* Jamal, now you will not able to escape explaining - * me how you were going to use this. :-) - */ - ret = NET_RX_DROP; - } + + ret = NET_RX_DROP; out: rcu_read_unlock(); -- Michele 'mydecay' Marchetto S.P.I.N.E. Group - www.spine-group.org - : send the line "unsubscribe linux-net" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html