數據結構
[TODO] 僅列出來,未整理,且最好附上關係圖
struct fib_table {
struct hlist_node tb_hlist; //用來將各個路由表連接成一個雙向鏈表
u32 tb_id; //路由標識,最多可以有256個路由表(靜態路由、策略路由等等表項)
unsigned tb_stamp;
int tb_default;
int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res); //搜索路由表項
int (*tb_insert)(struct fib_table *, struct fib_config *); //插入給定的路由表項
int (*tb_delete)(struct fib_table *, struct fib_config *); //刪除給定的路由表項
int (*tb_dump)(struct fib_table *table, struct sk_buff *skb, //dump出路由表的內容
struct netlink_callback *cb);
int (*tb_flush)(struct fib_table *table); //刷新路由表項,並刪除帶有RTNH_F_DEAD標誌的fib_node
void (*tb_select_default)(struct fib_table *table, //選擇一條默認的路由
const struct flowi *flp, struct fib_result *res);
unsigned char tb_data[0]; //路由表項的散列表的起始地址,指向fn_hash
};
struct fn_hash {
struct fn_zone *fn_zones[33];
struct fn_zone *fn_zone_list; //fn_zone鏈表
};
struct fn_zone {
struct fn_zone *fz_next; /* Next not empty zone 將不爲空的路由表項fn_zone鏈接在一起,該鏈表頭存儲在fn_hash的fn_zone_list中 */
struct hlist_head *fz_hash; /* Hash table pointer 指向存儲路由表項fib_node的散列表 */
int fz_nent; /* Number of entries 在zone的散列表中的fib_node的數目,用於判斷是否需要改變散列表的容量 */
int fz_divisor; /* Hash divisor 散列表fz_hash的容量,即散列表桶的數目每次擴大2倍,最大1024 */
u32 fz_hashmask; /* (fz_divisor - 1) */
#define FZ_HASHMASK(fz) ((fz)->fz_hashmask)
int fz_order; /* Zone order 掩碼fz_mask的長度 */
__be32 fz_mask; //利用fz_order構造得到的網絡掩碼
#define FZ_MASK(fz) ((fz)->fz_mask)
};
struct fib_node {
struct hlist_node fn_hash; //用於散列表中同一桶內的所有fib_node鏈接成一個雙向鏈表
struct list_head fn_alias; //指向多個fib_alias結構組成的鏈表
__be32 fn_key; //由IP和路由項的netmask與操作後得到,被用作查找路由表的搜索條件
struct fib_alias fn_embedded_alias; //內嵌的fib_alias結構,一般指向最後一個fib_alias
};
struct fib_alias {
struct list_head fa_list; //將所有fib_alias組成的鏈表
struct fib_info *fa_info; //指向fib_info,儲存如何處理路由信息
u8 fa_tos; //路由的服務類型比特位字段
u8 fa_type; //路由表項的類型,間接定義了當路由查找匹配時,應採取的動作
u8 fa_scope; //路由表項的作用範圍
u8 fa_state; //一些標誌位,目前只有FA_S_ACCESSED。表示該表項已經被訪問過。
#ifdef CONFIG_IP_FIB_TRIE
struct rcu_head rcu;
#endif
};
struct fib_info {
struct hlist_node fib_hash; //所有fib_info組成的散列表,該表爲全局散列表fib_info_hash
struct hlist_node fib_lhash; //當存在首源地址時,纔會將fib_info插入該散列表,該表爲全局散列表fib_info_laddrhash
struct net *fib_net;
int fib_treeref; //使用該fib_info結構的fib_node的數目
atomic_t fib_clntref; //引用計數,路由查找成功而被持有的引用計數
int fib_dead; //標記路由表項正在被刪除的標誌,當該標誌被設置爲1時,警告該數據結構將被刪除而不能再使用
unsigned fib_flags; //當前使用的唯一標誌是RTNH_F_DEAD,表示下一跳已無效
int fib_protocol; //設置路由的協議
__be32 fib_prefsrc; //首選源IP地址
u32 fib_priority; //路由優先級,默認爲0,值越小優先級越高
u32 fib_metrics[RTAX_MAX]; //與路由相關的度量值
#define fib_mtu fib_metrics[RTAX_MTU-1]
#define fib_window fib_metrics[RTAX_WINDOW-1]
#define fib_rtt fib_metrics[RTAX_RTT-1]
#define fib_advmss fib_metrics[RTAX_ADVMSS-1]
int fib_nhs; //可用的下一跳數量,通常爲1.只有支持多路徑路由時,才大於1
#ifdef CONFIG_IP_ROUTE_MULTIPATH
int fib_power;
#endif
struct fib_nh fib_nh[0]; //表示路由的下一跳
#define fib_dev fib_nh[0].nh_dev
};
struct fib_nh {
struct net_device *nh_dev; //該路由表項輸出網絡設備
struct hlist_node nh_hash; //fib_nh組成的散列表
struct fib_info *nh_parent; //指向所屬fib_info結構體
unsigned nh_flags;
unsigned char nh_scope;
#ifdef CONFIG_IP_ROUTE_MULTIPATH
int nh_weight;
int nh_power;
#endif
#ifdef CONFIG_NET_CLS_ROUTE
__u32 nh_tclassid;
#endif
int nh_oif; //輸出網絡設備索引
__be32 nh_gw; //網關地址
};
路由函數表的初始化過程
[TODO]