内核 FIB Trie 路由效果演示
通过动画展示下内核路由树(FIB trie)插入路由时,对应节点的变化。
👉 点击这里全屏查看动画
FIB trie 介绍
linux内核里的fib路由树,
如何插入一个fib 路由
查找插入点
一句话:遍历当前节点,如果前缀相同,根据index值,递归找孩子(子树).
【关键点1】get_cindex计算index值
1 | index = get_cindex(key, n); |
- 异或运算后,然后右移pos位。保留(前缀+bits位)
包含前缀运算
【关键点2】前缀检查:一石二鸟的判断
当前节点n和key的前缀是否一致。
n->bits表示该节点有2^bits个子节点,所以合法的index范围是[0, 2^bits)。如果index >= 2^bits,说明:
key和n->key在前缀部分就已经不同了(差异出现在pos+bits之上的高位)
换句话说:key不属于这个子树,前缀不匹配
备注:因为fib trie的根节点一定不为空。所以第一次算index值一定为0,不会出现前缀不匹配的场景。
1 | 930 static struct key_vector *fib_find_node(struct trie *t, |
场景1:当前一个节点的叶子
匹配条件:
- 前缀相同。
- index值对应的孩子节点指针为空
处理方式: - 创建叶子节点,挂到当前节点的第index个孩子。
例子:key: 9.9.0.0/16
场景2:前缀不同
匹配条件:
- 前缀不相同。
- index >= 2^bits:index值大于或者等于2的bits次方。
处理方式:
- 创建一个新的中间节点
- bit位置是根据前缀里不相同的位里,最高的一位。
- 当前节点挂到中间节点,当孩子。
- 创建一个叶子节点
- 新叶子节点挂到中间节点,当孩子。
- 中间节点,挂到父节点当孩子。
例如:增加路由9.24.0.0/24
场景3:前缀相同的叶子节点
相同前缀,不同掩码长度的。
在叶子节点里,向FA list里增加fib_alias节点。
例如:9.9.8.0/30 dev veth0
执行插入操作
1 | /* fib_insert_alias - 将新的 fib_alias 插入到叶子节点的链表中 |