Skip to content

Commit 4e3f4c3

Browse files
committed
draft
Signed-off-by: gray <[email protected]>
1 parent fabb29e commit 4e3f4c3

File tree

6 files changed

+56
-10
lines changed

6 files changed

+56
-10
lines changed

Diff for: bpf/kprobe_pwru.c

+25-1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ struct event_t {
8282
u64 ts;
8383
u64 print_skb_id;
8484
u64 print_shinfo_id;
85+
//u64 print_bpf_map_id;
8586
struct skb_meta meta;
8687
struct tuple tuple;
8788
s64 print_stack_id;
@@ -143,7 +144,8 @@ struct config {
143144
u8 output_shinfo: 1;
144145
u8 output_stack: 1;
145146
u8 output_caller: 1;
146-
u8 output_unused: 2;
147+
u8 output_bpf_map: 1;
148+
u8 output_unused: 1;
147149
u8 is_set: 1;
148150
u8 track_skb: 1;
149151
u8 track_skb_by_stackid: 1;
@@ -394,6 +396,21 @@ set_shinfo_btf(struct sk_buff *skb, u64 *event_id) {
394396
#endif
395397
}
396398

399+
static __always_inline void
400+
set_bpf_map(struct pt_regs *ctx, u64 cookie, u64 *event_id) {
401+
if (cookie == 1)
402+
bpf_printk("bpf_map_lookup/delete");
403+
else if (cookie == 2)
404+
bpf_printk("bpf_map_update");
405+
406+
struct bpf_map *map = (struct bpf_map *)PT_REGS_PARM1(ctx);
407+
408+
char name[16];
409+
BPF_CORE_READ_STR_INTO(&name, map, name);
410+
bpf_printk(" name=%s key_size=%ld value_size=%ld\n", &name, BPF_CORE_READ(map, key_size), BPF_CORE_READ(map, value_size));
411+
// TODO@gray: print/collect key and value hex
412+
}
413+
397414
static __always_inline u64
398415
get_stackid(struct pt_regs *ctx) {
399416
u64 caller_fp;
@@ -509,6 +526,13 @@ kprobe_skb(struct sk_buff *skb, struct pt_regs *ctx, bool has_get_func_ip, u64 *
509526
if (CFG.output_caller)
510527
bpf_probe_read_kernel(&event.caller_addr, sizeof(event.caller_addr), (void *)PT_REGS_SP(ctx));
511528

529+
if (CFG.output_bpf_map) {
530+
// TODO@gray: kernel>=5.15
531+
__u64 cookie = bpf_get_attach_cookie(ctx);
532+
if (cookie)
533+
set_bpf_map(ctx, cookie, NULL);
534+
}
535+
512536
bpf_map_push_elem(&events, &event, BPF_EXIST);
513537

514538
return BPF_OK;

Diff for: internal/pwru/config.go

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const (
2222
OutputShinfoMask
2323
OutputStackMask
2424
OutputCallerMask
25+
OutputBpfMapMask
2526
)
2627

2728
const (
@@ -66,6 +67,9 @@ func GetConfig(flags *Flags) (cfg FilterCfg, err error) {
6667
if flags.OutputCaller {
6768
cfg.OutputFlags |= OutputCallerMask
6869
}
70+
if flags.OutputBpfMap {
71+
cfg.OutputFlags |= OutputBpfMapMask
72+
}
6973
if flags.FilterTrackSkb {
7074
cfg.FilterFlags |= TrackSkbMask
7175
}

Diff for: internal/pwru/kprobe.go

+14-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616

1717
"github.com/cheggaaa/pb/v3"
1818
"github.com/cilium/ebpf"
19+
"github.com/cilium/ebpf/btf"
1920
"github.com/cilium/ebpf/link"
2021
"golang.org/x/sync/errgroup"
2122
)
@@ -246,7 +247,7 @@ func NewKprober(ctx context.Context, funcs Funcs, coll *ebpf.Collection, a2n Add
246247
return &k
247248
}
248249

249-
func NewNonSkbFuncsKprober(nonSkbFuncs []string, funcs Funcs, coll *ebpf.Collection) *kprober {
250+
func NewNonSkbFuncsKprober(nonSkbFuncs []string, funcs Funcs, bpfMapFuncs map[string]*btf.FuncProto, coll *ebpf.Collection) *kprober {
250251
slices.Sort(nonSkbFuncs)
251252
nonSkbFuncs = slices.Compact(nonSkbFuncs)
252253

@@ -263,7 +264,18 @@ func NewNonSkbFuncsKprober(nonSkbFuncs []string, funcs Funcs, coll *ebpf.Collect
263264
continue
264265
}
265266

266-
kp, err := link.Kprobe(fn, coll.Programs["kprobe_skb_by_stackid"], nil)
267+
var cookie uint64
268+
if proto, ok := bpfMapFuncs[fn]; ok {
269+
cookie = 1
270+
for _, p := range proto.Params {
271+
if p.Name == "value" {
272+
cookie = 2
273+
}
274+
}
275+
}
276+
277+
opts := &link.KprobeOptions{Cookie: cookie}
278+
kp, err := link.Kprobe(fn, coll.Programs["kprobe_skb_by_stackid"], opts)
267279
if err != nil {
268280
if errors.Is(err, os.ErrNotExist) {
269281
continue

Diff for: internal/pwru/types.go

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ type Flags struct {
4545
OutputShinfo bool
4646
OutputStack bool
4747
OutputCaller bool
48+
OutputBpfMap bool
4849
OutputLimitLines uint64
4950
OutputFile string
5051
OutputJson bool
@@ -81,6 +82,7 @@ func (f *Flags) SetFlags() {
8182
flag.BoolVar(&f.OutputShinfo, "output-skb-shared-info", false, "print skb shared info")
8283
flag.BoolVar(&f.OutputStack, "output-stack", false, "print stack")
8384
flag.BoolVar(&f.OutputCaller, "output-caller", false, "print caller function name")
85+
flag.BoolVar(&f.OutputBpfMap, "output-bpf-map", false, "print bpf helper arguments related to bpf maps")
8486
flag.Uint64Var(&f.OutputLimitLines, "output-limit-lines", 0, "exit the program after the number of events has been received/printed")
8587

8688
flag.StringVar(&f.OutputFile, "output-file", "", "write traces to file")

Diff for: internal/pwru/utils.go

+9-5
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@ func getAvailableFilterFunctions() (map[string]struct{}, error) {
4242
return availableFuncs, nil
4343
}
4444

45-
func GetFuncs(pattern string, spec *btf.Spec, kmods []string, kprobeMulti bool) (Funcs, error) {
45+
func GetFuncs(pattern string, spec *btf.Spec, kmods []string, kprobeMulti, bpfMap bool) (Funcs, map[string]*btf.FuncProto, error) {
4646
funcs := Funcs{}
47+
bpfMapFuncs := make(map[string]*btf.FuncProto)
4748

4849
type iterator struct {
4950
kmod string
@@ -52,7 +53,7 @@ func GetFuncs(pattern string, spec *btf.Spec, kmods []string, kprobeMulti bool)
5253

5354
reg, err := regexp.Compile(pattern)
5455
if err != nil {
55-
return nil, fmt.Errorf("failed to compile regular expression %v", err)
56+
return nil, nil, fmt.Errorf("failed to compile regular expression %v", err)
5657
}
5758

5859
var availableFuncs map[string]struct{}
@@ -68,13 +69,13 @@ func GetFuncs(pattern string, spec *btf.Spec, kmods []string, kprobeMulti bool)
6869
path := filepath.Join("/sys/kernel/btf", module)
6970
f, err := os.Open(path)
7071
if err != nil {
71-
return nil, fmt.Errorf("failed to open %s: %v", path, err)
72+
return nil, nil, fmt.Errorf("failed to open %s: %v", path, err)
7273
}
7374
defer f.Close()
7475

7576
modSpec, err := btf.LoadSplitSpecFromReader(f, spec)
7677
if err != nil {
77-
return nil, fmt.Errorf("failed to load %s btf: %v", module, err)
78+
return nil, nil, fmt.Errorf("failed to load %s btf: %v", module, err)
7879
}
7980
iters = append(iters, iterator{module, modSpec.Iterate()})
8081
}
@@ -108,6 +109,9 @@ func GetFuncs(pattern string, spec *btf.Spec, kmods []string, kprobeMulti bool)
108109
for _, p := range fnProto.Params {
109110
if ptr, ok := p.Type.(*btf.Pointer); ok {
110111
if strct, ok := ptr.Target.(*btf.Struct); ok {
112+
if bpfMap && strct.Name == "bpf_map" {
113+
bpfMapFuncs[fnName] = fnProto
114+
}
111115
if strct.Name == "sk_buff" && i <= 5 {
112116
name := fnName
113117
if kprobeMulti && it.kmod != "" {
@@ -123,7 +127,7 @@ func GetFuncs(pattern string, spec *btf.Spec, kmods []string, kprobeMulti bool)
123127
}
124128
}
125129

126-
return funcs, nil
130+
return funcs, bpfMapFuncs, nil
127131
}
128132

129133
func GetFuncsByPos(funcs Funcs) map[int][]string {

Diff for: main.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func main() {
9494
useKprobeMulti = true
9595
}
9696

97-
funcs, err := pwru.GetFuncs(flags.FilterFunc, btfSpec, flags.KMods, useKprobeMulti)
97+
funcs, bpfMapFuncs, err := pwru.GetFuncs(flags.FilterFunc, btfSpec, flags.KMods, useKprobeMulti, flags.OutputBpfMap)
9898
if err != nil {
9999
log.Fatalf("Failed to get skb-accepting functions: %s", err)
100100
}
@@ -250,7 +250,7 @@ func main() {
250250
}
251251

252252
if nonSkbFuncs := flags.FilterNonSkbFuncs; len(nonSkbFuncs) != 0 {
253-
k := pwru.NewNonSkbFuncsKprober(nonSkbFuncs, funcs, coll)
253+
k := pwru.NewNonSkbFuncsKprober(nonSkbFuncs, funcs, bpfMapFuncs, coll)
254254
defer k.DetachKprobes()
255255
}
256256

0 commit comments

Comments
 (0)