当然,我们选择路由1那章的遗留的接口进入分析
fib_lookup() 我们前面提到过fib初始化时,CONFIG_IP_MULTIPLE_TABLES 宏导致了两种方式的fib表初始化,
因此存在了有多路由表存在和无多路由表存在的情况,我们先看无多路由表的情况
static inline int
fib_lookup(struct net *net, const struct flowi *flp,
struct fib_result *res)
{
struct fib_table *table;
table = fib_get_table(net, RT_TABLE_LOCAL); 先查LOCAL
if (!table-> tb_lookup(table, flp, res))
return 0;
table = fib_get_table(net, RT_TABLE_MAIN); 再查MAIN
if (!table-> tb_lookup(table, flp, res))
return 0;
return -ENETUNREACH;
}
struct fib_result *res)
{
struct fib_table *table;
table = fib_get_table(net, RT_TABLE_LOCAL); 先查LOCAL
if (!table-> tb_lookup(table, flp, res))
return 0;
table = fib_get_table(net, RT_TABLE_MAIN); 再查MAIN
if (!table-> tb_lookup(table, flp, res))
return 0;
return -ENETUNREACH;
}
static inline struct fib_table *
fib_get_table(struct net *net, u32 id)
{
struct hlist_head *ptr;
ptr = id == RT_TABLE_LOCAL ?
&net->ipv4.fib_table_hash[ TABLE_LOCAL_INDEX] :
&net->ipv4.fib_table_hash[ TABLE_MAIN_INDEX];
return hlist_entry(ptr->first, struct fib_table, tb_hlist); 根据传入的id找到fib_table
}
{
struct hlist_head *ptr;
ptr = id == RT_TABLE_LOCAL ?
&net->ipv4.fib_table_hash[ TABLE_LOCAL_INDEX] :
&net->ipv4.fib_table_hash[ TABLE_MAIN_INDEX];
return hlist_entry(ptr->first, struct fib_table, tb_hlist); 根据传入的id找到fib_table
}
上一章的一幅图说明了这种结构
!table->
tb_lookup(table, flp, res)) 即
fn_hash_lookup
static int
fn_hash_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
{
int err;
struct fn_zone *fz;
struct fn_hash *t = (struct fn_hash *)tb->tb_data; 获得路由区队列
read_lock(&fib_hash_lock);
for (fz = t->fn_zone_list; fz; fz = fz->fz_next) { 扫描网络区
struct hlist_head *head;
struct hlist_node *node;
struct fib_node *f;
__be32 k = fz_key(flp->fl4_dst, fz); 取目标地址在该网络区的网络号 fl4_det&((fz)->fz_mask)
head = &fz->fz_hash [fn_hash(k, fz)]; fn_hash(k, fz)得到hash关键字 获得hash链头
fn_hash_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
{
int err;
struct fn_zone *fz;
struct fn_hash *t = (struct fn_hash *)tb->tb_data; 获得路由区队列
read_lock(&fib_hash_lock);
for (fz = t->fn_zone_list; fz; fz = fz->fz_next) { 扫描网络区
struct hlist_head *head;
struct hlist_node *node;
struct fib_node *f;
__be32 k = fz_key(flp->fl4_dst, fz); 取目标地址在该网络区的网络号 fl4_det&((fz)->fz_mask)
head = &fz->fz_hash [fn_hash(k, fz)]; fn_hash(k, fz)得到hash关键字 获得hash链头