免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3192 | 回复: 18

[网络子系统] fn_hash_select_default函数的疑问2 [复制链接]

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-11-17 06:20:00
发表于 2016-12-26 17:09 |显示全部楼层
本帖最后由 jiufei19 于 2016-12-28 17:01 编辑

前一篇帖子http://bbs.chinaunix.net/thread-4257706-1-1.html,我谈到了一个问题,后来基本解决,下面我再谈谈这个函数的逻辑处理中我无法理解的问题。

首先,无论有多少个缺省路由设置,在内核路由表中始终都只有一个fib_node结点对应缺省路由。然后我们假定该fib_node下有3个fib_alias结点,分别为fib_alias2~fib_alias4,并且假设每个fib_alias都有自己的独立fib_info对象,而每个fib_info中都有一个fib_nh对象。

其次,fib_alias结点按其fa_tos的降序进行排序,而具有相同fa_tos的fib_alias按各自下属fib_info的fib_priority的升序排列。

再次,假定fib_alias2~fib_alias4的tos分别为:tos2,tos2,tos4,即fib_alias2和fib_alias3的tos相同。
再次,由于每次路由查询fib_lookup总是返回首个符合要求的res,而由于fib_alias按tos降序排列,并在tos相同时按fib_priority升序排列,因此这里的res应该对应fib_alias2结点。

再次,假定每个fib_info的优先级分别为fib_priority2~fib_priority4,并且有fib_priority3大于fib_priority2。

再次,假定执行fn_hash_select_default之前,其他线程刚好添加了一条新的缺省路由器,即fib_alias1,我们假定fib_alias1的tos大于fib_alias2~fib_alias4,并包含下属fib_info1,其优先级为fib_priority1。

