为什么sk_buff->protocol以网络字节序存储?

6

由于sk_buff字段在本地处理,因此将其存储为主机序更有意义。诸如sk_buff->vlan_tci之类的字段采用主机序。是否有将一些字段sk_buff->protocolsk_buff->vlan_proto以网络/大端序格式存储的原因?

1个回答

8
根据http://vger.kernel.org/~davem/skb.html页面,sk_buffprotocol字段被网络使用:
unsigned short        protocol,

The 'protocol' field is initialized by routines such as 'eth_type_trans()'. It takes on one of the 'ETH_P_*' values defined in the 'linux/if_ether.h' header file. Even non-ethernet devices use these ethernet protocol type values to indicate what protocol should receive the packet. As long as we always have some ethernet protocol value for each and every protocol, this should not be a problem.

此外,skbuff.h 中的注释表明 protocol 是来自驱动程序的。
340 /** 
341  *      struct sk_buff - socket buffer
369  *      @protocol: Packet protocol from driver
391  *      @vlan_proto: vlan encapsulation protocol
392  *      @vlan_tci: vlan tag control information

因此,对于接收的数据包,协议是从以太网数据包字段“类型”(以太类型,网络字节序)填充的。http://en.wikipedia.org/wiki/Ethernet_frame:

以太网上的数据是以最高有效位为先的顺序传输的。在每个八位组中,最不重要的位是最先传输的。 以太类型(Ethernet II)或长度 2个八位组

对于发送的数据包,它将由网络堆栈填充,然后用于填充“类型”字段。

vlan_proto 是以太网数据包中第一个 protocol 字段的副本,通常在使用 802.1Q 标记http://en.wikipedia.org/wiki/EtherType 将其列为“带 VLAN 标记的帧 (IEEE 802.1Q)”)时为 0x8100。而第二个协议字段(VLAN 标记后面)将被用作真正的 protocol。因此,vlan_proto 也以网络顺序存储,因为它是从/到网络的。

TCI(要存储在 vlan_tci 中的信息)也是网络 802.1q 数据包 的一部分,它有 2 个字节(八位组)。但在处理网络字段时,它会通过 net/8021q/vlan_core.c 中的 vlan_untag() 转换为主机格式:

118 struct sk_buff *vlan_untag(struct sk_buff *skb)
119 {
120         struct vlan_hdr *vhdr;
121         u16 vlan_tci;

135         vhdr = (struct vlan_hdr *) skb->data;
136         vlan_tci = ntohs(vhdr->h_vlan_TCI);
137         __vlan_hwaccel_put_tag(skb, skb->protocol, vlan_tci);

我认为这是为了更轻松地进行TCI位操作。它们用于从TCI获取PCP(3位)、DEI(1位)和VID(12位)字段。此外,还有几个附加标志,VLAN_TAG_PRESENT存储在vlan_tci中,由__vlan_hwaccel_put_tag处理。
对于出站数据包,需要将主机TCI转换为网络TCI,使用vlan_insert_tag() from linux/if_vlan.h
277  * Inserts the VLAN tag into @skb as part of the payload
278  * Returns a VLAN tagged skb. If a new skb is created, @skb is freed.

285 static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb,
286                                               __be16 vlan_proto, u16 vlan_tci)
287 {

300         /* first, the ethernet type */
301         veth->h_vlan_proto = vlan_proto;
302 
303         /* now, the TCI */
304         veth->h_vlan_TCI = htons(vlan_tci);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接