Skip to content

Commit 6a5aae9

Browse files
committed
Add ebpf
1 parent 31c5336 commit 6a5aae9

File tree

6 files changed

+574
-0
lines changed

6 files changed

+574
-0
lines changed

ebpf/ebpf-kernel/bpf_bpfeb.go

Lines changed: 119 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ebpf/ebpf-kernel/bpf_bpfel.go

Lines changed: 121 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ebpf/ebpf-kernel/main.go

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
//go:build linux
2+
// +build linux
3+
4+
package main
5+
6+
import (
7+
"bytes"
8+
"encoding/binary"
9+
"errors"
10+
"log"
11+
"net"
12+
"os"
13+
"os/signal"
14+
"syscall"
15+
16+
"golang.org/x/sys/unix"
17+
18+
"github.com/cilium/ebpf"
19+
"github.com/cilium/ebpf/link"
20+
"github.com/cilium/ebpf/ringbuf"
21+
"github.com/cilium/ebpf/rlimit"
22+
)
23+
24+
// $BPF_CLANG and $BPF_CFLAGS are set by the Makefile.
25+
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc $BPF_CLANG -cflags $BPF_CFLAGS -type event bpf fentry.c -- -I../headers
26+
27+
func main() {
28+
if len(os.Args) < 2 {
29+
log.Fatalf("Please specify a network interface")
30+
}
31+
32+
ifaceName := os.Args[1]
33+
iface, err := net.InterfaceByName(ifaceName)
34+
if err != nil {
35+
log.Fatalf("lookup network iface %q: %s", ifaceName, err)
36+
}
37+
38+
objs := bpfObjects{}
39+
if err := loadBpfObjects(&objs, nil); err != nil {
40+
log.Fatalf("loading objects: %s", err)
41+
}
42+
defer objs.Close()
43+
44+
l, err := link.AttachXDP(link.XDPOptions{
45+
Program: objs.XdpProgFunc,
46+
Interface: iface.Index,
47+
})
48+
if err != nil {
49+
log.Fatalf("could not attach XDP program: %s", err)
50+
}
51+
defer l.Close()
52+
53+
log.Printf("Attached XDP program to iface %q (index %d)", iface.Name, iface.Index)
54+
55+
ticker := time.NewTicker(1 * time.Second)
56+
defer ticker.Stop()
57+
for range ticker.C {
58+
s, err := formatMapContents(objs.XdpStatsMap)
59+
if err != nil {
60+
log.Printf("Error reading map: %s", err)
61+
continue
62+
}
63+
log.Printf("Map contents:\n%s", s)
64+
}
65+
}
66+
67+
func intToIP(ipNum uint32) net.IP {
68+
ip := make(net.IP, 4)
69+
binary.BigEndian.PutUint32(ip, ipNum)
70+
return ip
71+
}
72+
73+
func saveDataToMap(desPort, srcAddr, port string) {
74+
// Allow the current process to lock memory for eBPF resources.
75+
if err := rlimit.RemoveMemlock(); err != nil {
76+
log.Fatal(err)
77+
}
78+
79+
outerMapSpec := ebpf.MapSpec{
80+
Name: "outer_map",
81+
Type: ebpf.ArrayOfMaps,
82+
KeySize: 10000,
83+
ValueSize: 10000,
84+
MaxEntries: 10000,
85+
Contents: make([]ebpf.MapKV, 5),
86+
InnerMap: &ebpf.MapSpec{
87+
Name: "inner_map",
88+
Type: ebpf.Array,
89+
KeySize: 100,
90+
ValueSize: 100,
91+
Flags: unix.BPF_F_INNER_MAP,
92+
MaxEntries: 1,
93+
},
94+
}
95+
96+
innerMapSpec := outerMapSpec.InnerMap.Copy()
97+
innerMapSpec.MaxEntries = 1000
98+
innerMapSpec.Contents = make([]ebpf.MapKV, innerMapSpec.MaxEntries)
99+
innerMapSpec = append(innerMapSpec, ebpf.MapKV{Key: desPort, Value: srcAddr+port})
100+
innerMap, err := ebpf.NewMap(innerMapSpec)
101+
if err != nil {
102+
log.Fatalf("inner_map: %v", err)
103+
}
104+
defer innerMap.Close()
105+
outerMapSpec.Contents = append(outerMapSpec.Contents, ebpf.MapKV{Key: i, Value: innerMap})
106+
}
107+
108+
func readMap(outerMapSpec ebpf.MapSpec) {
109+
outerMap, err := ebpf.NewMap(&outerMapSpec)
110+
if err != nil {
111+
log.Fatalf("outer_map: %v", err)
112+
}
113+
defer outerMap.Close()
114+
115+
mapIter := outerMap.Iterate()
116+
var outerMapKey uint32
117+
var innerMapID ebpf.MapID
118+
for mapIter.Next(&outerMapKey, &innerMapID) {
119+
innerMap, err := ebpf.NewMapFromID(innerMapID)
120+
if err != nil {
121+
log.Fatal(err)
122+
}
123+
innerMapInfo, err := innerMap.Info()
124+
if err != nil {
125+
log.Fatal(err)
126+
}
127+
log.Printf("outerMapKey %d, innerMap.Info: %+v", outerMapKey, innerMapInfo.)
128+
}
129+
}
130+
131+
func formatMapContents(m *ebpf.Map) (string, error) {
132+
var (
133+
sb strings.Builder
134+
key []byte
135+
val uint32
136+
)
137+
iter := m.Iterate()
138+
for iter.Next(&key, &val) {
139+
sourceIP := net.IP(key) // IPv4 source address in network byte order.
140+
packetCount := val
141+
sb.WriteString(fmt.Sprintf("\t%s => %d\n", sourceIP, packetCount))
142+
}
143+
return sb.String(), iter.Err()
144+
}

0 commit comments

Comments
 (0)