Încerc să trimit date (adresa IP) de la kernel space pentru utilizatorul spațiu, prin rularea următoarea BPF prorgam:
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 $@
Cu toate acestea tot primesc următoarele err:
58: (85) call bpf_map_update_elem#2
R1 type=map_value expected=map_ptr
verification time 272 usec
Poate cineva să mă ajute să înțeleg această eroare? În plus unde pot vedea bpf_printk
mesaje?
Bănuiesc că fișierul generat de a face nu include EVENTS
harta.. Dar nu sunt sigur cum să-l repare - dacă am adăuga un SEC("maps")
deasupra hărții kernel verificator nu reușește să localizați secțiunea la toate..
printk
apeluri?