pt->next=ptype_all; ptype_all=pt; } else { hash=ntohs(pt->type)&15; pt->next = ptype_base[hash]; ptype_base[hash] = pt; } br_write_unlock_bh(BR_NETPROTO_LOCK); } 此函数判断协议类型,然后加到ptype_base或者ptype_all中. void dev_remove_pack(struct packet_type *pt) { str...
ptype_base和ptype_all理解,netid_receive_skb()函数注解 在数据包接收过程的那篇笔记中可以知道,在数据包的处理函数netif_receive_skb中,会先看ptype_all中是否有注册的协议,如果有,则调用相应的处理函数,然后再到 ptype_base中,找到合适的协议,将skb发送到相关协议的处理函数.比如ip协议(ip_rcv)或者arp(arp...
所以在linux中使用了skb共享的计数,就是用skb->users计数来计算共享的地方。 许多人理解了ptype_all和ptype_base链的作用之后,就认为为什么不用下面的算法实现。 for(ptype=ptype_base[ntohs(type)&15];ptype;ptype=ptype->next) {if(ptype->type == type && (!ptype->dev || ptype->dev == skb...
<⼆>实现ptype_base和ptype_all链讲了上⾯的东西后咱们来看ptype_base及ptype_all链相关的东西。这两个链的作⽤在这⾥就不讲了。因为有了上⾯的东西,所以涉及到⼀个skbuff共享的问题,如果都⽤skb_clone或者skb_copy,那么性能将是很低的。所以在linux中使⽤了skb共享的计数,就是⽤skb->...
<二>实现ptype_base和ptype_all链 讲了上面的东西后咱们来看ptype_base及ptype_all链相关的东西。这两个链的作用在这里就不讲了。 因为有了上面的东西, 所以涉及到一个skbuff共享的问题, 如果都用skb_clone或者skb_copy,那么性能将是很低的。
可以看到,ptype_base为一个hash表,而ptype_all为一个双向链表.每一个里面注册的协议都用一个struct packet_type表示. struct packet_type { unsigned short type; /*协议类型*/ struct net_device *dev; int (*func) (struct sk_buff *, struct net_device *, ...