github.com/looshlee/beatles@v0.0.0-20220727174639-742810ab631c/pkg/endpoint/cache.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 endpoint 16 17 import ( 18 "fmt" 19 20 "github.com/cilium/cilium/common/addressing" 21 "github.com/cilium/cilium/pkg/identity" 22 "github.com/cilium/cilium/pkg/logging/logfields" 23 "github.com/cilium/cilium/pkg/mac" 24 "github.com/cilium/cilium/pkg/maps/lxcmap" 25 "github.com/cilium/cilium/pkg/option" 26 27 "github.com/sirupsen/logrus" 28 ) 29 30 // epInfoCache describes the set of lxcmap entries necessary to describe an Endpoint 31 // in the BPF maps. It is generated while holding the Endpoint lock, then used 32 // after releasing that lock to push the entries into the datapath. 33 // Functions below implement the EndpointFrontend interface with this cached information. 34 type epInfoCache struct { 35 // revision is used by the endpoint regeneration code to determine 36 // whether this cache is out-of-date wrt the underlying endpoint. 37 revision uint64 38 39 // For lxcmap.EndpointFrontend 40 keys []*lxcmap.EndpointKey 41 value *lxcmap.EndpointInfo 42 43 // For datapath.loader.endpoint 44 epdir string 45 id uint64 46 ifName string 47 ipvlan bool 48 49 // For datapath.EndpointConfiguration 50 identity identity.NumericIdentity 51 mac mac.MAC 52 ipv4 addressing.CiliumIPv4 53 ipv6 addressing.CiliumIPv6 54 conntrackLocal bool 55 requireARPPassthrough bool 56 requireEgressProg bool 57 requireRouting bool 58 requireEndpointRoute bool 59 cidr4PrefixLengths, cidr6PrefixLengths []int 60 options *option.IntOptions 61 62 // endpoint is used to get the endpoint's logger. 63 // 64 // Do NOT use this for fetching endpoint data directly; this structure 65 // is intended as a safe cache of endpoint data that is assembled while 66 // holding the endpoint lock, for use beyond the holding of that lock. 67 // Dereferencing fields in this endpoint is not guaranteed to be safe. 68 endpoint *Endpoint 69 } 70 71 // Must be called when endpoint is still locked. 72 func (e *Endpoint) createEpInfoCache(epdir string) *epInfoCache { 73 cidr6, cidr4 := e.GetCIDRPrefixLengths() 74 75 ep := &epInfoCache{ 76 revision: e.nextPolicyRevision, 77 keys: e.GetBPFKeys(), 78 79 epdir: epdir, 80 id: e.GetID(), 81 ifName: e.IfName, 82 ipvlan: e.HasIpvlanDataPath(), 83 84 identity: e.GetIdentity(), 85 mac: e.GetNodeMAC(), 86 ipv4: e.IPv4Address(), 87 ipv6: e.IPv6Address(), 88 conntrackLocal: e.ConntrackLocalLocked(), 89 requireARPPassthrough: e.RequireARPPassthrough(), 90 requireEgressProg: e.RequireEgressProg(), 91 requireRouting: e.RequireRouting(), 92 requireEndpointRoute: e.RequireEndpointRoute(), 93 cidr4PrefixLengths: cidr4, 94 cidr6PrefixLengths: cidr6, 95 options: e.Options.DeepCopy(), 96 97 endpoint: e, 98 } 99 100 var err error 101 ep.value, err = e.GetBPFValue() 102 if err != nil { 103 log.WithField(logfields.EndpointID, e.ID).WithError(err).Error("getBPFValue failed") 104 return nil 105 } 106 return ep 107 } 108 109 // InterfaceName returns the name of the link-layer interface used for 110 // communicating with the endpoint. 111 func (ep *epInfoCache) InterfaceName() string { 112 return ep.ifName 113 } 114 115 // MapPath returns tail call map path 116 func (ep *epInfoCache) MapPath() string { 117 return ep.endpoint.BPFIpvlanMapPath() 118 } 119 120 // GetID returns the endpoint's ID. 121 func (ep *epInfoCache) GetID() uint64 { 122 return ep.id 123 } 124 125 // StringID returns the endpoint's ID in a string. 126 func (ep *epInfoCache) StringID() string { 127 return fmt.Sprintf("%d", ep.id) 128 } 129 130 // GetIdentity returns the security identity of the endpoint. 131 func (ep *epInfoCache) GetIdentity() identity.NumericIdentity { 132 return ep.identity 133 } 134 135 // Logger returns the logger for the endpoint that is being cached. 136 func (ep *epInfoCache) Logger(subsystem string) *logrus.Entry { 137 return ep.endpoint.Logger(subsystem) 138 } 139 140 // HasIpvlanDataPath returns whether the endpoint's datapath is implemented via ipvlan. 141 func (ep *epInfoCache) HasIpvlanDataPath() bool { 142 return ep.ipvlan 143 } 144 145 // IPv4Address returns the cached IPv4 address for the endpoint. 146 func (ep *epInfoCache) IPv4Address() addressing.CiliumIPv4 { 147 return ep.ipv4 148 } 149 150 // IPv6Address returns the cached IPv6 address for the endpoint. 151 func (ep *epInfoCache) IPv6Address() addressing.CiliumIPv6 { 152 return ep.ipv6 153 } 154 155 // StateDir returns the directory for the endpoint's (next) state. 156 func (ep *epInfoCache) StateDir() string { return ep.epdir } 157 func (ep *epInfoCache) GetNodeMAC() mac.MAC { return ep.mac } 158 159 // GetBPFKeys returns all keys which should represent this endpoint in the BPF 160 // endpoints map 161 func (ep *epInfoCache) GetBPFKeys() []*lxcmap.EndpointKey { 162 return ep.keys 163 } 164 165 // GetBPFValue returns the value which should represent this endpoint in the 166 // BPF endpoints map 167 // Must only be called if init() succeeded. 168 func (ep *epInfoCache) GetBPFValue() (*lxcmap.EndpointInfo, error) { 169 return ep.value, nil 170 } 171 172 func (ep *epInfoCache) ConntrackLocalLocked() bool { 173 return ep.conntrackLocal 174 } 175 176 func (ep *epInfoCache) GetCIDRPrefixLengths() ([]int, []int) { 177 return ep.cidr6PrefixLengths, ep.cidr4PrefixLengths 178 } 179 180 func (ep *epInfoCache) GetOptions() *option.IntOptions { 181 return ep.options 182 } 183 184 // RequireARPPassthrough returns true if the datapath must implement ARP 185 // passthrough for this endpoint 186 func (ep *epInfoCache) RequireARPPassthrough() bool { 187 return ep.requireARPPassthrough 188 } 189 190 // RequireEgressProg returns true if the endpoint requires bpf_lxc with esction 191 // "to-container" to be attached at egress on the host facing veth pair 192 func (ep *epInfoCache) RequireEgressProg() bool { 193 return ep.requireEgressProg 194 } 195 196 // RequireRouting returns true if the endpoint requires BPF routing to be 197 // enabled, when disabled, routing is delegated to Linux routing 198 func (ep *epInfoCache) RequireRouting() bool { 199 return ep.requireRouting 200 } 201 202 // RequireEndpointRoute returns if the endpoint wants a per endpoint route 203 func (ep *epInfoCache) RequireEndpointRoute() bool { 204 return ep.requireEndpointRoute 205 }