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, by the
way `fexit` on `skb_clone()` and `skb_copy()`.

Signed-off-by: Leon Hwang <[email protected]>
  • Loading branch information
Asphaltt committed Oct 24, 2023
1 parent 8a0e6f1 commit 0dc1f2c
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 1 deletion.
18 changes: 18 additions & 0 deletions bpf/kprobe_pwru.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,24 @@ int kprobe_skb_lifetime_termination(struct pt_regs *ctx) {
return BPF_OK;
}

static __always_inline int
track_skb_clone(u64 old, u64 new) {
if (bpf_map_lookup_elem(&skb_addresses, &old))
bpf_map_update_elem(&skb_addresses, &new, &TRUE, BPF_ANY);

return BPF_OK;
}

SEC("fexit/skb_clone")
int BPF_PROG(fexit_skb_clone, u64 old, gfp_t mask, u64 new) {
return track_skb_clone(old, new);
}

SEC("fexit/skb_copy")
int BPF_PROG(fexit_skb_copy, u64 old, gfp_t mask, u64 new) {
return track_skb_clone(old, new);
}

SEC("fentry/tc")
int BPF_PROG(fentry_tc, struct sk_buff *skb) {
struct event_t event = {};
Expand Down
29 changes: 29 additions & 0 deletions internal/pwru/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,32 @@ func HaveBPFLinkKprobeMulti() bool {

return true
}

// Very hacky way to check whether tracing link is supported.
func HaveBPFLinkTracing() bool {
prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{
Name: "fexit_skb_clone",
Type: ebpf.Tracing,
Instructions: asm.Instructions{
asm.Mov.Imm(asm.R0, 0),
asm.Return(),
},
AttachType: ebpf.AttachTraceFExit,
AttachTo: "skb_clone",
License: "MIT",
})
if err != nil {
return false
}
defer prog.Close()

link, err := link.AttachTracing(link.TracingOptions{
Program: prog,
})
if err != nil {
return false
}
defer link.Close()

return true
}
35 changes: 34 additions & 1 deletion 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 == "fexit_skb_clone" ||
name == "fexit_skb_copy" {
continue
}
if err = libpcap.InjectFilters(program, flags.FilterPcap); err != nil {
Expand Down Expand Up @@ -152,10 +155,18 @@ 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")
}

haveFexit := pwru.HaveBPFLinkTracing()
if !flags.FilterTrackSkb || !haveFexit {
delete(bpfSpec.Programs, "fexit_skb_clone")
delete(bpfSpec.Programs, "fexit_skb_copy")
}

coll, err := ebpf.NewCollectionWithOptions(bpfSpec, opts)
if err != nil {
var (
Expand Down Expand Up @@ -228,6 +239,28 @@ func main() {
} else {
kprobes = append(kprobes, kp)
}

if haveFexit {
progs := []*ebpf.Program{
coll.Programs["fexit_skb_clone"],
coll.Programs["fexit_skb_copy"],
}
for _, prog := range progs {
fexit, err := link.AttachTracing(link.TracingOptions{
Program: prog,
})
bar.Increment()
if err != nil {
if !errors.Is(err, os.ErrNotExist) {
log.Fatalf("Opening tracing(%s): %s\n", prog, err)
} else {
ignored += 1
}
} else {
kprobes = append(kprobes, fexit)
}
}
}
}

funcsByPos := pwru.GetFuncsByPos(funcs)
Expand Down

0 comments on commit 0dc1f2c

Please sign in to comment.