Skip to content

Commit

Permalink
Support tracking skb clones
Browse files Browse the repository at this point in the history
With --filter-track-skb option, we're able to track sbk by its address.

Then, as for skb's clones/copies, we're able to track them too. We track
the skb clones/copies by kprobing `__skb_clone()` and `skb_copy_header()`,
whose callers include `skb_clone()` and `skb_copy()`.

Signed-off-by: Leon Hwang <[email protected]>
  • Loading branch information
Asphaltt committed Oct 23, 2023
1 parent 76019d2 commit 47289c3
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 11 deletions.
23 changes: 22 additions & 1 deletion bpf/kprobe_pwru.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,28 @@ int kprobe_skb_lifetime_termination(struct pt_regs *ctx) {

bpf_map_delete_elem(&skb_addresses, &skb);

return 0;
return BPF_OK;
}

static __always_inline int
track_skb_clone(struct pt_regs *ctx) {
u64 new = (u64) PT_REGS_PARM1(ctx);
u64 old = (u64) PT_REGS_PARM2(ctx);

if (bpf_map_lookup_elem(&skb_addresses, &old))
bpf_map_update_elem(&skb_addresses, &new, &TRUE, BPF_ANY);

return BPF_OK;
}

SEC("kprobe/__skb_clone")
int kprobe___skb_clone(struct pt_regs *ctx) {
return track_skb_clone(ctx);
}

SEC("kprobe/skb_copy_header")
int kprobe_skb_copy_header(struct pt_regs *ctx) {
return track_skb_clone(ctx);
}

SEC("fentry/tc")
Expand Down
38 changes: 28 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,10 @@ func main() {
}

for name, program := range bpfSpec.Programs {
if name == "kprobe_skb_lifetime_termination" {
// Skip the skb-tracking ones that should not inject pcap-filter.
if name == "kprobe_skb_lifetime_termination" ||
name == "kprobe___skb_clone" ||
name == "kprobe_skb_copy_header" {
continue
}
if err = libpcap.InjectFilters(program, flags.FilterPcap); err != nil {
Expand Down Expand Up @@ -152,8 +155,12 @@ func main() {
// deleted from the spec.
delete(bpfSpec.Programs, "fentry_tc")

// If not tracking skb, deleting the skb-tracking programs to reduce loading
// time.
if !flags.FilterTrackSkb {
delete(bpfSpec.Programs, "kprobe_skb_lifetime_termination")
delete(bpfSpec.Programs, "kprobe___skb_clone")
delete(bpfSpec.Programs, "kprobe_skb_copy_header")
}

coll, err := ebpf.NewCollectionWithOptions(bpfSpec, opts)
Expand Down Expand Up @@ -216,17 +223,28 @@ func main() {
bar := pb.StartNew(len(funcs))

if flags.FilterTrackSkb {
kp, err := link.Kprobe("kfree_skbmem", coll.Programs["kprobe_skb_lifetime_termination"], nil)
bar.Increment()
if err != nil {
if !errors.Is(err, os.ErrNotExist) {
log.Fatalf("Opening kprobe kfree_skbmem: %s\n", err)
progs := []struct {
hook string
prog *ebpf.Program
hint string
}{
{"kfree_skbmem", coll.Programs["kprobe_skb_lifetime_termination"], "skb lifetime termination"},
{"__skb_clone", coll.Programs["kprobe___skb_clone"], "skb clone tracking"},
{"skb_copy_header", coll.Programs["kprobe_skb_copy_header"], "skb copy tracking"},
}
for _, prog := range progs {
kp, err := link.Kprobe(prog.hook, prog.prog, nil)
bar.Increment()
if err != nil {
if !errors.Is(err, os.ErrNotExist) {
log.Fatalf("Opening kprobe %s: %s\n", prog.hook, err)
} else {
ignored += 1
log.Printf("Warn: %s not found, pwru is likely to mismatch skb due to lack of %s\n", prog.hook, prog.hint)
}
} else {
ignored += 1
log.Printf("Warn: kfree_skbmem not found, pwru is likely to mismatch skb due to lack of skb lifetime management\n")
kprobes = append(kprobes, kp)
}
} else {
kprobes = append(kprobes, kp)
}
}

Expand Down

0 comments on commit 47289c3

Please sign in to comment.