IPv6 route tree 原理.
IPv6路由采用二叉树的形式进行存储, 查找任意路由最多需要128次比较(128次,说法不太严格)。
因此其算法复杂度为常数,因此IPv6里没有像IPv4那样的cache。
树的节点: fib6_node
fib6_node 代表一条路由。
每个节点有一个leaf指针,leaf指向该路由的下一跳。大多数路由只有一个下一跳, 有的可能有多个下一跳。
如果有多个下一跳就按照metric值递增的顺序组成一个单向链表。
每个节点有左右两个孩子指针(left,right)。(废话二叉树还有别的孩子吗!!!)
每个节点有个指针parent指向父节点。
每个节点保存有掩码长度fn_bit信息, 而网络地址则保存在leaf指针指向的rt6_info节点中。
其中掩码长度是个关键信息。
随着树的深度增加,其掩码长度也在增加。
树的深度每增加1, 掩码长度fn_bit至少增加n(n>=1), 在最坏情况下, n=1.
路由查找:
查找目的地址IPa,
从根节点开始遍历:
fib6_node*p =root_node;
while(p!=NULL)
获取当前节点fib6_node的fn_bit和网络地址IP_XXXX
如果当前地址属于ip_XXXX/fn_bit这个网段。GOOD! Got it.
否则fib6_node转向下一个节点。
下一个节点是right还是left?
根据IPa的第fn_bit位的值是0(right) 还是1(left)决定.
注:这里的第fn_bit位是从1开始的序列而不是0。
即: 没有被包含在掩码内的那部分地址的最高一位bit_X
if bit_x的值是1
p= p->right;
else
p=p->left;
IPa:XXXXXXXXXXXXXXXXXXXX
^
相当于目的地IPa地址下有个浮标,随着遍历深度的增加。浮标不停的往后移动。
直到找到相应的路由为止,或者p为空, 路由查找失败。
本文描述的只是原理。
1. 在实现中为了寻找到最佳路由,遍历时是首先沉到树的最低部的节点,
然后再向树根方向反推。
2. 为了实现按源地址作路由,每个fib6_node下还有个指向子树的指针subtree。
子树的实现几乎没有变化只是对源IP地址进行类似的操作。
在增加或者删除一个节点的时候都保持这这个原则。即上一层的节点比下一层的节点的掩码长度要大(至少大1)。
如果增加的节点a和原有的节点b掩码长度相同。则还要临时引入一个新的节点p。 a 和b作为p的左右孩子。
p的掩码长度为a和b的前缀相同部分的长度。