Linux路由表实现(2)

本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
作者:gfree.wind@gmail.com
博客:linuxfocus.blog.chinaunix.net
   


昨天学习了路由表hash实现的查询以及相关的一些数据结构。为了更清楚的说明路由表hash的实现方式,今天主要写一下使用hash时的路由表的数据组织结构。

第一层的数据结构是struct fib_table。
    struct fib_table {
        struct hlist_node tb_hlist;
        u32        tb_id;
        int        tb_default;
        unsigned char    tb_data[0];
    };

其中最重要的是tb_data,它是真正的hash方式存储的数据,对于hash实现的路由表,其数据结构为struct fn_hash

    struct fn_hash {
        struct fn_zone    *fn_zones[33];
        struct fn_zone    *fn_zone_list;
    };

fn_zones为大小33的数组,其索引值正好对应掩码长度。即fn_zones[0]对应掩码为0的路由(默认路由),fn_zones[1]对应掩码为1的路由,一直到fn_zones[32]对应掩码为32的路由。那么fn_zone_list是做什么用的呢?fn_zone_list是为了最佳匹配的路由查找。

比如当前有且只有3条路由,
1) ip route add 0.0.0.0/0 via 10.1.1.1
2) ip route add 192.168.3.0/24 via 10.1.1.2
3) ip route add 192.168.3.155/32 via 10.1.1.3
路由1存储在fn_zones[0]中,路由2存储在fn_zones[24],路由3存储在fn_zones[32]中。
那么此时的fn_zone_list指向的是fn_zones[32],完整的链表为
fn_zone_list(即fn_zones[32]).next->fn_zones[24]->fn_zones[0]。
这样按照前文学习的fib_table_lookup代码,顺序遍历fn_zone_list,也就实现了对路由的最佳匹配。

那么继续看struct fn_zone
    struct fn_zone {
        struct fn_zone        *fz_next;    /* Next not empty zone    */
        struct hlist_head    *fz_hash;    /* Hash table pointer    */
        int            fz_nent;    /* Number of entries    */

        int            fz_divisor;    /* Hash divisor        */
        u32            fz_hashmask;    /* (fz_divisor - 1)    */
    #define FZ_HASHMASK(fz)        ((fz)->fz_hashmask)

        int            fz_order;    /* Zone order        */
        __be32            fz_mask;
    #define FZ_MASK(fz)        ((fz)->fz_mask)
    };


到了这层,就是一个hash的实现,fz_hash相当于hash中的桶。当查找路由时,通过hash函数得到hash值假设为h,则对应的桶为fz_hash[h]。

而桶中数据的组织结构为hlist,通过遍历该hlist,即得到每一个路由节点struct fib_node。
    struct fib_node {
        struct hlist_node    fn_hash;
        struct list_head    fn_alias;
        __be32            fn_key;
        struct fib_alias fn_embedded_alias;
    };


本想画一个图的。。但是发现自己不太会玩UML画图工具呵。
估计上面的文字描述已经把路由表hash的实现方式清晰的描述出来了,就不上图了。

而且刚刚下了最新的stable kernel代码2.39.3,路由表已经不支持hash方式的实现了,只剩下trie方式。所以我也就不在这个hash的实现上耽误时间了——那个UML工具,已经浪费了我半个小时的时间了。

下次开始研究路由表trie的实现方式了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值