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 }