ovs 最长前缀树匹配实现

1. 前缀树说明

1.1 概述

最长前缀树匹配是ovs流表查找的基础,是ovs中很重要的一个模块。和路由条目CIDR类似,它的定义是,有条目A1=a1,A2=a1a2,A3= a1a2a3,那么当用A4(A4= a1a2a3a4)去匹配A1、A2、A3时,A3将会被匹配到,因为它从左到右匹配到了最多值(a1a2a3).

比如存在路由条目:192.168.1.0/24和192.168.0.0/16时,当用192.168.1.1去匹配的时候,192.168.1.0/24将会被匹配到,因为它匹配的更多。

1.2 前缀树功能

最主要的目的是,输入一个值,从现有条目空间中,返回从最高位匹配最多的条目。

1.3 前缀树数据结构表示

ovs中使用二叉树实现最长前缀匹配的。

如上图,每个节点包含一定位数的值(prefix),是对A3= a1a2a3中,a1、a2、a3、ai的表示,在实现中,每个节点对应值的位数不大于32位。因此,从root根节点到达该node上的所有prefix集合就是该节点代表的项的值。比如图中的0100110110/10。

rules:表示该节点对应的有效条目数,如果为0,那么在树的条目空间中,并没有与该值/mask,对应的条目,但有时它必须在树中存在(虽然无效),如果它有两个子节点(如上图中虚线标识的节点1011/4)。

n_bits:表示从root根节点到达该节点所有的位数,同mask的意义。

2. ovs前缀树操作

ovs前缀树中节点表示的值是flow的字段(比如,源ip、目的ip、源端口、目的端口等)。所以在构建前缀树时,都会有个field项,该项表示该前缀树是依据flow流表中哪些字段构建的(比如源ip地址)。

2.1 初始化

树的表示:

/* Prefix trie for a 'field' */

struct cls_trie {

    const struct mf_field *field; /* Trie field, or NULL. */

    rcu_trie_ptr root;            /* NULL if none. */

};

把构建该前缀树依据的flow字段,赋予field。使root为null。

2.2 插入

/*

prefixmf位置对应的rule flow的值

*/

static void

trie_insert_prefix(rcu_trie_ptr *edge, const ovs_be32 *prefix, int mlen)

edge:根节点root

prefix:要插入项的前缀值,它是一个32位值的数组

mlen:插入项的前缀长度,即mask长度。

  1. 从root节点开始匹配每个节点的prefix,如果要插入项的prefix对应的位与该A节点prefix值完全相等,则完全匹配。
  2. 如果不完全匹配,即只匹配了该A节点的前i位prefix(0< i <该节点的prefix长度),那么把该A节点从i位拆分为2个新节点,拆分后的第2部分(原来A节点从i位后的prefix)为原来的A节点,并更新prefix值。如果要插入的节点完全匹配第1部分,那么更新第1部分为新节点,rules加1。否则新插入的节点作为第1部分的子节点存在。如图中,为了连接两个新节点可能会产生图中虚线标识的连接节点。
  3. 如果完全匹配,且要插入项的mask长度正好等于A节点的n_bits,即要插入项的所有prefix和从root到A节点的路径上的所有prefix完全匹配,那么该A节点是要插入的节点,把A节点的rules加1,表示该节点增加一个有效项。
  4. 如果完全匹配,但插入项的mask长度大于A节点的n_bits位,即要插入的项是一个更长mask的项,所有创建一个新节点,该节点的prefix为剩余的前缀,并且根据剩余前缀的最高有效位(0或1),插入到A节点中,作为A节点的子树。并更新rules为1。

2.3 查找

根据要查找的值value,从root节点开始,从value的最高有效位匹配途径节点的prefix,找到叶子节点,或者没找到叶子节点(没有找到最少匹配1位的项)。叶子节点即为查到的最长匹配的节点。

2.4 删除

同查找步骤,先找到匹配的节点,然后把该节点从树种删除,删除节点后可能会遇到合并前后两个节点的情况。比如删除图中的1011 1011/8节点,就会合并1011/4和1011 00/6节点为1个节点。

2.5 操作复杂度

容易得出,不管插入、查找、删除,最坏情况复杂度都是O(h),h是树的深度。h并不一定是log2n(n是前缀树表示值的最大位数),因为该前缀树的每个节点都可以最大表示32位的值。

所以该前缀树有比较好的操作性能和灵活度。

3. ovs前缀树应用

ovs内部的classfier都会用到前缀树,因为ovs的rule查找都是依据flow流字段的,而流字段很容易使用前缀树表示。

具体使用的,包括流表查找,隧道端口查找,ovs路由查找,隧道口映射查找等。当然,后续如果自己有这方面的功能需求,可以借鉴使用

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值