2017-10-17 151 views
3

我知道每个NIC都有RAM中的RX/TX环用于操作系统接收/发送数据包。环中的一个项目(包描述符)包括数据包的物理地址,数据包的长度等。我想知道这个描述符指向了sk_buff吗?并且如果数据包是一个GSO数据包会发生什么?这是真的,环中的一个描述符=一个数据包=一个sk_buff?RX/TX环和sk_buff之间的关系是什么?

+1

*“每个NIC的RX/TX环都在RAM中”* - 不正确。 NIC可以有深层的FIFO来保存帧。请参阅https://stackoverflow.com/questions/23574203/regarding-napi-implementation-in-linux-kernel/23598916#23598916 – sawdust

回答

1

我不知道,这是否描述符指向一个sk_buff的?

不完全是。 sk_buff是软件构造,大致包含元信息的数据结构描述网络数据的某些块与data本身。因此,网卡描述并不需要指向sk_buff - 它可能只指向数据缓冲区(DMA /物理地址使用)。

如果该数据包是GSO包,会发生什么?

这是一个非常模棱两可的问题,因为这些卸载可能在软件中实现(例如通过网络堆栈)并可能以硬件完成。

在前一种情况下,没有任何关于NIC SW描述符的讨论 - 上层应用程序提供了一个连续的数据块,并且网络堆栈从它产生较小的数据包,以便sk_buff -s移交给网络驱动程序已经描述了小包。

在后一种情况(HW卸载)网络驱动程序与数据的大块供给(由移交单sk_buff -s或sk_buff链它的装置),并且继而帖网络驱动程序适当的描述符到NIC - 它可能是一个指向大块数据的描述符,或者少数描述符指向相同连续数据缓冲区的较小部分 - 因为卸载魔法将发生在硬件中,所以这并不重要 - 总体而言数据块将被分割并且数据包头将被相应地前置,从而产生很多较小的网络数据包以便被连接。

这是真的,环中的一个描述符=一个数据包=一个sk_buff?

严格来说,。这取决于。您的网络驱动程序可能会被要求传输一个sk_buff描述一个数据缓冲区。但是,在某些情况下,您的驱动程序可能会决定发布多个指向同一块数据但具有不同偏移量的描述符 - 即提交将部分完成,并且NIC环中将有多个描述符与单个sk_buff相关。另外,一个分组不总是一样一个sk_buff - 的分组可以被呈现为每个与单独sk_buff所述的形成sk_buff一小撮(请找到nextprevfieldssk_buff)。

0

sk_buff与物理网络接口(至少不是直接的)无关。 sk_buff列出存储由套接字访问软件和内核协议处理程序(处理这些列表以添加/移除标题和/或改变数据,例如当采用加密时)所看到的数据。

低级驱动程序的职责是将sk_buff列表内容转换为物理网络适配器将理解的内容。特别是网络硬件可能真的很笨(就像在串行线路上进行网络连接一样),在这种情况下,驱动程序将基本读取sk_buff列表逐字节并通过线路发送。

更先进的适配器通常能够做到分散/聚集DMA - 鉴于RAM的地址的列表,他们将能够访问每个地址,无论是从那里得到报文数据或将接收到的数据传回。然而,这种机制的确切细节非常适用于特定的适配器,并且在很多情况下,单个供应商的产品之间甚至不一致。

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中。

相关问题