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

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package lbmap
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/cilium/ebpf"
    10  
    11  	"github.com/cilium/cilium/pkg/bpf"
    12  	"github.com/cilium/cilium/pkg/byteorder"
    13  	"github.com/cilium/cilium/pkg/loadbalancer"
    14  	"github.com/cilium/cilium/pkg/option"
    15  	"github.com/cilium/cilium/pkg/types"
    16  )
    17  
    18  const (
    19  	AffinityMatchMapName = "cilium_lb_affinity_match"
    20  	Affinity4MapName     = "cilium_lb4_affinity"
    21  	Affinity6MapName     = "cilium_lb6_affinity"
    22  )
    23  
    24  var (
    25  	// AffinityMatchMap is the BPF map to implement session affinity.
    26  	AffinityMatchMap *bpf.Map
    27  	Affinity4Map     *bpf.Map
    28  	Affinity6Map     *bpf.Map
    29  )
    30  
    31  // initAffinity creates the BPF maps for implementing session affinity.
    32  func initAffinity(params InitParams) {
    33  	AffinityMapMaxEntries = params.AffinityMapMaxEntries
    34  
    35  	AffinityMatchMap = bpf.NewMap(
    36  		AffinityMatchMapName,
    37  		ebpf.Hash,
    38  		&AffinityMatchKey{},
    39  		&AffinityMatchValue{},
    40  		AffinityMapMaxEntries,
    41  		0,
    42  	).WithCache().WithPressureMetric().
    43  		WithEvents(option.Config.GetEventBufferConfig(AffinityMatchMapName))
    44  
    45  	if params.IPv4 {
    46  		Affinity4Map = bpf.NewMap(
    47  			Affinity4MapName,
    48  			ebpf.LRUHash,
    49  			&Affinity4Key{},
    50  			&AffinityValue{},
    51  			AffinityMapMaxEntries,
    52  			0,
    53  		)
    54  	}
    55  
    56  	if params.IPv6 {
    57  		Affinity6Map = bpf.NewMap(
    58  			Affinity6MapName,
    59  			ebpf.LRUHash,
    60  			&Affinity6Key{},
    61  			&AffinityValue{},
    62  			AffinityMapMaxEntries,
    63  			0,
    64  		)
    65  	}
    66  }
    67  
    68  type AffinityMatchKey struct {
    69  	BackendID loadbalancer.BackendID `align:"backend_id"`
    70  	RevNATID  uint16                 `align:"rev_nat_id"`
    71  	Pad       uint16                 `align:"pad"`
    72  }
    73  
    74  type AffinityMatchValue struct {
    75  	Pad uint8 `align:"pad"`
    76  }
    77  
    78  // NewAffinityMatchKey creates the AffinityMatch key
    79  func NewAffinityMatchKey(revNATID uint16, backendID loadbalancer.BackendID) *AffinityMatchKey {
    80  	return &AffinityMatchKey{
    81  		BackendID: backendID,
    82  		RevNATID:  revNATID,
    83  	}
    84  }
    85  
    86  // String converts the key into a human readable string format
    87  func (k *AffinityMatchKey) String() string {
    88  	kHost := k.ToHost()
    89  	return fmt.Sprintf("%d %d", kHost.BackendID, kHost.RevNATID)
    90  }
    91  
    92  func (k *AffinityMatchKey) New() bpf.MapKey { return &AffinityMatchKey{} }
    93  
    94  // String converts the value into a human readable string format
    95  func (v *AffinityMatchValue) String() string    { return "" }
    96  func (v *AffinityMatchValue) New() bpf.MapValue { return &AffinityMatchValue{} }
    97  
    98  // ToNetwork returns the key in the network byte order
    99  func (k *AffinityMatchKey) ToNetwork() *AffinityMatchKey {
   100  	n := *k
   101  	// For some reasons rev_nat_index is stored in network byte order in
   102  	// the SVC BPF maps
   103  	n.RevNATID = byteorder.HostToNetwork16(n.RevNATID)
   104  	return &n
   105  }
   106  
   107  // ToHost returns the key in the host byte order
   108  func (k *AffinityMatchKey) ToHost() *AffinityMatchKey {
   109  	h := *k
   110  	h.RevNATID = byteorder.NetworkToHost16(h.RevNATID)
   111  	return &h
   112  }
   113  
   114  // Affinity4Key is the Go representation of lb4_affinity_key
   115  type Affinity4Key struct {
   116  	ClientID    uint64 `align:"client_id"`
   117  	RevNATID    uint16 `align:"rev_nat_id"`
   118  	NetNSCookie uint8  `align:"netns_cookie"`
   119  	Pad1        uint8  `align:"pad1"`
   120  	Pad2        uint32 `align:"pad2"`
   121  }
   122  
   123  // Affinity6Key is the Go representation of lb6_affinity_key
   124  type Affinity6Key struct {
   125  	ClientID    types.IPv6 `align:"client_id"`
   126  	RevNATID    uint16     `align:"rev_nat_id"`
   127  	NetNSCookie uint8      `align:"netns_cookie"`
   128  	Pad1        uint8      `align:"pad1"`
   129  	Pad2        uint32     `align:"pad2"`
   130  }
   131  
   132  // AffinityValue is the Go representing of lb_affinity_value
   133  type AffinityValue struct {
   134  	LastUsed  uint64 `align:"last_used"`
   135  	BackendID uint32 `align:"backend_id"`
   136  	Pad       uint32 `align:"pad"`
   137  }
   138  
   139  // String converts the key into a human readable string format.
   140  func (k *Affinity4Key) String() string {
   141  	return fmt.Sprintf("%d %d %d", k.ClientID, k.NetNSCookie, k.RevNATID)
   142  }
   143  
   144  func (k *Affinity4Key) New() bpf.MapKey { return &Affinity4Key{} }
   145  
   146  // String converts the key into a human readable string format.
   147  func (k *Affinity6Key) String() string {
   148  	return fmt.Sprintf("%d %d %d", k.ClientID, k.NetNSCookie, k.RevNATID)
   149  }
   150  
   151  func (k *Affinity6Key) New() bpf.MapKey { return &Affinity6Key{} }
   152  
   153  // String converts the value into a human readable string format.
   154  func (v *AffinityValue) String() string    { return fmt.Sprintf("%d %d", v.BackendID, v.LastUsed) }
   155  func (v *AffinityValue) New() bpf.MapValue { return &AffinityValue{} }