github.com/fafucoder/cilium@v1.6.11/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 // GetIdentityLocked returns the security identity of the endpoint. 136 func (ep *epInfoCache) GetIdentityLocked() identity.NumericIdentity { 137 return ep.identity 138 } 139 140 // Logger returns the logger for the endpoint that is being cached. 141 func (ep *epInfoCache) Logger(subsystem string) *logrus.Entry { 142 return ep.endpoint.Logger(subsystem) 143 } 144 145 // HasIpvlanDataPath returns whether the endpoint's datapath is implemented via ipvlan. 146 func (ep *epInfoCache) HasIpvlanDataPath() bool { 147 return ep.ipvlan 148 } 149 150 // IPv4Address returns the cached IPv4 address for the endpoint. 151 func (ep *epInfoCache) IPv4Address() addressing.CiliumIPv4 { 152 return ep.ipv4 153 } 154 155 // IPv6Address returns the cached IPv6 address for the endpoint. 156 func (ep *epInfoCache) IPv6Address() addressing.CiliumIPv6 { 157 return ep.ipv6 158 } 159 160 // StateDir returns the directory for the endpoint's (next) state. 161 func (ep *epInfoCache) StateDir() string { return ep.epdir } 162 func (ep *epInfoCache) GetNodeMAC() mac.MAC { return ep.mac } 163 164 // GetBPFKeys returns all keys which should represent this endpoint in the BPF 165 // endpoints map 166 func (ep *epInfoCache) GetBPFKeys() []*lxcmap.EndpointKey { 167 return ep.keys 168 } 169 170 // GetBPFValue returns the value which should represent this endpoint in the 171 // BPF endpoints map 172 // Must only be called if init() succeeded. 173 func (ep *epInfoCache) GetBPFValue() (*lxcmap.EndpointInfo, error) { 174 return ep.value, nil 175 } 176 177 func (ep *epInfoCache) ConntrackLocalLocked() bool { 178 return ep.conntrackLocal 179 } 180 181 func (ep *epInfoCache) GetCIDRPrefixLengths() ([]int, []int) { 182 return ep.cidr6PrefixLengths, ep.cidr4PrefixLengths 183 } 184 185 func (ep *epInfoCache) GetOptions() *option.IntOptions { 186 return ep.options 187 } 188 189 // RequireARPPassthrough returns true if the datapath must implement ARP 190 // passthrough for this endpoint 191 func (ep *epInfoCache) RequireARPPassthrough() bool { 192 return ep.requireARPPassthrough 193 } 194 195 // RequireEgressProg returns true if the endpoint requires bpf_lxc with esction 196 // "to-container" to be attached at egress on the host facing veth pair 197 func (ep *epInfoCache) RequireEgressProg() bool { 198 return ep.requireEgressProg 199 } 200 201 // RequireRouting returns true if the endpoint requires BPF routing to be 202 // enabled, when disabled, routing is delegated to Linux routing 203 func (ep *epInfoCache) RequireRouting() bool { 204 return ep.requireRouting 205 } 206 207 // RequireEndpointRoute returns if the endpoint wants a per endpoint route 208 func (ep *epInfoCache) RequireEndpointRoute() bool { 209 return ep.requireEndpointRoute 210 }