邻居子系统中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)就不太好明白了,请大家解惑,谢谢!
对dev->addr_len的检查估计是用于某些虚拟口上的ARP处理? nswcfd 发表于 2017-02-28 12:11
对dev->addr_len的检查估计是用于某些虚拟口上的ARP处理?
谢谢 nswcfd。
dev->addr_len如果为0,表示当前网络设备不需要硬件地址,当然似乎应该也就不需要创建邻居对象了。
这里我的疑问是既然已经不需要了,为何当lladdr也为0时,反而要创建邻居对象呢?
neighbor的代码和路由的代码耦合的比较深,通常情况下都需要有个neighbor的。(ip_finish_output) 本帖最后由 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:51 编辑
回复 5# jiufei19
哦,我终于想明白了,我之前的理解错误了。
其实它这里的逻辑是这样的:
(1)若lladdr为真,则一定要创建邻居对象;
(2)若dev->addr_len为0,则表明不需要邻居的物理地址,则尽管此时lladdr为0也没有关系,可以直接创建邻居对象
(3)若lladdr为0,但dev->addr_len为真,表明需要邻居物理地址,而此时因为lladdr为0,故无法创建邻居对象
再次感谢nswcfd:D 呵呵,我还真没有考虑的这么仔细呢。感谢分享 :)
页:
[1]