github.com/looshlee/beatles@v0.0.0-20220727174639-742810ab631c/pkg/maps/lbmap/ipv4.go (about) 1 // Copyright 2016-2019 Authors of Cilium 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package lbmap 16 17 import ( 18 "fmt" 19 "net" 20 "unsafe" 21 22 "github.com/cilium/cilium/common/types" 23 "github.com/cilium/cilium/pkg/bpf" 24 "github.com/cilium/cilium/pkg/byteorder" 25 "github.com/cilium/cilium/pkg/loadbalancer" 26 "github.com/cilium/cilium/pkg/u8proto" 27 ) 28 29 var ( 30 Service4Map = bpf.NewMap("cilium_lb4_services", 31 bpf.MapTypeHash, 32 &Service4Key{}, 33 int(unsafe.Sizeof(Service4Key{})), 34 &Service4Value{}, 35 int(unsafe.Sizeof(Service4Value{})), 36 MaxEntries, 37 0, 0, 38 func(key []byte, value []byte, mapKey bpf.MapKey, mapValue bpf.MapValue) (bpf.MapKey, bpf.MapValue, error) { 39 svcKey, svcVal := mapKey.(*Service4Key), mapValue.(*Service4Value) 40 41 if _, _, err := bpf.ConvertKeyValue(key, value, svcKey, svcVal); err != nil { 42 return nil, nil, err 43 } 44 45 return svcKey.ToNetwork(), svcVal.ToNetwork(), nil 46 }).WithCache() 47 Service4MapV2 = bpf.NewMap("cilium_lb4_services_v2", 48 bpf.MapTypeHash, 49 &Service4KeyV2{}, 50 int(unsafe.Sizeof(Service4KeyV2{})), 51 &Service4ValueV2{}, 52 int(unsafe.Sizeof(Service4ValueV2{})), 53 MaxEntries, 54 0, 0, 55 func(key []byte, value []byte, mapKey bpf.MapKey, mapValue bpf.MapValue) (bpf.MapKey, bpf.MapValue, error) { 56 svcKey, svcVal := mapKey.(*Service4KeyV2), mapValue.(*Service4ValueV2) 57 58 if _, _, err := bpf.ConvertKeyValue(key, value, svcKey, svcVal); err != nil { 59 return nil, nil, err 60 } 61 62 return svcKey.ToNetwork(), svcVal.ToNetwork(), nil 63 }).WithCache() 64 Backend4Map = bpf.NewMap("cilium_lb4_backends", 65 bpf.MapTypeHash, 66 &Backend4Key{}, 67 int(unsafe.Sizeof(Backend4Key{})), 68 &Backend4Value{}, 69 int(unsafe.Sizeof(Backend4Value{})), 70 MaxEntries, 71 0, 0, 72 func(key []byte, value []byte, mapKey bpf.MapKey, mapValue bpf.MapValue) (bpf.MapKey, bpf.MapValue, error) { 73 backendVal := mapValue.(*Backend4Value) 74 75 if _, _, err := bpf.ConvertKeyValue(key, value, mapKey, backendVal); err != nil { 76 return nil, nil, err 77 } 78 79 return mapKey, backendVal.ToNetwork(), nil 80 }).WithCache() 81 RevNat4Map = bpf.NewMap("cilium_lb4_reverse_nat", 82 bpf.MapTypeHash, 83 &RevNat4Key{}, 84 int(unsafe.Sizeof(RevNat4Key{})), 85 &RevNat4Value{}, 86 int(unsafe.Sizeof(RevNat4Value{})), 87 MaxEntries, 88 0, 0, 89 func(key []byte, value []byte, mapKey bpf.MapKey, mapValue bpf.MapValue) (bpf.MapKey, bpf.MapValue, error) { 90 revKey, revNat := mapKey.(*RevNat4Key), mapValue.(*RevNat4Value) 91 92 if _, _, err := bpf.ConvertKeyValue(key, value, revKey, revNat); err != nil { 93 return nil, nil, err 94 } 95 96 return revKey.ToNetwork(), revNat.ToNetwork(), nil 97 }).WithCache() 98 RRSeq4Map = bpf.NewMap("cilium_lb4_rr_seq", 99 bpf.MapTypeHash, 100 &Service4Key{}, 101 int(unsafe.Sizeof(Service4Key{})), 102 &RRSeqValue{}, 103 int(unsafe.Sizeof(RRSeqValue{})), 104 maxFrontEnds, 105 0, 0, 106 func(key []byte, value []byte, mapKey bpf.MapKey, mapValue bpf.MapValue) (bpf.MapKey, bpf.MapValue, error) { 107 svcKey := mapKey.(*Service4Key) 108 109 if _, _, err := bpf.ConvertKeyValue(key, value, svcKey, mapValue); err != nil { 110 return nil, nil, err 111 } 112 113 return svcKey.ToNetwork(), mapValue, nil 114 }).WithCache() 115 RRSeq4MapV2 = bpf.NewMap("cilium_lb4_rr_seq_v2", 116 bpf.MapTypeHash, 117 &Service4KeyV2{}, 118 int(unsafe.Sizeof(Service4KeyV2{})), 119 &RRSeqValue{}, 120 int(unsafe.Sizeof(RRSeqValue{})), 121 maxFrontEnds, 122 0, 0, 123 func(key []byte, value []byte, mapKey bpf.MapKey, mapValue bpf.MapValue) (bpf.MapKey, bpf.MapValue, error) { 124 svcKey := mapKey.(*Service4KeyV2) 125 126 if _, _, err := bpf.ConvertKeyValue(key, value, svcKey, mapValue); err != nil { 127 return nil, nil, err 128 } 129 130 return svcKey.ToNetwork(), mapValue, nil 131 }).WithCache() 132 ) 133 134 // Service4Key must match 'struct lb4_key' in "bpf/lib/common.h". 135 // +k8s:deepcopy-gen=true 136 // +k8s:deepcopy-gen:interfaces=github.com/cilium/cilium/pkg/bpf.MapKey 137 type Service4Key struct { 138 Address types.IPv4 `align:"address"` 139 Port uint16 `align:"dport"` 140 Slave uint16 `align:"slave"` 141 } 142 143 func (k Service4Key) IsIPv6() bool { return false } 144 func (k Service4Key) Map() *bpf.Map { return Service4Map } 145 func (k Service4Key) RRMap() *bpf.Map { return RRSeq4Map } 146 func (k Service4Key) NewValue() bpf.MapValue { return &Service4Value{} } 147 func (k *Service4Key) GetKeyPtr() unsafe.Pointer { return unsafe.Pointer(k) } 148 func (k *Service4Key) GetPort() uint16 { return k.Port } 149 func (k *Service4Key) SetPort(port uint16) { k.Port = port } 150 func (k *Service4Key) SetBackend(backend int) { k.Slave = uint16(backend) } 151 func (k *Service4Key) GetBackend() int { return int(k.Slave) } 152 153 func (k *Service4Key) String() string { 154 return fmt.Sprintf("%s:%d", k.Address, k.Port) 155 } 156 157 // ToNetwork converts Service4Key port to network byte order. 158 func (k *Service4Key) ToNetwork() ServiceKey { 159 n := *k 160 n.Port = byteorder.HostToNetwork(n.Port).(uint16) 161 return &n 162 } 163 164 // ToHost converts Service4Key port to network byte order. 165 func (k *Service4Key) ToHost() ServiceKey { 166 n := *k 167 n.Port = byteorder.NetworkToHost(n.Port).(uint16) 168 return &n 169 } 170 171 func (k *Service4Key) MapDelete() error { 172 return k.Map().Delete(k) 173 } 174 175 func NewService4Key(ip net.IP, port uint16, slave uint16) *Service4Key { 176 key := Service4Key{ 177 Port: port, 178 Slave: slave, 179 } 180 181 copy(key.Address[:], ip.To4()) 182 183 return &key 184 } 185 186 func (k *Service4Key) RevNatValue() RevNatValue { 187 return &RevNat4Value{ 188 Address: k.Address, 189 Port: k.Port, 190 } 191 } 192 193 // Service4Value must match 'struct lb4_service' in "bpf/lib/common.h". 194 // +k8s:deepcopy-gen=true 195 // +k8s:deepcopy-gen:interfaces=github.com/cilium/cilium/pkg/bpf.MapValue 196 type Service4Value struct { 197 Address types.IPv4 `align:"target"` 198 Port uint16 `align:"port"` 199 Count uint16 `align:"count"` 200 RevNat uint16 `align:"rev_nat_index"` 201 Weight uint16 `align:"weight"` 202 } 203 204 func NewService4Value(count uint16, target net.IP, port uint16, revNat uint16, weight uint16) *Service4Value { 205 svc := Service4Value{ 206 Count: count, 207 RevNat: revNat, 208 Port: port, 209 Weight: weight, 210 } 211 212 copy(svc.Address[:], target.To4()) 213 214 return &svc 215 } 216 217 func (s *Service4Value) GetValuePtr() unsafe.Pointer { return unsafe.Pointer(s) } 218 func (s *Service4Value) SetPort(port uint16) { s.Port = port } 219 func (s *Service4Value) GetPort() uint16 { return s.Port } 220 func (s *Service4Value) SetCount(count int) { s.Count = uint16(count) } 221 func (s *Service4Value) GetCount() int { return int(s.Count) } 222 func (s *Service4Value) SetRevNat(id int) { s.RevNat = uint16(id) } 223 func (s *Service4Value) SetWeight(weight uint16) { s.Weight = weight } 224 func (s *Service4Value) GetWeight() uint16 { return s.Weight } 225 func (s *Service4Value) IsIPv6() bool { return false } 226 227 func (s *Service4Value) SetAddress(ip net.IP) error { 228 ip4 := ip.To4() 229 if ip4 == nil { 230 return fmt.Errorf("Not an IPv4 address") 231 } 232 copy(s.Address[:], ip4) 233 return nil 234 } 235 236 func (s *Service4Value) GetAddress() net.IP { 237 return s.Address.IP() 238 } 239 240 // ToNetwork converts Service4Value to network byte order. 241 func (s *Service4Value) ToNetwork() ServiceValue { 242 n := *s 243 n.RevNat = byteorder.HostToNetwork(n.RevNat).(uint16) 244 n.Port = byteorder.HostToNetwork(n.Port).(uint16) 245 n.Weight = byteorder.HostToNetwork(n.Weight).(uint16) 246 return &n 247 } 248 249 // ToHost converts Service4Value to host byte order. 250 func (s *Service4Value) ToHost() ServiceValue { 251 n := *s 252 n.RevNat = byteorder.NetworkToHost(n.RevNat).(uint16) 253 n.Port = byteorder.NetworkToHost(n.Port).(uint16) 254 n.Weight = byteorder.NetworkToHost(n.Weight).(uint16) 255 return &n 256 } 257 258 func (s *Service4Value) RevNatKey() RevNatKey { 259 return &RevNat4Key{s.RevNat} 260 } 261 262 func (s *Service4Value) String() string { 263 return fmt.Sprintf("%s:%d (%d)", s.Address, s.Port, s.RevNat) 264 } 265 266 func (s *Service4Value) BackendAddrID() BackendAddrID { 267 return BackendAddrID(fmt.Sprintf("%s:%d", s.Address, s.Port)) 268 } 269 270 // +k8s:deepcopy-gen=true 271 // +k8s:deepcopy-gen:interfaces=github.com/cilium/cilium/pkg/bpf.MapKey 272 type RevNat4Key struct { 273 Key uint16 274 } 275 276 func NewRevNat4Key(value uint16) *RevNat4Key { 277 return &RevNat4Key{value} 278 } 279 280 func (k *RevNat4Key) IsIPv6() bool { return false } 281 func (k *RevNat4Key) Map() *bpf.Map { return RevNat4Map } 282 func (k *RevNat4Key) NewValue() bpf.MapValue { return &RevNat4Value{} } 283 func (k *RevNat4Key) GetKeyPtr() unsafe.Pointer { return unsafe.Pointer(k) } 284 func (k *RevNat4Key) String() string { return fmt.Sprintf("%d", k.Key) } 285 func (k *RevNat4Key) GetKey() uint16 { return k.Key } 286 287 // ToNetwork converts RevNat4Key to network byte order. 288 func (k *RevNat4Key) ToNetwork() RevNatKey { 289 n := *k 290 n.Key = byteorder.HostToNetwork(n.Key).(uint16) 291 return &n 292 } 293 294 // +k8s:deepcopy-gen=true 295 // +k8s:deepcopy-gen:interfaces=github.com/cilium/cilium/pkg/bpf.MapValue 296 type RevNat4Value struct { 297 Address types.IPv4 298 Port uint16 299 } 300 301 func (v *RevNat4Value) GetValuePtr() unsafe.Pointer { return unsafe.Pointer(v) } 302 303 // ToNetwork converts RevNat4Value to network byte order. 304 func (v *RevNat4Value) ToNetwork() RevNatValue { 305 n := *v 306 n.Port = byteorder.HostToNetwork(n.Port).(uint16) 307 return &n 308 } 309 310 func (v *RevNat4Value) String() string { 311 return fmt.Sprintf("%s:%d", v.Address, v.Port) 312 } 313 314 func NewRevNat4Value(ip net.IP, port uint16) *RevNat4Value { 315 revNat := RevNat4Value{ 316 Port: port, 317 } 318 319 copy(revNat.Address[:], ip.To4()) 320 321 return &revNat 322 } 323 324 type pad3uint8 [3]uint8 325 326 // DeepCopyInto is a deepcopy function, copying the receiver, writing into out. in must be non-nil. 327 func (in *pad3uint8) DeepCopyInto(out *pad3uint8) { 328 copy(out[:], in[:]) 329 return 330 } 331 332 // Service4KeyV2 must match 'struct lb4_key_v2' in "bpf/lib/common.h". 333 // +k8s:deepcopy-gen=true 334 // +k8s:deepcopy-gen:interfaces=github.com/cilium/cilium/pkg/bpf.MapKey 335 type Service4KeyV2 struct { 336 Address types.IPv4 `align:"address"` 337 Port uint16 `align:"dport"` 338 Slave uint16 `align:"slave"` 339 Proto uint8 `align:"proto"` 340 Pad pad3uint8 341 } 342 343 func NewService4KeyV2(ip net.IP, port uint16, proto u8proto.U8proto, slave uint16) *Service4KeyV2 { 344 key := Service4KeyV2{ 345 Port: port, 346 Proto: uint8(proto), 347 Slave: slave, 348 } 349 350 copy(key.Address[:], ip.To4()) 351 352 return &key 353 } 354 355 func (k *Service4KeyV2) String() string { 356 return fmt.Sprintf("%s:%d", k.Address, k.Port) 357 } 358 359 func (k *Service4KeyV2) GetKeyPtr() unsafe.Pointer { return unsafe.Pointer(k) } 360 func (k *Service4KeyV2) NewValue() bpf.MapValue { return &Service4ValueV2{} } 361 func (k *Service4KeyV2) IsIPv6() bool { return false } 362 func (k *Service4KeyV2) Map() *bpf.Map { return Service4MapV2 } 363 func (k *Service4KeyV2) RRMap() *bpf.Map { return RRSeq4MapV2 } 364 func (k *Service4KeyV2) SetSlave(slave int) { k.Slave = uint16(slave) } 365 func (k *Service4KeyV2) GetSlave() int { return int(k.Slave) } 366 func (k *Service4KeyV2) GetAddress() net.IP { return k.Address.IP() } 367 func (k *Service4KeyV2) GetPort() uint16 { return k.Port } 368 func (k *Service4KeyV2) MapDelete() error { return k.Map().Delete(k.ToNetwork()) } 369 370 func (k *Service4KeyV2) ToNetwork() ServiceKeyV2 { 371 n := *k 372 n.Port = byteorder.HostToNetwork(n.Port).(uint16) 373 return &n 374 } 375 376 // Service4ValueV2 must match 'struct lb4_service_v2' in "bpf/lib/common.h". 377 // +k8s:deepcopy-gen=true 378 // +k8s:deepcopy-gen:interfaces=github.com/cilium/cilium/pkg/bpf.MapValue 379 type Service4ValueV2 struct { 380 BackendID uint32 `align:"backend_id"` 381 Count uint16 `align:"count"` 382 RevNat uint16 `align:"rev_nat_index"` 383 Weight uint16 `align:"weight"` 384 Pad uint16 385 } 386 387 func NewService4ValueV2(count uint16, backendID loadbalancer.BackendID, revNat uint16, weight uint16) *Service4ValueV2 { 388 svc := Service4ValueV2{ 389 BackendID: uint32(backendID), 390 Count: count, 391 RevNat: revNat, 392 Weight: weight, 393 } 394 395 return &svc 396 } 397 398 func (s *Service4ValueV2) String() string { 399 return fmt.Sprintf("%d (%d)", s.BackendID, s.RevNat) 400 } 401 402 func (s *Service4ValueV2) GetValuePtr() unsafe.Pointer { return unsafe.Pointer(s) } 403 404 func (s *Service4ValueV2) SetCount(count int) { s.Count = uint16(count) } 405 func (s *Service4ValueV2) GetCount() int { return int(s.Count) } 406 func (s *Service4ValueV2) SetRevNat(id int) { s.RevNat = uint16(id) } 407 func (s *Service4ValueV2) GetRevNat() int { return int(s.RevNat) } 408 func (s *Service4ValueV2) SetWeight(weight uint16) { s.Weight = weight } 409 func (s *Service4ValueV2) GetWeight() uint16 { return s.Weight } 410 func (s *Service4ValueV2) RevNatKey() RevNatKey { return &RevNat4Key{s.RevNat} } 411 412 func (s *Service4ValueV2) SetBackendID(id loadbalancer.BackendID) { 413 s.BackendID = uint32(id) 414 } 415 func (s *Service4ValueV2) GetBackendID() loadbalancer.BackendID { 416 return loadbalancer.BackendID(s.BackendID) 417 } 418 419 func (s *Service4ValueV2) ToNetwork() ServiceValueV2 { 420 n := *s 421 n.RevNat = byteorder.HostToNetwork(n.RevNat).(uint16) 422 n.Weight = byteorder.HostToNetwork(n.Weight).(uint16) 423 return &n 424 } 425 426 // +k8s:deepcopy-gen=true 427 // +k8s:deepcopy-gen:interfaces=github.com/cilium/cilium/pkg/bpf.MapKey 428 type Backend4Key struct { 429 ID loadbalancer.BackendID 430 } 431 432 func NewBackend4Key(id loadbalancer.BackendID) *Backend4Key { 433 return &Backend4Key{ID: id} 434 } 435 436 func (k *Backend4Key) String() string { return fmt.Sprintf("%d", k.ID) } 437 func (k *Backend4Key) GetKeyPtr() unsafe.Pointer { return unsafe.Pointer(k) } 438 func (k *Backend4Key) NewValue() bpf.MapValue { return &Backend4Value{} } 439 func (k *Backend4Key) Map() *bpf.Map { return Backend4Map } 440 func (k *Backend4Key) SetID(id loadbalancer.BackendID) { k.ID = id } 441 func (k *Backend4Key) GetID() loadbalancer.BackendID { return k.ID } 442 443 // Backend4Value must match 'struct lb4_backend' in "bpf/lib/common.h". 444 // +k8s:deepcopy-gen=true 445 // +k8s:deepcopy-gen:interfaces=github.com/cilium/cilium/pkg/bpf.MapValue 446 type Backend4Value struct { 447 Address types.IPv4 `align:"address"` 448 Port uint16 `align:"port"` 449 Proto u8proto.U8proto `align:"proto"` 450 Pad uint8 451 } 452 453 func NewBackend4Value(ip net.IP, port uint16, proto u8proto.U8proto) (*Backend4Value, error) { 454 ip4 := ip.To4() 455 if ip4 == nil { 456 return nil, fmt.Errorf("Not an IPv4 address") 457 } 458 459 val := Backend4Value{ 460 Port: port, 461 Proto: proto, 462 } 463 copy(val.Address[:], ip.To4()) 464 465 return &val, nil 466 } 467 468 func (v *Backend4Value) String() string { 469 return fmt.Sprintf("%s://%s:%d", v.Proto, v.Address, v.Port) 470 } 471 472 func (v *Backend4Value) GetValuePtr() unsafe.Pointer { return unsafe.Pointer(v) } 473 474 func (b *Backend4Value) GetAddress() net.IP { return b.Address.IP() } 475 func (b *Backend4Value) GetPort() uint16 { return b.Port } 476 477 func (b *Backend4Value) BackendAddrID() BackendAddrID { 478 return BackendAddrID(fmt.Sprintf("%s:%d", b.Address, b.Port)) 479 } 480 481 func (v *Backend4Value) ToNetwork() BackendValue { 482 n := *v 483 n.Port = byteorder.HostToNetwork(n.Port).(uint16) 484 return &n 485 } 486 487 type Backend4 struct { 488 Key *Backend4Key 489 Value *Backend4Value 490 } 491 492 func NewBackend4(id loadbalancer.BackendID, ip net.IP, port uint16, proto u8proto.U8proto) (*Backend4, error) { 493 val, err := NewBackend4Value(ip, port, proto) 494 if err != nil { 495 return nil, err 496 } 497 498 return &Backend4{ 499 Key: NewBackend4Key(id), 500 Value: val, 501 }, nil 502 } 503 504 func (b *Backend4) IsIPv6() bool { return false } 505 func (b *Backend4) Map() *bpf.Map { return Backend4Map } 506 func (b *Backend4) GetID() loadbalancer.BackendID { return b.Key.GetID() } 507 func (b *Backend4) GetKey() BackendKey { return b.Key } 508 func (b *Backend4) GetValue() BackendValue { return b.Value }