免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: new_learner
打印 上一主题 下一主题

[bridge]加入到bridge中的interface能直接与ip层通信吗? [复制链接]

论坛徽章:
0
21 [报告]
发表于 2009-03-21 10:52 |显示全部楼层
原帖由 Godbach 于 2009-3-21 10:41 发表


我觉得桥一般不会像你这么用法。把一个内网和外网接口加到一个桥里。

是的,一般的确不是这样用的。
我这样用,只是处于试验和学习的目的。
我现在的疑问是,为什么这样用了以后,通过ip层找到了interface以后,packet却没有往外发?
希望能从源码级别上来了解这个问题。

论坛徽章:
0
22 [报告]
发表于 2009-03-22 16:35 |显示全部楼层
原帖由 kevert 于 2009-3-21 22:20 发表
数据报目的MAC是网关,那么肯定就会被br0收到,从而交给上层处理,如果数据报到了三层的话,那么找路由的时候肯定可以找到路由,至少会找到默认路由,可以考虑在dev_queue_xmit 处加上打印信息,看是否走到此处了。我觉得看你的组网图来说应该是通的,你在WAN侧抓包看是否网关会向PC所ping的WAN侧主机发送ARP请求。看是否网关学习到了对方的ARP。


从wan侧抓包的情况来看,网关已经学习到了wan侧主机的mac地址了,但无法在wan侧主机上抓到ping包。在ip_finish_output2()中加入打印信息,在ip层网关也的确把ping发出来了。

所以我一直怀疑是不是网关wan侧interface eth0加入了bridge,所以导致ip层在向下层发包的时候没有传入到eth0中。
看来是有必要在dev_queue_xmit ()加入打印信息,仔细调试一下。

论坛徽章:
0
23 [报告]
发表于 2009-03-22 16:36 |显示全部楼层
原帖由 Godbach 于 2009-3-21 23:25 发表
同意LZ的测试方式。先看看学到ARP没有. 至于在dev_queue_xmit上加调试信息,可能有些麻烦

arp已经学到了。
斑竹有什么建议吗?

论坛徽章:
0
24 [报告]
发表于 2009-03-23 22:25 |显示全部楼层
原帖由 kevert 于 2009-3-22 17:42 发表
之所以ICMP报文没有发送出去应该是跟ARP有关系的。
ip neigh ls 看看结果。
基本流程是这样子的:
ping报文到了网关,MAC地址是网关自己,因此br0收到这个报文,从而交给上层也就是IP层处理,IP层处理之后,找路由找到eth0,创建路由缓存,但是此时并没有对应WAN侧设备的ARP信息,因此创建一个邻居节点,将这个邻居节点和这条路由缓存关联起来,但是没有获取到ARP,所以,发送 ARP请求出去,也就是通过eth0发送ARP请求出去,这个请求的响应被网关eth0收到,本来这个请求的skb->dev指向的是eth0的,结果因为eth0又被加到桥里面去了,因此,使得这个请求被桥处理之后skb->dev变成了br0了,然后送给上层处理,此时,因为ARP请求是从eth0发出去的,但是结果回应却在ARP层看来是从br0收到的,而实际上内核创建一个邻居节点的时候需要两个条件: dev 以及 MAC地址,因此这样skb->dev变成了br0,从而导致匹配不上,从而导致ARP从eth0发送出去之后没有dev匹配不上,而导致没有响应,认为目的不可达,也就是eth0并没有学到WAN侧设备的MAC地址,而是认为可以通过br0到达,所以,你最终看到结果是学习到了ARP,但是是 br0学习到的,而不是eth0学习到的,使用 ip neigh ls 就可以很清楚的知道, arp -a 显示出来内容不够细致。

说了这么多,自己都觉得有点罗嗦了,不知道解决了你的疑问么。

不好意思回复晚了,今天公司网络有点问题。

非常感谢这位兄弟的帮忙,这个问题也正如你说的这样,与arp相关。
我试过在缓存里加入静态arp,网络就通了;如果把这条arp删掉,ping包就出不去。
分析流程也正如你描述的这样,非常准确,再次感谢你:)

当然也谢谢LS各位帮忙分析问题的兄弟!

论坛徽章:
0
25 [报告]
发表于 2009-03-27 23:20 |显示全部楼层
原帖由 kevert 于 2009-3-22 17:42 发表
之所以ICMP报文没有发送出去应该是跟ARP有关系的。
ip neigh ls 看看结果。
基本流程是这样子的:
ping报文到了网关,MAC地址是网关自己,因此br0收到这个报文,从而交给上层也就是IP层处理,IP层处理之后,找路由找到eth0,创建路由缓存,但是此时并没有对应WAN侧设备的ARP信息,因此创建一个邻居节点,将这个邻居节点和这条路由缓存关联起来,但是没有获取到ARP,所以,发送 ARP请求出去,也就是通过eth0发送ARP请求出去,这个请求的响应被网关eth0收到,本来这个请求的skb->dev指向的是eth0的,结果因为eth0又被加到桥里面去了,因此,使得这个请求被桥处理之后skb->dev变成了br0了,然后送给上层处理,此时,因为ARP请求是从eth0发出去的,但是结果回应却在ARP层看来是从br0收到的,而实际上内核创建一个邻居节点的时候需要两个条件: dev 以及 MAC地址,因此这样skb->dev变成了br0,从而导致匹配不上,从而导致ARP从eth0发送出去之后没有dev匹配不上,而导致没有响应,认为目的不可达,也就是eth0并没有学到WAN侧设备的MAC地址,而是认为可以通过br0到达,所以,你最终看到结果是学习到了ARP,但是是 br0学习到的,而不是eth0学习到的,使用 ip neigh ls 就可以很清楚的知道, arp -a 显示出来内容不够细致。

