__ip_append_data函数为何检查网卡是否支持UFO
UDP发送报文的流程会走到__ip_append_data函数,该函数判断如果传入的报文长度大于MTU并且网卡支持UFO功能,就会把该报文标记成UFO报文,由网卡来实现分片以此提高性能。if (((length > mtu) || (skb && skb_is_gso(skb))) &&
(sk->sk_protocol == IPPROTO_UDP) &&
(rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len)
err = ip_ufo_append_data(sk, queue, getfrag, from, length,
hh_len, fragheaderlen, transhdrlen,
maxfraglen, flags);
可是我觉得就算网卡不支持UFO,我们也可以把它当成UFO报文,因为dev_hard_start_xmit会判断如果网卡不支持UFO,就由软件实现分片,这样的话通过推迟分片也是可以适当提高性能的
大家怎么理解 围观围观,坐等大神回复 思路不错,感觉也是可以的。
PS,!rt->dst.header_len条件在判断什么?为什么是取反?
通常dst.header_len是零值还是非零值? 本帖最后由 firocu 于 2015-06-12 14:43 编辑
我认为是因为ip分片!
分片之后才是dev queue xmit.
回复 1# littlenewer
我找到了原始commit 信息:
git show c146066ab
commit c146066ab80267c3305de5dda6a4083f06df9265
Author: Steffen Klassert <steffen.klassert@secunet.com>
Date: Wed Jun 29 23:19:32 2011 +0000
ipv4: Don't use ufo handling on later transformed packets
We might call ip_ufo_append_data() for packets that will be IPsec
transformed later. This function should be used just for real
udp packets. So we check for rt->dst.header_len which is only
nonzero on IPsec handling and call ip_ufo_append_data() just
if rt->dst.header_len is zero.
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 4a7e16b..84f26e8 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -828,7 +828,7 @@ static int __ip_append_data(struct sock *sk,
cork->length += length;
if (((length > mtu) || (skb && skb_is_gso(skb))) &&
(sk->sk_protocol == IPPROTO_UDP) &&
- (rt->dst.dev->features & NETIF_F_UFO)) {
+ (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) {
err = ip_ufo_append_data(sk, queue, getfrag, from, length,
hh_len, fragheaderlen, transhdrlen,
mtu, flags);
回复 3# nswcfd
多谢!
回复 5# firocu
回复 4# firocu
ip分片后才是dev xmit我知道的,但不明白和这个问题有何关系,可否详细解释下
其实, 我也不太懂就是看了代码.
如果包大于mtu会被ip 分片, 应该不会到dev queue xmit, 也就轮不到dev_hard_start_xmit里面的代码了.
回复 7# littlenewer
回复 8# firocu
不管是大包还是小包,最终都会走到dev_hard_start_xmit,这个函数是驱动发包函数的公共入口
页:
[1]