在函数之间共享信息(BPF/XDP)

share information between function(BPF/XDP)

Objective: If process id/name = xxx then drop the packet 所以,我有点困惑。到目前为止,我知道您无法从 XDP 中提取进程信息,但 bpf trace 允许您跟踪它。 这是我可能的解决方案,使用 bpf 哈希映射在两个函数之间共享信息。如果进程名称 == xx 则 XDP_DROP。 (这可能是错误的,但我正在尝试)

但是我不知道如何使用BPF_HASHMAPS,我还没有阅读关于密件抄送的文档..

示例:从这个 hello 函数我可以跟踪事件

struct data_t {
    u32 pid;
    u64 ts;
    char comm[TASK_COMM_LEN];
};
BPF_PERF_OUTPUT(events);
int hello(struct pt_regs *ctx) {
    struct data_t data = {};
    data.pid = bpf_get_current_pid_tgid();
    data.ts = bpf_ktime_get_ns();
    bpf_get_current_comm(&data.comm, sizeof(data.comm));
    events.perf_submit(ctx, &data, sizeof(data));
    return 0;
}

用于删除打包程序的 XDP 函数

int udpfilter(struct xdp_md *ctx) {

  bpf_trace_printk("got a packet\n");
  //u32 cpu = bpf_get_smp_processor_id();
  //bpf_trace_printk("%s looking\n",cpu);
  //u32 pid = bpf_get_current_pid_tgid();
  
  return XDP_DROP;
}

现在如何获取 pid 值并在 XDP 函数中使用它,加上解决方案是否有意义。感谢您的帮助,非常感谢。

因此,如您所知,eBPF 程序可以在不同位置加载到内核中。 XDP 程序在网络驱动程序之后和网络堆栈之前加载。此时内核不知道数据包可能是哪个进程的,因为它将在网络堆栈中计算出所有这些。

您显示的 hello 程序是 kprobe(内核探测)的一个示例。它附加到您指定的任何内核函数,但它是一个跟踪工具,无法进行更改。

此外,一些辅助函数如 bpf_get_current_pid_tgid 依赖于程序类型。 bpf_get_current_pid_tgid 仅适用于 kprobes、uprobes、tracepoint 程序(perf 程序),实际上可能也适用于 socket 和 cGroup 程序,问题是没有一个非常明确的列表或概述哪些工作在哪里,这些是两个不错但不全面的链接:

最后归结为逻辑。内核只能让您访问它自己可以访问的数据和操作。因此,如果你想根据进程 ID 做网络相关的事情,你可能需要使用附加在此类信息可用位置的 eBPF 程序(请记住,这显然也更慢)。

因此,根据您具体想要做什么,您有以下几种选择:

  • 将 eBPF 程序附加到网络套接字 (BPF_PROG_TYPE_SOCKET_FILTER),以便您可以在套接字级别过滤数据包。这确实需要创建套接字的程序将程序附加到它。
  • 使用 cGroup 和 BPF_PROG_TYPE_CGROUP_SKB 程序来阻止数据包。由于您将程序附加到cGroup,因此不需要程序的配合。
  • 使用TC程序(BPF_PROG_TYPE_SCHED_ACT),在这个级别上已经解析了一个数据包,但您仍然需要将其匹配到一个进程
  • 使用XDP程序(BPF_PROG_TYPE_XDP)还是可以的,这个需要你解析所有层的网络包(Ethernet, VLAN, IP, UDP/TCP),然后手动提取协议、目标 IP 和目标端口。就像在 TC 程序中一样,您需要使用查找 table.
  • 将其与 pid 匹配

走 XDP 或 TC 路线时,您需要创建此查找 table。据我所知,您无法通过辅助函数访问内核的 table 。一些方法是:

  • 解析netstat -lpn的输出(协议、目标ip、目标端口和PID)并在映射中设置数据以供程序使用
  • 直接从 /sys 或 /proc 获取相同的数据(我不知道数据到底存储在哪里)
  • 在创建过程中记录哪些 PID 具有哪些套接字(使用第二个程序(kprobe/tracepoint))并将此数据设置在由 XDP/TC 程序和跟踪程序共享的映射中。 (不太确定如何在 BCC 中的程序之间共享映射,但使用 libbpf 时肯定可以)