jinxinxin163 发表于 2015-02-11 11:42

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发送么?
内核里有没有这样的机制,我的猜测是有的,可能需要内核配置来开启,或者、、、
希望有经验的童鞋给出点建议
谢谢啦

紫柳 发表于 2015-02-11 17:57

分片是在IP层用ip_fragment函数分的,查看下是不是添加其他数据头内容了?
还有 if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb))这句,也可能是第二个条件不满足导致丢包的,意思是你的网卡没有开GSO功能,用 ethtool --show-offload eth* 看下

jinxinxin163 发表于 2015-02-12 10:16

回复 2# 紫柳

测试发现,这两个条件都是1,所以导致free了

   

jinxinxin163 发表于 2015-02-13 10:55

搞定了:#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]
查看完整版本: linux eth0和eth1配置为网桥,转发1500以上的封包失败