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

BPF maps有什么用途?eBPF maps能否实现不同函数间的信息共享?

BPF maps核心用途与跨函数共享能力

BPF maps通用用途

  • 作为eBPF程序和用户空间进程之间的双向数据交互通道,用户态和内核态eBPF程序均可同步读写map内容
  • 实现不同eBPF程序间的数据共享,不管是同一钩子点的多个程序,还是不同钩子点(比如tracepoint程序和XDP程序)的程序,都可以通过挂载同一张map实现跨程序、跨函数的数据传递
  • 存储eBPF程序运行过程中的持久化状态,避免每次程序被触发时状态丢失
  • 作为内核向用户态上报事件的缓冲载体,比如perf buffer、ring buffer类型的map都可以实现高性能的事件上报

eBPF maps跨函数/跨程序共享的可行性

eBPF maps天生支持在不同函数、甚至不同钩子点的eBPF程序之间共享信息。eBPF maps是内核维护的通用键值存储结构,只要两个eBPF程序在代码中声明了同一张map(使用相同的类型、键值结构、map名称),或者通过文件描述符传递挂载同一张map,就可以互相读写对方写入的内容,完全满足你场景里的需求。
你提到的场景刚好是这种能力的典型用例:XDP程序运行在网络栈接收的极早期软中断上下文,本身没有进程上下文信息,无法直接获取数据包对应的进程名称,所以必须通过运行在进程上下文的tracepoint/kprobe类eBPF程序采集进程信息写入共享map,再由XDP程序读取map内容做匹配判断。

场景实现示例

你描述的场景需要两个eBPF程序配合,通过共享map传递规则:

  1. 第一个是挂载在sched_process_exec tracepoint的eBPF程序,负责抓取新执行的进程名称,匹配到目标进程时,将进程的网络命名空间(或其他你需要的匹配维度)写入共享map
  2. 第二个是挂载在网卡的XDP程序,读取共享map中的规则,匹配到对应数据包时直接返回XDP_DROP丢弃

核心eBPF代码示例(基于libbpf框架)

// 定义共享哈希表map,键为进程网络命名空间inode,值为是否需要拦截的标识
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 1024);
    __type(key, u32);
    __type(value, u8);
} process_filter_map SEC(".maps");

// 第一部分:tracepoint程序,抓取进程名匹配后写入map
SEC("tracepoint/sched/sched_process_exec")
int tracepoint_sched_process_exec(struct trace_event_raw_sched_process_exec *ctx) {
    char comm[16];
    u32 netns_inode;
    u8 filter_flag = 1;

    // 获取当前进程名称
    bpf_get_current_comm(&comm, sizeof(comm));
    // 匹配目标进程名
    if (__builtin_memcmp(comm, "something", sizeof("something") - 1) != 0) {
        return 0;
    }

    // 获取当前进程的网络命名空间inode作为键
    netns_inode = bpf_get_netns_cookie(NULL);
    // 写入共享map
    bpf_map_update_elem(&process_filter_map, &netns_inode, &filter_flag, BPF_ANY);
    return 0;
}

// 第二部分:XDP程序,读取map判断是否丢包
SEC("xdp")
int xdp_drop_filter(struct xdp_md *ctx) {
    u32 netns_inode;
    u8 *filter_flag;

    // 获取当前数据包所属的网络命名空间inode
    netns_inode = bpf_get_netns_cookie(ctx);
    // 查共享map判断是否需要拦截
    filter_flag = bpf_map_lookup_elem(&process_filter_map, &netns_inode);
    if (filter_flag && *filter_flag == 1) {
        // 匹配到规则直接丢包
        return XDP_DROP;
    }

    // 没有匹配规则正常放行
    return XDP_PASS;
}

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

补充说明

  • 上述示例用网络命名空间作为匹配维度,你也可以根据需求调整map的键为源IP、源端口等其他字段,实现更精准的匹配
  • 如果需要在进程退出时清理map规则,可以再加一个挂载sched_process_exit tracepoint的程序,匹配到目标进程退出时删除map中对应的条目
  • 所有eBPF程序对map的读写都是原子安全的,不需要额外加锁处理并发问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 10:15:07