网络安全 频道

Linux系统内核接收以太帧的处理程序

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;

}

}

......

// 再查指定协议的HASH链表

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;

}

}

......

// 该函数就是调用个协议的接收函数处理该skb包,进入第三层网络层处理

static __inline__ int deliver_skb(struct sk_buff *skb,

struct packet_type *pt_prev,

struct net_device *orig_dev)

{

atomic_inc(&skb->users);

return pt_prev->func(skb, skb->dev, pt_prev, orig_dev);

}

6. 结论

通过链表挂接方式,Linux内核可以很容易的添加各种协议的接收处理函数。

数据流程:

网卡驱动--->netif_rx()--->netif_receive_skb()->deliver_skb()->packet_type.fun

0
相关文章