RX / TX环和sk_buff之间的关系是什么?

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

我不知道这个描述符指向了sk_buff吗?

不完全是。 sk_buff是一个软件结构,粗略地说,是一个包含元信息的数据结构来描述一些网络数据块并指向 数据本身。 所以,NIC描述符不需要指向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 (请在sk_buff查找next和前next 字段 )。

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

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

更高级的适配器通常能够进行分散/聚集DMA – 给定RAM中的地址列表,他们将能够访问每个地址,并从那里获取分组数据或者将接收的数据返回。 然而,这种机制的确切细节是非常适应特定的,在很多情况下甚至在单一供应商的产品之间是不一致的。

Linux内核使用sk_buff数据结构来描述每个数据包。 当数据包到达NIC时,它会调用DMA引擎,通过存储在名为rx_ring的环形缓冲区中的空sk_buff's将数据包放入内核内存。 如果环形缓冲区已满,则传入的数据包将被丢弃。 当数据包在更高层被处理时,数据包数据保留在同一个内核内存中,避免了额外的内存拷贝。

http://www.ece.virginia.edu/cheetah/documents/papers/TCPlinux.pdf

最后一句话似乎表明,传入的数据包数据保存在内核内存的sk_buff结构中,没有冗余。 所以我会说你的问题的答案是肯定的,那个描述符会指向一个sk_buff。 是的,每个数据包放在rx_ring自己的sk_buff中。