我确实有一些 DPDK 经验,但目前我正在阅读许多有关 XDP 的博客。我正在尝试比较这两种技术并了解 DPDK 和 XDP 之间的差异。这引发了一些问题。我希望有人能帮助我解决以下问题:
预先感谢您的帮助!
我正在尝试编写一个可以访问套接字缓冲区数据的简单套接字过滤器 eBPF 程序。
#include <linux/bpf.h>
#include <linux/if_ether.h>
#define SEC(NAME) __attribute__((section(NAME), used))
SEC("socket_filter")
int myprog(struct __sk_buff *skb) {
void *data = (void *)(long)skb->data;
void *data_end = (void *)(long)skb->data_end;
struct ethhdr *eth = data;
if ((void*)eth + sizeof(*eth) > data_end)
return 0;
return 1;
}
Run Code Online (Sandbox Code Playgroud)
我正在使用 clang 进行编译:
clang -I./ -I/usr/include/x86_64-linux-gnu/asm \
-I/usr/include/x86_64-linux-gnu/ -O2 -target bpf -c test.c -o test.elf
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试加载程序时,出现以下验证器错误:
invalid bpf_context access off=80 size=4
Run Code Online (Sandbox Code Playgroud)
我对这个错误的理解是,当您尝试访问尚未检查为在 内的上下文数据时应该抛出它data_end,但是我的代码确实这样做了:
这是我的程序的说明
0000000000000000 packet_counter:
0: 61 12 50 00 00 00 00 00 …Run Code Online (Sandbox Code Playgroud) 因此,我按照此链接将 BPF 程序附加到用户空间探针,Dtrace 格式(请参阅用户静态定义的跟踪点部分)。
C程序:
#include <sys/sdt.h>
int main() {
DTRACE_PROBE("hello-usdt", "probe-main");
}
Run Code Online (Sandbox Code Playgroud)
确保包含探测信息的检查:
readelf -n hello_usdt
stapsdt 0x00000033 NT_STAPSDT (SystemTap probe descriptors)
Provider: "hello_usdt"
Name: "probe-main"
Location: 0x0000000000400535, Base: 0x00000000004005d4, Semaphore: 0x0000000000000000
Arguments:
Run Code Online (Sandbox Code Playgroud)
还有 tplist:
sudo /usr/share/bcc/tools/tplist -l /path/to/hello_usdt
/path/to/hello_usdt "hello_usdt":"probe-main"
Run Code Online (Sandbox Code Playgroud)
BPF程序的内容(usdt.py):
readelf -n hello_usdt
stapsdt 0x00000033 NT_STAPSDT (SystemTap probe descriptors)
Provider: "hello_usdt"
Name: "probe-main"
Location: 0x0000000000400535, Base: 0x00000000004005d4, Semaphore: 0x0000000000000000
Arguments:
Run Code Online (Sandbox Code Playgroud)
故障描述:
sudo ./usdt.py
Traceback (most recent call last):
File "./usdt.py", line 13, in <module>
usdt.enable_probe(probe …Run Code Online (Sandbox Code Playgroud) 目前,我正在跟踪 bpf 程序并发现一些我无法理解的内容。
有几个声明,例如:
struct bpf_map_def SEC("maps") map_parsing_context = {
...
};
struct {
...
} map_keys SEC(".maps");
Run Code Online (Sandbox Code Playgroud)
我的问题是:
__attribute__((section("name")))?map和之间有什么不同.map?它们只是用户定义的部分吗?想法是用来测量返回处理的数据包数量(称为工作)的argdist延迟持续时间。napi_poll()执行延迟与处理的数据包数量的比率napi_poll()将以直方图的形式给出处理每个数据包所需的平均时间。
我正在使用以下命令
argdist -H 'r:c:napi_poll():u64:$latency/$retval#avg time per packet (ns)'
这最终给了我错误Failed to attach BPF to kprobe,在 dmesg 中我收到类似的消息Could not insert probe at napi_poll+0: -2
我只是好奇为什么当类似的技巧适用时我无法kretprobes附加?napi_poll()net_rx_action()
当我将 xdp 与 eBPF 一起使用时,我想我可以使用 ip link 来设置模式。
例如,
ip link set dev eno1 xdpoffload obj xdp.o sec .text
Run Code Online (Sandbox Code Playgroud)
我想知道 xdpoffload 或通用或本机模式是如何在代码中实现的。
所以我正在查看其他代码,我发现了类似的内容:
attach_xdp(device, fn, flags)
Run Code Online (Sandbox Code Playgroud)
我认为 flags 是设置模式标志所在的地方?
如果有人能告诉我这是否属实,如果属实,我可以使用哪些数字来选择选项,那就太好了。
预先非常感谢您。