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

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package lbmap
     5  
     6  import (
     7  	"fmt"
     8  	"net"
     9  
    10  	"github.com/cilium/ebpf"
    11  
    12  	"github.com/cilium/cilium/pkg/bpf"
    13  	"github.com/cilium/cilium/pkg/byteorder"
    14  	cmtypes "github.com/cilium/cilium/pkg/clustermesh/types"
    15  	"github.com/cilium/cilium/pkg/loadbalancer"
    16  	"github.com/cilium/cilium/pkg/option"
    17  	"github.com/cilium/cilium/pkg/types"
    18  	"github.com/cilium/cilium/pkg/u8proto"
    19  )
    20  
    21  const (
    22  	// HealthProbe4MapName is the health datapath map name
    23  	HealthProbe4MapName = "cilium_lb4_health"
    24  
    25  	// SockRevNat4MapName is the BPF map name.
    26  	SockRevNat4MapName = "cilium_lb4_reverse_sk"
    27  
    28  	// SockRevNat4MapSize is the maximum number of entries in the BPF map.
    29  	SockRevNat4MapSize = 256 * 1024
    30  
    31  	// Service4MapV2Name is the name of the IPv4 LB Services v2 BPF map.
    32  	Service4MapV2Name = "cilium_lb4_services_v2"
    33  	// Backend4MapName is the name of the IPv4 LB backends BPF map.
    34  	Backend4MapName = "cilium_lb4_backends"
    35  	// Backend4MapV2Name is the name of the IPv4 LB backends v2 BPF map.
    36  	Backend4MapV2Name = "cilium_lb4_backends_v2"
    37  	// Backend4MapV3Name is the name of the IPv4 LB backends v3 BPF map.
    38  	Backend4MapV3Name = "cilium_lb4_backends_v3"
    39  	// RevNat4MapName is the name of the IPv4 LB reverse NAT BPF map.
    40  	RevNat4MapName = "cilium_lb4_reverse_nat"
    41  )
    42  
    43  var (
    44  	// MaxSockRevNat4MapEntries is the maximum number of entries in the BPF
    45  	// map. It is set by Init(), but unit tests use the initial value below.
    46  	MaxSockRevNat4MapEntries = SockRevNat4MapSize
    47  
    48  	// The following BPF maps are initialized in initSVC().
    49  
    50  	// Service4MapV2 is the IPv4 LB Services v2 BPF map.
    51  	Service4MapV2 *bpf.Map
    52  	// Backend4Map is the IPv4 LB backends BPF map.
    53  	Backend4Map *bpf.Map
    54  	// Backend4MapV2 is the IPv4 LB backends v2 BPF map.
    55  	Backend4MapV2 *bpf.Map
    56  	// Backend4MapV2 is the IPv4 LB backends v2 BPF map.
    57  	Backend4MapV3 *bpf.Map
    58  	// RevNat4Map is the IPv4 LB reverse NAT BPF map.
    59  	RevNat4Map *bpf.Map
    60  	// SockRevNat4Map is the IPv4 LB sock reverse NAT BPF map.
    61  	SockRevNat4Map *bpf.Map
    62  )
    63  
    64  // initSVC constructs the IPv4 & IPv6 LB BPF maps used for Services. The maps
    65  // have their maximum entries configured. Note this does not create or open the
    66  // maps; it simply constructs the objects.
    67  func initSVC(params InitParams) {
    68  	ServiceMapMaxEntries = params.ServiceMapMaxEntries
    69  	ServiceBackEndMapMaxEntries = params.BackEndMapMaxEntries
    70  	RevNatMapMaxEntries = params.RevNatMapMaxEntries
    71  
    72  	if params.IPv4 {
    73  		Service4MapV2 = bpf.NewMap(Service4MapV2Name,
    74  			ebpf.Hash,
    75  			&Service4Key{},
    76  			&Service4Value{},
    77  			ServiceMapMaxEntries,
    78  			0,
    79  		).WithCache().WithPressureMetric().
    80  			WithEvents(option.Config.GetEventBufferConfig(Service4MapV2Name))
    81  		Backend4Map = bpf.NewMap(Backend4MapName,
    82  			ebpf.Hash,
    83  			&Backend4Key{},
    84  			&Backend4Value{},
    85  			ServiceBackEndMapMaxEntries,
    86  			0,
    87  		).WithCache().WithPressureMetric().
    88  			WithEvents(option.Config.GetEventBufferConfig(Backend4MapName))
    89  		Backend4MapV2 = bpf.NewMap(Backend4MapV2Name,
    90  			ebpf.Hash,
    91  			&Backend4KeyV3{},
    92  			&Backend4Value{},
    93  			ServiceBackEndMapMaxEntries,
    94  			0,
    95  		).WithCache().WithPressureMetric().
    96  			WithEvents(option.Config.GetEventBufferConfig(Backend4MapV2Name))
    97  		Backend4MapV3 = bpf.NewMap(Backend4MapV3Name,
    98  			ebpf.Hash,
    99  			&Backend4KeyV3{},
   100  			&Backend4ValueV3{},
   101  			ServiceBackEndMapMaxEntries,
   102  			0,
   103  		).WithCache().WithPressureMetric().
   104  			WithEvents(option.Config.GetEventBufferConfig(Backend4MapV3Name))
   105  		RevNat4Map = bpf.NewMap(RevNat4MapName,
   106  			ebpf.Hash,
   107  			&RevNat4Key{},
   108  			&RevNat4Value{},
   109  			RevNatMapMaxEntries,
   110  			0,
   111  		).WithCache().WithPressureMetric().
   112  			WithEvents(option.Config.GetEventBufferConfig(RevNat4MapName))
   113  	}
   114  
   115  	if params.IPv6 {
   116  		Service6MapV2 = bpf.NewMap(Service6MapV2Name,
   117  			ebpf.Hash,
   118  			&Service6Key{},
   119  			&Service6Value{},
   120  			ServiceMapMaxEntries,
   121  			0,
   122  		).WithCache().WithPressureMetric().
   123  			WithEvents(option.Config.GetEventBufferConfig(Service6MapV2Name))
   124  		Backend6Map = bpf.NewMap(Backend6MapName,
   125  			ebpf.Hash,
   126  			&Backend6Key{},
   127  			&Backend6Value{},
   128  			ServiceBackEndMapMaxEntries,
   129  			0,
   130  		).WithCache().WithPressureMetric().
   131  			WithEvents(option.Config.GetEventBufferConfig(Backend6MapName))
   132  		Backend6MapV2 = bpf.NewMap(Backend6MapV2Name,
   133  			ebpf.Hash,
   134  			&Backend6KeyV3{},
   135  			&Backend6Value{},
   136  			ServiceBackEndMapMaxEntries,
   137  			0,
   138  		).WithCache().WithPressureMetric().
   139  			WithEvents(option.Config.GetEventBufferConfig(Backend6MapV2Name))
   140  		Backend6MapV3 = bpf.NewMap(Backend6MapV3Name,
   141  			ebpf.Hash,
   142  			&Backend6KeyV3{},
   143  			&Backend6ValueV3{},
   144  			ServiceBackEndMapMaxEntries,
   145  			0,
   146  		).WithCache().WithPressureMetric().
   147  			WithEvents(option.Config.GetEventBufferConfig(Backend6MapV3Name))
   148  		RevNat6Map = bpf.NewMap(RevNat6MapName,
   149  			ebpf.Hash,
   150  			&RevNat6Key{},
   151  			&RevNat6Value{},
   152  			RevNatMapMaxEntries,
   153  			0,
   154  		).WithCache().WithPressureMetric().
   155  			WithEvents(option.Config.GetEventBufferConfig(RevNat6MapName))
   156  	}
   157  }
   158  
   159  // The compile-time check for whether the structs implement the interfaces
   160  var _ RevNatKey = (*RevNat4Key)(nil)
   161  var _ RevNatValue = (*RevNat4Value)(nil)
   162  var _ ServiceKey = (*Service4Key)(nil)
   163  var _ ServiceValue = (*Service4Value)(nil)
   164  var _ BackendKey = (*Backend4Key)(nil)
   165  var _ BackendKey = (*Backend4KeyV3)(nil)
   166  var _ BackendValue = (*Backend4Value)(nil)
   167  var _ BackendValue = (*Backend4ValueV3)(nil)
   168  var _ Backend = (*Backend4)(nil)
   169  var _ Backend = (*Backend4V2)(nil)
   170  var _ Backend = (*Backend4V3)(nil)
   171  
   172  type RevNat4Key struct {
   173  	Key uint16
   174  }
   175  
   176  func NewRevNat4Key(value uint16) *RevNat4Key {
   177  	return &RevNat4Key{value}
   178  }
   179  
   180  func (k *RevNat4Key) Map() *bpf.Map   { return RevNat4Map }
   181  func (k *RevNat4Key) String() string  { return fmt.Sprintf("%d", k.ToHost().(*RevNat4Key).Key) }
   182  func (k *RevNat4Key) New() bpf.MapKey { return &RevNat4Key{} }
   183  func (k *RevNat4Key) GetKey() uint16  { return k.Key }
   184  
   185  // ToNetwork converts RevNat4Key to network byte order.
   186  func (k *RevNat4Key) ToNetwork() RevNatKey {
   187  	n := *k
   188  	n.Key = byteorder.HostToNetwork16(n.Key)
   189  	return &n
   190  }
   191  
   192  // ToHost converts RevNat4Key to host byte order.
   193  func (k *RevNat4Key) ToHost() RevNatKey {
   194  	h := *k
   195  	h.Key = byteorder.NetworkToHost16(h.Key)
   196  	return &h
   197  }
   198  
   199  type RevNat4Value struct {
   200  	Address types.IPv4 `align:"address"`
   201  	Port    uint16     `align:"port"`
   202  }
   203  
   204  // ToNetwork converts RevNat4Value to network byte order.
   205  func (v *RevNat4Value) ToNetwork() RevNatValue {
   206  	n := *v
   207  	n.Port = byteorder.HostToNetwork16(n.Port)
   208  	return &n
   209  }
   210  
   211  // ToHost converts RevNat4Value to host byte order.
   212  func (k *RevNat4Value) ToHost() RevNatValue {
   213  	h := *k
   214  	h.Port = byteorder.NetworkToHost16(h.Port)
   215  	return &h
   216  }
   217  
   218  func (v *RevNat4Value) String() string {
   219  	vHost := v.ToHost().(*RevNat4Value)
   220  	return net.JoinHostPort(vHost.Address.String(), fmt.Sprintf("%d", vHost.Port))
   221  }
   222  
   223  func (v *RevNat4Value) New() bpf.MapValue { return &RevNat4Value{} }
   224  
   225  type pad2uint8 [2]uint8
   226  
   227  // Service4Key must match 'struct lb4_key' in "bpf/lib/common.h".
   228  type Service4Key struct {
   229  	Address     types.IPv4 `align:"address"`
   230  	Port        uint16     `align:"dport"`
   231  	BackendSlot uint16     `align:"backend_slot"`
   232  	Proto       uint8      `align:"proto"`
   233  	Scope       uint8      `align:"scope"`
   234  	Pad         pad2uint8  `align:"pad"`
   235  }
   236  
   237  func NewService4Key(ip net.IP, port uint16, proto u8proto.U8proto, scope uint8, slot uint16) *Service4Key {
   238  	key := Service4Key{
   239  		Port:        port,
   240  		Proto:       uint8(proto),
   241  		Scope:       scope,
   242  		BackendSlot: slot,
   243  	}
   244  
   245  	copy(key.Address[:], ip.To4())
   246  
   247  	return &key
   248  }
   249  
   250  func (k *Service4Key) String() string {
   251  	kHost := k.ToHost().(*Service4Key)
   252  	addr := net.JoinHostPort(kHost.Address.String(), fmt.Sprintf("%d", kHost.Port))
   253  	if kHost.Scope == loadbalancer.ScopeInternal {
   254  		addr += "/i"
   255  	}
   256  	addr = fmt.Sprintf("%s (%d)", addr, kHost.BackendSlot)
   257  	return addr
   258  }
   259  
   260  func (k *Service4Key) New() bpf.MapKey { return &Service4Key{} }
   261  
   262  func (k *Service4Key) IsIPv6() bool            { return false }
   263  func (k *Service4Key) IsSurrogate() bool       { return k.GetAddress().IsUnspecified() }
   264  func (k *Service4Key) Map() *bpf.Map           { return Service4MapV2 }
   265  func (k *Service4Key) SetBackendSlot(slot int) { k.BackendSlot = uint16(slot) }
   266  func (k *Service4Key) GetBackendSlot() int     { return int(k.BackendSlot) }
   267  func (k *Service4Key) SetScope(scope uint8)    { k.Scope = scope }
   268  func (k *Service4Key) GetScope() uint8         { return k.Scope }
   269  func (k *Service4Key) GetAddress() net.IP      { return k.Address.IP() }
   270  func (k *Service4Key) GetPort() uint16         { return k.Port }
   271  func (k *Service4Key) MapDelete() error        { return k.Map().Delete(k.ToNetwork()) }
   272  
   273  func (k *Service4Key) RevNatValue() RevNatValue {
   274  	return &RevNat4Value{
   275  		Address: k.Address,
   276  		Port:    k.Port,
   277  	}
   278  }
   279  
   280  func (k *Service4Key) ToNetwork() ServiceKey {
   281  	n := *k
   282  	n.Port = byteorder.HostToNetwork16(n.Port)
   283  	return &n
   284  }
   285  
   286  // ToHost converts Service4Key to host byte order.
   287  func (k *Service4Key) ToHost() ServiceKey {
   288  	h := *k
   289  	h.Port = byteorder.NetworkToHost16(h.Port)
   290  	return &h
   291  }
   292  
   293  // Service4Value must match 'struct lb4_service' in "bpf/lib/common.h".
   294  type Service4Value struct {
   295  	BackendID uint32    `align:"$union0"`
   296  	Count     uint16    `align:"count"`
   297  	RevNat    uint16    `align:"rev_nat_index"`
   298  	Flags     uint8     `align:"flags"`
   299  	Flags2    uint8     `align:"flags2"`
   300  	Pad       pad2uint8 `align:"pad"`
   301  }
   302  
   303  func (s *Service4Value) New() bpf.MapValue { return &Service4Value{} }
   304  
   305  func (s *Service4Value) String() string {
   306  	sHost := s.ToHost().(*Service4Value)
   307  	return fmt.Sprintf("%d %d (%d) [0x%x 0x%x]", sHost.BackendID, sHost.Count, sHost.RevNat, sHost.Flags, sHost.Flags2)
   308  }
   309  
   310  func (s *Service4Value) SetCount(count int)   { s.Count = uint16(count) }
   311  func (s *Service4Value) GetCount() int        { return int(s.Count) }
   312  func (s *Service4Value) SetRevNat(id int)     { s.RevNat = uint16(id) }
   313  func (s *Service4Value) GetRevNat() int       { return int(s.RevNat) }
   314  func (s *Service4Value) RevNatKey() RevNatKey { return &RevNat4Key{s.RevNat} }
   315  func (s *Service4Value) SetFlags(flags uint16) {
   316  	s.Flags = uint8(flags & 0xff)
   317  	s.Flags2 = uint8(flags >> 8)
   318  }
   319  
   320  func (s *Service4Value) GetFlags() uint16 {
   321  	return (uint16(s.Flags2) << 8) | uint16(s.Flags)
   322  }
   323  
   324  func (s *Service4Value) SetSessionAffinityTimeoutSec(t uint32) {
   325  	// Go doesn't support union types, so we use BackendID to access the
   326  	// lb4_service.affinity_timeout field
   327  	s.BackendID = t
   328  }
   329  
   330  func (s *Service4Value) SetL7LBProxyPort(port uint16) {
   331  	// Go doesn't support union types, so we use BackendID to access the
   332  	// lb4_service.l7_lb_proxy_port field
   333  	s.BackendID = uint32(byteorder.HostToNetwork16(port))
   334  }
   335  
   336  func (s *Service4Value) SetBackendID(id loadbalancer.BackendID) {
   337  	s.BackendID = uint32(id)
   338  }
   339  func (s *Service4Value) GetBackendID() loadbalancer.BackendID {
   340  	return loadbalancer.BackendID(s.BackendID)
   341  }
   342  
   343  func (s *Service4Value) ToNetwork() ServiceValue {
   344  	n := *s
   345  	n.RevNat = byteorder.HostToNetwork16(n.RevNat)
   346  	return &n
   347  }
   348  
   349  // ToHost converts Service4Value to host byte order.
   350  func (s *Service4Value) ToHost() ServiceValue {
   351  	h := *s
   352  	h.RevNat = byteorder.NetworkToHost16(h.RevNat)
   353  	return &h
   354  }
   355  
   356  type Backend4KeyV3 struct {
   357  	ID loadbalancer.BackendID
   358  }
   359  
   360  func NewBackend4KeyV3(id loadbalancer.BackendID) *Backend4KeyV3 {
   361  	return &Backend4KeyV3{ID: id}
   362  }
   363  
   364  func (k *Backend4KeyV3) String() string                  { return fmt.Sprintf("%d", k.ID) }
   365  func (k *Backend4KeyV3) New() bpf.MapKey                 { return &Backend4KeyV3{} }
   366  func (k *Backend4KeyV3) Map() *bpf.Map                   { return Backend4MapV3 }
   367  func (k *Backend4KeyV3) SetID(id loadbalancer.BackendID) { k.ID = id }
   368  func (k *Backend4KeyV3) GetID() loadbalancer.BackendID   { return k.ID }
   369  
   370  type Backend4Key struct {
   371  	ID uint16
   372  }
   373  
   374  func (k *Backend4Key) String() string                  { return fmt.Sprintf("%d", k.ID) }
   375  func (k *Backend4Key) New() bpf.MapKey                 { return &Backend4Key{} }
   376  func (k *Backend4Key) Map() *bpf.Map                   { return Backend4Map }
   377  func (k *Backend4Key) SetID(id loadbalancer.BackendID) { k.ID = uint16(id) }
   378  func (k *Backend4Key) GetID() loadbalancer.BackendID   { return loadbalancer.BackendID(k.ID) }
   379  
   380  // Backend4Value must match 'struct lb4_backend' in "bpf/lib/common.h".
   381  type Backend4Value struct {
   382  	Address types.IPv4      `align:"address"`
   383  	Port    uint16          `align:"port"`
   384  	Proto   u8proto.U8proto `align:"proto"`
   385  	Flags   uint8           `align:"flags"`
   386  }
   387  
   388  func NewBackend4Value(ip net.IP, port uint16, proto u8proto.U8proto, state loadbalancer.BackendState) (*Backend4Value, error) {
   389  	ip4 := ip.To4()
   390  	if ip4 == nil {
   391  		return nil, fmt.Errorf("Not an IPv4 address")
   392  	}
   393  	flags := loadbalancer.NewBackendFlags(state)
   394  
   395  	val := Backend4Value{
   396  		Port:  port,
   397  		Proto: proto,
   398  		Flags: flags,
   399  	}
   400  	copy(val.Address[:], ip.To4())
   401  
   402  	return &val, nil
   403  }
   404  
   405  func (v *Backend4Value) String() string {
   406  	vHost := v.ToHost().(*Backend4Value)
   407  	return fmt.Sprintf("%s://%s:%d", vHost.Proto, vHost.Address, vHost.Port)
   408  }
   409  
   410  func (b *Backend4Value) New() bpf.MapValue { return &Backend4Value{} }
   411  
   412  func (b *Backend4Value) GetAddress() net.IP { return b.Address.IP() }
   413  func (b *Backend4Value) GetIPCluster() cmtypes.AddrCluster {
   414  	return cmtypes.AddrClusterFrom(b.Address.Addr(), 0)
   415  }
   416  func (b *Backend4Value) GetPort() uint16 { return b.Port }
   417  func (b *Backend4Value) GetFlags() uint8 { return b.Flags }
   418  func (b *Backend4Value) GetZone() uint8  { return 0 }
   419  
   420  func (v *Backend4Value) ToNetwork() BackendValue {
   421  	n := *v
   422  	n.Port = byteorder.HostToNetwork16(n.Port)
   423  	return &n
   424  }
   425  
   426  // ToHost converts Backend4Value to host byte order.
   427  func (v *Backend4Value) ToHost() BackendValue {
   428  	h := *v
   429  	h.Port = byteorder.NetworkToHost16(h.Port)
   430  	return &h
   431  }
   432  
   433  type Backend4ValueV3 struct {
   434  	Address   types.IPv4      `align:"address"`
   435  	Port      uint16          `align:"port"`
   436  	Proto     u8proto.U8proto `align:"proto"`
   437  	Flags     uint8           `align:"flags"`
   438  	ClusterID uint16          `align:"cluster_id"`
   439  	Zone      uint8           `align:"zone"`
   440  	Pad       uint8           `align:"pad"`
   441  }
   442  
   443  func NewBackend4ValueV3(addrCluster cmtypes.AddrCluster, port uint16, proto u8proto.U8proto, state loadbalancer.BackendState, zone uint8) (*Backend4ValueV3, error) {
   444  	addr := addrCluster.Addr()
   445  	if !addr.Is4() {
   446  		return nil, fmt.Errorf("Not an IPv4 address")
   447  	}
   448  
   449  	clusterID := addrCluster.ClusterID()
   450  	if addrCluster.ClusterID() > cmtypes.ClusterIDMax {
   451  		return nil, fmt.Errorf("ClusterID %d is too large. ClusterID > %d is not supported with Backend4ValueV3", clusterID, cmtypes.ClusterIDMax)
   452  	}
   453  
   454  	flags := loadbalancer.NewBackendFlags(state)
   455  
   456  	val := Backend4ValueV3{
   457  		Port:      port,
   458  		Proto:     proto,
   459  		Flags:     flags,
   460  		ClusterID: uint16(clusterID),
   461  		Zone:      zone,
   462  	}
   463  
   464  	ip4Array := addr.As4()
   465  	copy(val.Address[:], ip4Array[:])
   466  
   467  	return &val, nil
   468  }
   469  
   470  func (v *Backend4ValueV3) String() string {
   471  	vHost := v.ToHost().(*Backend4ValueV3)
   472  	if v.Zone != 0 {
   473  		return fmt.Sprintf("%s://%s[%s]", vHost.Proto, cmtypes.AddrClusterFrom(vHost.Address.Addr(), uint32(vHost.ClusterID)).String(), option.Config.GetZone(v.Zone))
   474  	}
   475  	return fmt.Sprintf("%s://%s", vHost.Proto, cmtypes.AddrClusterFrom(vHost.Address.Addr(), uint32(vHost.ClusterID)).String())
   476  }
   477  
   478  func (b *Backend4ValueV3) New() bpf.MapValue { return &Backend4ValueV3{} }
   479  
   480  func (b *Backend4ValueV3) GetAddress() net.IP { return b.Address.IP() }
   481  func (b *Backend4ValueV3) GetIPCluster() cmtypes.AddrCluster {
   482  	return cmtypes.AddrClusterFrom(b.Address.Addr(), uint32(b.ClusterID))
   483  }
   484  func (b *Backend4ValueV3) GetPort() uint16 { return b.Port }
   485  func (b *Backend4ValueV3) GetFlags() uint8 { return b.Flags }
   486  func (b *Backend4ValueV3) GetZone() uint8  { return b.Zone }
   487  
   488  func (v *Backend4ValueV3) ToNetwork() BackendValue {
   489  	n := *v
   490  	n.Port = byteorder.HostToNetwork16(n.Port)
   491  	return &n
   492  }
   493  
   494  // ToHost converts Backend4Value to host byte order.
   495  func (v *Backend4ValueV3) ToHost() BackendValue {
   496  	h := *v
   497  	h.Port = byteorder.NetworkToHost16(h.Port)
   498  	return &h
   499  }
   500  
   501  type Backend4V3 struct {
   502  	Key   *Backend4KeyV3
   503  	Value *Backend4ValueV3
   504  }
   505  
   506  func NewBackend4V3(id loadbalancer.BackendID, addrCluster cmtypes.AddrCluster, port uint16,
   507  	proto u8proto.U8proto, state loadbalancer.BackendState, zone uint8) (*Backend4V3, error) {
   508  	val, err := NewBackend4ValueV3(addrCluster, port, proto, state, zone)
   509  	if err != nil {
   510  		return nil, err
   511  	}
   512  
   513  	return &Backend4V3{
   514  		Key:   NewBackend4KeyV3(id),
   515  		Value: val,
   516  	}, nil
   517  }
   518  
   519  func (b *Backend4V3) Map() *bpf.Map          { return Backend4MapV3 }
   520  func (b *Backend4V3) GetKey() BackendKey     { return b.Key }
   521  func (b *Backend4V3) GetValue() BackendValue { return b.Value }
   522  
   523  type Backend4V2 struct {
   524  	Key   *Backend4KeyV3
   525  	Value *Backend4Value
   526  }
   527  
   528  func NewBackend4V2(id loadbalancer.BackendID, ip net.IP, port uint16, proto u8proto.U8proto,
   529  	state loadbalancer.BackendState) (*Backend4V2, error) {
   530  	val, err := NewBackend4Value(ip, port, proto, state)
   531  	if err != nil {
   532  		return nil, err
   533  	}
   534  
   535  	return &Backend4V2{
   536  		Key:   NewBackend4KeyV3(id),
   537  		Value: val,
   538  	}, nil
   539  }
   540  
   541  func (b *Backend4V2) Map() *bpf.Map          { return Backend4MapV2 }
   542  func (b *Backend4V2) GetKey() BackendKey     { return b.Key }
   543  func (b *Backend4V2) GetValue() BackendValue { return b.Value }
   544  
   545  type Backend4 struct {
   546  	Key   *Backend4Key
   547  	Value *Backend4Value
   548  }
   549  
   550  func (b *Backend4) Map() *bpf.Map          { return Backend4Map }
   551  func (b *Backend4) GetKey() BackendKey     { return b.Key }
   552  func (b *Backend4) GetValue() BackendValue { return b.Value }
   553  
   554  // SockRevNat4Key is the tuple with address, port and cookie used as key in
   555  // the reverse NAT sock map.
   556  type SockRevNat4Key struct {
   557  	Cookie  uint64     `align:"cookie"`
   558  	Address types.IPv4 `align:"address"`
   559  	Port    int16      `align:"port"`
   560  	_       int16
   561  }
   562  
   563  // SockRevNat4Value is an entry in the reverse NAT sock map.
   564  type SockRevNat4Value struct {
   565  	Address     types.IPv4 `align:"address"`
   566  	Port        int16      `align:"port"`
   567  	RevNatIndex uint16     `align:"rev_nat_index"`
   568  }
   569  
   570  func (k *SockRevNat4Key) Map() *bpf.Map { return SockRevNat4Map }
   571  
   572  func NewSockRevNat4Key(cookie uint64, addr net.IP, port uint16) *SockRevNat4Key {
   573  	var key SockRevNat4Key
   574  	key.Cookie = cookie
   575  	key.Port = int16(byteorder.NetworkToHost16(port))
   576  	copy(key.Address[:], addr.To4())
   577  
   578  	return &key
   579  }
   580  
   581  // String converts the key into a human readable string format.
   582  func (k *SockRevNat4Key) String() string {
   583  	return fmt.Sprintf("[%s]:%d, %d", k.Address, k.Port, k.Cookie)
   584  }
   585  
   586  func (k *SockRevNat4Key) New() bpf.MapKey { return &SockRevNat4Key{} }
   587  
   588  // String converts the value into a human readable string format.
   589  func (v *SockRevNat4Value) String() string {
   590  	return fmt.Sprintf("[%s]:%d, %d", v.Address, v.Port, v.RevNatIndex)
   591  }
   592  
   593  func (v *SockRevNat4Value) New() bpf.MapValue { return &SockRevNat4Value{} }
   594  
   595  // CreateSockRevNat4Map creates the reverse NAT sock map.
   596  func CreateSockRevNat4Map() error {
   597  	SockRevNat4Map = bpf.NewMap(SockRevNat4MapName,
   598  		ebpf.LRUHash,
   599  		&SockRevNat4Key{},
   600  		&SockRevNat4Value{},
   601  		MaxSockRevNat4MapEntries,
   602  		0,
   603  	).WithPressureMetric()
   604  	return SockRevNat4Map.OpenOrCreate()
   605  }