问题标签 [xdp-bpf]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - AF_XDP:尽管在 RX-Queue 0 上引导,但没有来自多播的数据包
我仍在使用 AF_XDP 套接字,我的程序仍然主要基于:https ://github.com/xdp-project/xdp-tutorial/tree/master/advanced03-AF_XDP
我现在想要接收多个多播流(这在我注册多播 IP 的方式上工作得很好,因为我已经使用默认的 Linux 套接字对其进行了测试,因此我不会共享代码,除非你们说有必要解决这个问题)。
因为我还不想更改我的程序以在 NIC 的多个 RX-Queue 上工作(逐步进行,但最终我必须这样做以增加吞吐量)我将流量引导到单个 RX-Queue这个命令:
过滤器似乎处于活动状态:
但无论出于何种原因,我都收到了确切的0
数据包。这是我正在使用的内核程序:
任何想法为什么?
编辑:
我变了:
并且做了
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* 参数的两个低位 * 的值。
因为XDP_REDIRECT = 4
我认为这按预期工作。
main()
此外,在解析命令行参数后,我在用户空间代码中添加了这个输出:
确实返回0
(因此选择了正确的 RX-Queue)。
Edit_2:奇怪的是,我之前能够接收到一个多播流(它以某种方式意外地在 RX-Queue 0 上结束)但是在执行ethtool
上面的 -command 之后我什么都没有收到。听起来很奇怪,但这就是我观察它的方式。
Edit_3:sudo ethtool -S eth20
返回:http: //ix.io/2cSC
c - AF_XDP: `BPF_MAP_TYPE_XSKMAP` 仅包含 `Operation not supported` 的条目
这是我所有的 XDP / BPF 内核代码:
我正在尝试过滤所有 IP-UDP 数据包并将它们发送到用户空间。我还计算了到达每个 RX-Queue 的数据包数量(用 表示ctx->rx_queue_index
)。
我的程序编译得很好,但无论出于何种原因,我的用户空间程序中都没有收到任何数据包。我已经在我的另一篇文章中讨论过这个问题:AF_XDP:尽管在 RX-Queue 0 上引导,但没有来自多播的数据包
我sudo ethtool -N eth20 flow-type udp4 action 0
事先执行了将所有数据包引导到 RX-Queue 0
。
我可以通过以下方式查看当前活动的所有 bpf 地图
但我认为只有125
和126
我的程序有关。
队列引导有效,因为sudo bpftool map dump id 125
我得到:
如您所见,只有 RX-Queue 0 的计数器大于 0。
但是,如果我看一下BPF_MAP_TYPE_XSKMAP
(用于将数据包传输到用户空间),我会得到:
该消息是否表明Operation not supported
我在用户空间程序中没有收到任何数据包?还是在运行时无法接收到值?我也觉得奇怪Found 0 elements
。
任何想法这里有什么问题?
c - AF-XDP:如何将 `ctx->data_meta` 从内核获取到用户空间?
我想为我的 AF-XDP 程序测量数据包延迟。我在看这个参考:https ://github.com/xdp-project/xdp-project/blob/master/areas/arm64/xdp_for_tsn.org
并将其调整为:
然后在用户空间中的访问发生如下:
但我无法将 XDP 程序加载到内核中:
我的意思是,这不应该是可能的——对吧?因为 XDP 完全是关于有效的内存访问,为什么在定义的边界之外的访问会data
一直data_end
有效?
恕我直言,如果保持不变,它可以工作ctx->data_meta
- 但是我在用户空间遇到了问题,因为我不知道它data_meta
的位置。是否有任何 libbpf 辅助函数来访问数据包元数据?
也可能是访问是有效的,但我的范围检查是错误的......
c - AF_XDP: `FRAME_SIZE` 和数据包实际大小的关系
我的 AF-XDP 用户空间程序基于本教程:https ://github.com/xdp-project/xdp-tutorial/tree/master/advanced03-AF_XDP
我目前正在尝试每秒解析约 360.000 个 RTP 数据包(检查连续序列号),但我每秒丢失大约 25 个(这意味着对于 25 个数据包,该语句previous_rtp_sqnz_nmbr + 1 == current_rtp_sqnz_nmbr
不成立)。
所以我尝试将分配的数据包数量NUM_FRAMES
从 228.000 增加到 328.000。默认情况下FRAME_SIZE
会XSK_UMEM__DEFAULT_FRAME_SIZE = 4096
导致1281Mbyte
分配(没问题,因为我有 32GB 的 RAM),但无论出于何种原因,此函数调用:
失败了
我不知道为什么?但是因为我知道我的 RTP 数据包不大于 1500 字节,所以我设置FRAME_SIZE 3072
了所以我现在在附近960Mbyte
(它可以正常工作)。
但是,我现在丢失了一半收到的数据包(这意味着对于 180.000 个数据包,前一个序列号与当前序列号不一致)。
因此我提出一个问题:FRAME_SIZE
数据包的实际大小与实际大小有什么关系?因为显然不可能相同。
编辑:我正在使用5.4.0-4-amd64 #1 SMP Debian 5.4.19-1 (2020-02-13) x86_64 GNU/Linux
并将libbpf
-repository 从这里复制到我的代码库中:https ://github.com/libbpf/libbpf
所以不知道这里提到的错误:https ://github.com/xdp-project/xdp-tutorial/issues/76是否仍然有效?
c - AF-XDP:仅加载内核程序一次,但将对 xsks-map 的访问分配给多个进程
据我了解,每个网络接口只能有一个 AF-XDP 内核程序。我想将来自单个网络接口的多个多播地址的数据包处理分配给多个进程。我编写了一个“加载器”程序来创建进程(到目前为止工作正常)。
我现在的问题是在加载程序中仅加载一次内核程序load_bpf_and_xdp_attach
,但是将对 xsks-map 的访问分配给多个进程。
load_bpf_and_xdp_attach
返回指向 a 的指针struct bpf_object*
。然后需要这个指针bpf_object__find_map_by_name
来访问bpf_map
文件描述符。
我的想法是将 的内容bpf_object
写入共享内存,从而将其分配给进程。但不幸的是,该结构bpf_object
是在libbpf.c
. 因此,我无法做到这一点:
这在我看来,libbpf
不想让任何人知道bpf_object
。
有什么想法可以实现我最初的想法吗?
如果每个进程都加载自己的内核程序版本,我最终会得到(amount of processes)
-xsks 映射,我认为这不明智。
编辑:我知道有一种方法可以重用地图,但是......似乎有点复杂
c - AF_XDP:不支持为“SO_XDP”设置“SO_TIMESTAMP”:协议不可用
为什么套接字SO_TIMESTAMP
不支持设置?AF_XDP
我的驱动程序的用户手册 ( mlnx 5.0
) 指出
根据 PCI 缓冲区中的拥塞情况,传入的数据包在它们被分发到 PCI 之前被打上时间戳。
据我所知,before distributed on the PCI
这意味着(还)没有涉及 Linux 内核 - 对吧?
我试过这样设置:
并得到:
设置失败
SO_TIMESTAMP
:协议不可用
SO_XDP
我从xsk.c
(https://github.com/libbpf/libbpf/blob/master/src/xsk.c)复制了定义:
不明白,为什么不支持。。。
linux - AF_XDP:将 `(SRC-IP, DST-IP, DST-Port)` 映射到 `BPF_MAP_TYPE_XSKMAP` 的索引
我想产生多个用户空间进程,每个进程都处理来自单个源(三倍(SRC-IP, DST-IP, DST-Port)
)的数据包。
因为要通过 AF-XDP 内核程序传递大量数据包并且时间很关键,所以我想到了内核程序中的一个单独的映射,该映射预先由用户空间程序填充。
该映射定义了从前面提到的三元组到索引的映射,然后用于bpf_redirect_map(&xsks_map, index, 0)
将数据包发送到用户空间中的特定套接字。
我最初的想法是将 src-ip、destination-ip 和目标端口连接成一个 (32 + 32 + 16) 位的值。
是否可以定义具有如此大键大小的映射?哪张地图最适合这个问题?此外,是否可以从用户空间填充地图?
c - AF_XDP:从堆栈中间接读取无效
我尝试实现我在这篇文章中谈到的映射:AF_XDP: map `(SRC-IP, DST-IP, DST-Port)` to index to `BPF_MAP_TYPE_XSKMAP`
我的内核程序有这张地图:
和
在 AF-XDP 程序中,我使用pckt_raw_idntfy
当前作为键处理的数据包的相应值创建了一个 -struct:
然后我在其中查找值xdp_packet_mapping
并将数据包重定向到用户空间,以防该值存在:
在用户空间中,我像这样填充地图:
编译工作正常,但如果我尝试执行程序(在程序启动后立即加载 AF-XDP 内核程序),我会收到以下错误:
任何想法我做错了什么?
编辑:感谢Qeole,用填充定义结构解决了这个问题:
c - AF_XDP:即使每个数据包都被重定向,也没有队列 ID 为 0 的套接字的数据包
我基于本教程:https ://github.com/xdp-project/xdp-tutorial/tree/master/advanced03-AF_XDP
我在用户空间中创建了一个套接字Queue-ID 0
。在我的内核 af-xdp 程序中,我过滤 UDP 数据包并通过xskmap
.
因为我显然希望用户空间程序接收数据包,所以我将内核程序中的数据包重定向到 index 0
:
我没有收到错误消息Didn't find connected socket for index 0!
,sudo cat /sys/kernel/debug/tracing/trace_pipe
但我在用户空间也没有收到任何数据包!
如果我只是继续运行程序并同时添加这样的 ethtool-rule:
我的用户空间程序突然开始接收数据包并且错误消息消失了。
我认为内核程序会接收发送到该接口的每个数据包,但不知何故,情况并非如此。我做错什么了?
c - AF-XDP:实现共享 Umem 套接字
我想实现 XDP_SHARED_UMEM:https ://www.kernel.org/doc/html/latest/networking/af_xdp.html#xdp-shared-umem-bind-flag
库libbpf
函数xsk_socket__create
( https://github.com/libbpf/libbpf/blob/master/src/xsk.c ) 检查该xsk_umem->refcount
值。如果它大于 1,则设置XDP_SHARED_UMEM
a 的选项struct sockaddr_xdp
。
因此,据我正确理解,我“只”需要传递要与之共享 umem 的套接字的原始 umem 结构,其余的由libbpf
.
我尝试这样做的方法是让第一个进程将其umem
-struct 复制到第二个进程可以从中加载它的共享内存区域。但是因为它struct xsk_umem
被定义在xsk.c
用户面前是隐藏的,所以我不能做这样的事情:
memcpy(shdm_ptr, umem, sizeof(struct xsk_umem))
我不知道他们如何期望有人使用共享的 umem 功能?