2、eBPF基础回顾:eBPF程序类型、eBPF Map、eBPF Helper函数、eBPF在内核网络路径中的挂载点
在深入跨节点丢包防护验证之前,必须牢固掌握eBPF的核心基础构件。本章将系统回顾eBPF程序类型、Map、Helper函数以及内核网络路径中的关键挂载点,为后续的观测与防护设计建立统一的技术语言。
2.1 eBPF程序类型:按功能域分类
eBPF程序类型决定了程序可以挂载的内核事件类型、可访问的上下文结构以及可调用的Helper函数集合。以下是网络观测场景中最常用的程序类型:
| 程序类型 | 挂载点/事件 | 典型用途 | 上下文结构 |
|---|---|---|---|
| XDP | 网卡驱动层(最早) | 高速丢包统计、DDoS防护、负载均衡 | xdp_md |
| TC (ingress/egress) | 内核协议栈入口/出口 | 流量整形、数据包过滤、隧道封装 | __sk_buff |
| Kprobe/Kretprobe | 内核函数入口/返回 | 跟踪内核函数调用(如 tcp_v4_connect) |
pt_regs |
| Tracepoint | 内核静态跟踪点 | 稳定的网络事件跟踪(如 net:netif_receive_skb) |
特定tracepoint结构 |
| Fentry/Fexit | 内核函数入口/返回(BPF trampoline) | 低开销的函数级跟踪,替代Kprobe | 函数参数结构 |
选型建议: 在跨节点丢包防护场景中,XDP 用于最早期的丢包检测与丢弃,TC 用于协议栈内的流量观测与标记,Tracepoint 用于稳定的连接级事件跟踪。三者组合可覆盖从网卡到传输层的完整路径。
2.2 eBPF Map:内核态与用户态的桥梁
eBPF Map是内核中的键值存储结构,用于在eBPF程序之间、eBPF程序与用户态之间共享数据。Map类型的选择直接影响数据访问的性能与语义。
- BPF_MAP_TYPE_HASH:通用哈希表,适用于流表、连接跟踪表。
- BPF_MAP_TYPE_ARRAY:固定大小数组,适用于计数器、统计指标。
- BPF_MAP_TYPE_PERCPU_HASH / PERCPU_ARRAY:每CPU副本,消除锁竞争,适用于高频率计数。
- BPF_MAP_TYPE_RINGBUF / BPF_MAP_TYPE_PERF_EVENT_ARRAY:事件输出通道,用于将观测数据推送到用户态。
- BPF_MAP_TYPE_LRU_HASH:带LRU淘汰机制的哈希表,适用于有上限的流表。
关键设计原则: 在丢包防护场景中,Per-CPU Array 用于记录每CPU的丢包计数器(无锁),LRU Hash 用于维护活跃流的状态表(自动淘汰过期流),Ringbuf 用于将丢包事件高效推送到用户态分析程序。
2.3 eBPF Helper函数:安全的内核能力调用
eBPF程序不能直接调用内核函数,必须通过Helper函数访问内核服务。Helper函数由内核提供,经过安全验证,确保不会破坏内核稳定性。
| Helper函数 | 功能 | 常用场景 |
|---|---|---|
bpf_map_lookup_elem |
查询Map中的元素 | 流表查找、计数器读取 |
bpf_map_update_elem |
更新Map中的元素 | 流表创建、计数器更新 |
bpf_skb_load_bytes |
从SKB中读取数据 | 解析数据包头部 |
bpf_skb_store_bytes |
向SKB中写入数据 | 修改数据包头部(如标记) |
bpf_redirect |
重定向数据包到其他接口 | XDP/TC中的流量转发 |
bpf_get_current_pid_tgid |
获取当前进程PID/TGID | 关联数据包与进程 |
bpf_ktime_get_ns |
获取高精度时间戳 | 延迟测量、丢包时间记录 |
版本兼容性注意: Helper函数的可用性取决于内核版本和eBPF程序类型。例如,
bpf_redirect 在XDP和TC中均可使用,但参数含义不同。在编写跨节点防护程序时,务必确认目标内核版本支持的Helper列表。
2.4 eBPF在内核网络路径中的挂载点
理解eBPF在内核网络路径中的挂载位置,是设计丢包观测与防护方案的前提。下图展示了数据包从网卡到套接字的完整路径,以及eBPF程序可以插入的关键挂载点。
2.5 挂载点与丢包防护的对应关系
在跨节点丢包防护验证中,不同挂载点承担不同的观测与干预职责:
- XDP (最早挂载点):在网卡驱动层直接处理数据包,适合做高速丢包统计和早期丢弃。丢包原因包括:XDP程序返回
XDP_DROP、驱动层环形缓冲区溢出。 - TC ingress (协议栈入口):在数据包进入协议栈之前进行观测,适合标记数据包、统计入站丢包。丢包原因包括:TC策略丢弃、队列满。
- Tracepoint (稳定事件源):挂载在
net:netif_receive_skb、tcp_drop等稳定跟踪点,适合记录丢包事件的时间、原因和上下文。 - Kprobe/Fentry (函数级跟踪):挂载在
__netif_receive_skb_core、tcp_v4_rcv等函数入口,适合捕获函数参数和返回值,定位丢包发生的精确位置。 - TC egress (协议栈出口):在数据包离开协议栈之前进行观测,适合统计出站丢包和流量整形。
实践要点: 在跨节点丢包防护中,建议采用 XDP + TC ingress + Tracepoint 三层观测架构:XDP负责最早期的丢包检测与防护,TC ingress负责协议栈内的流量标记与统计,Tracepoint负责稳定的丢包事件记录。三层数据通过eBPF Map关联,形成完整的丢包观测链路。