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

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

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

路由缓存插入条目

函数rt_intern_hash()

要插入的条目是rt,相应散列值是hash,首先通过hash值找到对应的bucket

rthp = &rt_hash_table[hash].chain;

然后对bucket进行一遍查询,这次查询的目的有两个:如果是超时的条目,则直接 删除;如果是与rt相同键值的条目,则删除并将rt插入头部返回。

while ((rth = *rthp) != NULL) {

if (rt_is_expired(rth)) { // 超时的条目

*rthp = rth->u.dst.rt_next;

rt_free (rth);

continue;

}

if (compare_keys(&rth->fl, &rt->fl) && compare_netns (rth, rt)) { //重复的条目

*rthp = rth->u.dst.rt_next;

rcu_assign_pointer(rth->u.dst.rt_next, rt_hash_table[hash].chain);

rcu_assign_pointer(rt_hash_table[hash].chain, rth);

……

}

……

rthp = &rth->u.dst.rt_next;

}

在扫描一遍后,如rt还未存在,则将其插入头部

rt ->u.dst.rt_next = rt_hash_table[hash].chain;

rcu_assign_pointer(rt_hash_table[hash].chain, rt);

如果新插入rt满足一定条件,还要与ARP邻居表进行绑定

Hint:缓存的每个bucket是没有头结点的,单向链表,它所使用 的插入和删除操作是值得学习的,简单实用。

路由缓存删除条目

rt_del()

要删除的条目是rt,相应散列 值是hash,首先通过hash值找到对应的bucket,然后遍历,如果条目超时,或找到rt,则删除它。

rthp = &rt_hash_table[hash].chain;

spin_lock_bh(rt_hash_lock_addr(hash));

ip_rt_put(rt);

while ((aux = *rthp) != NULL) {

if (aux == rt || rt_is_expired(aux)) {

*rthp = aux- >u.dst.rt_next;

rt_free(aux);

continue;

}

rthp = &aux->u.dst.rt_next;

}

spin_unlock_bh(rt_hash_lock_addr(hash));

路由表的创建

inet_init() -> ip_init() -> ip_fib_init() -> fib_net_init() -> ip_fib_net_init()[net/ipv4/fib_frontend.c]

首先为路由表分配空间, 这里的每个表项hlist_head实际都会链接一个单独的路由表,FIB_TABLE_HASHSZ表示了分配多少个路由表,一般情况下至少有两 个– LOCAL和MAIN。注意这里仅仅是表头的空间分配,还没有真正分配路由表空间。

net->ipv4.fib_table_hash = kzalloc(

sizeof(struct hlist_head)*FIB_TABLE_HASHSZ, GFP_KERNEL);

ip_fib_net_init() -> fib4_rules_init(),这里真正分配了路由表空间

local_table = fib_hash_table(RT_TABLE_LOCAL);

main_table = fib_hash_table(RT_TABLE_MAIN);

然后将local和main表链入之前的fib_table_hash中

hlist_add_head_rcu (&local_table->tb_hlist,

&net->ipv4.fib_table_hash [TABLE_LOCAL_INDEX]);

hlist_add_head_rcu(&main_table->tb_hlist,

&net- >ipv4.fib_table_hash[TABLE_MAIN_INDEX]);

最终生成结构如图,LOCAL表位于fib_table_hash[0],MAIN表位于 fib_table_hash[1];两张表通过结构tb_hlist链入链表,而tb_id则标识了功能,255是LOCAL表,254是MAIN表。

关于这 里的struct fn_hash,它表示了不同子网掩码长度的hash表[即fn_zone],对于ipv4,从0~32共33个。而fn_hash的实现则是 fib_table的最后一个参数unsigned char tb_data[0]。

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

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

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

热点阅读