Skip to content

Commit

Permalink
Merge branch 'main' into orsenthil-patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
yash97 authored Oct 8, 2024
2 parents a0cb275 + 16a8c7e commit 346a497
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 30 deletions.
5 changes: 1 addition & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/stretchr/testify v1.9.0
github.com/vishvananda/netlink v1.1.0
go.uber.org/zap v1.27.0
golang.org/x/sys v0.20.0
golang.org/x/sys v0.24.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
)

Expand All @@ -16,8 +16,5 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df // indirect
go.uber.org/multierr v1.10.0 // indirect
golang.org/x/mod v0.4.2 // indirect
golang.org/x/tools v0.1.1 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
7 changes: 2 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
Expand All @@ -31,18 +30,16 @@ golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.1 h1:wGiQel/hW0NnEkJUk8lbzkX2gFJU6PFxf1v5OlCfuOs=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
31 changes: 12 additions & 19 deletions pkg/maps/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,11 @@ type BpfMapAPIs interface {
// Get map value
GetMapEntry(key, value uintptr) error
// Update multiple map entries
BulkUpdateMapEntry(keyvalue map[uintptr]uintptr) error
BulkUpdateMapEntry(keyvalue map[string][]byte) error
// Delete multiple map entries
BulkDeleteMapEntry(keyvalue map[uintptr]uintptr) error
// Wrapper for delete and update map entries
BulkRefreshMapEntries(newMapContents map[string]uintptr) error
BulkRefreshMapEntries(newMapContents map[string][]byte) error
// Retrieve map info from pin path
GetMapFromPinPath(pinPath string) (BpfMapInfo, error)
}
Expand Down Expand Up @@ -456,9 +456,12 @@ func (m *BpfMap) BulkDeleteMapEntry(keyvalue map[uintptr]uintptr) error {
return nil
}

func (m *BpfMap) BulkUpdateMapEntry(keyvalue map[uintptr]uintptr) error {
func (m *BpfMap) BulkUpdateMapEntry(keyvalue map[string][]byte) error {
for k, v := range keyvalue {
err := m.UpdateMapEntry(k, v)
keyByte := []byte(k)
keyPtr := uintptr(unsafe.Pointer(&keyByte[0]))
valuePtr := uintptr(unsafe.Pointer(&v[0]))
err := m.UpdateMapEntry(keyPtr, valuePtr)
if err != nil {
log.Infof("One of the element update failed hence returning from bulk update")
return err
Expand All @@ -468,33 +471,23 @@ func (m *BpfMap) BulkUpdateMapEntry(keyvalue map[uintptr]uintptr) error {
return nil
}

func (m *BpfMap) BulkRefreshMapEntries(newMapContents map[string]uintptr) error {

// 1. Construct i/p to bulkMap
keyvaluePtr := make(map[uintptr]uintptr)

for k, v := range newMapContents {
keyByte := []byte(k)
log.Infof("Converted string to bytearray %v", keyByte)
keyPtr := uintptr(unsafe.Pointer(&keyByte[0]))
keyvaluePtr[keyPtr] = v
}
func (m *BpfMap) BulkRefreshMapEntries(newMapContents map[string][]byte) error {

// 2. Update all map entries
err := m.BulkUpdateMapEntry(keyvaluePtr)
// 1. Update all map entries
err := m.BulkUpdateMapEntry(newMapContents)
if err != nil {
log.Errorf("refresh map failed: during update %v", err)
return err
}

// 3. Read all map entries
// 2. Read all map entries
retrievedMapKeyList, err := m.GetAllMapKeys()
if err != nil {
log.Errorf("get all map keys failed: during Refresh %v", err)
return err
}

// 4. Delete stale Keys
// 3. Delete stale Keys
log.Infof("Check for stale entries and got %d entries from BPF map", len(retrievedMapKeyList))
for _, key := range retrievedMapKeyList {
log.Infof("Checking if key %s is deletable", key)
Expand Down
4 changes: 2 additions & 2 deletions pkg/maps/mocks/ebpf_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

144 changes: 144 additions & 0 deletions test/main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package main

import (
"encoding/binary"
"fmt"
"net"
"os"
"strings"
"syscall"
Expand Down Expand Up @@ -60,6 +62,8 @@ func main() {
{Name: "Test loading Maps without Program", Func: TestLoadMapWithNoProg},
{Name: "Test loading Map operations", Func: TestMapOperations},
{Name: "Test updating Map size", Func: TestLoadMapWithCustomSize},
{Name: "Test bulk Map operations", Func: TestBulkMapOperations},
{Name: "Test bulk refresh Map operations", Func: TestBulkRefreshMapOperations},
}

testSummary := make(map[string]string)
Expand Down Expand Up @@ -340,3 +344,143 @@ func TestLoadMapWithCustomSize() error {
return nil

}

func TestBulkMapOperations() error {
gosdkClient := goelf.New()
_, loadedMap, err := gosdkClient.LoadBpfFile("c/test-map.bpf.elf", "operations")
if err != nil {
fmt.Println("Load BPF failed", "err:", err)
return err
}

for mapName, _ := range loadedMap {
fmt.Println("Map Info: ", "Name: ", mapName)
}

type BPFInetTrieKey struct {
Prefixlen uint32
Addr [4]byte
}

const numEntries = 32 * 1000 // 32K entries

// Create 32K entries
mapToUpdate, ok := loadedMap["ingress_map"]
if !ok {
return fmt.Errorf("map 'ingress_map' not found")
}

for i := 0; i < numEntries; i++ {
dummykey := BPFInetTrieKey{
Prefixlen: 32,
Addr: [4]byte{byte(192 + i/256), byte(168 + (i/256)%256), byte(i % 256), 0},
}
dummyvalue := uint32(40)

err = mapToUpdate.CreateMapEntry(uintptr(unsafe.Pointer(&dummykey)), uintptr(unsafe.Pointer(&dummyvalue)))
if err != nil {
fmt.Println("Unable to Insert into eBPF map: ", err)
return err
}
}
fmt.Println("Created 32K entries successfully")

// Update 32K entries
for i := 0; i < numEntries; i++ {
dummykey := BPFInetTrieKey{
Prefixlen: 32,
Addr: [4]byte{byte(192 + i/256), byte(168 + (i/256)%256), byte(i % 256), 0},
}
dummyvalue := uint32(20)

err = mapToUpdate.UpdateMapEntry(uintptr(unsafe.Pointer(&dummykey)), uintptr(unsafe.Pointer(&dummyvalue)))
if err != nil {
fmt.Println("Unable to Update into eBPF map: ", err)
return err
}
}
fmt.Println("Updated 32K entries successfully")

return nil
}

func ComputeTrieKey(n net.IPNet) []byte {
prefixLen, _ := n.Mask.Size()
key := make([]byte, 8)

// Set the prefix length
key[0] = byte(prefixLen)

// Set the IP address
copy(key[4:], n.IP.To4())

fmt.Printf("Key: %v\n", key)
return key
}

type BPFInetTrieKey struct {
Prefixlen uint32
Addr [4]byte
}

func bpfInetTrieKeyToIPNet(key BPFInetTrieKey) net.IPNet {
ip := net.IPv4(key.Addr[0], key.Addr[1], key.Addr[2], key.Addr[3])
return net.IPNet{
IP: ip,
Mask: net.CIDRMask(int(key.Prefixlen), 32),
}
}

func TestBulkRefreshMapOperations() error {
gosdkClient := goelf.New()
_, loadedMap, err := gosdkClient.LoadBpfFile("c/test-map.bpf.elf", "operations")
if err != nil {
fmt.Println("Load BPF failed", "err:", err)
return err
}

for mapName, _ := range loadedMap {
fmt.Println("Map Info: ", "Name: ", mapName)
}

const numEntries = 32 * 1000 // 32K entries
// Create 32K entries
mapToUpdate, ok := loadedMap["ingress_map"]
if !ok {
return fmt.Errorf("map 'ingress_map' not found")
}

newMapContents := make(map[string][]byte, numEntries)
for i := 0; i < numEntries; i++ {
dummykey := BPFInetTrieKey{
Prefixlen: 32,
Addr: [4]byte{byte(1 + i/65536), byte(0 + (i/256)%256), byte(i % 256), 0},
}
dummyvalue := uint32(40)

err = mapToUpdate.CreateMapEntry(uintptr(unsafe.Pointer(&dummykey)), uintptr(unsafe.Pointer(&dummyvalue)))
if err != nil {
fmt.Println("Unable to Insert into eBPF map: ", err)
return err
}
dummyvalue = uint32(50)
ipnet := bpfInetTrieKeyToIPNet(dummykey)
fmt.Println(ipnet)
keyByte := ComputeTrieKey(ipnet)
dummyValueByteArray := make([]byte, 4)
binary.LittleEndian.PutUint32(dummyValueByteArray, dummyvalue)
newMapContents[string(keyByte)] = dummyValueByteArray

}
fmt.Println("Created 32K entries successfully")

// Update 32K entries
err = mapToUpdate.BulkRefreshMapEntries(newMapContents)
if err != nil {
fmt.Println("Unable to Bulk Refresh eBPF map: ", err)
return err
}
fmt.Println("Updated 32K entries successfully")

return nil
}

0 comments on commit 346a497

Please sign in to comment.