1

根据此处找到的 bpf_perf_event_output 文档:http: //man7.org/linux/man-pages/man7/bpf-helpers.7.html

“这些标志用于指示映射中必须为其放置值的索引,并用 BPF_F_INDEX_MASK 屏蔽。”

在以下代码中:

SEC("xdp_sniffer")
int xdp_sniffer_prog(struct xdp_md *ctx)
{

    void *data_end = (void *)(long)ctx->data_end;
    void *data = (void *)(long)ctx->data;

    if (data < data_end) {
        /* If we have reached here, that means this
        * is a useful packet for us. Pass on-the-wire
        * size and our cookie via metadata.
        */
        /* If we have reached here, that means this
        * is a useful packet for us. Pass on-the-wire
        * size and our cookie via metadata.
        */
        __u64 flags = BPF_F_INDEX_MASK;
        __u16 sample_size;
        int ret;
        struct S metadata;

        metadata.cookie = 0xdead;
        metadata.pkt_len = (__u16)(data_end - data);

        /* To minimize writes to disk, only
        * pass necessary information to userspace;
        * that is just the header info.
        */
        sample_size = min(metadata.pkt_len, SAMPLE_SIZE);
        flags |= (__u64)sample_size << 32;

        ret = bpf_perf_event_output(ctx, &my_map, flags,
                        &metadata, sizeof(metadata));
        if (ret)
            bpf_printk("perf_event_output failed: %d\n", ret);
    }
    return XDP_PASS;
}

它可以按您的预期工作,并存储给定 CPU 编号的信息。但是,假设我希望将所有数据包发送到索引 1。

我交换

__u64 flags = BPF_F_INDEX_MASK;

为了

__u64 flags = 0x1ULL;

代码正确编译并且没有抛出错误,但是根本没有数据包被保存。如果我希望将所有数据包都发送到索引 1,我做错了什么?

4

1 回答 1

0

部分答案:我认为没有理由不将数据包发送到 perf 缓冲区,但我怀疑错误出在用户空间代码上(未提供)。可能是您在尝试从缓冲区读取时没有“打开”所有 CPU 的 perf 事件。查看手册页perf_event_open(2):检查 和 的值组合是否pid允许cpu您读取为 CPU 1 写入的数据。

作为旁注,这是:

__u64 flags = BPF_F_INDEX_MASK;

具有误导性。掩码应该用来屏蔽索引,而不是设置它的值。BPF_F_CURRENT_CPU应该使用,前者只是碰巧工作,因为两个枚举属性具有相同的值。

于 2020-05-13T13:22:15.413 回答