diff --git a/examples/tcx/bpf_bpfeb.go b/examples/tcx/bpf_bpfeb.go index 6e978748d..3883b86a6 100644 --- a/examples/tcx/bpf_bpfeb.go +++ b/examples/tcx/bpf_bpfeb.go @@ -62,14 +62,14 @@ type bpfProgramSpecs struct { // // It can be passed ebpf.CollectionSpec.Assign. type bpfMapSpecs struct { - EgressPktCount *ebpf.MapSpec `ebpf:"egress_pkt_count"` - IngressPktCount *ebpf.MapSpec `ebpf:"ingress_pkt_count"` } // bpfVariableSpecs contains global variables before they are loaded into the kernel. // // It can be passed ebpf.CollectionSpec.Assign. type bpfVariableSpecs struct { + EgressPktCount *ebpf.VariableSpec `ebpf:"egress_pkt_count"` + IngressPktCount *ebpf.VariableSpec `ebpf:"ingress_pkt_count"` } // bpfObjects contains all objects after they have been loaded into the kernel. @@ -92,21 +92,18 @@ func (o *bpfObjects) Close() error { // // It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. type bpfMaps struct { - EgressPktCount *ebpf.Map `ebpf:"egress_pkt_count"` - IngressPktCount *ebpf.Map `ebpf:"ingress_pkt_count"` } func (m *bpfMaps) Close() error { - return _BpfClose( - m.EgressPktCount, - m.IngressPktCount, - ) + return _BpfClose() } // bpfVariables contains all global variables after they have been loaded into the kernel. // // It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. type bpfVariables struct { + EgressPktCount *ebpf.Variable `ebpf:"egress_pkt_count"` + IngressPktCount *ebpf.Variable `ebpf:"ingress_pkt_count"` } // bpfPrograms contains all programs after they have been loaded into the kernel. diff --git a/examples/tcx/bpf_bpfeb.o b/examples/tcx/bpf_bpfeb.o index 9662849e7..928c8527e 100644 Binary files a/examples/tcx/bpf_bpfeb.o and b/examples/tcx/bpf_bpfeb.o differ diff --git a/examples/tcx/bpf_bpfel.go b/examples/tcx/bpf_bpfel.go index d196e43fd..56d03d193 100644 --- a/examples/tcx/bpf_bpfel.go +++ b/examples/tcx/bpf_bpfel.go @@ -62,14 +62,14 @@ type bpfProgramSpecs struct { // // It can be passed ebpf.CollectionSpec.Assign. type bpfMapSpecs struct { - EgressPktCount *ebpf.MapSpec `ebpf:"egress_pkt_count"` - IngressPktCount *ebpf.MapSpec `ebpf:"ingress_pkt_count"` } // bpfVariableSpecs contains global variables before they are loaded into the kernel. // // It can be passed ebpf.CollectionSpec.Assign. type bpfVariableSpecs struct { + EgressPktCount *ebpf.VariableSpec `ebpf:"egress_pkt_count"` + IngressPktCount *ebpf.VariableSpec `ebpf:"ingress_pkt_count"` } // bpfObjects contains all objects after they have been loaded into the kernel. @@ -92,21 +92,18 @@ func (o *bpfObjects) Close() error { // // It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. type bpfMaps struct { - EgressPktCount *ebpf.Map `ebpf:"egress_pkt_count"` - IngressPktCount *ebpf.Map `ebpf:"ingress_pkt_count"` } func (m *bpfMaps) Close() error { - return _BpfClose( - m.EgressPktCount, - m.IngressPktCount, - ) + return _BpfClose() } // bpfVariables contains all global variables after they have been loaded into the kernel. // // It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. type bpfVariables struct { + EgressPktCount *ebpf.Variable `ebpf:"egress_pkt_count"` + IngressPktCount *ebpf.Variable `ebpf:"ingress_pkt_count"` } // bpfPrograms contains all programs after they have been loaded into the kernel. diff --git a/examples/tcx/bpf_bpfel.o b/examples/tcx/bpf_bpfel.o index 5ff34587e..7acc38c25 100644 Binary files a/examples/tcx/bpf_bpfel.o and b/examples/tcx/bpf_bpfel.o differ diff --git a/examples/tcx/main.go b/examples/tcx/main.go index e0ac83d94..d31acb153 100644 --- a/examples/tcx/main.go +++ b/examples/tcx/main.go @@ -1,8 +1,7 @@ // This program demonstrates attaching an eBPF program to a network interface -// with Linux TC (Traffic Control). The program counts ingress and egress -// packets using two ARRAY maps. -// The userspace program (Go code in this file) prints the contents -// of the two maps to stdout every second. +// with Linux TCX (Traffic Control with eBPF). The program counts ingress and egress +// packets using two variables. The userspace program (Go code in this file) +// prints the contents of the two variables to stdout every second. // This example depends on tcx bpf_link, available in Linux kernel version 6.6 or newer. package main @@ -78,20 +77,19 @@ func main() { } } -func formatCounters(ingressMap, egressMap *ebpf.Map) (string, error) { +func formatCounters(ingressVar, egressVar *ebpf.Variable) (string, error) { var ( ingressPacketCount uint64 egressPacketCount uint64 - key int32 ) // retrieve value from the ingress map - if err := ingressMap.Lookup(&key, &ingressPacketCount); err != nil { + if err := ingressVar.Get(&ingressPacketCount); err != nil { return "", err } // retrieve value from the egress map - if err := egressMap.Lookup(&key, &egressPacketCount); err != nil { + if err := egressVar.Get(&egressPacketCount); err != nil { return "", err } diff --git a/examples/tcx/tcx.c b/examples/tcx/tcx.c index 61996ba02..248f0c340 100644 --- a/examples/tcx/tcx.c +++ b/examples/tcx/tcx.c @@ -4,43 +4,17 @@ char __license[] SEC("license") = "Dual MIT/GPL"; -/* Define an ARRAY map for storing ingress packet count */ -struct { - __uint(type, BPF_MAP_TYPE_ARRAY); - __type(key, __u32); - __type(value, __u64); - __uint(max_entries, 1); -} ingress_pkt_count SEC(".maps"); - -/* Define an ARRAY map for storing egress packet count */ -struct { - __uint(type, BPF_MAP_TYPE_ARRAY); - __type(key, __u32); - __type(value, __u64); - __uint(max_entries, 1); -} egress_pkt_count SEC(".maps"); - -/* -Upon arrival of each network packet, retrieve and increment -the packet count from the provided map. -Returns TC_ACT_OK, allowing the packet to proceed. -*/ -static __always_inline int update_map_pkt_count(void *map) { - __u32 key = 0; - __u64 *count = bpf_map_lookup_elem(map, &key); - if (count) { - __sync_fetch_and_add(count, 1); - } - - return TC_ACT_OK; -} +__u64 ingress_pkt_count = 0; +__u64 egress_pkt_count = 0; SEC("tc") int ingress_prog_func(struct __sk_buff *skb) { - return update_map_pkt_count(&ingress_pkt_count); + __sync_fetch_and_add(&ingress_pkt_count, 1); + return TC_ACT_OK; } SEC("tc") int egress_prog_func(struct __sk_buff *skb) { - return update_map_pkt_count(&egress_pkt_count); + __sync_fetch_and_add(&egress_pkt_count, 1); + return TC_ACT_OK; }