AF_XDP:尽管在RX-Queue 0上进行了定向,但没有来自多播的数据包 [英] AF_XDP: No packets from multicast although steered on RX-Queue 0

查看:284
本文介绍了AF_XDP:尽管在RX-Queue 0上进行了定向,但没有来自多播的数据包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我仍在使用AF_XDP套接字,并且我的程序仍主要基于: https://github.com/xdp-project/xdp-tutorial/tree/master/advanced03-AF_XDP

I am still playing with the AF_XDP socket and my program is still largely based on: https://github.com/xdp-project/xdp-tutorial/tree/master/advanced03-AF_XDP

我现在希望接收多个多播流(这与我注册多播IP的方式很好,因为我已经使用默认的Linux套接字对其进行了测试,因此除非大家表示有必要解决该问题,否则我不会共享代码。)

I now want to receive multiple multicast streams (which works fine the way I register the multicast IPs because I have tested it with the default Linux socket thus I am not sharing the code unless you guys say it is necessary to solve the issue).

因为我现在还不想更改程序以使其能够在NIC的多个RX队列上运行(逐步进行,但最终我必须这样做以增加吞吐量)我使用以下命令将流量引导到单个RX队列中:

Because I don't want to change my program to work on multiple RX-Queues of the NIC just yet (go step by step, but eventually I have to do it to increase throughput) I steered the traffic onto a single RX-Queue with this command:

sudo ethtool -N eth20 flow-type udp4 action 0

过滤器似乎处于活动状态:

Filter seems to be active:

$ sudo ethtool -n eth20
48 RX rings available
Total 1 rules

Filter: 1023
        Rule Type: UDP over IPv4
        Src IP addr: 0.0.0.0 mask: 255.255.255.255
        Dest IP addr: 0.0.0.0 mask: 255.255.255.255
        TOS: 0x0 mask: 0xff
        Src port: 0 mask: 0xffff
        Dest port: 0 mask: 0xffff
        Action: Direct to queue 0

但是出于某种原因,我收到的正是 0 数据包。这是我正在使用的内核程序:

But for whatever reason, I receive exactly 0 packets. This is the Kernel-program I am using:

struct bpf_map_def SEC("maps") xsks_map = {
    .type = BPF_MAP_TYPE_XSKMAP,
    .key_size = sizeof(int),
    .value_size = sizeof(int),
    .max_entries = 64,  /* Assume netdev has no more than 64 queues */
};

SEC("xdp_sock")
int xdp_sock_prog(struct xdp_md *ctx) {

    int index = ctx->rx_queue_index;

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

    void *pos = data;
    struct ethhdr *eth = (struct ethhdr*)(pos);

    if(eth + sizeof(struct ethhdr) <= data_end) {

        if(bpf_ntohs(eth->h_proto) == ETH_P_IP) {
            struct iphdr *iph = (struct iphdr*)(pos + sizeof(struct ethhdr));

            if(iph + sizeof(struct iphdr) <= data_end) {

                if(iph->protocol == IPPROTO_UDP) {
                    const __u16 iph_sz_in_bytes = iph->ihl * 4;

                    if(iph + iph_sz_in_bytes <= data_end) {
                        struct udphdr *udh = (struct udphdr*)(pos + sizeof(struct ethhdr) + iph_sz_in_bytes);

                        if(udh + sizeof(struct udphdr) <= data_end) {

                            if (bpf_map_lookup_elem(&xsks_map, &index)) {
                                return bpf_redirect_map(&xsks_map, index, 0);
                            }
                        }
                    }
                }
            }
        }
    }

    return XDP_PASS;
}

任何想法为何?

编辑:

我更改了:

                    if (bpf_map_lookup_elem(&xsks_map, &index)) {
                        const int ret_val = bpf_redirect_map(&xsks_map, index, 0);
                        bpf_printk("RET-VAL: %d\n", ret_val);
                        return ret_val;
                    }

并且做了


sudo cat / sys / kernel / debug / tracing / trace_pipe

sudo cat /sys/kernel/debug/tracing/trace_pipe

返回:

ksoftirqd / 17-98 [017] ..s。 277979.654041:0:RET-VAL:4

根据 bpf_redirect_map 的描述:



  • 成功返回* XDP_REDIRECT ,或者两个$的值错误时** flags *参数的b $ b个低位*。

  • Returns * XDP_REDIRECT on success, or the value of the two lower bits * of the **flags* argument on error.

因为 XDP_REDIRECT = 4 我认为这可以按预期工作。

Because XDP_REDIRECT = 4 I assume this works as expected.

此外,我将此输出添加到 main()在解析命令行参数后发生:

Furthermore, I added this output in the user-space code in main() after parsing of command line arguments has happened:

printf("RX-Queue: %d\n", cfg.xsk_if_queue);

确实返回 0 (所以正确的RX -que被选中。)

Which indeed returns 0 (so correct RX-Queue is selected).

Edit_2:奇怪的是,我之前能够接收到一个多播流(由于某种原因,它意外地在RX-Queue 0上结束了。 ),但是在执行上述 ethtool -命令之后,我什么也没收到。听起来很奇怪,但这就是我的观察方式。

Edit_2: The strange thing is that I was able to receive a single multicast stream before (which somehow ended up on RX-Queue 0 by accident) but after executing the ethtool-command above I am not receiving anything at all. Sounds strange but that's how I observed it.

Edit_3: sudo ethtool -S eth20 返回: http://ix.io/2cSC

Edit_3: sudo ethtool -S eth20 returned: http://ix.io/2cSC

$ sudo bpftool prog show
39: cgroup_skb  tag 7be49e3934a125ba  gpl
        loaded_at 2020-02-28T08:00:06+0000  uid 0
        xlated 296B  not jited  memlock 4096B  map_ids 38,39
40: cgroup_skb  tag 2a142ef67aaad174  gpl
        loaded_at 2020-02-28T08:00:06+0000  uid 0
        xlated 296B  not jited  memlock 4096B  map_ids 38,39
41: cgroup_skb  tag 7be49e3934a125ba  gpl
        loaded_at 2020-02-28T08:00:06+0000  uid 0
        xlated 296B  not jited  memlock 4096B  map_ids 40,41
42: cgroup_skb  tag 2a142ef67aaad174  gpl
        loaded_at 2020-02-28T08:00:06+0000  uid 0
        xlated 296B  not jited  memlock 4096B  map_ids 40,41
43: cgroup_skb  tag 7be49e3934a125ba  gpl
        loaded_at 2020-02-28T08:00:06+0000  uid 0
        xlated 296B  not jited  memlock 4096B  map_ids 42,43
44: cgroup_skb  tag 2a142ef67aaad174  gpl
        loaded_at 2020-02-28T08:00:06+0000  uid 0
        xlated 296B  not jited  memlock 4096B  map_ids 42,43


推荐答案

我的用户空间代码中确实存在问题。即使禁用了轮询,我也轮询了套接字的文件描述符。因此,它永远不会返回。

There was indeed a problem in my user-space code. I polled the filedescriptor of the socket even though I disabled polling. Because of that it never returned.

这篇关于AF_XDP:尽管在RX-Queue 0上进行了定向,但没有来自多播的数据包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