山西长治供电公司_linux路由表的结构与算法分析_20160420

上传人:今*** 文档编号:105783928 上传时间:2019-10-13 格式:DOC 页数:18 大小:161KB
返回 下载 相关 举报
山西长治供电公司_linux路由表的结构与算法分析_20160420_第1页
第1页 / 共18页
山西长治供电公司_linux路由表的结构与算法分析_20160420_第2页
第2页 / 共18页
山西长治供电公司_linux路由表的结构与算法分析_20160420_第3页
第3页 / 共18页
山西长治供电公司_linux路由表的结构与算法分析_20160420_第4页
第4页 / 共18页
山西长治供电公司_linux路由表的结构与算法分析_20160420_第5页
第5页 / 共18页
点击查看更多>>
资源描述

《山西长治供电公司_linux路由表的结构与算法分析_20160420》由会员分享,可在线阅读,更多相关《山西长治供电公司_linux路由表的结构与算法分析_20160420(18页珍藏版)》请在金锄头文库上搜索。

1、Linux路由表的结构与算法分析 路由是网络栈的核心部分。路由表本身的设计很大情度上影响着路由的性能,并且好的设计 能减少系统资源的消耗,这两方面尤其体现在路由表的查找上。目前的内核路由存在两种查找算法,一种为HASH算法,另一种为LC-trie算法,前者是目 前内核使用的缺省算法,而后者更适用在超大路由表的情况,它在这种情况提高查找效率的同时,大大地增加了算法本身的复杂性和内存的消耗。综上,这两种算法 各有其适用的场合,本文分析了基于2.6.18内核路由部分的代码在HASH算法上路由表结构的实现,并且在文章最后给出了一个简单的策略路由的应用。 一、路由表的结构 为了支持策略路由,Linux使

2、用了多个路由表而不是一个,即使不使用策略路由,Linux也使用了 两个路由表,一个用于上传给本地上层协议,另一个则用于转发。Linux使用多个路由表而不是一个,使不同策略的路由存放在不同的表中,有效地被免了查找 庞大的路由表,在一定情度上提高了查找了效率。 路由表本身不是由一个结构表示,而是由多个结构组合而成。路由表可以说是一个分层的结构组合。在第一层,它先将所有的路由根据子网掩码(netmask)的长度(032)分成33个部分(struct fn_zone),然后在同一子网掩码(同一层)中,再根据子网的不同(如10.1.1.0/24和10.1.2.0/24),划分为第二层 (struct f

3、ib_node),在同一子网中,有可能由于TOS等属性的不同而使用不同的路由,这就是第三层(struct fib_alias),第三层结构表示一个路由表项,而每个路由表项又包括一个相应的参数,如协议,下一跳路由地址等等,这就是第四层(struct fib_info)。分层的好处是显而易见的,它使路由表的更加优化,逻辑上也更加清淅,并且使数据可以共享(如struct fib_info),从而减少了数据的冗余。struct fib_table *fib_tablesRT_TABLE_MAX+1; / RT_TABLE_MAX 为255 图1为一个路由表的总体结构。自上而下由左向右看,它首先为一个f

4、ib_table结构指针的数组,它被定义为: struct fib_table unsigned char tb_id; unsigned tb_stamp; int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res); int (*tb_insert)(struct fib_table *table, struct rtmsg *r, void (*tb_select_default)(struct fib_table *table, const struct flowi *f

5、lp, struct fib_result *res); unsigned char tb_data0; 每个fib_table结构在内核中表示一个路由表: +图1(引自1)这个结构中包括这个表的ID,以及主要的一些用于操作路由表的函数指针,这里我们只关心最后一域tb_data0,这是一个零长的数组,它在内核中也较为常见,它表示struct fn_hash struct fn_zone *fn_zones33;struct fn_zone *fn_zone_list;指向这个结构的末尾。由图1可以看到,这个结构的末尾接着便是一个struct fn_hash结构,这个结构是随fib_table结

6、构一起分配的,所以fib_table-tb_data就是fn_hash。 struct fn_zone struct fn_zone *fz_next; /* Next not empty zone */ struct hlist_head *fz_hash; /* Hash table pointer */ int fz_nent; /* Number of entries */ int fz_divisor; /* Hash divisor */ u32 fz_hashmask; /* (fz_divisor - 1) */#define FZ_HASHMASK(fz) (fz)-fz_h

7、ashmask) int fz_order; /* Zone order */ u32 fz_mask;#define FZ_MASK(fz) (fz)-fz_mask); 这个fn_zone域就是我们上面提前的结构,用于将路由根据子网掩码的长度分开成33个部分,其中fn_zones0用于默认网关。而fn_zone_list域就是将正在使用的fn_zone链成一个链表。接着再深入到struct fn_zone结构中:这个结构中有两个域比较重要,一个为fz_hash域,它指向一个HASH表的表头,这个HASH的长度是fz_divisor。并且这个HASH表的长度是可变的,当表长达到一个限定值时,

