EBPF: Jak používat `bpf_map_update_elem` chcete odeslat data z prostoru jádra?

0

Otázka

Snažím se poslat data (IP adresa) z prostoru jádra do uživatelského prostoru, spuštěním následujícího BPF složky:

struct bpf_map_def EVENTS = {
    .type        = BPF_MAP_TYPE_HASH,
    .key_size    = sizeof(__u32),
    .value_size  = sizeof(__u32),
    .max_entries = 1,
};


SEC("xdp")
int _xdp_ip_filter(struct xdp_md *ctx) {
    bpf_printk("got a packet\n");     
    void *data_end = (void *)(long)ctx->data_end;
    void *data     = (void *)(long)ctx->data;
    struct ethhdr *eth = data;

    // check packet size
    if (eth + 1 > data_end) {
        return XDP_PASS;
    }

    // get the source address of the packet
    struct iphdr *iph = data + sizeof(struct ethhdr);
    if (iph + 1 > data_end) {
        return XDP_PASS;
    }

    __u32 ip_src = iph->saddr;
    bpf_printk("source ip address is %u\n", ip_src);

    // key of the maps
    __u32 key = 0;

    bpf_printk("starting xdp ip filter\n");
    // send the ip to the userspace program.
    bpf_map_update_elem(&EVENTS, &key, &ip_src, BPF_ANY);
    return XDP_PASS;
}

Makefile:

CLANG   ?= clang
LLC     ?= llc
OPT     ?= opt
DIS     ?= llvm-dis

ARCH    ?= $(shell uname -m | sed -e 's/aarch64/arm64/' -e 's/x86_64/x86/')
KERNEL  ?= /usr/src/linux

CFLAGS += \
    -O2 -g -emit-llvm                        \
    -D__KERNEL__                             \
    -D__BPF_TRACING__                        \
    -Wno-unused-value                        \
    -Wno-pointer-sign                        \
    -Wno-compare-distinct-pointer-types      \
    -Wno-address-of-packed-member            \
    -Wno-tautological-compare                \
    -Wno-unknown-warning-option              \
    -Wno-gnu-variable-sized-type-not-at-end  \
    -fno-asynchronous-unwind-tables

bytecode.$(ARCH).o: bytecode.c
    $(CLANG) $(CFLAGS) -c $< -o -              | \
    $(OPT) -O2 -mtriple=bpf-pc-linux           | \
    $(DIS)                                     | \
    $(LLC) -march=bpf $(LLC_FLAGS) -filetype=obj -o $@

Nicméně jsem stále následující chyba:

58: (85) call bpf_map_update_elem#2
R1 type=map_value expected=map_ptr
verification time 272 usec

Může mi někdo pomoci pochopit tuto chybu? Kromě toho, kde můžu vidět bpf_printk zprávy?

Mám podezření, že soubor vytvořený se nezahrnuje EVENTS mapa.. Ale nejsem si jistá, jak to opravit - pokud bych přidat SEC("maps") nad mapou jádra ověřovatel se nezdaří, vyhledejte sekci..

bpf c ebpf xdp-bpf
2021-11-24 05:42:58
1

Nejlepší odpověď

2

Chybí:

  • SEC("maps") v mapě prohlášení (jak jste uhodli).
  • Licenční prohlášení.

#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>

#include <bpf/bpf_helpers.h>

struct bpf_map_def SEC("maps") EVENTS = {
    .type        = BPF_MAP_TYPE_HASH,
    .key_size    = sizeof(__u32),
    .value_size  = sizeof(__u32),
    .max_entries = 1,
};


SEC("xdp")
int _xdp_ip_filter(struct xdp_md *ctx) {
    bpf_printk("got a packet\n");     
    void *data_end = (void *)(long)ctx->data_end;
    void *data     = (void *)(long)ctx->data;
    struct ethhdr *eth = data;

    // check packet size
    if (eth + 1 > data_end) {
        return XDP_PASS;
    }

    // get the source address of the packet
    struct iphdr *iph = data + sizeof(struct ethhdr);
    if (iph + 1 > data_end) {
        return XDP_PASS;
    }

    __u32 ip_src = iph->saddr;
    bpf_printk("source ip address is %u\n", ip_src);

    // key of the maps
    __u32 key = 0;

    bpf_printk("starting xdp ip filter\n");
    // send the ip to the userspace program.
    bpf_map_update_elem(&EVENTS, &key, &ip_src, BPF_ANY);
    return XDP_PASS;
}

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

Byl jsem schopen nahrát a připojit se:

make
sudo ip link set dev wlp59s0 xdp obj ./bytecode.o sec xdp
2021-11-24 09:38:58

Díky!!! Kde mohu vidět printk hovory?
Nimrodshn

Můžete použít bpftool prog tracelog pro.
pchaigno

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................