【Linux 内核网络协议栈源码剖析】系统网络协议栈初始化及数据传输通道建立过程 (2)

ip_init 函数同样完成该协议接收函数对链路层的注册,同时由于路由表项与网络设备绑定的原因,也必须注册网络设备变化事件监听函数对此类事件进行监听。

/* * IP registers the packet type and then calls the subprotocol initialisers */ //IP初始化函数 void ip_init(void) { ip_packet_type.type=htons(ETH_P_IP); //将IP协议对应的packet_type插入到ptype_base指向的队列中,完成对下层的注册 dev_add_pack(&ip_packet_type); /* So we flush routes when a device is downed */ //注册网络接收设备时间处理函数 register_netdevice_notifier(&ip_rt_notifier); /* ip_raw_init(); ip_packet_init(); ip_tcp_init(); ip_udp_init();*/ }
看到没,arp_init 函数和 ip_init 函数内部都调用了 dev_add_pack 函数向链路层模块注册。
将协议对应的packet_type插入到ptype_base指向的队列中,完成对下层的注册 /* * Add a protocol ID to the list. Now that the input handler is * smarter we can dispense with all the messy stuff that used to be * here. */ void dev_add_pack(struct packet_type *pt) { if(pt->type==htons(ETH_P_ALL)) dev_nit++; pt->next = ptype_base; ptype_base = pt; }
至此,网络栈初始化工作全部完成,经过 inet_proto_init,arp_init,ip_init 函数的执行,系统完成了由下而上的各层接口之间的衔接。
1> 链路层和网络层经过 ptype_base 指向的 packet_type 结构队列进行衔接,每个packet_type 结构表示一个网络层协议,结构中定义有网络层协议号及其接收函数,链路层模块将根据链路层首部中标识的网络层协议号在队列中进行查找,从而调用对应的接收函数将数据包上传给网络层协议进行处理。
2> 网络层和传输层通过inet_protos散列表进行衔接,表中每个表项指向一个inet_protocol结构队列,每个inet_protocol结构表示一个传输层协议,结构中定义有传输层协议号及其接收函数,网络层模块将根据网络层协议首部中标识的传输层协议号在inet_protos表中进行匹配查询,从而得到传输层协议对应的inet_protocol结构,调用该结构中注册的接收函数,将数据包上传给传输层进行处理。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgypgs.html