见之前的文章fib数据结构
路由fib创建
当通过netlink,操作类型为RTM_NEWROUTE时,调用inet_rtm_newroute函数添加路由。
功能:a)、将用户空间配置内容传过来------rtm_to_fib_config(保存路由表项的 ip 类型 tos 出接口 网关 metric 目的ip等信息)
b)、路由表的创建------------------fib_new_table(根据table id 查找创建路由表)
c)、路由表项的添加-----------------fib_table_insert
static int rtm_to_fib_config(struct net *net, struct sk_buff *skb, struct nlmsghdr *nlh, struct fib_config *cfg) { struct nlattr *attr; int err, remaining; struct rtmsg *rtm; err = nlmsg_validate(nlh, sizeof(*rtm), RTA_MAX, rtm_ipv4_policy); memset(cfg, 0, sizeof(*cfg)); //跳过nlh的硬件头部,让rtm指向nlh的内容,即将nlh赋值给rtm rtm = nlmsg_data(nlh); //将rtm的内容,赋值给cfg cfg->fc_dst_len = rtm->rtm_dst_len;//掩码长度 cfg->fc_tos = rtm->rtm_tos; //好像是默认为0 cfg->fc_table = rtm->rtm_table;//路由表id: connected为0;kernel route为255 //如果id为0,kernel会将id设为254 cfg->fc_protocol = rtm->rtm_protocol;//协议类型:connected和kernel route都为11 cfg->fc_scope = rtm->rtm_scope;//范围:connected为253;kernel route为254 cfg->fc_type = rtm->rtm_type;//类型:connected为1;kernel route为2 cfg->fc_flags = rtm->rtm_flags;//connected和kernel route都为1024 cfg->fc_nlflags = nlh->nlmsg_flags; ------------------------------------------------- }
其核心代码为fib_table_insert
主要逻辑有:
- fib_create_info
- fib_find_alias
- switchdev_fib_ipv4_add
- fib_insert_alias
- rt_cache_flush
目前路由采用trie 算法,trie是一种最长前缀匹配算法,对于大量路由的情况下查找效率高于hash,但是这种算法会消耗更多的内存、算法更加复杂;代码就不看了