diff --git a/config.go b/config.go index b3eddd7..d8cace6 100644 --- a/config.go +++ b/config.go @@ -13,6 +13,7 @@ import ( type Config struct { Iface string PerfOutput bool + SkbTrack bool SkbFilename string PcapFilename string PcapFilterExp string @@ -23,11 +24,12 @@ var ( bpfObjects bpf.BpfObjects ) -func initConfig() { +func mustInitConfig() { flag.StringVarP(&config.Iface, "interface", "i", "lo", "interface to capture") flag.BoolVarP(&config.PerfOutput, "perf-output", "", false, "use bpf_perf_event_output to lift payload size limit") flag.StringVarP(&config.SkbFilename, "skb-filename", "s", "skbdump.skb", "output skb filename") flag.StringVarP(&config.PcapFilename, "pcap-filename", "w", "skbdump.pcap", "output pcap filename") + flag.BoolVarP(&config.SkbTrack, "skb-track", "t", false, "track skb by address") flag.Parse() config.PcapFilterExp = strings.Join(flag.Args(), " ") diff --git a/internal/bpf/bpf.go b/internal/bpf/bpf.go index 4e2f785..d9dab50 100644 --- a/internal/bpf/bpf.go +++ b/internal/bpf/bpf.go @@ -32,8 +32,17 @@ type Skb struct { Data []byte } +type LoadOptions struct { + Filter []bpf.Instruction + BpfConfig BpfConfig +} + +type BpfConfig struct { + SkbTrack bool +} + type BpfObjects interface { - Load(cbpf []bpf.Instruction) error + Load(LoadOptions) error IngressFilter() *ebpf.Program EgressFilter() *ebpf.Program PollSkb(context.Context) (<-chan Skb, error) diff --git a/internal/bpf/headers/skbdump.h b/internal/bpf/headers/skbdump.h index 8d7f8ca..ba53e9d 100644 --- a/internal/bpf/headers/skbdump.h +++ b/internal/bpf/headers/skbdump.h @@ -61,3 +61,12 @@ struct skb_meta { __u32 cb[5]; }; #endif + +#ifndef SKBDUMP_CONFIG_DEFINED +#define SKBDUMP_CONFIG_DEFINED +struct skbdump_config { + bool skb_track; +}; + +static volatile const struct skbdump_config SKBDUMP_CONFIG = {}; +#endif diff --git a/internal/bpf/pcap_filter.go b/internal/bpf/pcap_filter.go index 05cdfb6..e2ebd91 100644 --- a/internal/bpf/pcap_filter.go +++ b/internal/bpf/pcap_filter.go @@ -41,6 +41,10 @@ func mustFindUpDevice() string { } func MustPcapCompile(expr string) (insts []bpf.Instruction) { + if len(expr) == 0 { + return + } + buf := (*C.char)(C.calloc(C.PCAP_ERRBUF_SIZE, 1)) defer C.free(unsafe.Pointer(buf)) diff --git a/internal/bpf/perf/bpf.go b/internal/bpf/perf/bpf.go index d9acac6..e5d5b1a 100644 --- a/internal/bpf/perf/bpf.go +++ b/internal/bpf/perf/bpf.go @@ -72,8 +72,8 @@ func (o *PerfBpfObjects) setFilter(cbpfFilter []bpf.Instruction) (err error) { return } -func (o *PerfBpfObjects) Load(cbpfFilter []bpf.Instruction) (err error) { - if err = o.setFilter(cbpfFilter); err != nil { +func (o *PerfBpfObjects) Load(opts internalbpf.LoadOptions) (err error) { + if err = o.setFilter(opts.Filter); err != nil { return } if err = errors.WithStack(o.spec.LoadAndAssign(o.objs, nil)); err != nil { diff --git a/internal/bpf/perf/skbdump_bpfel_x86.o b/internal/bpf/perf/skbdump_bpfel_x86.o index 819c252..1df85cd 100644 Binary files a/internal/bpf/perf/skbdump_bpfel_x86.o and b/internal/bpf/perf/skbdump_bpfel_x86.o differ diff --git a/internal/bpf/queue/bpf.go b/internal/bpf/queue/bpf.go index cb67345..fec673a 100644 --- a/internal/bpf/queue/bpf.go +++ b/internal/bpf/queue/bpf.go @@ -15,29 +15,34 @@ import ( //go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang -no-strip -target native -type skb_meta -type skb_data Skbdump ./skbdump.c -- -I../headers -I. -Wall const ( - /* bpf bytecode - 00000000000467a8 : + /* + 00000000000467c8 : ; { - 36085: r6 = r1 - 36086: r7 = 0 + 36089: r6 = r1 ; bpf_skb_pull_data(skb, 0); - 36087: r2 = 0 - 36088: call 39 + 36090: r2 = 0 + 36091: call 39 ; __u64 skb_addr = (__u64)(void *)skb; - 36089: *(u64 *)(r10 - 104) = r6 - 36090: r2 = r10 - 36091: r2 += -104 - ; if (bpf_map_lookup_elem(&skb_address, &skb_addr)) - 36092: r1 = 0 ll - 36094: call 1 - GotoIndex -> 36095: if r0 != 0 goto +11 + 36092: *(u64 *)(r10 - 104) = r6 + ; if (SKBDUMP_CONFIG.skb_track && bpf_map_lookup_elem(&skb_address, &skb_addr)) + 36093: r1 = 0 ll + 36095: r1 = *(u8 *)(r1 + 0) + 36096: if r1 == 0 goto +6 + 36097: r2 = r10 + 36098: r2 += -104 + ; if (SKBDUMP_CONFIG.skb_track && bpf_map_lookup_elem(&skb_address, &skb_addr)) + 36099: r1 = 0 ll + 36101: call 1 + GotoIndex -> 36102: if r0 != 0 goto +11 + + 0000000000046838 : ; if (!pcap_filter((void *)(long)skb->data, (void *)(long)skb->data_end)) - 36096: r1 = *(u32 *)(r6 + 80) - 36097: r2 = *(u32 *)(r6 + 76) - FilterIndex -> 36098: if r2 >= r1 goto +71 + 36103: r1 = *(u32 *)(r6 + 80) + 36104: r2 = *(u32 *)(r6 + 76) + FilterIndex -> 36105: if r2 >= r1 goto +72 */ - FilterIndex = 12 - GotoIndex = 9 + FilterIndex = 14 + GotoIndex = 11 ) type QueueBpfObjects struct { @@ -85,8 +90,11 @@ func (o *QueueBpfObjects) setFilter(cbpfFilter []bpf.Instruction) (err error) { return } -func (o *QueueBpfObjects) Load(cbpfFilter []bpf.Instruction) (err error) { - if err = o.setFilter(cbpfFilter); err != nil { +func (o *QueueBpfObjects) Load(opts internalbpf.LoadOptions) (err error) { + if err = errors.WithStack(o.spec.RewriteConstants(map[string]interface{}{"SKBDUMP_CONFIG": opts.BpfConfig})); err != nil { + return + } + if err = o.setFilter(opts.Filter); err != nil { return } if err = errors.WithStack(o.spec.LoadAndAssign(o.objs, nil)); err != nil { diff --git a/internal/bpf/queue/skbdump.c b/internal/bpf/queue/skbdump.c index 969ff31..b6ec892 100644 --- a/internal/bpf/queue/skbdump.c +++ b/internal/bpf/queue/skbdump.c @@ -39,7 +39,7 @@ void handle_skb(struct __sk_buff *skb, bool ingress) bpf_skb_pull_data(skb, 0); __u64 skb_addr = (__u64)(void *)skb; - if (bpf_map_lookup_elem(&skb_address, &skb_addr)) + if (SKBDUMP_CONFIG.skb_track && bpf_map_lookup_elem(&skb_address, &skb_addr)) goto cont; if (!pcap_filter((void *)(long)skb->data, (void *)(long)skb->data_end)) diff --git a/internal/bpf/queue/skbdump.pcap b/internal/bpf/queue/skbdump.pcap deleted file mode 100644 index 15c9aaa..0000000 Binary files a/internal/bpf/queue/skbdump.pcap and /dev/null differ diff --git a/internal/bpf/queue/skbdump.skb b/internal/bpf/queue/skbdump.skb deleted file mode 100644 index 762a863..0000000 --- a/internal/bpf/queue/skbdump.skb +++ /dev/null @@ -1,24 +0,0 @@ -{"IsIngress":false,"TimeNs":22798410924418,"Address":18446624211059296256,"Len":98,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":0,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":true,"TimeNs":22798410951565,"Address":18446624211059296256,"Len":98,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":1,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":false,"TimeNs":22798410993987,"Address":18446624211059296768,"Len":98,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":0,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":true,"TimeNs":22798411001064,"Address":18446624211059296768,"Len":98,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":1,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":false,"TimeNs":22799434902458,"Address":18446624200494574848,"Len":98,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":0,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":true,"TimeNs":22799434918996,"Address":18446624200494574848,"Len":98,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":1,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":false,"TimeNs":22799434947422,"Address":18446624200494572032,"Len":98,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":0,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":true,"TimeNs":22799434950608,"Address":18446624200494572032,"Len":98,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":1,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":false,"TimeNs":22800331022272,"Address":18446624200123522816,"Len":86,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":0,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":true,"TimeNs":22800331042803,"Address":18446624200123522816,"Len":86,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":1,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":false,"TimeNs":22800331067365,"Address":18446624200123520000,"Len":86,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":0,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":true,"TimeNs":22800331071384,"Address":18446624200123520000,"Len":86,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":1,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":false,"TimeNs":22800331608883,"Address":18446624211092693504,"Len":182,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":0,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":true,"TimeNs":22800331628029,"Address":18446624211092693504,"Len":182,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":1,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":false,"TimeNs":22800332011541,"Address":18446624211092695552,"Len":198,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":0,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":true,"TimeNs":22800332024790,"Address":18446624211092695552,"Len":198,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":1,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":false,"TimeNs":22800341248282,"Address":18446624229995436288,"Len":86,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":0,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":true,"TimeNs":22800341263047,"Address":18446624229995436288,"Len":86,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":1,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":false,"TimeNs":22800341281025,"Address":18446624229995432448,"Len":86,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":0,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":true,"TimeNs":22800341283866,"Address":18446624229995432448,"Len":86,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":1,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":false,"TimeNs":22800341573853,"Address":18446624211092696320,"Len":182,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":0,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":true,"TimeNs":22800341584199,"Address":18446624211092696320,"Len":182,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":1,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":false,"TimeNs":22800341772700,"Address":18446624211092695808,"Len":198,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":0,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} -{"IsIngress":true,"TimeNs":22800341777295,"Address":18446624211092695808,"Len":198,"PktType":0,"Mark":0,"QueueMapping":0,"Protocol":8,"VlanPresent":0,"VlanTci":0,"VlanProto":0,"Priority":0,"IngressIfindex":1,"Ifindex":1,"TcIndex":0,"Cb":[0,0,0,0,0]} diff --git a/internal/bpf/queue/skbdump_bpfel_x86.o b/internal/bpf/queue/skbdump_bpfel_x86.o index a9fe5f6..7306e09 100644 Binary files a/internal/bpf/queue/skbdump_bpfel_x86.o and b/internal/bpf/queue/skbdump_bpfel_x86.o differ diff --git a/main.go b/main.go index f4a7f4f..f40155d 100644 --- a/main.go +++ b/main.go @@ -20,7 +20,7 @@ import ( ) func init() { - initConfig() + mustInitConfig() if err := rlimit.RemoveMemlock(); err != nil { log.Fatalf("Failed to remove rlimit memlock: %v", err) } @@ -37,7 +37,10 @@ func main() { ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() - if err = bpfObjects.Load(bpf.MustPcapCompile(config.PcapFilterExp)); err != nil { + if err = bpfObjects.Load(bpf.LoadOptions{ + Filter: bpf.MustPcapCompile(config.PcapFilterExp), + BpfConfig: bpf.BpfConfig{SkbTrack: config.SkbTrack}, + }); err != nil { return }