Skip to content

Commit

Permalink
--filter-track-skb can track skbs re-built from veth_convert_skb_to_x…
Browse files Browse the repository at this point in the history
…dp_buff

When XDP is attached to a veth, skbs will be consumed and re-created on
that veth. This is done in the function veth_convert_skb_to_xdp_buff():

```
// drivers/net/veth.c
static int veth_convert_skb_to_xdp_buff(struct veth_rq *rq,
					struct xdp_buff *xdp,
					struct sk_buff **pskb)
{
	struct sk_buff *skb = *pskb;
[...]
		nskb = build_skb(page_address(page), PAGE_SIZE);
[...]
		skb_copy_header(nskb, skb);
[...]
		consume_skb(skb);
		skb = nskb;
[...]
}
```

This causes problems for pwru --filter-track-skb because of the new skb
addresses. I ran into a lot of situations where I lost track of NAT-ed
traffic at veth when cilium kind cluster is created by "kind.sh --xdp".

This patch allows pwru to keep track of the new skbs at XDP-attached
veth devices.

Signed-off-by: gray <[email protected]>
  • Loading branch information
jschwinger233 authored and brb committed Jul 7, 2024
1 parent b33c3bb commit 7a33683
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 3 deletions.
32 changes: 32 additions & 0 deletions bpf/kprobe_pwru.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ struct {
__uint(max_entries, MAX_TRACK_SIZE);
} skb_addresses SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__type(key, __u64); // pid_tgid
__type(value, __u64); // struct sk_buff **
__uint(max_entries, MAX_TRACK_SIZE);
} veth_skbs SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__type(key, struct sk_buff *);
Expand Down Expand Up @@ -686,4 +693,29 @@ int BPF_PROG(fentry_xdp, struct xdp_buff *xdp) {
return BPF_OK;
}

SEC("kprobe/veth_convert_skb_to_xdp_buff")
int kprobe_veth_convert_skb_to_xdp_buff(struct pt_regs *ctx) {
struct sk_buff **skb = (struct sk_buff **)PT_REGS_PARM3(ctx);
u64 skb_addr;
bpf_probe_read_kernel(&skb_addr, sizeof(skb_addr), (void *)skb);
if (bpf_map_lookup_elem(&skb_addresses, &skb_addr)) {
u64 pid_tgid = bpf_get_current_pid_tgid();
bpf_map_update_elem(&veth_skbs, &pid_tgid, &skb, BPF_ANY);
}
return BPF_OK;
}

SEC("kretprobe/veth_convert_skb_to_xdp_buff")
int kretprobe_veth_convert_skb_to_xdp_buff(struct pt_regs *ctx) {
u64 pid_tgid = bpf_get_current_pid_tgid();
struct sk_buff ***skb = (struct sk_buff ***)bpf_map_lookup_elem(&veth_skbs, &pid_tgid);
if (skb && *skb) {
u64 skb_addr;
bpf_probe_read_kernel(&skb_addr, sizeof(skb_addr), (void *)*skb);
bpf_map_update_elem(&skb_addresses, &skb_addr, &TRUE, BPF_ANY);
bpf_map_delete_elem(&veth_skbs, &pid_tgid);
}
return BPF_OK;
}

char __license[] SEC("license") = "Dual BSD/GPL";
18 changes: 18 additions & 0 deletions internal/pwru/skb_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,24 @@ func TrackSkb(coll *ebpf.Collection, haveFexit, trackSkbClone bool) *skbTracker
t.links = append(t.links, kp)
}

kp, err = link.Kretprobe("veth_convert_skb_to_xdp_buff", coll.Programs["kretprobe_veth_convert_skb_to_xdp_buff"], nil)
if err != nil {
if !errors.Is(err, os.ErrNotExist) {
log.Fatalf("Opening kretprobe veth_convert_skb_to_xdp_buff: %s\n", err)
}
} else {
t.links = append(t.links, kp)
}

kp, err = link.Kprobe("veth_convert_skb_to_xdp_buff", coll.Programs["kprobe_veth_convert_skb_to_xdp_buff"], nil)
if err != nil {
if !errors.Is(err, os.ErrNotExist) {
log.Fatalf("Opening kprobe veth_convert_skb_to_xdp_buff: %s\n", err)
}
} else {
t.links = append(t.links, kp)
}

if haveFexit && trackSkbClone {
progs := []*ebpf.Program{
coll.Programs["fexit_skb_clone"],
Expand Down
9 changes: 6 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,12 @@ func main() {

for name, program := range bpfSpec.Programs {
// 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" {
switch name {
case "kprobe_skb_lifetime_termination",
"fexit_skb_clone",
"fexit_skb_copy",
"kprobe_veth_convert_skb_to_xdp_buff",
"kretprobe_veth_convert_skb_to_xdp_buff":
continue
}
if name == "fentry_xdp" {
Expand Down

0 comments on commit 7a33683

Please sign in to comment.