Linux内核IP层的报文处理流程--从网卡接收的报文处理流程
本文主要讲解了Linux内核IP层的整体架构和对从网卡接受的报文处理流程,使用的内核的版本是2.6.32.27
为了方便理解,本文采用整体流程图加伪代码的方式对Linxu内核中IP整体实现架构和对网卡报文的处理流程进行了讲解,希望可以对大家有所帮助。阅读本文章假设大家对C语言有了一定的了解
IP层的整体实现架构
IP层接受底层数据报文的处理流程
//-----------------------------------------------------------------------------------------------/*包的本地投递*/int ip_local_deliver(struct sk_buff *skb){/*收集并组装IP分片,如果还没有收集完成,那么就等待IP分片组装完成*/if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {if (ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER))return 0;}/*进入NF_IP_LOCAL_IN的过滤器处理,处理完成后进入ip_local_deliver_finish*/return NF_HOOK(PF_INET, NF_INET_LOCAL_IN, skb, skb->dev, NULL, ip_local_deliver_finish);}/*IP层处理完成后的协议分发函数*/static int ip_local_deliver_finish(struct sk_buff *skb){resubmit:/*如果是RAW-IP报文,送往RAW-IP对应的处理???*/raw = raw_local_deliver(skb, protocol);/*MAX_INET_PROTOS-1 为IP报头中协议的模, *这里计算对应协议在ipprot中被散列的位置*/hash = protocol & (MAX_INET_PROTOS - 1);/*IP层上的ipprot负责管理所有的传输协议*/ipprot = rcu_dereference(inet_protos[hash]);/*如果找到相应的协议,那么调用对应的处理例程*/if (ipprot != NULL) {ret = ipprot->handler(skb);if (ret < 0) {protocol = -ret;goto resubmit;}}/*找不到相应的处理例程*/ else {/*又是RAW-IP报文,会在RAW-IP处理例程??? * 就丢弃,并想对端发送ICMP_DEST_UNREACH,ICMP_PROT_UNREACH*/if (!raw) {icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0);} kfree_skb(skb);}return 0;}static const struct net_protocol tcp_protocol = {.handler =tcp_v4_rcv, /*TCP*/};static const struct net_protocol udp_protocol = {.handler =udp_rcv, /*UDP*/};static const struct net_protocol icmp_protocol = {.handler =icmp_rcv, /*ICMP*/};static const struct net_protocol igmp_protocol = {.handler =igmp_rcv, /*IGMP*/};
关于二层数据报文的处理流程和是如何送到三层进行处理,请参考我前面的博客
《Linux内核二层数据包接收流程》
希望大家批评指正