Chinaunix首页 | 论坛 | 博客
  • 博客访问: 680768
  • 博文数量: 404
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 1237
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-03 10:45
文章分类

全部博文(404)

文章存档

2017年(1)

2016年(27)

2015年(39)

2014年(55)

2013年(66)

2012年(216)

分类:

2012-10-31 20:33:15

原文地址:查询一个路由 作者:lwchsz

前面已经分析了FIB表中的单位:路由表,路由哈希表,路由域,路由节点,路由别名,路由信息。拿到一张具体的路由表,根据其提供的成员方法tb_lookup,可以为一个具体的目的地址查询到一条路由。tb_lookup的函数定义如下:
    int fn_hash_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
    tb是一张路由表的指针,由调用者指定(根据路由策略),flp指定目的地址(只要填成员dn_u.ip4_u.daddr即可),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
    };
    prefixlen是网络地址长度,nh_sel为路由信息中下一跳的数量(有多路径时大于1)。
    fn_hash_lookup先根据tb找到路由哈希表(tb->tb_data),然后根据flp指定的目的地址找到具体的路由域中的路由节点 (遍历fb_hash->fn_zone_list链表,拿目的地址跟路由域的成员fz_mask生成key,再到路由域的哈希表中去匹配路由节 点)。
    匹配到具体的路由节点后,调用函数fib_semantic_match寻找路由节点中的路由别名,最后生成查询结果。找到具体的路由别名后,其成员fa_state置FA_S_ACCESSED。
    下面看几个具体的例子,试验环境的eth0接口的IP地址是172.16.48.2,以目的地址172.16.48.2在RT_TABLE_LOCAL表中查询路由,得到的结果如下:
    struct fib_result{
        .prefixlen = 32;
        .nh_sel = 0;
        .type = RTN_LOCAL;
        .scope = RT_SCOPE_HOST;
        struct fib_info{
            .flags = 0;
            .protocol = RTPROT_KERNEL;
            .prefsrc = 172.16.48.2;
            .priority = 0;
            .nhs = 1;
            struct fib_nh{
                dev name: eth0
                flags: 0
                scope: RT_SCOPE_NOWHERE
                gw: 0.0.0.0
            }
        }
    }
    显然,这是预期的信息:使用接口eth0,本地接收。
    同样的查询,如果在RT_TABLE_MAIN中做,就会有不同的结果,前面讲过,main表中存放的是除本地接口地址,广播地址,NAT地址之外的没有指明所属表的路由。下面是其查询结果:
    struct fib_result{
        .prefixlen = 24;
        .nh_sel = 0;
        .type = RTN_UNICAST;
        .scope = RT_SCOPE_LINK;
        struct fib_info{
            .flags = 0;
            .protocol = RTPROT_KERNEL;
            .prefsrc = 172.16.48.2;
            .priority = 0;
            .nhs = 1;
            struct fib_nh{
                dev name: eth0
                flags: 0
                scope: RT_SCOPE_HOST
                gw: 0.0.0.0
            }
        }
    }
    显然这不是预期的结果。路由规则保证了对于任何一次路由查询,总会先查local表,再查main表,所以可以避免上述现象的发生。
阅读(338) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~