问题标签 [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.

0 投票
0 回答
555 浏览

bpf - 如何捕获XDP用户空间程序发送的数据包

假设我有 XDP 内核和用户程序。内核代码检查入口数据包并将它们“转发”到 XDP 用户空间程序。XDP 用户空间程序然后进行一些处理并将数据包发送出去(可能是同一个 NIC 或其他)。出于控制原因,我们要检查XDP 用户空间代码发送的传出数据包。我们的第一个想法是使用 tc 并将 BPF 代码插入到 egress 部分,显然没有用。

任何想法?

EDIT1:出口程序:

跑: sudo tc filter add dev ens13 egress bpf da obj layercoop.o sec tx

EDIT2:代码
用户:https
://github.com/torvalds/linux/blob/master/samples/bpf/xdpsock_user.c 内核(不感兴趣):https ://github.com/torvalds/linux/blob/master/ samples/bpf/xdpsock_kern.c
我想转发传入的数据包,所以运行它make -j 4; sudo ./xdpsock -i ens13 -l

0 投票
0 回答
264 浏览

linux - samples/bpf/xdpsock_user.c:xsk_configure_socket:331: errno: 1/“不允许操作”

我有一个与XDP program ip link error: Prog section denied: Operation not allowed类似的问题,Linux 5.4.0 除外。

我能够运行一些 XDP eBPF 程序,但不能运行 AF_XDP:

但是,rxq_info 示例程序确实有效:

并且 XDP 已启用(否则 rxq_info 示例程序将无法工作):

失败的调用在这里:https ://elixir.bootlin.com/linux/v5.4/source/tools/lib/bpf/xsk.c#L475 。为什么运行 xdpsock 会导致错误?

0 投票
1 回答
247 浏览

c - BPF:“bpf_obj_get_info_by_fd”因“无效参数”而失败

我尝试BPF_MAP_TYPE_XSKMAP在我的用户空间程序中获取 fd。

这是代码:

bpf_obj_get_info_by_fd(cfg->prog_fd, &prog_info, &prog_info_len)但不幸的是,我在调用:时收到错误消息Failed to obtain prog_info 1: Invalid argument

我不知道这是不是因为 XDP 程序是从另一个进程加载的?同一个进程是否必须获取也加载了AF-XDP程序的程序信息?

编辑:我在用户空间程序中唯一更改的是填充一个BPF_MAP_TYPE_HASHvia bpf_map_update_elem(条目在那里,用 观察bpftool map dump id <id>)并bpf_map_lookup_elem在我的 XDP 程序中使用(相同的哈希映射)。

突然,错误变为: Failed to obtain prog_info 1: Bad address

0 投票
1 回答
91 浏览

ebpf - 是否可以构建分段的 Ipv4 数据包,并在 xdp / ebpf 程序中检测泪滴攻击?

好吧,我正在尝试实现基于 eBPF 和 xdp 驱动程序的泪滴攻击数据包过滤。而且我不知道该怎么做...是否可以通过使用这些仪器来检测 ipv4 片段重叠?

0 投票
0 回答
1132 浏览

c - AF_XDP-Socket 与 Linux 套接字:为什么我的 AF-XDP 套接字会丢失数据包,而通用 linux 套接字却不会?

我正在比较 AF-XDP 套接字和 Linux 套接字,它们可以处理多少个数据包而不会丢失数据包(数据包丢失定义为当前数据包的 RTP 序列号不等于以前的数据包+ 1)。

我注意到我的 AF-XDP 套接字程序(我无法确定这个问题是否与内核程序或用户空间程序有关)~25每秒丢失大约数据390.000包,而具有通用 linux 套接字的等效程序不会丢失任何数据包。

我实现了一个所谓的distributor程序,它加载 XDP 内核程序一次,设置一个通用 linux 套接字,并setsockopt(IP_ADD_MEMBERSHIP)为我通过命令行传递给程序的每个多播地址添加到这个通用套接字。在此之后,distributor加载BPF_MAP_TYPE_HASH放置在 XDP 内核程序中的文件描述符并插入流量路由,以防单个 AF-XDP 套接字稍后需要共享其 umem。

然后,XDP 内核程序检查每个 IPv4/UDP 数据包是否在该哈希映射中存在条目。这基本上看起来像这样:

如果idx存在,这意味着在BPF_MAP_TYPE_XSKMAP.

在完成所有这些之后,通过传递应该由该进程处理的所有多播地址(包括目标端口)distributor产生一个新进程(一个进程处理一个 RX 队列)。fork()如果没有足够的 RX-Queue,某些进程可能会收到多个多播地址。这意味着他们将使用SHARED UMEM.

我基本上将我的 AF-XDP 用户空间程序定位在这个示例代码上:https ://github.com/torvalds/linux/blob/master/samples/bpf/xdpsock_user.c

我正在使用相同的xsk_configure_umem,xsk_populate_fill_ringxsk_configure_socket功能。

因为我认为我不需要此应用程序的最大延迟,所以我将进程发送到睡眠指定时间(大约1 - 2ms),之后它循环通过每个 AF-XDP 套接字(大多数时候它只是一个套接字)并处理该套接字的每个接收到的数据包,验证没有丢失任何数据包:

在我看来,这并没有什么太花哨的东西,但不知何故,即使我的 UMEM 接近 1GB 的 RAM,我也会在数据~25包周围丢失数据包。390.000

相比之下,我的通用 linux 套接字程序看起来像这样(简而言之):

-program 为每个给定的distributor多播 IP 创建一个新进程,以防使用通用 linux 套接字(因为在通用套接字中没有复杂的方法,例如 SHARED-UMEM,我不会为每个进程的多个多播流而烦恼)。后来我当然加入了多播成员:

并开始处理数据包(不是休眠,而是以busy-loop类似的方式):

差不多就是这样。

请不要在所描述的用例中开始丢失我不使用的数据包SHARED UMEM,它只是一个接收多播流的单个 RX-Queue。如果我处理较小的多播流,150.000 ppsAF-XDP 解决方案不会丢失任何数据包。但这也是相反的方式 - 因为520.000 pps在同一个 RX-Queue 上(使用SHARED UMEM)我失去了12.000 pps.

有什么我想念的想法吗?

0 投票
1 回答
172 浏览

linux - AF-XDP:小数据包有问题吗?

在 AF-XDP 套接字框架 (+ libbpf) 中是否存在关于数据包大小的已知(或可能未知)错误?

我的应用程序遇到奇怪的数据包丢失:

  • IPv4/UDP/RTP 数据包流,所有数据包大小相同(1442 字节):无数据包丢失
  • IPv4/UDP/RTP 数据包流,其中几乎所有数据包的大小都相同(1492 字节),除了一个特殊的“标记”数据包(只有 357 字节,但它们也是 IPv4/UDP 数据包):所有标记数据包都会丢失

bpf_printk我在我的 XDP-Kernelprogram 中添加了一条语句:

永远不会通过 观察到此输出sudo cat /sys/kernel/debug/tracing/trace_pipe。所以我的内核过滤器甚至没有收到这些小的 RTP 标记数据包——难怪我在用户空间中没有收到它们。

ethtool -S <if>给我看这个号码:rx_256_to_511_bytes_phy。这个数字的增长速度与标记数据包应该进来的速度相似(大约 30/s)。所以这意味着我的 NIC 确实收到了数据包,但我的 XDP 程序没有 - 为什么?

知道什么可能是这个问题的原因吗?

0 投票
1 回答
348 浏览

c - AF-XDP - `XDP_USE_NEED_WAKEUP` 如何工作,例如“如何减少 ksoftirqd 负载”?

我尝试在我的网卡的单个 RX-Queue 上最大化吞吐量。我当前的设置是Shared Umem通过在同一个 RX-Queue 上设置多个套接字来利用该功能,每个套接字都引用同一个 Umem。

然后我的内核 XDP 程序通过BPF_MAP_TYPE_XSKMAP. 这一切工作正常,但在大约 600.000 pps 时,ksoftirqd/18达到 100% 的 CPU 负载(我将我的用户空间应用程序移动到另一个核心,taskset -c 1以减少核心 18 上的负载)。我的用户空间应用程序没有超过 14% 的 CPU 负载,所以不幸的是,我无法处理更多数据包的原因是因为大量的中断。

然后,我阅读了 xdp 绑定标志,该标志XDP_USE_NEED_WAKEUP将 Umem 填充环发送到睡眠状态,从而减少了中断开销(据我正确理解,关于这个主题的信息并不多)。因为 Umem Fill-Ring 可能正在睡觉,所以必须定期检查:

fds包含struct pollfd每个套接字的文件描述符。我不太确定在哪里添加XDP_USE_NEED_WAKEUP标志,但这是我使用它的方式:

我观察到它对负载的影响很小,ksoftirqd/18并且我能够比以前多处理 50.000 pps(但这也可能是因为系统的一般负载发生了变化 - 我不确定:/)。但我也注意到,这XDP_USE_NEED_WAKEUP不起作用,Shared Umem因为 libbpf 有这个代码xsk.c

如您所见,bind_flags仅当Umemarefcount为 1 时才使用(它不能小于该值,因为它在 的上方某处递增xsk_socket__create)。但是因为对于每个创建的套接字,refcount都会增加 - 这些bind_flags仅用于第一个套接字(refcount仍然是<= 1)。

我不太明白为什么XDP_USE_NEED_WAKEUP只能用于一个插座?事实上,我完全不明白如果这个标志实际上影响了 Umem,为什么它与套接字有关?

尽管如此,我正在寻找一种减少中断开销的方法——有什么想法可以实现吗?我需要至少 1.000.000 pps。

0 投票
1 回答
1464 浏览

xdp-bpf - 如何使用 XDP 在 NIC 和 WIFI 之间转发数据包

我正在尝试重定向 NIC 和 WIFI 之间的流量。我正在尝试从 eth0 转发数据包,通过 wlan0 发送偶数数据包,通过 wlan1 发送奇数数据包。

我无法成功地将数据包从一个接口重定向到另一个接口,除非这些接口是虚拟的(例如在 xdp-tutorial 中创建的接口)。

是否有一个简单的示例将入口数据包从带有 MAC 28:f1:f1:f1:f1:f1 的 eth0 重定向到带有 MAC e4:f1:f1:f1:f1:f1 的 wlan0?(例如 MAC) 如果我通过以太网端口连接第二台计算机(假设路由正确)并 ping 8.8.8.8,它会通过 wlan0 发送数据包吗?

我将不胜感激在这方面的任何帮助。

编辑:

我使用的代码是来自xdp-tutorial的代码

分步设置:

最后一条命令输出:

相关的 BPF 代码是

地图的内容是:

0 投票
0 回答
349 浏览

c - BPF/XDP:为什么 `bpf_ntohs` 会产生验证器错误?

我对 BPF/XDP 验证程序有疑问。我尝试过滤 UDP 数据包并在数据包末尾写入时间戳(使用udh->len)。因为udh->len是网络字节顺序,我首先必须将其转换为“主机”字节顺序。所以我这样尝试:

但我明白了math between pkt pointer and register with unbounded min value is not allowed

因为我想不出这种方法会失败,所以我试图删除bpf_ntohs只是为了测试目的(我知道它不会那样工作):

但我实际上能够以这种方式运行我的程序 - 任何想法为什么bpf_ntohs会产生验证程序错误?

0 投票
2 回答
1150 浏览

c - XDP/BPF:是否有用户空间替代 `bpf_ktime_get_ns`?

我想在我的 XDP 程序中收到的数据包中插入一个时间戳。我知道如何获取时间戳的唯一方法是调用bpf_ktime_get_ns.

但是创建可比较时间戳的用户空间等效函数是什么?据我所知,ktime_get_ns返回自系统启动以来的时间(以纳秒为单位)。有

但这仅返回自系统启动以来的时间(以为单位)。所以这里不可能进行精确的测量(微秒级会很好)。

编辑:这纯粹是我的错。@Qeole 和@tuilagio 是完全正确的。在获取时间戳指针的用户空间代码中,我在指针算术中犯了一个错误。