eBPF:尾调用

时间:2018-01-15 17:07:25

标签: c sockets linux-kernel bpf

我正在使用tail calls的{​​{1}}功能,似乎简单的代码无法加载:

BPF

所以我用struct bpf_map_def SEC("maps") jmp_table = { .type = BPF_MAP_TYPE_PROG_ARRAY, .key_size = sizeof(u32), .value_size = sizeof(u32), .max_entries = 8, }; SEC("sockops") int bpf1(struct bpf_sock_ops *sk_ops) { return 1; } SEC("sockops") int bpf2(struct bpf_sock_ops *sk_ops) { return 1; } SEC("sockops") int bpf3(struct bpf_sock_ops *sk_ops) { return 1; } SEC("sockops") int bpf_main(struct bpf_sock_ops *sk_ops) { __u32 port = bpf_ntohl(sk_ops->remote_port); switch (port) { case 5000: bpf_tail_call(sk_ops, &jmp_table, 1); break; case 6000: bpf_tail_call(sk_ops, &jmp_table, 2); break; case 7000: bpf_tail_call(sk_ops, &jmp_table, 3); break; } sk_ops->reply = 0; return 1; } char _license[] SEC("license") = "GPL"; u32 _version SEC("version") = LINUX_VERSION_CODE; 编译了它并加载了llv-3.8

bpftool

所以$ sudo ./bpftool prog load bpf_main.o /sys/fs/bpf/p1 libbpf: load bpf program failed: Invalid argument libbpf: -- BEGIN DUMP LOG --- libbpf: unreachable insn 2 libbpf: -- END LOG -- libbpf: failed to load program 'sockops' libbpf: failed to load object 'bpf_main.o' Error: failed to load program 提到:

man 2 bpf

我不知道这个小小的简单程序有什么问题,EINVAL For BPF_PROG_LOAD, indicates an attempt to load an invalid program. eBPF programs can be deemed invalid due to unrecognized instructions, the use of reserved fields, jumps out of range, infinite loops or calls of unknown functions. 也失败了:

llvm-objdump

更新1

根据Qeole的建议,我升级到$ llvm-objdump-3.8 -arch-name=bpf -disassemble ./tcp_metrics_kern.o ./tcp_metrics_kern.o: file format ELF64-unknown LLVM ERROR: error: no disassembler for target bpfel-unknown-unknown ,重建了我的程序,现在抱怨不同:

clang-5.0

现在我可以调查ELF部分:

$ sudo ./bpftool prog load bpf_main.o /sys/fs/bpf/p1
libbpf: relocation failed: no 10 section
Error: failed to load program

以下是可用的部分:

$ llvm-objdump-5.0 -disassemble -source ./bpf_main.o

./bpf_main.o:   file format ELF64-BPF

Disassembly of section sockops:
bpf1:
       0:       b7 00 00 00 01 00 00 00         r0 = 1
       1:       95 00 00 00 00 00 00 00         exit

bpf2:
       2:       b7 00 00 00 01 00 00 00         r0 = 1
       3:       95 00 00 00 00 00 00 00         exit

bpf3:
       4:       b7 00 00 00 01 00 00 00         r0 = 1
       5:       95 00 00 00 00 00 00 00         exit

bpf_main:
...

看来 $ llvm-objdump-5.0 -section-headers ./bpf_main.o ./bpf_main.o: file format ELF64-BPF Sections: Idx Name Size Address Type 0 00000000 0000000000000000 1 .strtab 000000a5 0000000000000000 2 .text 00000000 0000000000000000 TEXT DATA 3 sockops 000001f8 0000000000000000 TEXT DATA 4 .relsockops 00000030 0000000000000000 5 maps 0000001c 0000000000000000 DATA 6 .rodata.str1.16 00000021 0000000000000000 DATA 7 .rodata.str1.1 0000000e 0000000000000000 DATA 8 license 00000004 0000000000000000 DATA 9 version 00000004 0000000000000000 DATA 10 .eh_frame 00000090 0000000000000000 DATA 11 .rel.eh_frame 00000040 0000000000000000 12 .symtab 00000138 0000000000000000 无法找到bpftool部分?

更新2

我继续尝试:-)首先,我使用最新提交.eh_frame修复字符串比较更新libbpf,然后使用d77be68955475fc2321e73fe006240248f2f8fef重建程序,但不包括{{1}部分,我也给出了独特的部分名称,例如sockops0,sockops1等等。现在-fno-asynchronous-unwind-tables成功但.eh_frame只转储一个程序,这个程序非常先行,在我的例子中它是bpf1()。

目前我可以说bpf_object__load_progs()将obj-> nr_programs报告为4,这对我的例子来说很有意义。

0 个答案:

没有答案