我知道每个NIC在RAM中都有其RX / TX环,用于OS接收/发送数据包。并且环中的一个项(包描述符)包括包的物理地址,包的长度等等。我想这个描述符是否指向sk_buff?如果数据包是GSO数据包会发生什么?这是真的,环中的一个描述符=一个数据包=一个sk_buff?
答案 0 :(得分:1)
我想知道这个描述符是否指向sk_buff?
不完全是。 sk_buff是一个软件构造,大致是一个包含元信息的数据结构,描述一些网络数据和指向到data本身。因此,NIC描述符不需要指向sk_buff
- 它可能只指向数据缓冲区(使用DMA /物理地址)。
如果数据包是GSO数据包会怎样?
这是一个非常模糊的问题,因为这样的卸载可以在软件中实现(例如,通过网络堆栈),并且可以在硬件中完成。
在前一种情况下,没有什么可以讨论NIC SW描述符 - 上层应用程序提供连续的数据块,并且网络堆栈从中生成较小的数据包,因此sk_buff
- 递给到网络驱动程序已经描述了小数据包。
在后一种情况下(硬件卸载),网络驱动程序提供了大量数据(通过将单个sk_buff
- 或sk_buff
链移交给它)和网络驱动程序反过来将适当的描述符发布到NIC - 它可能是指向大块数据的一个描述符,或者指向同一个连续数据缓冲区的较小部分的少数描述符 - 自卸载魔法以来它并不重要将在HW中进行 - 整个数据块将被切片,并且数据包头将相应地预先设置,从而产生许多较小的网络数据包,以便通过网络进行。
这是真的,环中的一个描述符=一个包=一个sk_buff?
严格来说,不。这取决于。可能会要求您的网络驱动程序传输一个描述一个数据缓冲区的sk_buff
。但是,在某些情况下,您的驱动程序可能会决定发布指向同一数据块但具有不同偏移量的多个描述符 - 即提交将部分完成,并且NIC的环中将有多个描述符与单个相关sk_buff
。此外,一个数据包并不总是与一个数据包sk_buff
相同 - 数据包可能会显示为少数几个段,每个段用一个单独的sk_buff
形成sk_buff
} 链(请在next
中找到prev
和sk_buff
fields。
答案 1 :(得分:0)
sk_buff
与物理网络接口无关(至少不是直接)。 sk_buff
列出了套接字访问软件和内核协议处理程序所看到的存储数据(操作这些列表以添加/删除标头和/或更改数据,例如,当使用加密时)。
低级别驱动程序的责任是将sk_buff
列表内容转换为物理网络适配器将理解的内容。特别是,网络硬件可能非常愚蠢(比如通过串行线进行网络连接),在这种情况下,驱动程序基本上会逐字节地读取sk_buff
列表,并通过网络发送它们。
更高级的适配器通常能够执行分散/收集DMA - 给定RAM中的地址列表,它们将能够访问每个地址,并从那里获取分组数据或将接收的数据放回。但是,这种机制的确切细节非常适用于特定应用程序,并且在许多情况下,单个供应商的产品之间甚至不一致。
答案 2 :(得分:0)
Linux内核使用sk_buff数据结构来描述每个 包。当数据包到达NIC时,它会调用DMA引擎 通过存储在其中的空sk_buff将数据包放入内核内存中 一个叫做rx_ring的环形缓冲区。如果是,则丢弃传入的数据包 环形缓冲区已满。在更高层处理数据包时, 分组数据保留在同一个内核内存中,避免任何额外的内存 记忆副本。
http://www.ece.virginia.edu/cheetah/documents/papers/TCPlinux.pdf
最后一句似乎表明传入的数据包数据在没有冗余的情况下保存在sk_buff结构的内核内存中。所以我说你的问题的答案是肯定的,那个描述符会指向一个sk_buff。是的,每个数据包都放在rx_ring中自己的sk_buff中。