设为首页 加入收藏

TOP

Linux 网络发包流程(二)
2023-08-26 21:10:45 】 浏览:104
Tags:Linux 包流程
系统负责处理与物理网络接口相关的操作,包括数据包的封装和发送,以及从物理接口接收数据包并进行解析

网络设备子系统不但处理数据包的格式转换,如在以太网中添加帧头和帧尾,以及从帧中提取数据

还负责处理硬件相关的操作,如发送和接收数据包的时钟同步、物理层错误检测等

  • 到达网卡发送队列

接着网络设备子系统会选择一个合适的网卡发送队列并把 skb 添加到队列中(绕过软中断处理程序)

然后,内核会调用网卡驱动的入口函数 dev_hard_start_xmit 来触发数据包的发送

在一些情况下,邻居子系统还会将 skb 数据包添加到软中断队列(softnet_data)上,并触发软中断(NET_TX_SOFTIRQ)

这个过程是为了将 skb 数据包交给软中断处理程序进行进一步处理和发送。软中断处理程序会负责实际的数据包发送

这就是为什么一般服务器上查看 /proc/softirqs,一般 NET_RX 都要比 NET_TX 大的多的原因之一

即对于收包来说,都是要经过 NET_RX 软中断;而对于发包来说,只有某些情况下才触发 NET_TX 软中断

网卡驱动发送

驱动程序从发送队列中读取 skb 的描述信息,将其挂到 RingBuffer 上(前面提到的igb_tx_buffer 数组)

接着将 skb 的描述信息映射到网卡可访问的内存 DMA 区域中(前面提到的e1000_adv_tx_desc 数组)

网卡会直接从 e1000_adv_tx_desc 数组中根据描述信息读取实际数据并将数据发送到网络。这样就完成了数据包的发送过程

收尾工作

当数据发送完成后,网卡设备会触发一个硬件中断(NET_RX_SOFTIRQ),这个硬中断通常称为“发送完成中断”或者“发送队列清理中断”

这个硬中断的主要作用是执行发送完成的清理工作,包括释放之前为数据包分配的内存,即释放 skb 内存和 RingBuffer 内存

最后,当收到这个 TCP 报文的 ACK 应答时,传输层就会释放原始的 skb(前面有讲到发送的其实是 skb 的拷贝版)

可以看到,当数据发送完成以后,通过硬中断的方式来通知驱动发送完毕,而这个中断类型是 NET_RX_SOFTIRQ

前面我们讲到过网卡收到一个网络包的时候,会触发 NET_RX_SOFTIRQ中断去告诉 CPU 有数据要处理

也就是说,无论是网卡接收一个网络包还是发送网络包结束之后,触发的都是 NET_RX_SOFTIRQ

总结

最后总结一下在 Linux 系统中发送网络数据包的流程:
image

  • 应用程序通过 socket 提供的接口进行系统调用,将数据从用户态拷贝到内核态的 socket 缓冲区中
  • 网络协议栈从 socket 缓冲区中拿取数据,并按照 TCP/IP 协议栈从上到下逐层处理
    • 传输层处理:以 TCP 为例,在传输层中会复制一份数据(为了丢失重传),然后为数据封装 TCP 头
    • 网络层处理:选取路由(确认下一跳的 IP)、填充 IP 头、netfilter 过滤、对超过 MTU 大小的数据包进行分片等操作
    • 邻居子系统和网络设备子系统处理:在这里数据会被进一步处理和封装,然后被添加到网卡的发送队列中
  • 驱动程序从发送队列中读取 skb 的描述信息然后挂在 RingBuffer 上,接着将 skb 的描述信息映射到网卡可访问的内存 DMA 区域中
  • 网卡将数据发送到网络
  • 当数据发送完成后触发硬中断,释放 skb 内存和 RingBuffer 内存
首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇【技术积累】Linux中的命令行【理.. 下一篇CentOS7.6安装VMware Tools小白保..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目