You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在eBPF的XDP钩子中将数据包载荷复制到自定义缓冲区?

eBPF/XDP数据包载荷存储到自定义缓冲区的BPF验证器问题

我希望在eBPF & XDP钩子中将数据包的载荷存储到自定义缓冲区,但无法通过BPF验证器。对比他人代码未发现差异。

代码中已检查载荷长度应小于MTU(代码中设为1500),缓冲区大小为(1<<20),远大于MTU。

内核代码(.kern)

#define BUFFER_SIZE (1<<20)
#define MTU 1500

struct my_buffer {
    __u32 len;
    char buf[BUFFER_SIZE + 5];
};
struct bpf_map_def SEC("maps") map_my_buffer = {
    .type = BPF_MAP_TYPE_ARRAY,
    .key_size = sizeof(unsigned int),
    .value_size = sizeof(struct my_buffer),
    .max_entries = 1,
};


SEC("WriteBuffer")
int WriteBuffer_main(struct xdp_md *ctx) {
    void *data_end = (void *)(long)ctx->data_end;
    void *data = (void *)(long)ctx->data;
    char *payload = data + sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr);
    if (payload >= data_end) return XDP_PASS;

    unsigned int zero = 0;
    struct my_buffer *fd = bpf_map_lookup_elem(&map_my_buffer, &zero);
    if (!fd) return XDP_PASS; // can't find the context...

    __u32 data_len = data_end - (void *)payload;
    if (data_len > MTU) return XDP_PASS;

    for (__u32 i = 0; i < MTU && payload + i + 1 <= data_end; i++) {
        fd -> buf[i] = payload[i];
    }

    return XDP_DROP;
}

BPF验证器错误信息

67: (bf) r2 = r5
68: (57) r2 &= 4064
69: (0f) r9 += r2
70: (bf) r5 = r2
71: (71) r1 = *(u8 *)(r4 -16)
72: (7b) *(u64 *)(r10 -16) = r1
73: (71) r1 = *(u8 *)(r4 -15)
invalid access to packet, off=120 size=1, R4(id=0,off=135,r=120)
R4 offset is outside of the packet
processed 60 insns (limit 1000000) max_states_per_insn 0 total_states 5 peak_states 5 mark_read 4

更新

按照pchaigno的指导,我将循环修改为:

for (__u32 i = 0; i <= MTU && i < data_len && payload + i + 1 <= data_end; ++i) {
    fd -> buf[i] = payload[i];
}

之后通过了验证...但我认为这三个条件存在冗余,不太合理。

内容的提问来源于stack exchange,提问作者Zezhou Wang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 18:45:49