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

标签 networking linux-kernel linux-device-driver endianness

由于sk_buff字段在本地处理,将其存储在主机顺序中更有意义。 sk_buff->vlan_tci 等字段是在主机顺序。存储某些字段是否有原因 sk_buff->protocol , sk_buff->vlan_proto网络/大端格式?

最佳答案

根据http://vger.kernel.org/~davem/skb.html页, protocol sk_buff 的字段IS被网络使用:

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

所以,对于传入的数据包 protocol从以太网数据包字段“TYPE”(ethertype,network endian)填充
http://en.wikipedia.org/wiki/Ethernet_frame :

Data on Ethernet is transmitted most-significant octet first. Within each octet, however, the least-significant bit is transmitted first. Ethertype (Ethernet II) or length 2 octets



对于传出的数据包,它由网络堆栈填充,然后用于填充“TYPE”字段。
vlan_proto是第一个 protocol 的副本来自以太网数据包的字段,当 802.1Q tagging 时通常为 0x8100已使用(http://en.wikipedia.org/wiki/EtherType 将其列为“VLAN 标记帧 (IEEE 802.1Q)”)。第二个协议(protocol)字段(在 VLAN 标记之后)将用作真实的 protocol .所以,vlan_proto也存储为网络订单,因为它来自/到网络。

TCI(存储在 vlan_tci 中的信息)也是网络 802.1q packet 的一部分,它有 2 个字节(八位字节)。但在处理网络字段时,通过 vlan_untag() in net/8021q/vlan_core.c 转换为主机格式:
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 转换为用于传出数据包的网络, 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);

关于networking - 为什么 sk_buff->protocol 以网络字节序存储?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23548020/

相关文章:

linux - 用于访问 Wifi 网络的优化 TCP 堆栈?

linux-kernel - Linux 内核(Samsung Exynos5422)中如何实现异构多处理(HMP)调度?

C: Linux Kernel - 如何在 struct ieee80211_mgmt 中使用 union 的变量字段数组 (u8 variable[0])?

c - Linux内核模块中的Write函数被重复调用

multithreading - 我们可以使用 x86_64 CPU 原子在 PCI Express 上生成复合原子操作吗?

c - linux终端使用printk打印数据

networking - 无法通过IP地址访问本地主机

c - 查找本地子网上所有可用的计算机

linux - 当您调用 select(2) 时,内核如何确定套接字已准备就绪?

c - 为什么内核在访问 32 位系统的内核模块中的系统调用表后会出现 panic ?