github.com/noironetworks/cilium-net@v1.6.12/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  }