加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_丽江站长网 (http://www.0888zz.com/)- 科技、建站、数据工具、云上网络、机器学习!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Linux内核分析 - 网络[四]:路由表

发布时间:2016-05-29 07:21:34 所属栏目:Linux 来源:网络整理
导读:路由表 在内核中存在路由表fib_table_hash和路由缓存表rt_hash_table。路由缓存表主要是为了加速路由的查找, 每次路由查询都会先查找路由缓存,再查找路由表。

注意到这里fn_zone 还只是空指针,我们还只完成了路由表初始化的一部分。在启动阶段还会调用inet_rtm_newroute() -> fib_table_insert() -> fn_new_zone() [fib_hash.c]来创建fn_zone结构,前面已经讲过,fn_zone一共有33个,其中掩码长度为0[/0]表示为默 认路由,fn_zone可以理解为相同掩码的地址集合。

首先为fn_zone分配空间

struct fn_zone *fz = kzalloc (sizeof(struct fn_zone), GFP_KERNEL);

传入参数z代表掩码长度, z = 0的掩码用于默认路由,一般只有一个,所以 fz_centerisor只需设为1;其它设为16;这里要提到fz_centerisor的作用,fz->fz_hash并不是个单链表,而是一个哈希表,而哈 希表的大小就是fz_centerisor。

if (z) {

fz->fz_centerisor = 16;

} else {

fz->fz_centerisor = 1;

}

fz_hashmask实际是用于求余数的,当算出hash值,再hash & fz_hashmask就得出了在哈希表的位置;而 fz_hash就是下一层的哈希表了,前面已经提过路由表被多组分层了,这里fz_hash就是根据fz_centerisor大小来创建的;fz_order 就是子网掩码长度;fz_mask就是子网掩码。

fz->fz_hashmask = (fz->fz_centerisor - 1);

fz->fz_hash = fz_hash_alloc(fz->fz_centerisor);

fz->fz_order = z;

fz->fz_mask = inet_make_mask(z);

从子网长度大于新添加fz的fn_zone中挑选一个不为空的fn_zones[i],将新创建的fz设成fn_zones[i].next;然后将fz根据掩码 长度添加到fn_zones[]中相应位置;fn_zone_list始终指向掩码长度最长的fn_zone。

for (i=z+1; i<=32; i++)

if (table->fn_zones[i])

break;

if (i>32) {

fz->fz_next = table- >fn_zone_list;

table->fn_zone_list = fz;

} else {

fz->fz_next = table->fn_zones [i]->fz_next;

table->fn_zones[i]->fz_next = fz;

}

table->fn_zones[z] = fz;

这里的fn_hash是数组与链表的结合体,看下fn_hash定义

struct fn_hash {

struct fn_zone *fn_zones [33];

struct fn_zone *fn_zone_list;

};

fn_hash包含33数组元素,每个元素存放一定掩码长度的 fn_zone,其中fn_zone[i]存储掩码长度为i。而fn_zone通过内部属性fz_next又彼此串连起来,形成单向链表,其中 fn_zone_list可以看作链表头,而这里链表的组织顺序是倒序的,即从掩码长到短。

Linux内核分析 - 网络[四]:路由表

到这里,fz_hash所 分配的哈希表还没有插入内容,这部分为fib_insert_node()完成。

inet_rtm_newroute() -> fib_table_insert() -> fib_insert_node() [net/ipv4/fib_hash.c]

这里f是fib_node,可以理解为具有相同网络地址的路由项集合。根 据fn_key(网络地址)和fz(掩码长度)来计算hash值,决定将f插入fz_hash的哪个项。

struct hlist_head *head = &fz->fz_hash[fn_hash(f->fn_key, fz)];

hlist_add_head(&f->fn_hash, head);

}

(编辑:应用网_丽江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读