pwru icon indicating copy to clipboard operation
pwru copied to clipboard

pwru: Add --filter-skb-expr and --filter-xdp-expr

Open Asphaltt opened this issue 10 months ago • 5 comments

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:

  1. Parse provided C expression to AST.
  2. Validate AST as expectation.
  3. Convert AST to offsets based on BTF info.
  4. Generate bpf_probe_read_kernel() based on converted offsets.
  5. Generate jmp insn for the compare op in the C expression.
  6. 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

Asphaltt avatar Feb 04 '25 04:02 Asphaltt

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...

jschwinger233 avatar Feb 05 '25 07:02 jschwinger233

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.

jschwinger233 avatar Feb 05 '25 08:02 jschwinger233

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?

brb avatar Apr 04 '25 11:04 brb

Could we use BPF_PROG_TEST_RUN to 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.

Asphaltt avatar Apr 04 '25 12:04 Asphaltt

I will review it next week once I am back from holidays.

brb avatar Apr 17 '25 07:04 brb