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

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package neighborsmap
     5  
     6  import (
     7  	"net"
     8  	"sync"
     9  	"unsafe"
    10  
    11  	"github.com/cilium/ebpf"
    12  
    13  	"github.com/cilium/cilium/pkg/bpf"
    14  	"github.com/cilium/cilium/pkg/option"
    15  	"github.com/cilium/cilium/pkg/types"
    16  )
    17  
    18  const (
    19  	// Map4Name is the BPF map name.
    20  	Map4Name = "cilium_nodeport_neigh4"
    21  	// Map6Name is the BPF map name.
    22  	Map6Name = "cilium_nodeport_neigh6"
    23  )
    24  
    25  var (
    26  	neigh4Map *bpf.Map
    27  	neigh6Map *bpf.Map
    28  	once      sync.Once
    29  )
    30  
    31  func neighMapsGet() (*bpf.Map, *bpf.Map) {
    32  	once.Do(func() {
    33  		neigh4Map = bpf.NewMap(Map4Name,
    34  			ebpf.LRUHash,
    35  			&Key4{},
    36  			&Value{},
    37  			option.Config.NeighMapEntriesGlobal,
    38  			0,
    39  		)
    40  		neigh6Map = bpf.NewMap(Map6Name,
    41  			ebpf.LRUHash,
    42  			&Key6{},
    43  			&Value{},
    44  			option.Config.NeighMapEntriesGlobal,
    45  			0,
    46  		)
    47  	})
    48  	return neigh4Map, neigh6Map
    49  }
    50  
    51  // Key4 is the IPv4 for the IP-to-MAC address mappings.
    52  type Key4 struct {
    53  	ipv4 types.IPv4
    54  }
    55  
    56  // Key6 is the IPv6 for the IP-to-MAC address mappings.
    57  type Key6 struct {
    58  	ipv6 types.IPv6
    59  }
    60  
    61  // SizeofNeighKey6 is the size of type NeighKey6.
    62  const SizeofNeighKey6 = int(unsafe.Sizeof(Key6{}))
    63  
    64  // Value is the MAC address for the IP-to-MAC address mappings.
    65  type Value struct {
    66  	macaddr types.MACAddr
    67  	_       uint16
    68  }
    69  
    70  // SizeOfNeighValue is the size of type NeighValue.
    71  const SizeOfNeighValue = int(unsafe.Sizeof(Value{}))
    72  
    73  // String converts the key into a human readable string format.
    74  func (k *Key4) String() string  { return k.ipv4.String() }
    75  func (k *Key4) New() bpf.MapKey { return &Key4{} }
    76  
    77  // String converts the key into a human readable string format.
    78  func (k *Key6) String() string  { return k.ipv6.String() }
    79  func (k *Key6) New() bpf.MapKey { return &Key6{} }
    80  
    81  // String converts the value into a human readable string format.
    82  func (v *Value) String() string    { return v.macaddr.String() }
    83  func (k *Value) New() bpf.MapValue { return &Value{} }
    84  
    85  // InitMaps creates the nodeport neighbors maps in the kernel.
    86  func InitMaps(ipv4, ipv6 bool) error {
    87  	neigh4Map, neigh6Map := neighMapsGet()
    88  	if ipv4 {
    89  		if err := neigh4Map.Create(); err != nil {
    90  			return err
    91  		}
    92  	}
    93  	if ipv6 {
    94  		if err := neigh6Map.Create(); err != nil {
    95  			return err
    96  		}
    97  	}
    98  	return nil
    99  }
   100  
   101  // NeighRetire retires a cached neigh entry from the LRU cache
   102  func NeighRetire(ip net.IP) {
   103  	var neighMap *bpf.Map
   104  	if len(ip) == net.IPv4len {
   105  		neighMap, _ = neighMapsGet()
   106  	} else {
   107  		_, neighMap = neighMapsGet()
   108  	}
   109  	if err := neighMap.Open(); err != nil {
   110  		return
   111  	}
   112  	defer neighMap.Close()
   113  	if len(ip) == net.IPv4len {
   114  		key := &Key4{}
   115  		copy(key.ipv4[:], ip.To4())
   116  		neighMap.Delete(key)
   117  	} else {
   118  		key := &Key6{}
   119  		copy(key.ipv6[:], ip.To16())
   120  		neighMap.Delete(key)
   121  	}
   122  }