jiufei19 发表于 2017-02-27 16:00

邻居子系统中neigh_event_ns函数的问题【已解决】

本帖最后由 jiufei19 于 2017-03-09 21:52 编辑

内核版本V2.6.23~V4.x

当本机收到一个ARP REQUEST后,将调用arp_process函数进行处理,因此有如下代码片段:


   833   if (arp->ar_op == htons(ARPOP_REQUEST) &&
   834         ip_route_input(skb, tip, sip, 0, dev) == 0) {
   835
   836         rt = (struct rtable*)skb->dst;
   837         addr_type = rt->rt_type;
   838
   839         if (addr_type == RTN_LOCAL) {
   840             n = neigh_event_ns(&arp_tbl, sha, &sip, dev);

而neigh_event_ns函数定义如下:

1074 struct neighbour *neigh_event_ns(struct neigh_table *tbl,
1075                  u8 *lladdr, void *saddr,
1076                  struct net_device *dev)
1077 {
1078   struct neighbour *neigh = __neigh_lookup(tbl, saddr, dev,
1079                        lladdr || !dev->addr_len);
1080   if (neigh)
1081         neigh_update(neigh, lladdr, NUD_STALE,
1082                  NEIGH_UPDATE_F_OVERRIDE);
1083   return neigh;
1084 }

接着再来看看__neigh_lookup函数的实现代码:

323 __neigh_lookup(struct neigh_table *tbl, const void *pkey, struct net_device *dev, int creat)
324 {   
325   struct neighbour *n = neigh_lookup(tbl, pkey, dev);
326
327   if (n || !creat)
328         return n;
329
330   n = neigh_create(tbl, pkey, dev);
331   return IS_ERR(n) ? NULL : n;
332 }

假定neigh_lookup始终查找失败,则:

(1)假设lladdr为空,dev->addr_len=0,那么lladdr || !dev->addr_len就为真,于是creat为真,则!creat为假,于是就需要调用neigh_create创建一个邻居对象

(2)假设lladdr为空,dev->addr_len=真,那么lladdr || !dev->addr_len就为假,于是creat为假,则!creat为真,于是就不调用neigh_create创建一个邻居对象

我的疑问就是(1)和(2)这到底是啥逻辑?其中(2)还似乎能理解下,但是(1)就不太好明白了,请大家解惑,谢谢!




nswcfd 发表于 2017-02-28 12:11

对dev->addr_len的检查估计是用于某些虚拟口上的ARP处理?

jiufei19 发表于 2017-03-05 09:20

nswcfd 发表于 2017-02-28 12:11
对dev->addr_len的检查估计是用于某些虚拟口上的ARP处理?

谢谢 nswcfd。
dev->addr_len如果为0,表示当前网络设备不需要硬件地址,当然似乎应该也就不需要创建邻居对象了。
这里我的疑问是既然已经不需要了,为何当lladdr也为0时,反而要创建邻居对象呢?


nswcfd 发表于 2017-03-07 16:16

neighbor的代码和路由的代码耦合的比较深,通常情况下都需要有个neighbor的。(ip_finish_output)

jiufei19 发表于 2017-03-09 17:54

本帖最后由 jiufei19 于 2017-03-09 18:00 编辑

nswcfd 发表于 2017-03-07 16:16
neighbor的代码和路由的代码耦合的比较深,通常情况下都需要有个neighbor的。(ip_finish_output)
没有理解nswcfd所说的意思呢?:D


根据代码的逻辑,若lladdr不为0,则若dev->addr_len为0,则表示当前网络设备不需要硬件地址,此时似乎也就没有必要创建邻居对象了,故源码中的这个逻辑没有问题,但是在dev->addr_len为0下,若lladdr也为0,则反而需要创建邻居对象,这个逻辑我没有搞明白是啥意思

jiufei19 发表于 2017-03-09 21:47

本帖最后由 jiufei19 于 2017-03-09 21:51 编辑

回复 5# jiufei19


哦,我终于想明白了,我之前的理解错误了。

其实它这里的逻辑是这样的:

(1)若lladdr为真,则一定要创建邻居对象;
(2)若dev->addr_len为0,则表明不需要邻居的物理地址,则尽管此时lladdr为0也没有关系,可以直接创建邻居对象
(3)若lladdr为0,但dev->addr_len为真,表明需要邻居物理地址,而此时因为lladdr为0,故无法创建邻居对象

再次感谢nswcfd:D

nswcfd 发表于 2017-03-16 15:20

呵呵,我还真没有考虑的这么仔细呢。感谢分享 :)
页: [1]
查看完整版本: 邻居子系统中neigh_event_ns函数的问题【已解决】