int netif_receive_skb(struct sk_buff *skb)
{
//首先对VLAN报文进行处理
if (vlan_rx_hook && vlan_rx_hook(&skb, skb->dev))
return NET_RX_SUCCESS;
//遍历ptype_all链表,paket_type.type 为 ETH_P_ALL
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, orig_dev);
pt_prev = ptype;
}
}
//网桥处理,有3种可能
// 1. skb为单播,进入网桥设备,最终发送时将skb->dev由网桥设备brdev,跟换为实际的dev。
// 2.再次进入netif_receive_skb,进行协议栈的处理
// 3.丢弃报文
if (handle_bridge(&skb, &pt_prev, &ret, orig_dev)) {
goto out;
}
type = skb->protocol;
//根据协议栈类型,遍历注册的协议栈处理函数。packet_type->func()
//转而进入L3 处理,如:ip_rcv() arp_rcv()等
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, orig_dev);
pt_prev = ptype;
}
}
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
* me how you were going to use this. :-)
*/
ret = NET_RX_DROP;
}
out:
rcu_read_unlock();
return ret;