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  }