pwru
pwru copied to clipboard
pwru: Add --filter-skb-expr and --filter-xdp-expr
Fixes #11
I'm porting such feature from bpfsnoop's --filter-arg 'skb->dev->ifindex == 11'.
The following message is valid even though it was wrote for the original draft PR.
If we want to filter some info dynamically like 'skb->dev->ifindex == 11', it is better to compile the simple C expression to bpf instructions directly.
In order to achieve it, we can:
- Parse provided C expression to AST.
- Validate AST as expectation.
- Convert AST to offsets based on BTF info.
- Generate
bpf_probe_read_kernel()based on converted offsets. - Generate jmp insn for the compare op in the C expression.
- Replace the insns of stub function with the generated insns.
As a result, add --filter-skb-expr to filter skb dynamically, and add --filter-xdp-expr to filter xdp dynamically.
For examples, the jited insns of --filter-skb-expr 'skb->dev->ifindex == 11' is
; bpf/kprobe_pwru.c:233:0 filter_skb_expr(struct sk_buff *skb)
0xffffffffc018f2d4: 0f 1f 44 00 00 nopl (%rax, %rax)
0xffffffffc018f2d9: 66 90 nop
0xffffffffc018f2db: 55 pushq %rbp
0xffffffffc018f2dc: 48 89 e5 movq %rsp, %rbp
0xffffffffc018f2df: 48 81 ec 08 00 00 00 subq $8, %rsp
0xffffffffc018f2e6: 48 89 fa movq %rdi, %rdx
0xffffffffc018f2e9: 48 83 c2 10 addq $0x10, %rdx
0xffffffffc018f2ed: be 08 00 00 00 movl $8, %esi
0xffffffffc018f2f2: 48 89 ef movq %rbp, %rdi
0xffffffffc018f2f5: 48 83 c7 f8 addq $-8, %rdi
0xffffffffc018f2f9: e8 c2 e6 b1 f4 callq 0xffffffffb4cad9c0 ; bpf_probe_read_kernel+0x0 kernel/trace/bpf_trace.c:233
0xffffffffc018f2fe: 48 8b 55 f8 movq -8(%rbp), %rdx
0xffffffffc018f302: 48 85 d2 testq %rdx, %rdx
0xffffffffc018f305: 74 2f je 0xffffffffc018f336 ; filter_skb_expr+0x62 bpf/kprobe_pwru.c:233 [bpf]
0xffffffffc018f307: 48 81 c2 e0 00 00 00 addq $0xe0, %rdx
0xffffffffc018f30e: be 08 00 00 00 movl $8, %esi
0xffffffffc018f313: 48 89 ef movq %rbp, %rdi
0xffffffffc018f316: 48 83 c7 f8 addq $-8, %rdi
0xffffffffc018f31a: e8 a1 e6 b1 f4 callq 0xffffffffb4cad9c0 ; bpf_probe_read_kernel+0x0 kernel/trace/bpf_trace.c:233
0xffffffffc018f31f: 48 8b 55 f8 movq -8(%rbp), %rdx
0xffffffffc018f323: 48 c1 e2 20 shlq $0x20, %rdx
0xffffffffc018f327: 48 c1 ea 20 shrq $0x20, %rdx
0xffffffffc018f32b: b8 01 00 00 00 movl $1, %eax
0xffffffffc018f330: 48 83 fa 0b cmpq $0xb, %rdx
0xffffffffc018f334: 74 02 je 0xffffffffc018f338 ; filter_skb_expr+0x64 bpf/kprobe_pwru.c:233 [bpf]
0xffffffffc018f336: 31 c0 xorl %eax, %eax
0xffffffffc018f338: c9 leave
0xffffffffc018f339: c3 retq
0xffffffffc018f33a: cc int3
The jited insns of --filter-xdp-expr 'xdp->rxq->dev->ifindex == 9' is
; bpf/kprobe_pwru.c:659:0 filter_xdp_expr(struct xdp_buff *xdp)
0xffffffffc018f168: 0f 1f 44 00 00 nopl (%rax, %rax)
0xffffffffc018f16d: 66 90 nop
0xffffffffc018f16f: 55 pushq %rbp
0xffffffffc018f170: 48 89 e5 movq %rsp, %rbp
0xffffffffc018f173: 48 81 ec 08 00 00 00 subq $8, %rsp
0xffffffffc018f17a: 48 89 fa movq %rdi, %rdx
0xffffffffc018f17d: 48 83 c2 20 addq $0x20, %rdx
0xffffffffc018f181: be 08 00 00 00 movl $8, %esi
0xffffffffc018f186: 48 89 ef movq %rbp, %rdi
0xffffffffc018f189: 48 83 c7 f8 addq $-8, %rdi
0xffffffffc018f18d: e8 2e e8 b1 f4 callq 0xffffffffb4cad9c0 ; bpf_probe_read_kernel+0x0 kernel/trace/bpf_trace.c:233
0xffffffffc018f192: 48 8b 55 f8 movq -8(%rbp), %rdx
0xffffffffc018f196: 48 85 d2 testq %rdx, %rdx
0xffffffffc018f199: 74 49 je 0xffffffffc018f1e4 ; filter_xdp_expr+0x7c bpf/kprobe_pwru.c:659 [bpf]
0xffffffffc018f19b: be 08 00 00 00 movl $8, %esi
0xffffffffc018f1a0: 48 89 ef movq %rbp, %rdi
0xffffffffc018f1a3: 48 83 c7 f8 addq $-8, %rdi
0xffffffffc018f1a7: e8 14 e8 b1 f4 callq 0xffffffffb4cad9c0 ; bpf_probe_read_kernel+0x0 kernel/trace/bpf_trace.c:233
0xffffffffc018f1ac: 48 8b 55 f8 movq -8(%rbp), %rdx
0xffffffffc018f1b0: 48 85 d2 testq %rdx, %rdx
0xffffffffc018f1b3: 74 2f je 0xffffffffc018f1e4 ; filter_xdp_expr+0x7c bpf/kprobe_pwru.c:659 [bpf]
0xffffffffc018f1b5: 48 81 c2 e0 00 00 00 addq $0xe0, %rdx
0xffffffffc018f1bc: be 08 00 00 00 movl $8, %esi
0xffffffffc018f1c1: 48 89 ef movq %rbp, %rdi
0xffffffffc018f1c4: 48 83 c7 f8 addq $-8, %rdi
0xffffffffc018f1c8: e8 f3 e7 b1 f4 callq 0xffffffffb4cad9c0 ; bpf_probe_read_kernel+0x0 kernel/trace/bpf_trace.c:233
0xffffffffc018f1cd: 48 8b 55 f8 movq -8(%rbp), %rdx
0xffffffffc018f1d1: 48 c1 e2 20 shlq $0x20, %rdx
0xffffffffc018f1d5: 48 c1 ea 20 shrq $0x20, %rdx
0xffffffffc018f1d9: b8 01 00 00 00 movl $1, %eax
0xffffffffc018f1de: 48 83 fa 09 cmpq $9, %rdx
0xffffffffc018f1e2: 74 02 je 0xffffffffc018f1e6 ; filter_xdp_expr+0x7e bpf/kprobe_pwru.c:659 [bpf]
0xffffffffc018f1e4: 31 c0 xorl %eax, %eax
0xffffffffc018f1e6: c9 leave
0xffffffffc018f1e7: c3 retq
0xffffffffc018f1e8: cc int3
I like it, it's also the on the roadmap, thank you. I'll try to review it ... not later than the end of next week...
if this goes stable, we can deprecate --filter-mark --filter-netns --filter-ifname in favor of --filter-skb-expr skb->dev->nd_net.net->ns.inum == 0xff000233.
The RFC makes sense to me. Could we use BPF_PROG_TEST_RUN to test some of the filters?
if this goes stable, we can deprecate --filter-mark --filter-netns --filter-ifname in favor of --filter-skb-expr skb->dev->nd_net.net->ns.inum == 0xff000233.
How does the filter look like for --filter-ifname?
Could we use
BPF_PROG_TEST_RUNto test some of the filters?
Sure. I will add some tests if I have time for it.
How does the filter look like for
--filter-ifname?
--filter-name should be converted to --filter-ifindex like skb->dev->ifindex == 3.
I will review it next week once I am back from holidays.