github.com/cilium/cilium@v1.16.2/pkg/maps/lbmap/source_range.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/cilium/pkg/bpf"
    11  	"github.com/cilium/cilium/pkg/byteorder"
    12  	"github.com/cilium/cilium/pkg/cidr"
    13  	"github.com/cilium/cilium/pkg/ebpf"
    14  	"github.com/cilium/cilium/pkg/option"
    15  	"github.com/cilium/cilium/pkg/types"
    16  )
    17  
    18  const (
    19  	SourceRange4MapName = "cilium_lb4_source_range"
    20  	SourceRange6MapName = "cilium_lb6_source_range"
    21  	lpmPrefixLen4       = 16 + 16 // sizeof(SourceRangeKey4.RevNATID)+sizeof(SourceRangeKey4.Pad)
    22  	lpmPrefixLen6       = 16 + 16 // sizeof(SourceRangeKey6.RevNATID)+sizeof(SourceRangeKey6.Pad)
    23  )
    24  
    25  type SourceRangeKey interface {
    26  	GetCIDR() *cidr.CIDR
    27  	GetRevNATID() uint16
    28  
    29  	// Convert fields to network byte order.
    30  	ToNetwork() SourceRangeKey
    31  
    32  	// ToHost converts fields to host byte order.
    33  	ToHost() SourceRangeKey
    34  }
    35  
    36  // The compile-time check for whether the structs implement the interface
    37  var _ SourceRangeKey = (*SourceRangeKey4)(nil)
    38  var _ SourceRangeKey = (*SourceRangeKey6)(nil)
    39  
    40  type SourceRangeKey4 struct {
    41  	PrefixLen uint32     `align:"lpm_key"`
    42  	RevNATID  uint16     `align:"rev_nat_id"`
    43  	Pad       uint16     `align:"pad"`
    44  	Address   types.IPv4 `align:"addr"`
    45  }
    46  
    47  func (k *SourceRangeKey4) String() string {
    48  	kHost := k.ToHost().(*SourceRangeKey4)
    49  	return fmt.Sprintf("%s (%d)", kHost.GetCIDR().String(), kHost.GetRevNATID())
    50  }
    51  
    52  func (k *SourceRangeKey4) New() bpf.MapKey { return &SourceRangeKey4{} }
    53  
    54  func (k *SourceRangeKey4) ToNetwork() SourceRangeKey {
    55  	n := *k
    56  	// For some reasons rev_nat_index is stored in network byte order in
    57  	// the SVC BPF maps
    58  	n.RevNATID = byteorder.HostToNetwork16(n.RevNATID)
    59  	return &n
    60  }
    61  
    62  // ToHost returns the key in the host byte order
    63  func (k *SourceRangeKey4) ToHost() SourceRangeKey {
    64  	h := *k
    65  	h.RevNATID = byteorder.NetworkToHost16(h.RevNATID)
    66  	return &h
    67  }
    68  
    69  func (k *SourceRangeKey4) GetCIDR() *cidr.CIDR {
    70  	var (
    71  		c  net.IPNet
    72  		ip types.IPv4
    73  	)
    74  	c.Mask = net.CIDRMask(int(k.PrefixLen)-lpmPrefixLen4, 32)
    75  	k.Address.DeepCopyInto(&ip)
    76  	c.IP = ip.IP()
    77  	return cidr.NewCIDR(&c)
    78  }
    79  func (k *SourceRangeKey4) GetRevNATID() uint16 {
    80  	return k.RevNATID
    81  }
    82  
    83  type SourceRangeKey6 struct {
    84  	PrefixLen uint32     `align:"lpm_key"`
    85  	RevNATID  uint16     `align:"rev_nat_id"`
    86  	Pad       uint16     `align:"pad"`
    87  	Address   types.IPv6 `align:"addr"`
    88  }
    89  
    90  func (k *SourceRangeKey6) String() string {
    91  	kHost := k.ToHost().(*SourceRangeKey6)
    92  	return fmt.Sprintf("%s (%d)", kHost.GetCIDR().String(), kHost.GetRevNATID())
    93  }
    94  
    95  func (k *SourceRangeKey6) New() bpf.MapKey { return &SourceRangeKey6{} }
    96  
    97  func (k *SourceRangeKey6) ToNetwork() SourceRangeKey {
    98  	n := *k
    99  	// For some reasons rev_nat_index is stored in network byte order in
   100  	// the SVC BPF maps
   101  	n.RevNATID = byteorder.HostToNetwork16(n.RevNATID)
   102  	return &n
   103  }
   104  
   105  // ToHost returns the key in the host byte order
   106  func (k *SourceRangeKey6) ToHost() SourceRangeKey {
   107  	h := *k
   108  	h.RevNATID = byteorder.NetworkToHost16(h.RevNATID)
   109  	return &h
   110  }
   111  
   112  func (k *SourceRangeKey6) GetCIDR() *cidr.CIDR {
   113  	var (
   114  		c  net.IPNet
   115  		ip types.IPv6
   116  	)
   117  	c.Mask = net.CIDRMask(int(k.PrefixLen)-lpmPrefixLen6, 128)
   118  	k.Address.DeepCopyInto(&ip)
   119  	c.IP = ip.IP()
   120  	return cidr.NewCIDR(&c)
   121  }
   122  func (k *SourceRangeKey6) GetRevNATID() uint16 {
   123  	return k.RevNATID
   124  }
   125  
   126  type SourceRangeValue struct {
   127  	Pad uint8 // not used
   128  }
   129  
   130  func (v *SourceRangeValue) String() string    { return "" }
   131  func (v *SourceRangeValue) New() bpf.MapValue { return &SourceRangeValue{} }
   132  
   133  var (
   134  	// SourceRange4Map is the BPF map for storing IPv4 service source ranges to
   135  	// check if option.Config.EnableSVCSourceRangeCheck is enabled.
   136  	SourceRange4Map *bpf.Map
   137  	// SourceRange6Map is the BPF map for storing IPv6 service source ranges to
   138  	// check if option.Config.EnableSVCSourceRangeCheck is enabled.
   139  	SourceRange6Map *bpf.Map
   140  )
   141  
   142  // initSourceRange creates the BPF maps for storing both IPv4 and IPv6
   143  // service source ranges.
   144  func initSourceRange(params InitParams) {
   145  	SourceRangeMapMaxEntries = params.SourceRangeMapMaxEntries
   146  
   147  	if params.IPv4 {
   148  		SourceRange4Map = bpf.NewMap(
   149  			SourceRange4MapName,
   150  			ebpf.LPMTrie,
   151  			&SourceRangeKey4{},
   152  			&SourceRangeValue{},
   153  			SourceRangeMapMaxEntries,
   154  			bpf.BPF_F_NO_PREALLOC,
   155  		).WithCache().WithPressureMetric().
   156  			WithEvents(option.Config.GetEventBufferConfig(SourceRange4MapName))
   157  	}
   158  
   159  	if params.IPv6 {
   160  		SourceRange6Map = bpf.NewMap(
   161  			SourceRange6MapName,
   162  			ebpf.LPMTrie,
   163  			&SourceRangeKey6{},
   164  			&SourceRangeValue{},
   165  			SourceRangeMapMaxEntries,
   166  			bpf.BPF_F_NO_PREALLOC,
   167  		).WithCache().WithPressureMetric().
   168  			WithEvents(option.Config.GetEventBufferConfig(SourceRange6MapName))
   169  	}
   170  }
   171  
   172  func srcRangeKey(cidr *cidr.CIDR, revNATID uint16, ipv6 bool) bpf.MapKey {
   173  	ones, _ := cidr.Mask.Size()
   174  	id := byteorder.HostToNetwork16(revNATID)
   175  	if ipv6 {
   176  		key := &SourceRangeKey6{PrefixLen: uint32(ones) + lpmPrefixLen6, RevNATID: id}
   177  		copy(key.Address[:], cidr.IP.To16())
   178  		return key
   179  	} else {
   180  		key := &SourceRangeKey4{PrefixLen: uint32(ones) + lpmPrefixLen4, RevNATID: id}
   181  		copy(key.Address[:], cidr.IP.To4())
   182  		return key
   183  	}
   184  }