2

当Linux内核分配像skbuff这样的结构时,分配的数据区域(skbuff->tail - skbuff->head)是否总是一个连续的内存块,或者这可以是不连续的吗?

4

1 回答 1

0

简短的回答:
是的。内存范围 [ skbuff->end - skbuff->head] 始终是一个连续的内存块。

长答案:
仍然是,但是如果您的 skbuff 是碎片化的(稍后我将解释如何检查它是否碎片化),那么您的数据将不会位于一个连续的内存块上。请注意,范围内的数据[skbuff->end - skbuff->head]仍然在一个连续的内存块中,但并非分片的 skbuff 的所有数据都在范围内[skbuff->end - skbuff->head]

如果您想更深入地了解如何使用fragmented skbuff,那么我建议您阅读这篇文章(并从本标题开始阅读When SKB is Non Linear)。我认为那里的解释很清楚,也很形象化。

我怎么知道我的 skbuff 是碎片化的?
如果您不是分配 skbuff 的人,并且您想了解您正在使用的 skbuff 的数据是否碎片,您可以检查以下值skb->data_len

  • 如果它等于 0,那么 skbuff 是线性的(不是分段的 - 数据位于连续的内存块上)并且数据的大小是skb->len.
  • 如果它大于 0,则 skbuff 不是线性的(数据是分段的),skb->len仍然是完整帧的长度,并且skb->data_len是所有数据片段的总长度,不包括第一个片段。

您也可以只调用skb_is_nonlinear(),如果它返回true,则 skbuff 是碎片化的(位于物理非连续内存上)。

奖励:
如果你收到了一个碎片化的 skbuff 并且你不能使用碎片化的 skbuff(因为你的硬件不支持它或其他一些原因),那么你可以通过使用函数 skb_copy ()。但请记住,此功能将创建原始 skbuff 的副本,因此此操作将花费您……
嗯……并且不要忘记释放原始 skbuff。

于 2020-10-30T12:50:21.260 回答