Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: cilium/pwru
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 3ad913403d6c1598039503ecc39dd511736811a2
Choose a base ref
..
head repository: cilium/pwru
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 8bbc13b08cdba42604d06d412ced9c0a95eaadd7
Choose a head ref
Showing with 82 additions and 124 deletions.
  1. +2 −58 internal/pwru/kprobe.go
  2. +0 −60 internal/pwru/skb_tracker.go
  3. +80 −6 main.go
60 changes: 2 additions & 58 deletions internal/pwru/kprobe.go
Original file line number Diff line number Diff line change
@@ -18,13 +18,6 @@ import (
"golang.org/x/sync/errgroup"
)

type kprober struct {
links []link.Link

kprobeMulti bool
kprobeBatch uint
}

type Kprobe struct {
hookFunc string // internal use
HookFuncs []string
@@ -122,16 +115,13 @@ func AttachKprobes(ctx context.Context, bar *pb.ProgressBar, kps []Kprobe, batch
}

// DetachKprobes detaches kprobes concurrently.
func (k *kprober) DetachKprobes() {
func DetachKprobes(links []link.Link, batch uint) {
log.Println("Detaching kprobes...")

links := k.links
bar := pb.StartNew(len(links))
defer bar.Finish()

batch := k.kprobeBatch

if k.kprobeMulti || batch >= uint(len(links)) {
if batch == 0 || batch >= uint(len(links)) {
for _, l := range links {
_ = l.Close()
bar.Increment()
@@ -198,49 +188,3 @@ func AttachKprobeMulti(ctx context.Context, bar *pb.ProgressBar, kprobes []Kprob

return
}

func KprobeFuncs(ctx context.Context, funcs Funcs, coll *ebpf.Collection, a2n Addr2Name, useKprobeMulti bool, batch uint) *kprober {
msg := "kprobe"
if useKprobeMulti {
msg = "kprobe-multi"
}
log.Printf("Attaching kprobes (via %s)...\n", msg)

ignored := 0
bar := pb.StartNew(len(funcs))

pwruKprobes := make([]Kprobe, 0, len(funcs))
funcsByPos := GetFuncsByPos(funcs)
for pos, fns := range funcsByPos {
fn, ok := coll.Programs[fmt.Sprintf("kprobe_skb_%d", pos)]
if ok {
pwruKprobes = append(pwruKprobes, Kprobe{HookFuncs: fns, Prog: fn})
} else {
ignored += len(fns)
bar.Add(len(fns))
}
}

var k kprober
k.kprobeMulti = useKprobeMulti
k.kprobeBatch = batch

if !useKprobeMulti {
l, i := AttachKprobes(ctx, bar, pwruKprobes, batch)
k.links = l
ignored += i
} else {
l, i := AttachKprobeMulti(ctx, bar, pwruKprobes, a2n)
k.links = l
ignored += i
}
bar.Finish()
select {
case <-ctx.Done():
return nil
default:
}
log.Printf("Attached (ignored %d)\n", ignored)

return &k
}
60 changes: 0 additions & 60 deletions internal/pwru/skb_tracker.go

This file was deleted.

86 changes: 80 additions & 6 deletions main.go
Original file line number Diff line number Diff line change
@@ -14,8 +14,10 @@ import (
"syscall"
"time"

pb "github.com/cheggaaa/pb/v3"
"github.com/cilium/ebpf"
"github.com/cilium/ebpf/btf"
"github.com/cilium/ebpf/link"
"github.com/cilium/ebpf/rlimit"
"golang.org/x/sys/unix"

@@ -222,15 +224,87 @@ func main() {
log.Fatalf("No kprobe/tc-bpf/xdp to trace!")
}

if flags.FilterTrackSkb && len(funcs) != 0 {
t := pwru.TrackSkb(coll, haveFexit)
defer t.Close()
var kprobes []link.Link
defer func() {
batch := uint(0)
if !useKprobeMulti {
batch = flags.FilterKprobeBatch
}
pwru.DetachKprobes(kprobes, batch)
}()

msg := "kprobe"
if useKprobeMulti {
msg = "kprobe-multi"
}
log.Printf("Attaching kprobes (via %s)...\n", msg)
ignored := 0
bar := pb.StartNew(len(funcs))

if len(funcs) != 0 {
k := pwru.KprobeFuncs(ctx, funcs, coll, addr2name, useKprobeMulti, flags.FilterKprobeBatch)
defer k.DetachKprobes()
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)
} else {
ignored += 1
log.Printf("Warn: kfree_skbmem not found, pwru is likely to mismatch skb due to lack of skb lifetime management\n")
}
} 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)
}
}
}
}

pwruKprobes := make([]pwru.Kprobe, 0, len(funcs))
funcsByPos := pwru.GetFuncsByPos(funcs)
for pos, fns := range funcsByPos {
fn, ok := coll.Programs[fmt.Sprintf("kprobe_skb_%d", pos)]
if ok {
pwruKprobes = append(pwruKprobes, pwru.Kprobe{HookFuncs: fns, Prog: fn})
} else {
ignored += len(fns)
bar.Add(len(fns))
}
}
if !useKprobeMulti {
l, i := pwru.AttachKprobes(ctx, bar, pwruKprobes, flags.FilterKprobeBatch)
kprobes = append(kprobes, l...)
ignored += i
} else {
l, i := pwru.AttachKprobeMulti(ctx, bar, pwruKprobes, addr2name)
kprobes = append(kprobes, l...)
ignored += i
}
bar.Finish()
select {
case <-ctx.Done():
return
default:
}
log.Printf("Attached (ignored %d)\n", ignored)

log.Println("Listening for events..")