EBPF ยังไงต้องใช้ bpf_map_update_elem`เพื่อส่งข้อมูลจากเคอร์เนลงอวกาศ?

0

คำถาม

ฉันกำลังพยายามส่งข้อมูล(หมายเลขไอพีของ)จากเคอร์เนลที่พื้นที่ที่ผู้ใช้อวกาศโดยวิ่งต่อไปนี้ 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;
}

สคริปต์ makefilelanguage:

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 $@

แต่ฉันได้ติดตาม err:

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

ใครก็ได้ช่วยฉันเข้าใจเรื่องนี้เกิดข้อผิดพลาด? ที่เพิ่มมานอกเหนือจากที่ไหนได้ฉันเห็น bpf_printk จดหมาย?

ฉันต้องสงสัยงแฟ้มที่ถูกสร้างโดยทำให้ยังไม่รวม EVENTS แผนที่..แต่ฉันไม่แน่ใจว่าวิธีที่จะซ่อมมันได้ถ้าฉันเพิ่ม SEC("maps") อยู่เหนือแผนที่ที่เคอร์เนล verifier มันล้มเหลวที่จะค้นหาส่วนตลอด..

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

คำตอบที่ดีที่สุด

2

คุณหายตัวไป:

  • SEC("maps") ในแผนที่ปล่อยให้เธอได้หายใจอยู่อี(อย่างที่คุณมีเดา).
  • ทะเบียนรถเช็คปล่อยให้เธอได้หายใจอยู่อีก

#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";

ฉันสามารถเรียกใช้งานแล้วให้แนบเป็นสิ่งที่แนบมาด้วยกับ:

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

ขอบคุณ! ได้ที่ไหนฉันเห็น printk เรีย?
Nimrodshn

คุณสามารถใช้ bpftool prog tracelog สำหรับเรื่องนั้น
pchaigno

ในภาษาอื่นๆ

หน้านี้อยู่ในภาษาอื่นๆ

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

ดังอยู่ในนี้หมวดหมู่

ดังคำถามอยู่ในนี้หมวดหมู่