ebpfbpfbcc-bpfxdp-bpf

share information between function(BPF/XDP)


Objective: If process id/name = xxx then drop the packet So, I am bit confused. So far I know you can't extract process information from XDP but bpf trace allows you to trace it. Here's my probable solution, use bpf hash maps to share information between two function. If process name == xx then XDP_DROP. (This maybe wrong, but something I was trying)

But I am confused how to use BPF_HASHMAPS, I read the documentation on bcc yet..

Example: From this hello function I can trace events

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 function to drop packer

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;
}

Now how do I fetch pid value and use it in XDP function, plus does the solution even makes any sense. Thanks for the help, really appreciated.


Solution

  • So, as you know eBPF programs can be loaded into the kernel at different locations. XDP programs are loaded just after the network driver and just before the network stack. At this point the kernel doesn't know for which process a packet might be since it will figure all of that out in the network stack.

    The hello program you are showing is an example of a kprobe(kernel probe). It attaches to whatever kernel function you specify, but it is a tracing tool, can't make changes.

    Also, some helper functions like bpf_get_current_pid_tgid are program type dependent. bpf_get_current_pid_tgid only works in kprobes, uprobes, tracepoint programs (perf programs), the may actually also work in socket and cGroup programs, the issue is that there is not a very clear list or overview of which work where, these are two good but non-comprehensive links:

    In the end it comes down to logic. The kernel can only give you access to data and actions it has access to itself. So if you want to do network related things based on process ID's you might need to use an eBPF program attached at a location where such info is available(keep in mind that this is obviously also slower).

    So depending on what exactly you want to do you have a few options:

    When going the XDP or TC route you need to create this lookup table. As far as I know you can't access the table of the kernel via helper functions. A few approaches are: