github.com/cilium/cilium@v1.16.2/pkg/maps/srv6map/sid.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package srv6map
     5  
     6  import (
     7  	"fmt"
     8  	"strconv"
     9  
    10  	"github.com/cilium/ebpf"
    11  	"github.com/cilium/hive/cell"
    12  
    13  	"github.com/cilium/cilium/pkg/bpf"
    14  	"github.com/cilium/cilium/pkg/datapath/linux/config/defines"
    15  	"github.com/cilium/cilium/pkg/option"
    16  	"github.com/cilium/cilium/pkg/types"
    17  )
    18  
    19  const (
    20  	sidMapName    = "cilium_srv6_sid"
    21  	maxSIDEntries = 16384
    22  )
    23  
    24  // SIDKey is a key for the SIDMap. Implements bpf.MapKey.
    25  type SIDKey struct {
    26  	SID types.IPv6
    27  }
    28  
    29  func (k *SIDKey) New() bpf.MapKey {
    30  	return &SIDKey{}
    31  }
    32  
    33  func (k *SIDKey) String() string {
    34  	return fmt.Sprintf("sid=%s", k.SID.String())
    35  }
    36  
    37  // SIDValue is a value for the SIDMap. Implements bpf.MapValue.
    38  type SIDValue struct {
    39  	VRFID uint32
    40  }
    41  
    42  func (v *SIDValue) New() bpf.MapValue {
    43  	return &SIDValue{}
    44  }
    45  
    46  func (v *SIDValue) String() string {
    47  	return fmt.Sprintf("vrfid=%d", v.VRFID)
    48  }
    49  
    50  // SIDMap is the internal representation of an SRv6 SID map.
    51  type SIDMap struct {
    52  	*bpf.Map
    53  }
    54  
    55  // SRv6SIDIterateCallback represents the signature of the callback function
    56  // expected by the IterateWithCallback method, which in turn is used to iterate
    57  // all the keys/values of an SRv6 SID map.
    58  type SRv6SIDIterateCallback func(*SIDKey, *SIDValue)
    59  
    60  // IterateWithCallback iterates through all the keys/values of an SRv6 SID map,
    61  // passing each key/value pair to the cb callback.
    62  func (m *SIDMap) IterateWithCallback(cb SRv6SIDIterateCallback) error {
    63  	return m.DumpWithCallback(func(k bpf.MapKey, v bpf.MapValue) {
    64  		key := k.(*SIDKey)
    65  		value := v.(*SIDValue)
    66  		cb(key, value)
    67  	})
    68  }
    69  
    70  func newSIDMap(dc *option.DaemonConfig, lc cell.Lifecycle) (bpf.MapOut[*SIDMap], defines.NodeOut) {
    71  	if !dc.EnableSRv6 {
    72  		return bpf.MapOut[*SIDMap]{}, defines.NodeOut{}
    73  	}
    74  
    75  	m := bpf.NewMap(
    76  		sidMapName,
    77  		ebpf.Hash,
    78  		&SIDKey{},
    79  		&SIDValue{},
    80  		maxSIDEntries,
    81  		bpf.BPF_F_NO_PREALLOC,
    82  	)
    83  
    84  	lc.Append(cell.Hook{
    85  		OnStart: func(ctx cell.HookContext) error {
    86  			return m.OpenOrCreate()
    87  		},
    88  		OnStop: func(ctx cell.HookContext) error {
    89  			return m.Close()
    90  		},
    91  	})
    92  
    93  	nodeOut := defines.NodeOut{
    94  		NodeDefines: defines.Map{
    95  			"SRV6_SID_MAP":      sidMapName,
    96  			"SRV6_SID_MAP_SIZE": strconv.FormatUint(maxSIDEntries, 10),
    97  		},
    98  	}
    99  
   100  	return bpf.NewMapOut(&SIDMap{m}), nodeOut
   101  }
   102  
   103  // OpenSIDMap opens the SIDMap on bpffs
   104  func OpenSIDMap() (*SIDMap, error) {
   105  	m, err := bpf.OpenMap(bpf.MapPath(sidMapName), &SIDKey{}, &SIDValue{})
   106  	if err != nil {
   107  		return nil, err
   108  	}
   109  	return &SIDMap{m}, nil
   110  }