免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3472 | 回复: 3
打印 上一主题 下一主题

[网络子系统] linux eth0和eth1配置为网桥,转发1500以上的封包失败 [复制链接]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-02-11 11:42 |只看该作者 |倒序浏览
我们的设备运行 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->
  1. int br_dev_queue_push_xmit(struct sk_buff *skb)
  2. {
  3.         /* drop mtu oversized packets except gso */
  4.         if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb))
  5.                 kfree_skb(skb);
  6.         else {
  7.                 /* ip_refrag calls ip_fragment, doesn't copy the MAC header. */
  8.                 if (nf_bridge_maybe_copy_header(skb))
  9.                         kfree_skb(skb);
  10.                 else {
  11.                         skb_push(skb, ETH_HLEN);

  12.                         dev_queue_xmit(skb);
  13.                 }
  14.         }

  15.         return 0;
  16. }
复制代码
看起来当封包大于1500的时候,会被下面这句代码当掉:
if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb))
                kfree_skb(skb);
但是,我的问题是,当封包大小大于1500的时候,难道协议栈不会分片,然后再调用br_dev_queue_push_xmit发送么?
内核里有没有这样的机制,我的猜测是有的,可能需要内核配置来开启,或者、、、
希望有经验的童鞋给出点建议
谢谢啦

论坛徽章:
3
巳蛇
日期:2014-04-24 17:25:352015年辞旧岁徽章
日期:2015-03-03 16:54:15NBA常规赛纪念章
日期:2015-05-04 22:32:03
2 [报告]
发表于 2015-02-11 17:57 |只看该作者
分片是在IP层用ip_fragment函数分的,查看下是不是添加其他数据头内容了?
还有 if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb))这句,也可能是第二个条件不满足导致丢包的,意思是你的网卡没有开GSO功能,用 ethtool --show-offload eth* 看下

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
3 [报告]
发表于 2015-02-12 10:16 |只看该作者
回复 2# 紫柳

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

   

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
4 [报告]
发表于 2015-02-13 10:55 |只看该作者
搞定了:
  1. #if defined(CONFIG_NF_CONNTRACK_IPV4) || defined(CONFIG_NF_CONNTRACK_IPV4_MODULE)
  2. static int br_nf_dev_queue_xmit(struct sk_buff *skb)
  3. {
  4.         if (skb->nfct != NULL &&
  5.             (skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb)) &&
  6.             skb->len > skb->dev->mtu &&
  7.             !skb_is_gso(skb))
  8.                 return ip_fragment(skb, br_dev_queue_push_xmit);
  9.         else
  10.                 return br_dev_queue_push_xmit(skb);
  11. }
  12. #else
  13. static int br_nf_dev_queue_xmit(struct sk_buff *skb)
  14. {
  15.         return br_dev_queue_push_xmit(skb);
  16. }
  17. #endif
复制代码
重编内核并且配置 CONFIG_NF_CONNTRACK_IPV4 就好了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP