Skip to content

Commit

Permalink
maps: switch maglev to cilium/ebpf package
Browse files Browse the repository at this point in the history
Signed-off-by: Gilberto Bertin <gilberto@isovalent.com>
  • Loading branch information
jibi committed Jun 21, 2021
1 parent 9fb9c33 commit 879f9eb
Show file tree
Hide file tree
Showing 9 changed files with 434 additions and 299 deletions.
33 changes: 15 additions & 18 deletions cilium/cmd/bpf_lb_maglev_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@ import (
"errors"
"strconv"

"github.com/cilium/cilium/pkg/bpf"
"github.com/cilium/cilium/pkg/command"
"github.com/cilium/cilium/pkg/common"
"github.com/cilium/cilium/pkg/ebpf"
"github.com/cilium/cilium/pkg/maps/lbmap"

"github.com/spf13/cobra"
"golang.org/x/sys/unix"
)

var bpfMaglevGetCmd = &cobra.Command{
Expand All @@ -47,24 +46,22 @@ var bpfMaglevGetCmd = &cobra.Command{
lookupTables := map[string][]string{}
found := false

for _, name := range []string{lbmap.MaglevOuter4MapName, lbmap.MaglevOuter6MapName} {
// See bpf_lb_maglev_list.go comment for why we use low-level routines
// to open and access the maps
if m, err := bpf.OpenMap(name); err != nil {
continue
} else {
err := bpf.LookupElement(m.GetFd(), key.GetKeyPtr(), val.GetValuePtr())
if err != nil {
if errors.Is(err, unix.ENOENT) {
continue
}
Fatalf("Unable to retrieve entry from %s with key %s: %s",
name, key, err)
} else {
found = true
parseMaglevEntry(key, val, lookupTables)
tableSize, err := lbmap.OpenMaglevMaps()
if err != nil {
Fatalf("Cannot initialize maglev maps: %s", err)
}

for name, m := range lbmap.GetOpenMaglevMaps() {
if err := m.Lookup(key, val); err != nil {
if errors.Is(err, ebpf.ErrKeyNotExist) {
continue
}
Fatalf("Unable to retrieve entry from %s with key %v: %s",
name, key, err)
}

found = true
parseMaglevEntry(key, val, tableSize, lookupTables)
}

if !found {
Expand Down
65 changes: 21 additions & 44 deletions cilium/cmd/bpf_lb_maglev_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@ package cmd

import (
"fmt"
"unsafe"

"github.com/spf13/cobra"

"github.com/cilium/cilium/pkg/bpf"
"github.com/cilium/cilium/pkg/command"
"github.com/cilium/cilium/pkg/common"
"github.com/cilium/cilium/pkg/maps/lbmap"
Expand Down Expand Up @@ -48,57 +46,36 @@ var bpfMaglevListCmd = &cobra.Command{
},
}

var lookupTableSize = 0

func parseMaglevEntry(key bpf.MapKey, value bpf.MapValue, tables map[string][]string) {
k := key.(*lbmap.MaglevOuterKey)
v := value.(*lbmap.MaglevOuterVal)

// Determine lookup table size by inspecting the first inner map
if lookupTableSize == 0 {
fd, err := bpf.MapFdFromID(int(v.FD))
if err != nil {
Fatalf("Unable to get map fd by id %d: %s", v.FD, err)
}
m, err := bpf.GetMapInfoByFd(uint32(fd))
if err != nil {
Fatalf("Unable to get map info by fd %d: %s", fd, err)
}
lookupTableSize = int(m.ValueSize) / 2
func parseMaglevEntry(key *lbmap.MaglevOuterKey, value *lbmap.MaglevOuterVal, tableSize uint32, tables map[string][]string) {
innerMap, err := lbmap.MaglevInnerMapFromID(int(value.FD), tableSize)
if err != nil {
Fatalf("Unable to get map fd by id %d: %s", value.FD, err)
}

table := make([]uint16, lookupTableSize)
zero := uint32(0)
fd, err := bpf.MapFdFromID(int(v.FD))
if err != nil {
Fatalf("Unable to get map fd by id %d: %s", v.FD, err)
innerKey := lbmap.MaglevInnerKey{
Zero: 0,
}
if err := bpf.LookupElement(int(fd), unsafe.Pointer(&zero), unsafe.Pointer(&table[0])); err != nil {
Fatalf("Unable to lookup element in map by fd %d: %s", fd, err)
innerValue, err := innerMap.Lookup(&innerKey)
if err != nil {
Fatalf("Unable to lookup element in map by fd %d: %s", value.FD, err)
}
tables[k.ToNetwork().String()] = []string{fmt.Sprintf("%v", table)}

tables[fmt.Sprintf("%d", key.ToNetwork().RevNatID)] = []string{fmt.Sprintf("%v", innerValue.BackendIDs)}
}

func dumpMaglevTables(tables map[string][]string) {
parse := func(key bpf.MapKey, value bpf.MapValue) {
parseMaglevEntry(key, value, tables)
tableSize, err := lbmap.OpenMaglevMaps()
if err != nil {
Fatalf("Cannot initialize maglev maps: %s", err)
}

for _, name := range []string{lbmap.MaglevOuter4MapName, lbmap.MaglevOuter6MapName} {
// We cannot directly access the maps via lbmap.MaglevOuter{4,6}Map, as
// both are not initialized, and they cannot be initialized due to
// option.Config.MaglevTableSize not set in the cilium cli. Thus, we need
// to open map with the lower-level helper and set the fields required
// for the maps traversal.
if m, err := bpf.OpenMap(name); err != nil {
continue
} else {
m.MapKey = &lbmap.MaglevOuterKey{}
m.MapValue = &lbmap.MaglevOuterVal{}
m.DumpParser = bpf.ConvertKeyValue
if err := m.DumpWithCallbackIfExists(parse); err != nil {
Fatalf("Unable to dump %s: %s", name, err)
}
parse := func(key *lbmap.MaglevOuterKey, value *lbmap.MaglevOuterVal) {
parseMaglevEntry(key, value, tableSize, tables)
}

for name, m := range lbmap.GetOpenMaglevMaps() {
if err := m.IterateWithCallback(parse); err != nil {
Fatalf("Unable to dump %s: %v", name, err)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion daemon/cmd/datapath.go
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ func (d *Daemon) initMaps() error {
}

if option.Config.NodePortAlg == option.NodePortAlgMaglev {
if err := lbmap.InitMaglevMaps(option.Config.EnableIPv4, option.Config.EnableIPv6); err != nil {
if err := lbmap.InitMaglevMaps(option.Config.EnableIPv4, option.Config.EnableIPv6, uint32(option.Config.MaglevTableSize)); err != nil {
return err
}
}
Expand Down
42 changes: 42 additions & 0 deletions pkg/ebpf/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,17 @@ type MapSpec = ciliumebpf.MapSpec

const (
PerCPUHash = ciliumebpf.PerCPUHash
Array = ciliumebpf.Array
HashOfMaps = ciliumebpf.HashOfMaps

PinByName = ciliumebpf.PinByName
)

var (
ErrKeyNotExist = ciliumebpf.ErrKeyNotExist
LoadPinnedMap = ciliumebpf.LoadPinnedMap
)

// IterateCallback represents the signature of the callback function expected by
// the IterateWithCallback method, which in turn is used to iterate all the
// keys/values of a map.
Expand All @@ -56,6 +63,37 @@ func NewMap(spec *MapSpec) *Map {
}
}

// OpenMap opens the given bpf map and generates the Map object based on the
// information stored in the bpf map.
func OpenMap(mapName string) (*Map, error) {
path := bpf.MapPath(mapName)

newMap, err := LoadPinnedMap(path, nil)
if err != nil {
return nil, err
}

m := &Map{
Map: newMap,
path: path,
}

registerMap(m)

return m, nil
}

func MapFromID(id int) (*Map, error) {
newMap, err := ciliumebpf.NewMapFromID(ciliumebpf.MapID(id))
if err != nil {
return nil, err
}

return &Map{
Map: newMap,
}, nil
}

// OpenOrCreate tries to open or create the eBPF map identified by the spec in
// the Map object.
func (m *Map) OpenOrCreate() error {
Expand All @@ -66,6 +104,10 @@ func (m *Map) OpenOrCreate() error {
return nil
}

if m.spec == nil {
return fmt.Errorf("cannot create map: nil map spec")
}

opts := ciliumebpf.MapOptions{
PinPath: bpf.MapPrefixPath(),
}
Expand Down

0 comments on commit 879f9eb

Please sign in to comment.