1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
package main
import (
"fmt"
"log"
"net"
"net/netip"
"os"
"time"
"github.com/cilium/ebpf"
"github.com/cilium/ebpf/link"
)
type Usage struct {
ingress uint64
egress uint64
}
func main() {
if len(os.Args) < 2 {
log.Fatalf("Please specify a network interface")
}
ifaceName := os.Args[1]
iface, err := net.InterfaceByName(ifaceName)
if err != nil {
log.Fatalf("lookup network iface %q: %s", ifaceName, err)
}
// Load pre-compiled programs into the kernel.
objs := bpfObjects{}
if err := loadBpfObjects(&objs, nil); err != nil {
log.Fatalf("loading objects: %s", err)
}
defer objs.Close()
// Attach the program.
ingressLink, err := link.AttachTCX(link.TCXOptions{
Interface: iface.Index,
Program: objs.IngressFunc,
Attach: ebpf.AttachTCXIngress,
})
if err != nil {
log.Fatalf("could not attach TCx program: %s", err)
}
defer ingressLink.Close()
// Attach the program to Egress TC.
egressLink, err := link.AttachTCX(link.TCXOptions{
Interface: iface.Index,
Program: objs.EgressFunc,
Attach: ebpf.AttachTCXEgress,
})
if err != nil {
log.Fatalf("could not attach TCx program: %s", err)
}
defer egressLink.Close()
ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()
for range ticker.C {
prettyPrint(objs.IngressIp4UsageMap, objs.EgressIp4UsageMap)
}
}
func prettyPrint(ingress *ebpf.Map, egress *ebpf.Map) {
ipUsage := make(map[netip.Addr]Usage)
var key netip.Addr
var value uint64
iter := ingress.Iterate()
for iter.Next(&key, &value) {
ipUsage[key] = Usage {
ingress: value,
}
}
iter = egress.Iterate()
for iter.Next(&key, &value) {
usage, ok := ipUsage[key]
if (ok) {
usage.egress = value
} else {
usage = Usage { egress: value }
}
ipUsage[key] = usage
}
fmt.Print("\033[H\033[2J")
fmt.Printf("%15s\t%16s\t%16s\n", "ip", "down", "up")
for ip4, usage := range ipUsage {
fmt.Printf("%15s\t%16d\t%16d\n", ip4, usage.ingress, usage.egress)
}
}
|