目录
1. 初衷
我学习dpdk的初衷非常简单,长期的目标是学习DPDK的优化原理,并在此基础上对现有的工作代码进行优化;短期目标是为了面试,因为实在是问的太多了,而我也仅仅是看了《深入浅出DPDK》这本书的前几个章节,基本上面试官深入询问,便不知道所以然。
面试官还经常问另一个问题:DPDK源码你看过多少?
既然如此,那我就裸辞在家,开始撸DPDK源码。并将学习笔记整理出来,供大家一起讨论学习。
早些时候,只看过DPDK中的无锁队列,在实现上确实很优秀,通过学习无锁队列,真正意义上接触到了缓存一致性、内存屏障等非常重要的概念。之后在阅读代码中,发现很多地方都用到了内存屏障,例如Linux内核中的RCU机制实现特别内存屏障。可以说内存屏障在内核态|多核并发中非常重要,鉴于此更加坚信,DPDK代码非常有必要进行仔细阅读。毕竟可以涨姿势呀!
这里先从DPDK中的路由算法开始:LPM路由匹配算法。
2. LPM设计原理概要
路由可以说是整个互联网的核心和基础。对于网络设备,路由模块一般是一个比较大的功能,它也是影响转发效率的关键因素。关于路由表查找算法,曾经看到一篇非常详细的文章:Internet路由之路由表查找算法概述-哈希/LC-Trie树/256-way-mtrie树
在DPDK中,实现了两种路由匹配算法:
- 精确匹配
- 最长前缀匹配(LPM)
本文主要介绍最长前缀匹配。
DPDK中的LPM实现综合考虑了时间和空间问题,做了一个比较好的折中,将32位的地址空间分为两部分:
- 高24位
- 低8位
这是专门针对路由表查询设计的数据结构。通过这种方式,将IP地址空间分为二级表的方式进行查询。前缀的24位共有2^24个条目(16x1024x1024个),也就是说IP地址的前三个字节对应的数值在表中存在一一对应项。低8位的256个条目可以根据需求进行分配,这样可以极大的节省空间。
经过有关部门的统计分析,当查找的IP掩码长度绝大多数是小于等于24位的,因此这部分可以通过一次内存访问便可以找到对应的路由;当查找的IP掩码长度超过24时,需要两次访问内存,而这种情况相对较少。因此DPDK实现的LPM算法兼顾了时间和空间效率。
3. LPM路由查找算法
3.1 LPM相关的数据结构
LPM主要的结构体为:
- 一张有2^24条目的一级表,称之为tbl24
- 多张(DPDK源码中为256张)有2^8条目的二级表,称之为tbl24
3.1.1 tbl24数据结构
参数 | 说明 |
next_hop | 这个作为下一跳着实有点特殊,只有一个字节 |
valid | 当前一级表tbl24表项是否生效 |
ext_entry | 是否存在二级表tbl8 |
depth | 规则深度,实际上为掩码长度 |
3.1.2 tbl8数据结构
参数 | 说明 |
next_hop | 这个作为下一跳着实有点特殊,只有一个字节 |
valid | 当前tbl8条目是否生效 |
valid_group | 有效组标记 |
depth | 规则深度,实际上为掩码长度 |