说了这么多,自己都觉得有点罗嗦了,不知道解决了你的疑问么。


这两天又看了一下代码,kevert兄是不是认为在ip_finish_output2()中,skb实际上是没有发送出去的,直接在这个函数里被free了?
见下面代码:

  1. static inline int ip_finish_output2(struct sk_buff *skb)
  2. {

  3.         。。。。。。

  4.         if (hh)
  5.         {
  6.                 int hh_alen;

  7.                 read_lock_bh(&hh->hh_lock);
  8.                 hh_alen = HH_DATA_ALIGN(hh->hh_len);
  9.                   memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);  /*填充ethernet header*/
  10.                 read_unlock_bh(&hh->hh_lock);
  11.                 skb_push(skb, hh->hh_len);
  12.                 return hh->hh_output(skb);   /*dev_queue_xmit()*/
  13.         }
  14.         else if (dst->neighbour)
  15.                 return dst->neighbour->output(skb); /*neigh_resolve_output()*/

  16.         /**************** 1 ***********/
  17.         if (net_ratelimit())
  18.                 printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n");
  19.         kfree_skb(skb);
  20.         return -EINVAL;
  21. }
复制代码

你的意思是不是代码运行了到了/**************** 1 ***********/处,所以skb被free掉了?

另外,根据你提到的:
IP层处理之后,找路由找到eth0,创建路由缓存,但是此时并没有对应WAN侧设备的ARP信息,因此创建一个邻居节点,将这个邻居节点和这条路由缓存关联起来,但是没有获取到ARP,所以,发送 ARP请求出去,

请问一下这个"因此创建一个邻居节点"的代码是在哪里呢?
我跟到了这个函数调用路径:

  1. ip_route_input_slow()-->rt_intern_hash()-->arp_bind_neighbour()-->__neigh_lookup_errno()-->neigh_create()
复制代码

但好像还是没看到哪里在发送arp request packet?
请kevert兄指点一下迷津。。。。谢谢~

论坛徽章:
0
26 [报告]
发表于 2009-03-28 00:05 |显示全部楼层
原帖由 new_learner 于 2009-3-27 23:20 发表


你的意思是不是代码运行了到了/**************** 1 ***********/处,所以skb被free掉了?


可能我理解错了,代码应该没有运行到/**************** 1 ***********/这里
而是运行到了

  1. else if (dst->neighbour)
  2.                 return dst->neighbour->output(skb); /*neigh_resolve_output()*/
复制代码

只是dst->neighbour->output()没有运行成功。

论坛徽章:
0
27 [报告]
发表于 2009-03-31 17:49 |显示全部楼层
原帖由 kevert 于 2009-3-29 10:38 发表
大概应该是这样子:
如果没有学习到ARP,那么就会将路由层发过来的报文先存储在该邻居节点的一个缓存队列上,当ARP尝试几次之后没有学到之后,就会认为该邻居不可达,从而设置该邻居的状态为NUD_FAILED,然后邻 ...

谢谢kevert的讲解。
我想最后arp reply没有与arp request对应起来的根本原因在这段代码:

  1. arp_rcv()-->arp_process()-->__neigh_lookup()-->neigh_lookup()

  2. struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
  3.                                struct net_device *dev)
  4. {
  5.         struct neighbour *n;
  6.         int key_len = tbl->key_len;
  7.         u32 hash_val = tbl->hash(pkey, dev) & tbl->hash_mask;   /*¼ÆËã³öhashÖµ*/
  8.        
  9.         NEIGH_CACHE_STAT_INC(tbl, lookups);

  10.         read_lock_bh(&tbl->lock);
  11.         for (n = tbl->hash_buckets[hash_val]; n; n = n->next)
  12.         {   
  13.                                 /*从这里可以看出,要匹配到tbl->hash_buckets里的元素,需要pkey和dev同时满足。
  14.                      但由于对arp的处理在bridge之后(可以参看netif_receive_skb()),在tbl->hash_buckets的n->dev
  15.                                是eth0,但接受进来的arp reply的dev却是br0,所以这里无法做到匹配,导致arp_process()中没有运行到
  16.                      neigh_update()这个函数里*/
  17.                 if (dev == n->dev && !memcmp(n->primary_key, pkey, key_len))
  18.                 {
  19.                         neigh_hold(n);
  20.                         NEIGH_CACHE_STAT_INC(tbl, hits);
  21.                         break;
  22.                 }
  23.         }
  24.         read_unlock_bh(&tbl->lock);
  25.         return n;   
  26. }
复制代码

论坛徽章:
0
28 [报告]
发表于 2009-03-31 23:58 |显示全部楼层
原帖由 kevert 于 2009-3-31 22:25 发表



是的,正解。因为找不到,所以导致ARP认为通过eth0无法到达该WAN设备。从而使得不通。


谢谢kevert的指点
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP