| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> DPDK源码学习: LPM路由匹配算法 -> 正文阅读 |
|
[数据结构与算法]DPDK源码学习: LPM路由匹配算法 |
在DPDK中,实现了两种路由匹配算法:
本文主要介绍最长前缀匹配。 DPDK中的LPM实现综合考虑了时间和空间问题,做了一个比较好的折中,将32位的地址空间分为两部分:
这是专门针对路由表查询设计的数据结构。通过这种方式,将IP地址空间分为二级表的方式进行查询。前缀的24位共有2^24个条目(16x1024x1024个),也就是说IP地址的前三个字节对应的数值在表中存在一一对应项。低8位的256个条目可以根据需求进行分配,这样可以极大的节省空间。 经过有关部门的统计分析,当查找的IP掩码长度绝大多数是小于等于24位的,因此这部分可以通过一次内存访问便可以找到对应的路由;当查找的IP掩码长度超过24时,需要两次访问内存,而这种情况相对较少。因此DPDK实现的LPM算法兼顾了时间和空间效率。 LPM路由查找算法LPM相关的数据结构LPM主要的结构体为:
tbl24数据结构
tbl8数据结构
LPM数据结构数据结构之间的关系
LPM结构的创建LPM路由表的创建是通过rte_lpm_create()函数实现的。而LPM的核心数据结构为struct rte_lpm, 因此LPM的创建主要对创建rte_lpm对应的对象。其中为了灵活配置路由规模,采用传参的方式动态分配LPM路由表(这用到了0长度数组)。申请的LPM是一个连续内存,而非常见的链式存储。这个比较特殊,优点嘛,就是快。 它的原理很简单: 根据传递的参数来确定支持的规则数,并在此基础上分配LPM空间。 代码实现如下: LPM 添加路由路由表项的添加是在rte_lpm_add函数中完成的。 首先需要获取目的网段所在的网络地址: 在LPM中,rule是在按照掩码位数来组织的:IPv4的掩码位数范围:0-31, 每一个长度的掩码下有可能存在多条路由。 在路由匹配算法中采用最长前缀匹配,因此最初的遍历方式如下: 比如说掩码长度为24时的路由有多条:
这部分条目是存储在rules_tbl中的,每一个掩码长度对应的区间,通过(begin, begin+used)来标记空间范围。该rules结构主要是为了方便维护tbl24+tbl8二级表,当路由删除时,需要重新确定下一跳,通过rules结构可以比较优雅的找到。 rules结构是LPM一个较为高级的数据结构,它的目的主要是:方便路由表的增删改,尤其在删除某一条路由时需要根据最长前缀匹配原则重新确定下一跳。rule的数据结构可参考上图,由于是顺序存储,优点是查找效率高,但是不方便扩展,增删元素都需要移动后续元素。这也是rule代码实现中比较重要的部分,但是rule中并未移动所有后续元素,而是每一个掩码组只移动第一个和最后一个,大大减少了内存的拷贝。 基于此前提再阅读rule的实现会比较简单。 rule_add此函数接口用来添加路由规则,路由规则实际上就是IP和掩码组成的结构。在网络层中,有两个重要的表(日常统称为路由表,并未细分):FIB和RIB。其中RIB为路由路由信息表,包含网络的拓扑信息,而FIB表则是RIB中最佳的路由构成的表,转发报文时使用FIB表。在DPDK的LPM中,rule表和tbl24/tbl8的关系有点类似于RIB和FIB的关系。
规则是按掩码长度划分的: 下面开始介绍rule_add流程: 首先需要判断是否存在达到该子网的路由,如果存在,则只需要更新rule表的nexthop即可。如果不存在则需要找到插入位置,后续分配空间插入路由信息 时使用。
由于所有的rule全部存储在一个大数组里(rules+_bl数组), 如果插入元素/删除元素需要移动后续元素。 缺点是插入删除开销大,需要频繁移动元素;优点就快,效率高。 插入元素时,并非将所有后续元素都后移一位,而是每组移动一个(每组第一个移到下一组第一个位置),这样就可以减少内存拷贝的开销。
rule_delete在rule_add中已经知道rule的组织结构,因此删除时,最主要的工作在于:将后续元素向前移动1个空间。这里也是:将每掩码组的最后一个移动到前一掩码组的最后一个。这样便完成了元素的删除,同时无需进行大量数据的拷贝工作。 tbl8_allocrule组两个重要函数已经说明完毕,后面便需要介绍lpm中的tbl相关的两个重要函数: 通过前面的描述,已经知道DPDK中,LPM查找匹配算法将IP分为两部分,分别对应tbl24, tbl8。当添加路由时,如果掩码长度小于等于24,则使用add_depth_small添加路由;当掩码长度大于24时,使用add_depth_big添加路由。这里先介绍下tbl8的申请函数此接口用来从连续的内存中申请一个tbl8表空间。 add_depth_small首先是获取IP的高24位, 从而可以根据索引直接找到tbl24中的对应项。由于添加的路由子网掩码可能小于24, 例如:192.168.32.0/20, 它在tbl24表中存在多个表项(掩码越短,对应的条目越多),因此需要将涉及的子网都进行修改。 在tbl24中没有此表项(valid=0), 或者有此表项且掩码长度小于当前子网掩码长度,此时需要更新tbl24的下一跳和掩码 修改完毕tbl24,但是未修改包含tbl8表中的项。比如说先添加一条10.28.1.1/32的路由表项,再添加一条10.28.1.0/24的表项,此时便需要修改tbl8中的一部分路由表项。 此函数中又分为三种情况分别处理: Tbl24中没有表项(valid=0)
LPM路由规则删除路由的删除应该也是最能体现算法效率的地方。如何在删除一个路由后,能快速更新相关子网的路由信息这是问题的关键。 例如:在删除第一条路由时,此子网的下一跳该设置为多少? 虽然我们已经知道遵循最长掩码匹配原则,但是在实现过程中出现了多种优秀的算法。这里主要看看DPDK是如何实现LPM删除的。
删除操作比添加更为复杂些,因为不仅需要删除,还需要找接盘侠。 rte_lpm_delete此函数用来删除路由,它的基本逻辑如下:
rule_find实现:rule_find函数实现比较简单,它首先根据掩码长度(depth)确定rule所在ruleTable中的位置(first_rule)以及区间范围[first_rule, first_rule+used_rules], 然后遍历此范围内的所有rules,直到找到匹配的新rule(ip_masked相等即匹配成功)。 rule_delete实现由于rule是通过数组来维护存储的(有点类似链表的顺序存储,可以快速查询),因此在删除之后需要将后续节点进行移动。但是考虑到大量内存拷贝导致的效率低下问题,dpdk采用了有限个元素移动:因为每次只删除一个rule,后续每一个rule组只需向前移动一个节点即可,无需全部移动。明白了这个原则,看代码就会容易很多 Find_previous_rule实现它是用来查找前一条路由。由于需要删除当前路由,而此子网下的路由需要重新查询更新,查询的原则是:从掩码长度<=depth-1开始递减(因为遵循最长掩码匹配,因此需要从最大的开始匹配)。如果存在包含当前子网的路由,则返回此路由的索引(rule_index)。 delete_depth_small实现:当掩码长度≤24时,删除路由时分为两种情况进行: 不存在此路由。此时需要删除该子网下所有条目的路由信息,既包括tbl24表也包括tbl8表中条目。 如果只使用了tbl24表,则只需要修改tbl24; 如果同时使用了tbl8表,则需要将tbl8表条目全部修改。 delete_depth_big实现:当掩码长度大于24时,使用此接口删除路由。当掩码长度大于24,此时主要涉及tbl8表项,因此主要操作对象为tbl8。该函数也分为两个情况进行处理: 不存在替代路由。将子网范围内的表项全部清除(valid=0) LPM路由清空清空操作比较容易,由于是连续地址空间,只需要将lpm结构清空即可。 DPDK学习资料DPDK 系统性学习视频课程 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 10:44:05- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |