可以使用GSO对IPv4数据包的附加标头进行分段?

时间:2016-02-04 16:23:13

标签: c networking tcp kernel gso

我遇到了数据包分段问题。我已经从许多来源中读到了关于GSO的信息,这是一种用于分割大小大于以太网MTU(1500 B)的数据包的通用方法。但是,我没有找到对我所怀疑的疑问的答案。

如果我们在L2和L3层之间添加一组新的字节(例如名称为'NH'的新标题),内核必须能够通过NH并将sk_buff指针调整到L3的开头根据L3协议类型的“策略”卸载数据包(例如IPv4分段)。我的想法是修改 skb_network_protocol()功能。如果我没有错,这个函数可以使 skb_mac_gso_segment()为不同类型的L3协议正确调用GSO函数。但是,我无法正确分割我的数据包。

我有一个通过网络转发数据包的内核模块(OVS,Open vSwitch)。在我运行的测试(h1 --ping-- h2)上,主机生成大ICMP数据包,然后发送小于或等于MTU大小的数据包。这些分组由附加新报头NH的第一交换机接收,因此如果分组具有1500B,则它变为1500B + NH长度。这就是问题,交换机已经收到来自主机的碎片数据包,交换机在数据包中添加了更多的字节(VLAN类型)。

因此,起初,我试图ping大数据包,但它没有用。在OVS中,在调用 dev_queue_xmit()之前,可以通过调用 skb_gso_segment()来对数据包进行分段。但是,数据包需要经过 netif_needs_gso()检查的条件。但我不确定是否必须使用 skb_gso_segment()来正确分割数据包。

我还注意到,对于 needs_gso_segment()函数为true, skb_shinfo(skb) - > gso_size 必须为true。但是,gso_size对于所有接收的数据包始终为零值。因此,我通过将随机值归因于gso_size(例如1448B)进行了测试。现在,在我的测试中,我能够从h1 ping到h2,但前两个数据包丢失了。在另一项测试中,TCP的性能极差。从那时起,我一直在收到内核警告:“ [5212.694418] [c1642e50]?skb_warn_bad_offload + 0xd0 / 0xd8

对于小数据包(< MTU)我没有遇到麻烦,ping工作正常。 TCP工作正常,但对于小窗口大小。

有人知道发生了什么事吗?当我收到大包时,我应该总是使用GSO吗?是否可以分段碎片化的IPv4数据包?

由于新标头位于L2和L3之间,我认为由于附加标头而导致的IPv4数据包的扩大与VLAN的情况类似。 VLAN如何处理分段问题?

提前致谢,

0 个答案:

没有答案