分享

linux网桥内核实现分析(三)---协议类型查找过程

 enchen008 2012-04-10

------------------------------------------------------------------------------------------

以下是我根据 linux-2.6.23.9版本内核源代码所做阅读笔记,属个人兴趣而为,希望找到有共同兴趣

的朋友一起讨论和研究,有谬误之处,笔者水平有限,欢迎大家拍砖:)

------------------------------------------------------------------------------------------

 

static struct list_head ptype_base[16] __read_mostly; 

static struct list_head ptype_all __read_mostly;   

 

所有协议的packet_type存放在两条协议链中,ptype_base和ptype_all,从声明可以看出,ptype_base 为哈希链表,ptype_all为双向链.系统使用dev_add_pack函数将指定协议类型的packet_type添加到这两个表中。

 

针对于ETH_P_ALL类型的数据报文将在ptype_all表中找到自己对应的packet_type结构。

 

而ETH_P_IP,ETH_P_ARP等协议的数据报文将在ptype_base中找到自己对应协议的

packet_type.相应的,如果协议类型为ETH_P_IP,那么packet_type->func就是ip_rcv,如果协议类型是ETH_P_ARP,那么packet_type->func就是arp_rcv.

 

目前,只发现了系统创建了一个PF_PACKE类型的socket才会将一个packet_type结构加到ptype_all链表中。

 

netif_receive_skb函数

这个函数用来作协议链的匹配和分发,以下的代码用于在协议链上寻找匹配的协议

 

//先匹配ptype_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;

              }

       }

 

//再匹配ptype_base协议链

 

type = skb->protocol;

       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;

              }

       }

 

deliver_skb函数将负责调用packet_type->func,对于IP协议实际上调用了ip_rcv.

netif_receive­_skb同样调用了网桥的入口,handle_bridge函数

 

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多