由于sk_buff
字段在本地处理,因此将其存储为主机序更有意义。诸如sk_buff->vlan_tci
之类的字段采用主机序。是否有将一些字段sk_buff->protocol
,sk_buff->vlan_proto
以网络/大端序格式存储的原因?
由于sk_buff
字段在本地处理,因此将其存储为主机序更有意义。诸如sk_buff->vlan_tci
之类的字段采用主机序。是否有将一些字段sk_buff->protocol
,sk_buff->vlan_proto
以网络/大端序格式存储的原因?
sk_buff
的protocol
字段被网络使用:
此外,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);
VLAN_TAG_PRESENT
存储在vlan_tci
中,由__vlan_hwaccel_put_tag
处理。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);