Linux 内核网络协议栈 中最重要的数据结构 SKB

时间:2022-12-13 11:04:02

在计算机的世界里,备份是一种美德。-------------漫步云端


 作为内核网络协议部分最重要的数据结构SKB,有很多值得仔细推敲的问题。

 

SKB这种说法实际包含了两部分,即skb描述符和skb数据

Skb描述符即内核中的skbuff结构体,里面含有大量的指针变量,运用指针的好处是显然的。

Skb 数据部分一般包括两大部分,线性数据部分和非线性数据部分(即聚合I/O部分),这些数据是在内存中不同位置的,由skbuff中的相应指针来定位。

 

在网络协议栈中,复制数据是一件低效率的事情,因此应该尽量避免对数据的复制,相反,仅仅修改关于数据的有关信息是很方便的,而且开销很小。

 

举个不恰当的例子:

比如中国的商品要出口到很多国家,不同国家的人因为语言不同,这样商品的说明书就不一样。这里的商品说明书就好比skbuff结构体,记录了商品的信息,如果商品自身有变化,直接修改说明书就可以了,而不用让别人先去按照你的方法生产同样一份商品,然后才能确认该商品的属性,直接看说明书,省事多了。

 

内核中有几个操作SKB 的函数,这些函数仅仅是对指针进行了移动操作,即仅仅修改了“说明书”中的信息,真正的数据复制动作,由别的函数完成。

 

有关于SKB 的复制,需要分以下两种情形:

 

情形一:不需要对数据进行修改操作

 

既然不用修改数据,那能做的操作无非就是移动指针了,也就是仅仅需要修改“说明书”,所以,此时仅仅需要复制skb描述符即可,不同的skb描述符中的信息可能不相同,这要看各个skb对数据的具体需求。比如,有的skb需要全部的数据,而有的可能仅仅需要一部分数据。

情形一的操作在内核中叫做对skb的克隆,相应的实现函数为:

Struct sk_buff *skb_clone();

 

情形二:既需要修改skb描述符,同时也需要修改数据

 

在此情形下,又有两种情况:

1.只有线性数据区

2.既含有线性数据又含有非线性数据

 

对于情况1,内核中的处理函数为pskb_copy();

对于情况2,内核中的处理函数为 skb_copy();

 

 

对于情形二中的两种情况,不论哪一种复制,在复制之前都要做好备份,否则,如果其余的子模块需要原始数据,则会引发灾难。


以上是关于skb克隆与复制的解释,错误之处,请各位指正。转载请注明出处。