linux makefile 教程 非常详细,且易懂

网卡接收数据包流转图概述:
第一阶段:网卡接收数据包
1. 数据包通过DMA从网卡拷贝到内存的Ring buffer缓冲区中。
2. 网卡触发硬中断通知CPU收包。
3. CPU调用网卡驱动注册的硬中断处理函数,记录硬件中断频率并将驱动napi_struct传过来的poll_list添加到CPU变量softnet_data里的poll_list中。
4. 硬中断处理函数向内核软中断线程ksoftirqd发出NET_RX_SOFTIRQ软中断请求。
5. ksoftirqd执行软中断处理函数net_rx_action。
6. net_rx_action调用驱动注册的poll函数从Ring buffer开始轮询收包。
第二阶段:包在内核各个模块中的流转
1. poll收包函数从Ring buffer取出数据并封装为sk_buff结构,传递至netdevice子系统层处理。
2. 数据包经过netfilter模块的PREROUTING链进行预处理。
3. ip_rcv函数进行IP层简单处理,随后调用NF_HOOK函数宏将控制权交给netfilter模块。
4. 数据包进行路由处理后,如果是本机处理则发送到上层协议处理,否则经过netfilter模块的INPUT链规则处理后传递至上层协议。
5. 根据协议类型决定调用不同的收包函数,如tcp、udp或icmp。
第三阶段:应用层收包
涉及握手阶段、连接状态、fd、socket、sock关系和应用层收包流程图。其中,fd是文件描述符,socket是应用层程序和内核协议栈的接口,sock表示网络连接的结构。一个数据包达到tcp层后,先发送到sock对应的接收队列中,然后触发回调函数更新sock对应的fd为可读状态,内核通过检测机制检测到fd可读状态后,通知应用程序接收数据包。
第四阶段:数据包的发送
1. tcp层处理:通过tcp_sendmsg等函数链发送数据包,申请并封装sk_buff结构,更新TCP控制块字段,将sk_buff加入到sock发送队列,如果是零拷贝方式则进行零拷贝相关处理。
2. ip层处理:通过ip_queue_xmit等函数链进行IP层处理,包括查找路由缓存、设置IP头部字段等。
3. netdevice子系统层处理:通过dev_queue_xmit等函数进行数据包发送,包括Traffic Control处理、dev_hard_start_xmit调用以及网卡驱动层处理。
4. 网卡驱动层处理:具体驱动发送数据的函数处理数据包发送,包括将skb放入网卡发送队列、通知网卡发送数据包、处理中断和skb清理工作。
整体流转图:数据包从网卡接收开始,经过中断处理、内核各模块处理、应用层处理,最后通过tcp/ip层发送出去,期间涉及多个函数和结构的交互。
