Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Add --filter-skb-expr and --filter-xdp-expr #499

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Asphaltt
Copy link
Contributor

@Asphaltt Asphaltt commented Feb 4, 2025

Fixes #11

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 Asphaltt force-pushed the feat/dynamic-skb-meta branch from c4003a5 to aa80c7c Compare February 4, 2025 04:05
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

```asm
; 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

```asm
; 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
```

Signed-off-by: Leon Hwang <[email protected]>
@Asphaltt Asphaltt force-pushed the feat/dynamic-skb-meta branch from aa80c7c to ab85e03 Compare February 4, 2025 04:07
@jschwinger233
Copy link
Member

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
Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add skb metadata dynamic filters
2 participants