8、将重建这个HASH表,被免出现HASH冲突表过长造成查找效率降低。 为了提高查找的效率,内核使用了大量的HASH表,而路由表就是一个例子。在图1中可以看到,等长子网掩码的路由存放在同一个fn_zone中,而根据到不同子网(fib_node)的路由键值(fn_key),将它HASH到相应的链表中。struct fib_node struct hlist_node fn_hash; struct list_head fn_alias; u32 fn_key; 这个键值其实就是这个子网值了(如10.1.1.0/24,则子网值为 10.1.1),得到这个键值通过n = fn_hash()函数HASH之

9、后就是这个子网对应的HASH值,然后就可以插入到相应的fz_hashn链表中了。冲突的fib_node由 fn_hash域相链,而fn_alias则是指向到达这个子网的路由了。struct fib_alias struct list_head fa_list; struct rcu_head rcu; struct fib_info *fa_info; u8 fa_tos; u8 fa_type; u8 fa_scope; u8 fa_state; 当到达这个子网的路由由于TOS等属性的不同可存在着多个路由时,它们就通过fib_alias中fa_list域将这些路由表项链成一个链表。这个结构中

10、的另一个域fa_info指向一个fib_info结构,这个才是存放真正重要路由信息的结构。struct fib_info struct hlist_node fib_hash; struct hlist_node fib_lhash; int fib_dead; unsigned fib_flags; int fib_protocol; u32 fib_prefsrc; u32 fib_priority; int fib_nhs; struct fib_nh fib_nh0;#define fib_dev fib_nh0.nh_dev; 这个结构里面是一个用于路由的标志和属性,其中最重要的一个

11、域是fib_nh0, 在这里,我们再次看到了零长数组的应用,它是通过零长来实现变长结构的功能的。因为,我们需要一个定长的fib_info结构,但是在这个结构末尾,我们 需要的fib_nh结构的个数是不确定的,它在运行时确定。这样,我们就可以通过这种结构组成,在运行时为fib_info分配空间的时候,同时在其末尾 分配所需的若干个fib_nh结构数组,并且这个结构数组可以通过fib_info-fib_nhn来访问,在完成fib_info的分配后 将fib_nhs域置为这个数组的长度。 另一方面,fib_info也是HASH表的一个应用,结构中存在着两个域,分别是 fib_hash 和fib_lh

12、ash,它们都用于HASH链表。这个结构在完成分配后,将被用fib_hash域链入fib_info_hash表中,如果这个路由存在 首选源地址,这个fib_info将同时被用fib_lhash链入fib_info_laddrhash表中。这样,就可以根据不同目的实现快速查找了。 Struct fib_nh也是一个重要的结构。它存放着下一跳路由的地址(nh_gw)。刚刚已经提到,一个路由(fib_alias)可能有多个fib_nh结构, 它表示这个路由有多个下一跳地址,即它是多路径(multipath)的。下一跳地址的选择也有多种算法,这些算法都是基于nh_weight, nh_power域的。nh_hash域则是用于将nh_hash链入HASH表的。struct fib_nh struct net_device *nh_dev; struct hlist_node nh_hash; struct fib_info *nh_parent; unsigned nh_flags; unsigned char nh_scope;#ifdef CONFIG_IP_ROUTE_MULTIPATH int nh_weight; int nh_power;#endif#ifdef CONFIG

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号