1. 前言
对于一个从运营商网络进入路由器的报文,最后还能顺利抵达某台服务器,那背后经历的旅程比我们想象得更复杂。它既要快,还得准。整个转发流程就像一条高速生产线:重复性极强、多样性丰富、逻辑复杂、性能要求苛刻。
如果我们不了解每个环节是如何协同处理包,那就很难真正把网络性能挖到极致。想让转发更快,先搞清楚转发框架怎么运作,这就是本章的主角。
2. 网络报文的处理模块如何划分?
从宏观角度看,网络包处理主要分成两大阵营:
- 硬件负责加速数据通道
- 软件负责策略与调度控制
你可以把它看成高速公路的两个系统: 一个负责修路铺桥(硬件),一个负责红绿灯与交通指挥(软件)。
标准的数据处理流程可以拆成如下模块:
| 模块 | 简介 |
|---|---|
| Packet Input | 收包,从网卡进入系统 |
| Pre-processing | 粗粒度检查,如过滤与解析 |
| Input Classification | 精细识别,如流分类 |
| Ingress Queuing | 进入入口队列,描述符FIFO |
| Delivery & Scheduling | 调度包去哪个CPU核心处理 |
| Accelerator | 硬件卸载,如加解密、压缩、校验 |
| Egress Queueing | 出口队列,按QoS决定优先级 |
| Post Processing | 从软件侧做收尾释放资源 |
| Packet Output | 最终发包到线缆上,奔向下一跳 |
硬件能做的,软件不要抢;软件做的事,尽量让CPU并行干
硬件卸载能显著提升以下任务性能:
• checksum offload
• RSS分流
• VLAN、VXLAN、MACsec处理
• IPsec加解密等专用引擎
• TSO/LSO、GRO/GSO类分片合并
软件层多依赖算法优化、NUMA亲和性、多核并行等方式追性能
一句“提纲挈领”的总结:
硬件负责“快车道”,软件负责“大脑”。
想拿满性能分数,这两者都得调到最佳状态。
接下来,我们会基于不同网络框架(Linux内核、DPDK)来深入对照:模块如何协作?性能差距从何而来?游戏规则到底变在哪里?
这正是 DPDK 所擅长重新洗牌的地方。
3. 转发框架介绍
网络转发的核心挑战在于既要保证吞吐量,也要保证处理灵活性。传统网络处理器(NP)为此发展出两种经典转发模型:
• Pipeline(流水线模型)
• Run to Completion(运行至终结模型,简称 RTC)
这两种模型的思想,也正是 DPDK 在通用处理器上追求极致性能的理论基础。
3.1 Pipeline 流水线模型
流水线模型借鉴工业制造: 把一个完整的网络报文处理流程拆分为多个阶段,每个阶段由独立的处理引擎负责,通过队列连接。
| 优点 | 说明 |
|---|---|
| 性能强 | CPU 密集与 I/O 密集任务分离,互不干扰 |
| 可扩展 | 阶段数量与核资源可按需扩展 |
| 延迟均衡 | 队列调节处理速率,防止堵塞 |
典型结构如 Ezchip NPA: 多个专用 TOP(Task Optimized Processor)单元依次执行解析、查表、修改等任务,严格流水化。 劣势是顺序固定,灵活性较弱,某些流程倒回会显著降低性能。
3.2 Run to Completion 运行至终结模型(RTC)
与流水线相反,RTC 模型强调:单个 CPU 核从报文进入到发送,完整执行全部处理流程.
AMCC 345x NP 就采用此模型: 多个 NP 核同时处理不同报文,每个核内部运行完整微码,让报文快速“走完一生”。
| 优点 | 不足 |
|---|---|
| 逻辑耦合低、实现简单 | 单核处理能力成为瓶颈 |
| 横向扩展容易(多核并行) | 无法利用更多核提升单报文性能 |
3.3 DPDK中RTC与Pipeline的融合
在DPDK中,Run to Completion(RTC) 和 Pipeline 并不是孤立存在的,而是根据报文处理的复杂度和性能要求灵活结合使用,形成一个高效的包处理体系。
3.3.1 核心思想
-
RTC模型:一个线程(绑定到CPU核)从报文接收(RX)到发送(TX)处理整个报文生命周期。
优点:- 实现简单,逻辑集中。
- 利用CPU缓存和硬件指令(如AES-NI、CRC加速)高效完成加解密、校验等操作。
- 特别适合处理简单、快速路径报文,例如基本的L2/L3转发。
-
Pipeline模型:将报文处理拆分为多个功能模块(Module),每个模块只处理特定事务,通过队列串联形成流水线。
优点:- 可以并行处理多个报文,提高CPU利用率。
- 适合复杂报文处理,例如ACL匹配、流量计量、路由查表、报文修改。
- 可以跨多个CPU核分布,提高整体吞吐。
DPDK的创新之处在于:通过合理设计调度和线程绑定,将两种模型结合,兼顾性能与灵活性。
3.3.2 结合方法
-
快速路径走RTC
- 对于普通报文或无需复杂处理的报文,直接由一个worker线程全程处理(RX→解析→TX),即RTC模式。
- 每个核可独立处理多个流,通过轮询队列(poll mode)避免中断开销。
- RTC线程充分利用CPU本地缓存,减少跨核通信,提高简单报文的转发速率。
-
复杂路径走Pipeline
-
对于需要执行多级处理(如ACL、LPM查表、报文修改、加解密)的报文,经过 Pipeline分发 到不同模块:
- Module A:解析报文、提取元数据
- Module B:ACL/路由查表
- Module C:修改报文头或执行QoS动作
- Module D:发送到目标端口
-
每个模块可部署在不同核上,并行处理不同报文,提高吞吐。
-
-
融合策略
-
使用 Packet Distributor 将报文分发到RTC线程或Pipeline模块:
- 简单报文 → RTC线程
- 复杂报文 → Pipeline模块
-
Distributor依据报文特征(如流标识、协议类型、长度)进行智能调度。
-
处理完的Pipeline报文可返回RTC线程做最终发送或进入另一个Pipeline阶段,形成灵活的多级处理链。
-
3.3.3 举例说明
假设有一个包含以下功能的网络应用:
- L2/L3转发
- ACL匹配
- 路由查表(LPM)
- 报文修改(NAT/修改VLAN)
DPDK可这样处理:
-
RTC线程:快速处理普通的L2/L3报文,直接接收并发送。
-
Pipeline模块:复杂报文经过分发:
- Module 1:ACL匹配
- Module 2:LPM查表
- Module 3:报文修改
-
最后返回RTC线程发送。
这样一条报文只需在Pipeline中经过相关模块,而无需RTC线程处理每一步,保证高吞吐同时保持低延迟。
4. 转发算法
在高速报文转发中,仅有框架是不够的,核心在于如何快速识别和匹配报文中的字段,从而决定报文的处理和转发策略。DPDK提供了一整套算法体系,包括精确匹配(Exact Match)、最长前缀匹配(Longest Prefix Matching, LPM)、ACL规则,以及多核报文分发(Packet Distributor)。这些算法结合前面讲到的 RTC和Pipeline模型,形成了高性能的数据平面处理链路。
4.1 精确匹配(Exact Match)
精确匹配是最直观的匹配方式:报文字段必须完全匹配才算命中。为了保证高速查找,DPDK采用了 哈希表:
-
原理
- 对每个需要匹配的字段计算哈希值(数字签名),快速定位对应条目。
- 哈希性能受负载因子 L=n/k 控制,L过大容易冲突,过小浪费空间。
-
冲突解决
- 分离链表:冲突条目用链表串起来,查找时遍历链表。
- 开放地址:冲突条目顺序放入下一个空桶,减少链表操作,但连续冲突可能增加延迟。
-
CRC加速
-
DPDK支持 CRC32 作为哈希签名。CRC检验本质上是对数据做 多项式模2运算(异或) ,附加校验码确保数据正确性。
-
示例:
10011011 + 11001010 = 01010001 -
生成多项式约定了CRC规则,例如CRC32的多项式:
X32 + X26 + X23 + X22 + X16 + X12 + X11 + X10 + X8 + X7 + X5 + X4 + X2 + X1 + 1 -
DPDK对CRC做了优化:
- 支持8字节/4字节单位处理。
- 利用硬件SSE4.2指令
crc32q/crc32l加速。 - 查表法优化,空间换时间。
-
支持并行查找函数
rte_hash_lookup_multi,可同时处理多条报文,提高吞吐。
-
4.2 最长前缀匹配(LPM)
LPM主要用于IP路由表查找。目标是找到与目的地址匹配的最长子网前缀:
-
DPDK实现用 两级表:
- 前24位在
tbl24查找。 - 若需要扩展,用后8位在
tbl8查找下一跳。
- 前24位在
-
特点:
- 大部分查找只需一次内存访问(命中tbl24)。
- 空间换时间,兼顾性能与大规模路由表。
struct rte_lpm_tbl24_entry {
union { uint8_t next_hop; uint8_t tbl8_gindex; };
uint8_t valid :1;
uint8_t ext_entry :1;
uint8_t depth :6;
};
struct rte_lpm_tbl8_entry {
uint8_t next_hop;
uint8_t valid :1;
uint8_t valid_group :1;
uint8_t depth :6;
};
4.3 ACL算法
ACL(Access Control List)通过 N元组匹配 对报文进行策略分类,实现防火墙、流量控制等功能:
- 支持创建上下文、添加规则、分类报文、销毁资源。
- 匹配字段通过
rte_acl_field_def定义:
struct rte_acl_field_def {
uint8_t type; // 字段类型
uint8_t size; // 字节长度
uint8_t field_index;
uint8_t input_index;
uint32_t offset; // 偏移
};
-
每条规则可定义优先级和类别掩码。内部用 多层Tier结构 匹配每个字节,最终确定命中路径。
-
这种结构类似“决策树”,多核Pipeline中可以并行处理多个ACL查询。
4.4 报文分发(Packet Distributor)
DPDK的报文分发模块用于 多核环境下高效调度:
-
一个
distributor将报文分发到多个worker核上处理。 -
Mbuf的tag可由硬件或软件提供,用于保证同一流的报文总是分配给同一个worker。
-
核心API:
rte_distributor_process:分发报文,处理backlog。rte_distributor_get_pkt:worker获取报文。
-
可结合
ordering库保证报文顺序。