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{} }