我们已经了解了整个路由表的数据结构,下面看看如何在路由表中查询一个路由信息。my_inet模块提供的路由查询接口定义如下:
int myfn_hash_lookup(struct fib_table *tb,
const struct flowi *flp, struct fib_result *res)
参数tb指定查询哪一张路由表;结构flp指定要查询的目的IP地址;res返回路由查询的结果。下面是结构struct fib_result的定义:
struct fib_result {
unsigned char prefixlen;
unsigned char nh_sel;
unsigned char type;
unsigned char scope;
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
__u32 network;
__u32 netmask;
#endif
struct fib_info *fi;
#ifdef CONFIG_IP_MULTIPLE_TABLES
struct fib_rule *r;
#endif
};
前面已经介绍过,tb->tb_data是一个zone哈希表,里面存放了所有的详细路由信息。同时,它还以链表的形式组织所有的zone。在
myfn_hash_lookup的实现中,就是通过遍历这张链表来查找信息的。当找到一个结构fib_node,其成员fn_key跟我们的目的地址一
致时,这就是我们想要找的fib_node。
对于找到的fib_node,我们遍历其成员fn_alias链表,对链表上每一个struct
fib_alias,我们首先判断其tos,如果跟flp的tos不符则跳到下一个,再判断其scope,如果小于flp的scope,也直接跳到下一
个。然后,我们置成员fa_state为FA_S_ACCESSED,表示该fib_alias被访问过。
接下来,我们访问该结构的成员struct
fib_info,如果其成员fib_flags中存在标志RTNH_F_DEAD,表示路由信息中的下一跳已经dead,也跳过。然后,遍历
fib_info的成员fib_nh,也就是一个结构体struct
fib_nh的数组,如果找到一个fib_nh项,其输出接口跟flp->oif相等,则填充查询结果,即结构体struct
fib_result:
res->prefixlen = zone->fz_order;
res->nh_sel = fib_info->fib_nhs;
res->type = fib_node->fib_alias->fa_type;
res->scope = fib_node->fib_alias->fa_scope;
res->fi = fib_node->fib_indo->fa_info;
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
res->netmask = zone->fz_mask;
res->network = fib_node->fn_key & (0xFFFFFFFF >> (32 - fib_node->fz_order));
#endif
atomic_inc(&res->fi->fib_clntref);
阅读(421) | 评论(0) | 转发(0) |