You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多网卡场景下eBPF tracepoint netif_receive_skb追踪异常咨询

问题分析与解决方案

核心结论

netif_receive_skb tracepoint是全局共享的,并非每个网卡对应独立实例。所有网卡的数据包只要进入Linux网络栈的接收路径,都会触发该tracepoint。你遇到的双网卡下部分数据包无法捕获的问题,核心原因是代码中使用了错误的tracepoint参数结构体,导致无法正确获取sk_buff(skb)指针,进而没有执行后续的捕获逻辑。

问题根源

你的代码中,SEC("tp/net/netif_receive_skb")对应的tracepoint参数结构体应该是struct trace_event_raw_netif_receive_skb,但你错误地使用了struct trace_event_raw_consume_skb——这两个结构体属于不同的tracepoint,字段定义完全不同,导致BPF_CORE_READ(args, skbaddr)读取的skb地址无效,后续trace_skb逻辑无法正常执行,表现为部分数据包无法被捕获。

修正后的代码示例

#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_core_read.h>

#define TP_NETIF_RECEIVE_SKB 1

static int trace_skb(struct sk_buff *skb, int tp_type) {
    // 读取数据包所属的网卡索引,用于验证是否捕获到多网卡的包
    __u32 ifindex = BPF_CORE_READ(skb, dev, ifindex);
    bpf_printk("Captured packet on interface: %d", ifindex);
    
    // 这里添加你原有的数据包处理逻辑
    return 0;
}

SEC("tp/net/netif_receive_skb")
int net_netif_receive_skb(struct trace_event_raw_netif_receive_skb *args) {
    // 正确读取netif_receive_skb tracepoint的skb指针
    struct sk_buff *skb = BPF_CORE_READ(args, skb);
    return trace_skb(skb, TP_NETIF_RECEIVE_SKB);
}

char _license[] SEC("license") = "GPL";

额外排查点

如果修正后仍存在部分网卡数据包无法捕获的情况,可以检查以下内容:

  • XDP程序干扰:如果次要网卡加载了XDP程序(如XDP_DROP或XDP_REDIRECT),数据包会在进入netif_receive_skb之前被处理,不会触发该tracepoint。
  • 硬件卸载配置:部分网卡开启的硬件卸载功能(如TCP分段卸载、巨型帧合并)可能导致数据包绕过netif_receive_skb路径,但这种情况非常罕见。
  • 内核版本兼容性:不同内核版本的tracepoint结构体可能存在差异,确保使用bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h生成对应内核版本的头文件,并通过BPF CORE特性兼容不同版本。

内容的提问来源于stack exchange,提问作者hundredmiles

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 16:57:43