前面讲到过,FIB里的最基本单位是路由信息(struct fib_info),它保存了关于路由的下一跳信息,本地接口的IP地址等,一个路由项对应一个路由别名(struct fib_alias),路由别名由路由信息再加上tos,type,scope,state等信息组成。目的地址相同的路由项的路由别名共享一个路由节点 (struct fib_node),路由节点的作用就是用于管理路由别名。
下面再看看路由域struct fib_zone,下面是其定义:
struct fn_zone {
struct fn_zone *fz_next;
struct hlist_head *fz_hash;
int fz_nent;
int fz_divisor;
u32 fz_hashmask;
#define FZ_HASHMASK(fz) ((fz)->fz_hashmask)
int fz_order;
u32 fz_mask;
#define FZ_MASK(fz) ((fz)->fz_mask)
};
fz_order和fz_mask记录的是该路由域包含的路由节点的目的地址的长度和子网掩码,比如子网单播路由172.16.48.0的 fz_order就是24,fz_mask就是255.255.255.0,所有fz_order相同的路由节点都存放在同一个路由域中,fz_hash 就是用于存放路由节点的哈希表,哈希表的大小由fz_divisor记录,fz_hashmask为哈希表掩码,总是fz_divisor- 1,fz_nent记录该域中当前含有的路由节点的数量。
fz_divisor的初始值一般总为16,当哈希表fz_hash不够大时(fz_nent>fz_divisor*2),需要扩大哈希表。
因为在IP协议中,目的地址的最大长度为32,所以,需要有33个路由域(0-32),33个路由域组织在一起,组成一个路由哈希表struct fn_hash,其定义如下:
struct fn_hash {
struct fn_zone *fn_zones[33];
struct fn_zone *fn_zone_list;
};
fn_zone_list是路由域的链表,把fn_zones数组中所有的路由域按目的地址从大到小组织成链表放在一起。当我们需要查找一个路由节点的时 候,首先根据目的地址长度Z找到路由域fn_hash->fn_zones[Z],然后再根据哈希算法在路由域的fz_hash中找到一个链表,再 遍历这个链表即可找到需要的路由节点。
在策略路由中,允许存在多个路由表,路由表由结构体struct fib_table表示。其定义如下:
struct fib_table {
unsigned char tb_id;
unsigned tb_stamp;
int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res);
int (*tb_insert)(struct fib_table *table, struct rtmsg *r,
struct kern_rta *rta, struct nlmsghdr *n,
struct netlink_skb_parms *req);
int (*tb_delete)(struct fib_table *table, struct rtmsg *r,
struct kern_rta *rta, struct nlmsghdr *n,
struct netlink_skb_parms *req);
int (*tb_dump)(struct fib_table *table, struct sk_buff *skb,
struct netlink_callback *cb);
int (*tb_flush)(struct fib_table *table);
void (*tb_select_default)(struct fib_table *table,
const struct flowi *flp, struct fib_result *res);
unsigned char tb_data[0];
};
tb_id是路由表的标识符,id为RT_TABLE_MAIN和RT_TABLE_LOCAL的两张路由表是内核定义的,RT_TBALE_LOCAL 称为本地路由表,本地接口地址,广播地址,已及NAT地址都放在这个表。该路由表由系统自动维护,管理员不能直接修改。RT_TABLE_MAIN称为主 路由表,如果没有指明路由所属的表,所有的路由都默认都放在这个表里。
tb_data即为路由哈希表,存放着33个路由域(大部分时间,大部分路由域都是空的)。每个路由表的路由哈希表都是独立的,互不相干的。将由路由策略来决定某次路由查询使用那个路由表的路由哈希表。
其它是路由表提供的一些操作路由哈希表的方法,包括查询一条路由,插入,删除,刷新路由等。
全局变量fib_tables是一个路由表的数组,只存在于系统支持策略路由的情况下,共有256项,所以,系统最多可以建立256张路由表。
至此,路由表,路由哈希表,路由域,路由节点,路由别名,路由信息的概念都已介绍完毕,要让路由表能真正工作起来,还需要路由规则来帮助决定在具体情况下使用哪一张路由表。
下面再看看路由域struct fib_zone,下面是其定义:
struct fn_zone {
struct fn_zone *fz_next;
struct hlist_head *fz_hash;
int fz_nent;
int fz_divisor;
u32 fz_hashmask;
#define FZ_HASHMASK(fz) ((fz)->fz_hashmask)
int fz_order;
u32 fz_mask;
#define FZ_MASK(fz) ((fz)->fz_mask)
};
fz_order和fz_mask记录的是该路由域包含的路由节点的目的地址的长度和子网掩码,比如子网单播路由172.16.48.0的 fz_order就是24,fz_mask就是255.255.255.0,所有fz_order相同的路由节点都存放在同一个路由域中,fz_hash 就是用于存放路由节点的哈希表,哈希表的大小由fz_divisor记录,fz_hashmask为哈希表掩码,总是fz_divisor- 1,fz_nent记录该域中当前含有的路由节点的数量。
fz_divisor的初始值一般总为16,当哈希表fz_hash不够大时(fz_nent>fz_divisor*2),需要扩大哈希表。
因为在IP协议中,目的地址的最大长度为32,所以,需要有33个路由域(0-32),33个路由域组织在一起,组成一个路由哈希表struct fn_hash,其定义如下:
struct fn_hash {
struct fn_zone *fn_zones[33];
struct fn_zone *fn_zone_list;
};
fn_zone_list是路由域的链表,把fn_zones数组中所有的路由域按目的地址从大到小组织成链表放在一起。当我们需要查找一个路由节点的时 候,首先根据目的地址长度Z找到路由域fn_hash->fn_zones[Z],然后再根据哈希算法在路由域的fz_hash中找到一个链表,再 遍历这个链表即可找到需要的路由节点。
在策略路由中,允许存在多个路由表,路由表由结构体struct fib_table表示。其定义如下:
struct fib_table {
unsigned char tb_id;
unsigned tb_stamp;
int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res);
int (*tb_insert)(struct fib_table *table, struct rtmsg *r,
struct kern_rta *rta, struct nlmsghdr *n,
struct netlink_skb_parms *req);
int (*tb_delete)(struct fib_table *table, struct rtmsg *r,
struct kern_rta *rta, struct nlmsghdr *n,
struct netlink_skb_parms *req);
int (*tb_dump)(struct fib_table *table, struct sk_buff *skb,
struct netlink_callback *cb);
int (*tb_flush)(struct fib_table *table);
void (*tb_select_default)(struct fib_table *table,
const struct flowi *flp, struct fib_result *res);
unsigned char tb_data[0];
};
tb_id是路由表的标识符,id为RT_TABLE_MAIN和RT_TABLE_LOCAL的两张路由表是内核定义的,RT_TBALE_LOCAL 称为本地路由表,本地接口地址,广播地址,已及NAT地址都放在这个表。该路由表由系统自动维护,管理员不能直接修改。RT_TABLE_MAIN称为主 路由表,如果没有指明路由所属的表,所有的路由都默认都放在这个表里。
tb_data即为路由哈希表,存放着33个路由域(大部分时间,大部分路由域都是空的)。每个路由表的路由哈希表都是独立的,互不相干的。将由路由策略来决定某次路由查询使用那个路由表的路由哈希表。
其它是路由表提供的一些操作路由哈希表的方法,包括查询一条路由,插入,删除,刷新路由等。
全局变量fib_tables是一个路由表的数组,只存在于系统支持策略路由的情况下,共有256项,所以,系统最多可以建立256张路由表。
至此,路由表,路由哈希表,路由域,路由节点,路由别名,路由信息的概念都已介绍完毕,要让路由表能真正工作起来,还需要路由规则来帮助决定在具体情况下使用哪一张路由表。