linux eth0和eth1配置为网桥,转发1500以上的封包失败
我们的设备运行 linux-2.6.37,设备上有两个网卡,eth0 和eth1把设备上的两个网卡eth0和eth1添加到网桥br0
然后eth0和eth1分别连接pc0和pc1
pc0 ip: 192.168.1.2
pc1 ip: 192.168.1.3
在pc0上ping pc1
当ping封包小于1472时,能够ping通
但是ping封包大于1472,就ping不通了
查看内核代码,调用路径应该是:
netif_receive_skb->handle_bridge->br_handle_frame->br_handle_frame_finish->br_forward->br_forward_finish->int br_dev_queue_push_xmit(struct sk_buff *skb)
{
/* drop mtu oversized packets except gso */
if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb))
kfree_skb(skb);
else {
/* ip_refrag calls ip_fragment, doesn't copy the MAC header. */
if (nf_bridge_maybe_copy_header(skb))
kfree_skb(skb);
else {
skb_push(skb, ETH_HLEN);
dev_queue_xmit(skb);
}
}
return 0;
}看起来当封包大于1500的时候,会被下面这句代码当掉:
if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb))
kfree_skb(skb);
但是,我的问题是,当封包大小大于1500的时候,难道协议栈不会分片,然后再调用br_dev_queue_push_xmit发送么?
内核里有没有这样的机制,我的猜测是有的,可能需要内核配置来开启,或者、、、
希望有经验的童鞋给出点建议
谢谢啦 分片是在IP层用ip_fragment函数分的,查看下是不是添加其他数据头内容了?
还有 if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb))这句,也可能是第二个条件不满足导致丢包的,意思是你的网卡没有开GSO功能,用 ethtool --show-offload eth* 看下 回复 2# 紫柳
测试发现,这两个条件都是1,所以导致free了
搞定了:#if defined(CONFIG_NF_CONNTRACK_IPV4) || defined(CONFIG_NF_CONNTRACK_IPV4_MODULE)
static int br_nf_dev_queue_xmit(struct sk_buff *skb)
{
if (skb->nfct != NULL &&
(skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb)) &&
skb->len > skb->dev->mtu &&
!skb_is_gso(skb))
return ip_fragment(skb, br_dev_queue_push_xmit);
else
return br_dev_queue_push_xmit(skb);
}
#else
static int br_nf_dev_queue_xmit(struct sk_buff *skb)
{
return br_dev_queue_push_xmit(skb);
}
#endif
重编内核并且配置 CONFIG_NF_CONNTRACK_IPV4 就好了
页:
[1]