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 }