linux网络学习

ipv4报文处理流程

1、物理层网卡收到报文,产生中断进入中断处理程序:net_interrupt,判断中断是由接收到分组引发后,控制权转移到net_rx;

2、net_rx函数分配一个新的sk_buf,从网卡取出分组内容到内存;

3、netif_rx负责将接收到的分组放置到一个特定于cpu的等待队列上,标记软中断:NET_RX_SOFTIRQ,并退出中断上下文;

4、net_rx_action从等待队列取出一个套接字缓冲区(分组),分析分组的类型,以便根据分组类型将分组传递给网络层的接收函数,如ip_rcv;

5、ip_rcv检验分组,包括校验和是否一致、分组是否达到了ip首部的最小长度、分组的协议号是否为ipv4),检查后调用netfilter挂钩(NF_IP_PRE_ROUTE),使得用户空间可以对分组数据进行操作,挂钩位置处理完成后(分组可能被修改过),需要路由选择(ip_route_input)进一步的处理,本地处理(ip_local_deliver)or分组转发(ip_forward);

6a、ip_local_deliver,如果ip是分片的,调用ip_defrag重新组合分片分组的各个部分, 属于同一分组的各个分片保存在一个独立的等待队列中,直至所有分片到达后,ip_frag_reasm将各个分片重新组合起来,释放套接字缓冲区,留下了分片缓存(内核在一个独立的缓存中管理原本属于一个分组的各个分片),如果分组的分片没有全部到达,ip_defrag返回一个null指针,终止网络层的分组处理,在所有分片都到达后,恢复处理;

7a、分组分片合并完成后,调用netfilter挂钩NF_IP_LOCAL_IN,恢复在ip_local_deliver_finish函数中的处理;调用传输层对应的接收例程,tcp_v4_rcv/udp_rcv

6b、ip_forward,分组转发:如果目标计算机不在本地网络,需要相邻网络结构和相关的外出路径信息(路由表提供,路由表由内核通过多种数据结构实现并管理),ip_forward在TTL<=1时丢弃分组,否则调用netfilter挂钩NF_IF_FORWARD,然后内核在ip_forward_finish中恢复处理,将分组传递到路由期间选择、保存在skb->dst->output中的发送函数。

 8、ip_queue_xmit(网络层发送数据的函数),查找可用于该分组的路由,在发送第一个分组时,内核需要查找一个新的路由。在ip_send_check为分组生成校验和之后,内核调用netfilter挂钩NF_IP_LOCAL_OUT,接下来调用dst_output函数(skb->dst->output:ip_output)

9、ip_output,首先调用挂钩NF_IF_POST_ROUTING,接下来是ip_finish_output。如果有必要进行分组分片,调用ip_fragment,否则,直接调用ip_finish_output2,该函数在有足够空间容纳硬件首部时,调用由路由层设置的函数dst->neighbour->output(通常指向dev_queue_xmit)

源码位置:include/net

相关文件:skbuff.h net/core/dev.c

相关函数:register_netdev

相关命令:ls -l /sys/class/net

 

TCP/IP模型:应用层(http、ftp)、传输层(tcp、udp)、网络层(ip、icmp、igmp)、物理层(mac)

  物理层在Linux体现为网卡驱动程序,struct net_device描述该网卡,物理层接口通过DMAC判断是否收发报文(组播、广播及单播)、快转(查找快转表项forward报文)

  网络层负责路由报文、分组、分配ip地址,

  传输层负责构建面向连接或无连接的服务

  应用层使用(ip_addr,port)唯一标识提供实际的应用,如Http、ftp、pop3、telnet等

 

为了保证收发时对报文处理的性能,避免各层次之间来回复制分组数据,内核使用了一种特殊的结构体struct sk_buff描述报文,同时使用了sk_buff_head表头实现了套接字缓冲区的等待队列用于管理分组(双向循环列表)

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。