下面,fn_hash_select_default函数的如下红色代码就很难理解了:

   298     hlist_for_each_entry(f, node, &fz->fz_hash[0], fn_hash) {
   299         struct fib_alias *fa;
   300
   301         list_for_each_entry(fa, &f->fn_alias, fa_list) {
   302             struct fib_info *next_fi = fa->fa_info;
   303
   304             if (fa->fa_scope != res->scope ||
   305                 fa->fa_type != RTN_UNICAST)
   306                 continue;
   307
   308             if (next_fi->fib_priority > res->fi->fib_priority)
   309                 break;
   310             if (!next_fi->fib_nh[0].nh_gw ||
   311                 next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
   312                 continue;
   313             fa->fa_state |= FA_S_ACCESSED;
   314
   315             if (fi == NULL) {
   316                 if (next_fi != res->fi)        
   317                     break;



  我们以第308-309行为例进行说明,由于在第301行是按当前fib_node的下属fib_alias结点链表进行遍历的,所以应该从首个fib_alias1开始进行处理,而不是从fib_alias2进行处理,而我们假设fib_alias1的优先级属性,即next_fi->fib_priority比res->fi->fib_priority大,那么这里就立刻break了,即跳出第301行的遍历,不再检查后续fib_alias2~fib_alias4,显然这个处理逻辑太让人费解了,这到底是啥意思???




论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-11-17 06:20:00
发表于 2016-12-27 10:49 |显示全部楼层
本帖最后由 jiufei19 于 2016-12-27 22:41 编辑

回复 1# jiufei19

昨天仔细思考了下,这个问题看来只能有一个理由可以解释,即对于缺省路由,是没有tos设置的,如果我的这个猜测正确的话,则可以解释fn_hash_select_default函数不对tos进行判断,而直接就是对fib_priority进行检查的原因了。



假设第301的遍历操作找到一个fib_alias,并且next_fi->fib_priority小于res->fi->fib_priority,则此时第316行的if条件必然不成立,如下红色代码所示:

301         list_for_each_entry(fa, &f->fn_alias, fa_list) {
   302             struct fib_info *next_fi = fa->fa_info;
   ...                ...
   307
   308             if (next_fi->fib_priority > res->fi->fib_priority)
   309                 break;

   ...               ...
   315             if (fi == NULL) {
  316                 if (next_fi != res->fi)         
   317                     break;
   318             } else if (!fib_detect_death(fi, order, &last_resort,
   319                              &last_idx, &fn_hash_last_dflt)) {
   320                 if (res->fi)
   321                     fib_info_put(res->fi);
   322                 res->fi = fi;                  
   323                 atomic_inc(&fi->fib_clntref);
   324                 fn_hash_last_dflt = order;
   325                 goto out;
   326             }
   327             fi = next_fi;
   328             order++;
   329         }// end of list_for_each_entry

这里next_fi不等于res->fi的原因是在fib_lookup后,系统又添加了一条缺省路由,且其优先级别高于之前fib_lookup所查询到的res所对应的旧的缺省路由,但是为啥明明找到了一条新的更高优先级的缺省路由(fib_priority值更小)后,就立刻break,不再继续查找余下的fib_alias了,相反,当next_fi等于res->fi时,表明自从上次fib_lookup查询到某个缺省路由后,此时尚无新的更高优先级的缺省路由被加入,因此第327行将next_fi保存在fi中,随后返回到第301行继续遍历下一个fib_alias,这到底是什么逻辑?

这个fn_hash_select_default函数的逻辑实在让人摸不清头脑呢,还望各位大侠能解惑!



论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
发表于 2016-12-27 12:00 |显示全部楼层
回复 2# jiufei19


都放假了,谁还回答你问题

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-11-17 06:20:00
发表于 2016-12-27 12:20 |显示全部楼层
回复 3# _nosay

_nosay能回答我这个疑问吗?

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
发表于 2016-12-27 12:50 |显示全部楼层
回复 4# jiufei19


我不会,我知道有几位版主和nswcfd他们,功力深厚,不过要等他们看到你的帖子。

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
发表于 2016-12-30 11:47 |显示全部楼层
即对于缺省路由,是没有tos设置的,

暂时不能回答楼主的问题,不过这个逻辑似乎不太成立。
就算没有显式的进行tos配置,创建fib/alias的时候也是有tos值的,只不过是默认值。
除非存在对这个默认值进行特殊处理的代码,否则大概不是这个原因吧。

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
发表于 2016-12-30 19:58 |显示全部楼层
select_default是在不开启MULTIPATH的情况下启用的,估计是早期的多路径的解决方案(并且只针对默认路由)?

由于fib-lookup只返回(满足tos/scope/oif)的第一个alias(某个默认路由),其它的alias被屏蔽了。
不知道使用select_default_route的初衷,是不是给其它alias一个机会?

之前好像真没怎么关注这一点呢……

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-11-17 06:20:00
发表于 2016-12-30 22:24 |显示全部楼层
nswcfd 发表于 2016-12-30 11:47
暂时不能回答楼主的问题,不过这个逻辑似乎不太成立。
就算没有显式的进行tos配置,创建fib/alias的时候 ...

非常感谢nswcfd的答复,虽然没有解决我的问题。
nswcfd说的不错,就算没有tos的显式设置,也有隐式设置,其实就是为0。

不过如果当前所有fib_alias的tos都为0,或者都不为0且相同,则只比较fib_priority的大小才是有意义的,否则因为tos和fib_priority属于不同级别的属性,而该函数只按fib_priority进行比较就很令人费解,正因为如此,我才猜测此时tos不起任何作用。

然而,的确这个函数的逻辑太另类了,很难用文字描述清楚它究竟想干啥。

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-11-17 06:20:00
发表于 2016-12-30 22:34 |显示全部楼层
nswcfd 发表于 2016-12-30 19:58
select_default是在不开启MULTIPATH的情况下启用的,估计是早期的多路径的解决方案(并且只针对默认路由) ...

假设在进行fn_hash_select_default之前,另外一个线程插入了一个新的缺省路由,且其对应的fib_alias排在之前fib_lookup所查找到的res对应的fib_alias之前,则按此函数逻辑,第316行立刻break,那么就跳到第334行goto out处,则此函数处理完毕。似乎想表达这样一个意思,即因为又找到了一个有更高优先级的缺省路由,则就可以暂时继续使用之前那个res对应的缺省路由,哪怕该res对应的缺省路由网关最终不可达也没有关系,因为毕竟已经有一个新的更高优先级缺省路由存在了。反之,如果没有找到有更高优先级的,则原来res对应的那个仍然是目前最高优先级的,则我们需要继续判断其的确是否仍然可用,如果不可用,就继续遍历和其同级的或者较低优先级的其他缺省路由。

该函数的逻辑大体如此,不过虽然我大概知道其逻辑是这样,但是仍然感到很困惑,例如之前那个对tos缺乏检查的问题。


论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-11-17 06:20:00
发表于 2017-01-03 11:29 |显示全部楼层
回复 9# jiufei19

烦请各位大侠帮助我解决此问题
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP