3. 云原生网络数据平面基础
在 DPU 云原生网络加速工程中,理解 Linux 网络数据平面的收发包路径是后续一切优化的起点。无论是用 eBPF 卸载、用 TC 做流量整形,还是把 OVS 数据面下沉到 DPU,本质上都是在回答同一个问题:一个数据包从网卡进入系统,到最终被容器里的进程读到,中间经过了哪些环节,每个环节的开销在哪里,哪些环节可以被旁路或加速。
一、Linux 网络协议栈的收发包路径
先看接收方向。网卡收到报文后,通过 DMA 把数据写入预先分配的接收环形缓冲区(RX Ring),然后发起中断。为了降低高频小包场景下的中断开销,现代网卡普遍启用 NAPI 机制:中断处理函数只做少量工作,随后触发软中断(NET_RX_SOFTIRQ),由内核在轮询模式下批量从 RX Ring 取包。每个报文被包装成 sk_buff(简称 skb),这是贯穿整个协议栈的核心数据结构,记录了报文数据指针、协议头偏移、所属网络命名空间等信息。
skb 随后沿协议栈向上传递:链路层处理(如 VLAN 剥离、ARP 判断)→ 网络层 ip_rcv 做路由查找与 netfilter PREROUTING 钩子 → 判断是本地投递还是转发。若是本地投递,进入 ip_local_deliver,经过 netfilter INPUT 钩子,再交给传输层。TCP 在 tcp_v4_rcv 中完成连接查找、序号校验、乱序重组,把数据放入 socket 接收队列,最后唤醒阻塞在 recv() 上的应用进程,通过 copy_to_user 把数据拷贝到用户态。
发送方向基本对称:应用调用 send() 写入 socket 发送缓冲区,TCP 负责分段、拥塞控制与重传,IP 层做路由与分片判断,netfilter OUTPUT/POSTROUTING 钩子依次执行,最后进入 qdisc(排队规则)排队,由网卡驱动通过 TX Ring 发出。整个路径中,skb 的分配与释放、跨层函数调用、用户态与内核态之间的数据拷贝,是三个最主要的固定开销来源。
二、netfilter 与 TC:两个关键的钩子框架
netfilter 是内核协议栈内的包过滤与处理框架,它在收发包路径上埋了五个钩子点:PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING。iptables/nftables 就是基于这些钩子实现的。它的特点是工作在协议栈内部、能感知连接状态(conntrack),但代价是每个包都要走一遍规则链匹配,规则多时线性查找开销明显。
TC(Traffic Control)则位于更靠下的位置,直接挂在网络设备的收发队列上。它分为 ingress 和 egress 两个方向:egress 通过 qdisc 实现排队、整形、限速;ingress 则通过 clsact qdisc 挂载过滤器,可以在协议栈处理之前就对包做分类、丢弃或重定向。TC 的 eBPF 挂载点(tc ingress / tc egress)是当前云原生数据面最常用的加速入口之一,因为它比 netfilter 更早介入,且能直接操作 skb 甚至做 XDP 级别的重定向。
三、OVS 与 eBPF:从内核模块到可编程数据面
OVS(Open vSwitch)是虚拟化与容器网络中广泛使用的虚拟交换机,传统实现由内核 datapath 模块加用户态 ovs-vswitchd 组成。第一个包走慢路径上送用户态查流表,后续命中流表的包走快路径直接在内核转发。它的优势是功能完整、支持 OpenFlow,但内核模块与用户态之间的交互、以及多级流表匹配,会带来额外延迟。
eBPF 提供了另一条路线:把转发逻辑编译成字节码,挂到 TC、XDP 或 socket 层,在内核中安全执行,无需修改内核源码、无需加载内核模块。在云原生场景中,Cilium 就是典型代表——它用 eBPF 替代了大量 iptables 规则和 OVS 流表,实现服务负载均衡、网络策略与可观测性。相比 OVS,eBPF 数据面路径更短、可编程性更强,但需要处理内核版本兼容与程序复杂度管理。
四、容器网络命名空间与 veth 对
容器网络隔离的基础是 network namespace。每个容器拥有独立的 netns,里面有自己的网卡、路由表、iptables 规则和端口空间。要让容器与外界通信,通常使用 veth 对:一对虚拟网卡,一端在容器 netns 内(如 eth0),另一端在宿主机 netns 内(如 veth1234)。从一端发出的包会立刻从另一端出现,相当于一根虚拟网线。
宿主机侧通常再把 veth 接入网桥(如 docker0、cni0)或 OVS 网桥,由网桥完成同主机内容器间转发;跨主机则依赖 VXLAN 等隧道封装。下面这张图把本节的核心对象串起来:从网卡到协议栈、netfilter/TC 钩子、OVS/eBPF 数据面,再到容器 netns 与 veth 对的位置关系。
五、把路径串起来看加速机会
理解了上述结构,就能定位常见的加速点。第一,用 XDP 在驱动层直接处理包,绕过 skb 分配,适合 DDoS 清洗和简单转发。第二,用 TC eBPF 在 ingress/egress 做服务负载均衡和策略执行,替代大量 iptables 规则,避免规则链线性匹配。第三,用 eBPF 或 OVS 卸载把容器间转发从协议栈中拉出来,减少 netfilter 与路由查找开销。第四,在 DPU 上把这些数据面进一步下沉,让宿主机 CPU 专注于业务。
一个可参考的观察方法是:在宿主机上用 tc -s qdisc show dev eth0 查看队列统计,用 bpftool prog show 确认 eBPF 程序挂载点与运行次数,用 ovs-dpctl dump-flows 查看 OVS 快路径流表命中情况。若发现大量包走了慢路径或 iptables 规则命中数极高,就说明数据面还有下沉空间。这些命令的具体输出会随内核版本和配置不同而变化,实际使用时以本机结果为准。