Documentation ¶
Overview ¶
The calc package implements a calculation graph for Felix's dynamic state. The graph filters and transforms updates from the backend Syncer into a stream of host-specific updates to policies, profiles, endpoints and IP sets.
The graph is available either with a synchronous callback API or as a channel-based async API. The async version of the API is recommended because it includes and EventBuffer to efficiently batch IP set updates. In addition, it converts the callbacks into structs from the felix/proto package, which are ready to be marshaled directly to the felix front-end.
// Using the async API. asyncCalcGraph := calc.NewAsyncCalcGraph("hostname", outputChannel, nil) syncer := fc.datastore.Syncer(asyncCalcGraph) syncer.Start() asyncCalcGraph.Start() for event := range outputChannel { switch event := event.(type) { case *proto.XYZ: ... ... }
The best explanation of the wiring of the calculation graph nodes is in the code comments inside NewCalculationGraph.
Index ¶
- Constants
- Variables
- func ModelHostEndpointToProto(ep *model.HostEndpoint, tiers, untrackedTiers, preDNATTiers []*proto.TierInfo, ...) *proto.HostEndpoint
- func ModelWorkloadEndpointToProto(ep *model.WorkloadEndpoint, tiers []*proto.TierInfo) *proto.WorkloadEndpoint
- func ParsedRulesToActivePolicyUpdate(key model.PolicyKey, rules *ParsedRules) *proto.ActivePolicyUpdate
- func PolKVLess(i, j PolKV) bool
- func TierLess(i, j tierInfoKey) bool
- type ActiveRulesCalculator
- func (arc *ActiveRulesCalculator) OnStatusUpdate(status api.SyncStatus)
- func (arc *ActiveRulesCalculator) OnUpdate(update api.Update) (_ bool)
- func (arc *ActiveRulesCalculator) RegisterPolicyMatchListener(listener PolicyMatchListener)
- func (arc *ActiveRulesCalculator) RegisterWith(localEndpointDispatcher, allUpdDispatcher *dispatcher.Dispatcher)
- type AsyncCalcGraph
- type Block
- type CalcGraph
- type ConfigBatcher
- type DataplanePassthru
- type DatastoreNotReady
- type EncapsulationCalculator
- type EncapsulationResolver
- type EndpointKeyToProfileIDMap
- type EventHandler
- type EventSequencer
- func (buf *EventSequencer) Flush()
- func (buf *EventSequencer) OnConfigUpdate(globalConfig, hostConfig map[string]string)
- func (buf *EventSequencer) OnDatastoreNotReady()
- func (buf *EventSequencer) OnEncapUpdate(encap config.Encapsulation)
- func (buf *EventSequencer) OnEndpointTierUpdate(key model.Key, endpoint interface{}, filteredTiers []TierInfo)
- func (buf *EventSequencer) OnGlobalBGPConfigUpdate(cfg *v3.BGPConfiguration)
- func (buf *EventSequencer) OnHostIPRemove(hostname string)
- func (buf *EventSequencer) OnHostIPUpdate(hostname string, ip *net.IP)
- func (buf *EventSequencer) OnHostIPv6Remove(hostname string)
- func (buf *EventSequencer) OnHostIPv6Update(hostname string, ip *net.IP)
- func (buf *EventSequencer) OnHostMetadataRemove(hostname string)
- func (buf *EventSequencer) OnHostMetadataUpdate(hostname string, ip4 *net.IPNet, ip6 *net.IPNet, asnumber string, ...)
- func (buf *EventSequencer) OnIPPoolRemove(key model.IPPoolKey)
- func (buf *EventSequencer) OnIPPoolUpdate(key model.IPPoolKey, pool *model.IPPool)
- func (buf *EventSequencer) OnIPSetAdded(setID string, ipSetType proto.IPSetUpdate_IPSetType)
- func (buf *EventSequencer) OnIPSetMemberAdded(setID string, member labelindex.IPSetMember)
- func (buf *EventSequencer) OnIPSetMemberRemoved(setID string, member labelindex.IPSetMember)
- func (buf *EventSequencer) OnIPSetRemoved(setID string)
- func (buf *EventSequencer) OnNamespaceRemove(id proto.NamespaceID)
- func (buf *EventSequencer) OnNamespaceUpdate(update *proto.NamespaceUpdate)
- func (buf *EventSequencer) OnPolicyActive(key model.PolicyKey, rules *ParsedRules)
- func (buf *EventSequencer) OnPolicyInactive(key model.PolicyKey)
- func (buf *EventSequencer) OnProfileActive(key model.ProfileRulesKey, rules *ParsedRules)
- func (buf *EventSequencer) OnProfileInactive(key model.ProfileRulesKey)
- func (buf *EventSequencer) OnRouteRemove(dst string)
- func (buf *EventSequencer) OnRouteUpdate(update *proto.RouteUpdate)
- func (buf *EventSequencer) OnServiceAccountRemove(id proto.ServiceAccountID)
- func (buf *EventSequencer) OnServiceAccountUpdate(update *proto.ServiceAccountUpdate)
- func (buf *EventSequencer) OnServiceRemove(update *proto.ServiceRemove)
- func (buf *EventSequencer) OnServiceUpdate(update *proto.ServiceUpdate)
- func (buf *EventSequencer) OnVTEPRemove(dst string)
- func (buf *EventSequencer) OnVTEPUpdate(update *proto.VXLANTunnelEndpointUpdate)
- func (buf *EventSequencer) OnWireguardRemove(nodename string)
- func (buf *EventSequencer) OnWireguardUpdate(nodename string, wg *model.Wireguard)
- type FelixSender
- type IPSetData
- type L3RouteResolver
- func (c *L3RouteResolver) OnBlockUpdate(update api.Update) (_ bool)
- func (c *L3RouteResolver) OnHostIPUpdate(update api.Update) (_ bool)
- func (c *L3RouteResolver) OnPoolUpdate(update api.Update) (_ bool)
- func (c *L3RouteResolver) OnResourceUpdate(update api.Update) (_ bool)
- func (c *L3RouteResolver) OnWorkloadUpdate(update api.Update) (_ bool)
- func (c *L3RouteResolver) RegisterWith(allUpdDispatcher, localDispatcher *dispatcher.Dispatcher)
- type ParsedRule
- type ParsedRules
- type PipelineCallbacks
- type PolKV
- type PolicyMatchListener
- type PolicyResolver
- func (pr *PolicyResolver) Flush()
- func (pr *PolicyResolver) OnDatamodelStatus(status api.SyncStatus)
- func (pr *PolicyResolver) OnPolicyMatch(policyKey model.PolicyKey, endpointKey model.Key)
- func (pr *PolicyResolver) OnPolicyMatchStopped(policyKey model.PolicyKey, endpointKey model.Key)
- func (pr *PolicyResolver) OnUpdate(update api.Update) (filterOut bool)
- func (pr *PolicyResolver) RegisterCallback(cb PolicyResolverCallbacks)
- func (pr *PolicyResolver) RegisterWith(allUpdDispatcher, localEndpointDispatcher *dispatcher.Dispatcher)
- type PolicyResolverCallbacks
- type PolicySorter
- type Pool
- type ProfileDecoder
- type Ref
- type RefType
- type RouteInfo
- type RouteTrie
- func (r *RouteTrie) AddHost(cidr ip.CIDR, nodeName string)
- func (r *RouteTrie) AddRef(cidr ip.CIDR, nodename string, rt RefType)
- func (r *RouteTrie) Get(cidr ip.CIDR) RouteInfo
- func (r *RouteTrie) MarkCIDRDirty(cidr ip.CIDR)
- func (r *RouteTrie) RemoveBlockRoute(cidr ip.CIDR)
- func (r *RouteTrie) RemoveHost(cidr ip.CIDR, nodeName string)
- func (r *RouteTrie) RemovePool(cidr ip.CIDR)
- func (r *RouteTrie) RemoveRef(cidr ip.CIDR, nodename string, rt RefType)
- func (r *RouteTrie) SetRouteSent(cidr ip.CIDR, sent bool)
- func (r *RouteTrie) UpdateBlockRoute(cidr ip.CIDR, nodeName string)
- func (r *RouteTrie) UpdatePool(cidr ip.CIDR, poolType proto.IPPoolType, natOutgoing bool, crossSubnet bool)
- type RuleScanner
- func (rs *RuleScanner) OnPolicyActive(key model.PolicyKey, policy *model.Policy)
- func (rs *RuleScanner) OnPolicyInactive(key model.PolicyKey)
- func (rs *RuleScanner) OnProfileActive(key model.ProfileRulesKey, profile *model.ProfileRules)
- func (rs *RuleScanner) OnProfileInactive(key model.ProfileRulesKey)
- type StatsCollector
- type StatsUpdate
- type SyncerCallbacksDecoupler
- type TierInfo
- type VXLANResolver
- type ValidationFilter
Constants ¶
const ( // Compromise: shorter is better for occupancy and readability. Longer is better for // collision-resistance. 16 chars gives us 96 bits of entropy, which is fairly collision // resistant. RuleIDLength = 16 )
Variables ¶
var AllSelector selector.Selector
AllSelector is a pre-calculated copy of the "all()" selector.
var ( DummyDropRules = model.ProfileRules{ InboundRules: []model.Rule{{Action: "deny"}}, OutboundRules: []model.Rule{{Action: "deny"}}, } )
Functions ¶
func ModelHostEndpointToProto ¶
func ModelHostEndpointToProto(ep *model.HostEndpoint, tiers, untrackedTiers, preDNATTiers []*proto.TierInfo, forwardTiers []*proto.TierInfo) *proto.HostEndpoint
func ModelWorkloadEndpointToProto ¶
func ModelWorkloadEndpointToProto(ep *model.WorkloadEndpoint, tiers []*proto.TierInfo) *proto.WorkloadEndpoint
func ParsedRulesToActivePolicyUpdate ¶
func ParsedRulesToActivePolicyUpdate(key model.PolicyKey, rules *ParsedRules) *proto.ActivePolicyUpdate
Types ¶
type ActiveRulesCalculator ¶
type ActiveRulesCalculator struct { // Callback objects. RuleScanner ruleScanner PolicyMatchListeners []PolicyMatchListener OnPolicyCountsChanged func(numTiers, numPolicies, numProfiles, numALPPolicies int) OnAlive func() // contains filtered or unexported fields }
ActiveRulesCalculator calculates the set of policies and profiles (i.e. the rules) that are active for the particular endpoints that it's been told about. It emits events when the set of active rules changes.
For example, if the ActiveRulesCalculator is fed *all* the policies/profiles along with the endpoints that are on the local host then its output (via the callback objects) will indicate exactly which policies/profiles are active on the local host.
When looking at policies, the ActiveRules calculator is only interested in the selector attached to the policy itself (which determines the set of endpoints that it applies to). The rules in a policy may also contain selectors; those are ignored here; they are mapped to IP sets by the RuleScanner.
func NewActiveRulesCalculator ¶
func NewActiveRulesCalculator() *ActiveRulesCalculator
func (*ActiveRulesCalculator) OnStatusUpdate ¶
func (arc *ActiveRulesCalculator) OnStatusUpdate(status api.SyncStatus)
func (*ActiveRulesCalculator) OnUpdate ¶
func (arc *ActiveRulesCalculator) OnUpdate(update api.Update) (_ bool)
func (*ActiveRulesCalculator) RegisterPolicyMatchListener ¶
func (arc *ActiveRulesCalculator) RegisterPolicyMatchListener(listener PolicyMatchListener)
func (*ActiveRulesCalculator) RegisterWith ¶
func (arc *ActiveRulesCalculator) RegisterWith(localEndpointDispatcher, allUpdDispatcher *dispatcher.Dispatcher)
type AsyncCalcGraph ¶
type AsyncCalcGraph struct { CalcGraph *CalcGraph // contains filtered or unexported fields }
func NewAsyncCalcGraph ¶
func NewAsyncCalcGraph( conf *config.Config, outputChannels []chan<- interface{}, healthAggregator *health.HealthAggregator, ) *AsyncCalcGraph
func (*AsyncCalcGraph) OnStatusUpdated ¶
func (acg *AsyncCalcGraph) OnStatusUpdated(status api.SyncStatus)
func (*AsyncCalcGraph) OnUpdates ¶
func (acg *AsyncCalcGraph) OnUpdates(updates []api.Update)
func (*AsyncCalcGraph) Start ¶
func (acg *AsyncCalcGraph) Start()
type Block ¶
type Block struct {
NodeName string // Set for each route that comes from an IPAM block.
}
type CalcGraph ¶
type CalcGraph struct { // AllUpdDispatcher is the input node to the calculation graph. AllUpdDispatcher *dispatcher.Dispatcher // contains filtered or unexported fields }
func NewCalculationGraph ¶
func NewCalculationGraph(callbacks PipelineCallbacks, conf *config.Config, liveCallback func()) *CalcGraph
func (*CalcGraph) OnStatusUpdated ¶
func (g *CalcGraph) OnStatusUpdated(update api.SyncStatus)
type ConfigBatcher ¶
type ConfigBatcher struct {
// contains filtered or unexported fields
}
func NewConfigBatcher ¶
func NewConfigBatcher(hostname string, callbacks configCallbacks) *ConfigBatcher
func (*ConfigBatcher) OnDatamodelStatus ¶
func (cb *ConfigBatcher) OnDatamodelStatus(status api.SyncStatus)
func (*ConfigBatcher) OnUpdate ¶
func (cb *ConfigBatcher) OnUpdate(update api.Update) (filterOut bool)
func (*ConfigBatcher) RegisterWith ¶
func (cb *ConfigBatcher) RegisterWith(allUpdDispatcher *dispatcher.Dispatcher)
type DataplanePassthru ¶
type DataplanePassthru struct {
// contains filtered or unexported fields
}
DataplanePassthru passes through some datamodel updates to the dataplane layer, removing some duplicates along the way. It maps OnUpdate() calls to dedicated method calls for consistency with the rest of the dataplane API.
func NewDataplanePassthru ¶
func NewDataplanePassthru(callbacks passthruCallbacks, ipv6Support bool) *DataplanePassthru
func (*DataplanePassthru) OnUpdate ¶
func (h *DataplanePassthru) OnUpdate(update api.Update) (filterOut bool)
func (*DataplanePassthru) RegisterWith ¶
func (h *DataplanePassthru) RegisterWith(dispatcher *dispatcher.Dispatcher)
type DatastoreNotReady ¶
type DatastoreNotReady struct{}
type EncapsulationCalculator ¶
type EncapsulationCalculator struct {
// contains filtered or unexported fields
}
EncapsulationCalculator is a helper struct to aid in calculating if IPIP and/or VXLAN encapsulation should be enabled based on the existing IP Pools and their configuration. It is used by EncapsulationResolver in this file, where it watches for encapsulation changes to restart Felix, and by Run() in daemon.go, where it calculates the encapsulation state that will be effectively used by Felix.
func NewEncapsulationCalculator ¶
func NewEncapsulationCalculator(config *config.Config, ippoolKVPList *model.KVPairList) *EncapsulationCalculator
func (*EncapsulationCalculator) IPIPEnabled ¶
func (c *EncapsulationCalculator) IPIPEnabled() bool
func (*EncapsulationCalculator) VXLANEnabled ¶
func (c *EncapsulationCalculator) VXLANEnabled() bool
func (*EncapsulationCalculator) VXLANEnabledV6 ¶
func (c *EncapsulationCalculator) VXLANEnabledV6() bool
type EncapsulationResolver ¶
type EncapsulationResolver struct {
// contains filtered or unexported fields
}
EncapsulationResolver is a Calculation Graph component that watches IP pool updates and calculates if the IPIP or VXLAN encaps should be enabled or disabled. The new Encapsulation is sent to the dataplane, which restarts Felix if it changed.
func NewEncapsulationResolver ¶
func NewEncapsulationResolver(config *config.Config, callbacks encapCallbacks) *EncapsulationResolver
func (*EncapsulationResolver) OnPoolUpdate ¶
func (r *EncapsulationResolver) OnPoolUpdate(update api.Update) (filterOut bool)
func (*EncapsulationResolver) OnStatusUpdate ¶
func (r *EncapsulationResolver) OnStatusUpdate(status api.SyncStatus)
func (*EncapsulationResolver) RegisterWith ¶
func (r *EncapsulationResolver) RegisterWith(dispatcher *dispatcher.Dispatcher)
type EndpointKeyToProfileIDMap ¶
type EndpointKeyToProfileIDMap struct {
// contains filtered or unexported fields
}
EndpointKeyToProfileIDMap is a specialised map that calculates the deltas to the profile IDs when making an update.
func NewEndpointKeyToProfileIDMap ¶
func NewEndpointKeyToProfileIDMap() *EndpointKeyToProfileIDMap
type EventHandler ¶
type EventHandler func(message interface{})
type EventSequencer ¶
type EventSequencer struct { Callback EventHandler // contains filtered or unexported fields }
EventSequencer buffers and coalesces updates from the calculation graph then flushes them when Flush() is called. It flushed updates in a dependency-safe order.
func NewEventSequencer ¶
func NewEventSequencer(conf configInterface) *EventSequencer
func (*EventSequencer) Flush ¶
func (buf *EventSequencer) Flush()
func (*EventSequencer) OnConfigUpdate ¶
func (buf *EventSequencer) OnConfigUpdate(globalConfig, hostConfig map[string]string)
func (*EventSequencer) OnDatastoreNotReady ¶
func (buf *EventSequencer) OnDatastoreNotReady()
func (*EventSequencer) OnEncapUpdate ¶
func (buf *EventSequencer) OnEncapUpdate(encap config.Encapsulation)
func (*EventSequencer) OnEndpointTierUpdate ¶
func (buf *EventSequencer) OnEndpointTierUpdate(key model.Key, endpoint interface{}, filteredTiers []TierInfo, )
func (*EventSequencer) OnGlobalBGPConfigUpdate ¶
func (buf *EventSequencer) OnGlobalBGPConfigUpdate(cfg *v3.BGPConfiguration)
func (*EventSequencer) OnHostIPRemove ¶
func (buf *EventSequencer) OnHostIPRemove(hostname string)
func (*EventSequencer) OnHostIPUpdate ¶
func (buf *EventSequencer) OnHostIPUpdate(hostname string, ip *net.IP)
func (*EventSequencer) OnHostIPv6Remove ¶
func (buf *EventSequencer) OnHostIPv6Remove(hostname string)
func (*EventSequencer) OnHostIPv6Update ¶
func (buf *EventSequencer) OnHostIPv6Update(hostname string, ip *net.IP)
func (*EventSequencer) OnHostMetadataRemove ¶
func (buf *EventSequencer) OnHostMetadataRemove(hostname string)
func (*EventSequencer) OnHostMetadataUpdate ¶
func (*EventSequencer) OnIPPoolRemove ¶
func (buf *EventSequencer) OnIPPoolRemove(key model.IPPoolKey)
func (*EventSequencer) OnIPPoolUpdate ¶
func (buf *EventSequencer) OnIPPoolUpdate(key model.IPPoolKey, pool *model.IPPool)
func (*EventSequencer) OnIPSetAdded ¶
func (buf *EventSequencer) OnIPSetAdded(setID string, ipSetType proto.IPSetUpdate_IPSetType)
func (*EventSequencer) OnIPSetMemberAdded ¶
func (buf *EventSequencer) OnIPSetMemberAdded(setID string, member labelindex.IPSetMember)
func (*EventSequencer) OnIPSetMemberRemoved ¶
func (buf *EventSequencer) OnIPSetMemberRemoved(setID string, member labelindex.IPSetMember)
func (*EventSequencer) OnIPSetRemoved ¶
func (buf *EventSequencer) OnIPSetRemoved(setID string)
func (*EventSequencer) OnNamespaceRemove ¶
func (buf *EventSequencer) OnNamespaceRemove(id proto.NamespaceID)
func (*EventSequencer) OnNamespaceUpdate ¶
func (buf *EventSequencer) OnNamespaceUpdate(update *proto.NamespaceUpdate)
func (*EventSequencer) OnPolicyActive ¶
func (buf *EventSequencer) OnPolicyActive(key model.PolicyKey, rules *ParsedRules)
func (*EventSequencer) OnPolicyInactive ¶
func (buf *EventSequencer) OnPolicyInactive(key model.PolicyKey)
func (*EventSequencer) OnProfileActive ¶
func (buf *EventSequencer) OnProfileActive(key model.ProfileRulesKey, rules *ParsedRules)
func (*EventSequencer) OnProfileInactive ¶
func (buf *EventSequencer) OnProfileInactive(key model.ProfileRulesKey)
func (*EventSequencer) OnRouteRemove ¶
func (buf *EventSequencer) OnRouteRemove(dst string)
func (*EventSequencer) OnRouteUpdate ¶
func (buf *EventSequencer) OnRouteUpdate(update *proto.RouteUpdate)
func (*EventSequencer) OnServiceAccountRemove ¶
func (buf *EventSequencer) OnServiceAccountRemove(id proto.ServiceAccountID)
func (*EventSequencer) OnServiceAccountUpdate ¶
func (buf *EventSequencer) OnServiceAccountUpdate(update *proto.ServiceAccountUpdate)
func (*EventSequencer) OnServiceRemove ¶
func (buf *EventSequencer) OnServiceRemove(update *proto.ServiceRemove)
func (*EventSequencer) OnServiceUpdate ¶
func (buf *EventSequencer) OnServiceUpdate(update *proto.ServiceUpdate)
func (*EventSequencer) OnVTEPRemove ¶
func (buf *EventSequencer) OnVTEPRemove(dst string)
func (*EventSequencer) OnVTEPUpdate ¶
func (buf *EventSequencer) OnVTEPUpdate(update *proto.VXLANTunnelEndpointUpdate)
func (*EventSequencer) OnWireguardRemove ¶
func (buf *EventSequencer) OnWireguardRemove(nodename string)
func (*EventSequencer) OnWireguardUpdate ¶
func (buf *EventSequencer) OnWireguardUpdate(nodename string, wg *model.Wireguard)
type FelixSender ¶
type IPSetData ¶
type IPSetData struct { // The selector and named port that this IP set represents. To represent an unfiltered named // port, set selector to AllSelector. If NamedPortProtocol == ProtocolNone then // this IP set represents a selector only, with no named port component. Selector selector.Selector // NamedPortProtocol identifies the protocol (TCP or UDP) for a named port IP set. It is // set to ProtocolNone for a selector-only IP set. NamedPortProtocol labelindex.IPSetPortProtocol // NamedPort contains the name of the named port represented by this IP set or "" for a // selector-only IP set NamedPort string // The service that this IP set represents, in namespace/name format. Service string // Type of the ip set to represent for this service. This allows us to create service // IP sets with and without port information. ServiceIncludePorts bool // contains filtered or unexported fields }
func (*IPSetData) DataplaneProtocolType ¶
func (d *IPSetData) DataplaneProtocolType() proto.IPSetUpdate_IPSetType
DataplaneProtocolType returns the dataplane driver protocol type of this IP set. One of the proto.IPSetUpdate_IPSetType constants.
type L3RouteResolver ¶
type L3RouteResolver struct { OnAlive func() // contains filtered or unexported fields }
L3RouteResolver is responsible for indexing :
- IPAM blocks - IP pools - Node metadata (either from the Node resource, if available, or from HostIP)
and emitting a set of longest prefix match routes that include:
- The relevant destination CIDR. - The IP pool type that contains the CIDR (or none). - Other metadata about the containing IP pool. - Whether this (/32) CIDR is a host or not. (or /128 for IPv6) - For workload CIDRs, the IP and name of the host that contains the workload.
The BPF dataplane use the above to form a map of IP space so it can look up whether a particular IP belongs to a workload/host/IP pool etc. and where to forward that IP to if it needs to. The VXLAN dataplane combines routes for remote workloads with VTEPs from the VXLANResolver to form VXLAN routes.
func NewL3RouteResolver ¶
func NewL3RouteResolver(hostname string, callbacks routeCallbacks, useNodeResourceUpdates bool, routeSource string) *L3RouteResolver
func (*L3RouteResolver) OnBlockUpdate ¶
func (c *L3RouteResolver) OnBlockUpdate(update api.Update) (_ bool)
func (*L3RouteResolver) OnHostIPUpdate ¶
func (c *L3RouteResolver) OnHostIPUpdate(update api.Update) (_ bool)
OnHostIPUpdate gets called whenever a node IP address changes.
func (*L3RouteResolver) OnPoolUpdate ¶
func (c *L3RouteResolver) OnPoolUpdate(update api.Update) (_ bool)
OnPoolUpdate gets called whenever an IP pool changes.
func (*L3RouteResolver) OnResourceUpdate ¶
func (c *L3RouteResolver) OnResourceUpdate(update api.Update) (_ bool)
func (*L3RouteResolver) OnWorkloadUpdate ¶
func (c *L3RouteResolver) OnWorkloadUpdate(update api.Update) (_ bool)
func (*L3RouteResolver) RegisterWith ¶
func (c *L3RouteResolver) RegisterWith(allUpdDispatcher, localDispatcher *dispatcher.Dispatcher)
type ParsedRule ¶
type ParsedRule struct { Action string IPVersion *int Protocol *numorstring.Protocol SrcNets []*net.IPNet SrcPorts []numorstring.Port SrcNamedPortIPSetIDs []string DstNets []*net.IPNet DstPorts []numorstring.Port DstNamedPortIPSetIDs []string ICMPType *int ICMPCode *int SrcIPSetIDs []string DstIPSetIDs []string DstIPPortSetIDs []string NotProtocol *numorstring.Protocol NotSrcNets []*net.IPNet NotSrcPorts []numorstring.Port NotSrcNamedPortIPSetIDs []string NotDstNets []*net.IPNet NotDstPorts []numorstring.Port NotDstNamedPortIPSetIDs []string NotICMPType *int NotICMPCode *int NotSrcIPSetIDs []string NotDstIPSetIDs []string // These fields allow us to pass through the raw match criteria from the V3 datamodel, // unmodified. The selectors above are formed in the update processor layer by combining the // original selectors, namespace selectors an service account matches into one. OriginalSrcSelector string OriginalSrcNamespaceSelector string OriginalDstSelector string OriginalDstNamespaceSelector string OriginalNotSrcSelector string OriginalNotDstSelector string OriginalSrcServiceAccountNames []string OriginalSrcServiceAccountSelector string OriginalDstServiceAccountNames []string OriginalDstServiceAccountSelector string OriginalSrcService string OriginalSrcServiceNamespace string OriginalDstService string OriginalDstServiceNamespace string // These fields allow us to pass through the HTTP match criteria from the V3 datamodel. The iptables dataplane // does not implement the match, but other dataplanes such as Dikastes do. HTTPMatch *model.HTTPMatch Metadata *model.RuleMetadata }
ParsedRule is like a backend.model.Rule, except the selector matches and named ports are replaced with pre-calculated ipset IDs.
type ParsedRules ¶
type ParsedRules struct { // For NetworkPolicies, Namespace is set to the original namespace of the NetworkPolicy. // For GlobalNetworkPolicies and Profiles, "". Namespace string InboundRules []*ParsedRule OutboundRules []*ParsedRule // Untracked is true if these rules should not be "conntracked". Untracked bool // PreDNAT is true if these rules should be applied before any DNAT. PreDNAT bool OriginalSelector string }
ParsedRules holds our intermediate representation of either a policy's rules or a profile's rules. As part of its processing, the RuleScanner converts backend rules into ParsedRules. Where backend rules contain selectors and named ports, ParsedRules only contain IPSet IDs. The RuleScanner calculates the relevant IDs as it processes the rules and diverts the details of the active selectors and named ports to the named port index, which figures out the members that should be in those IP sets.
type PipelineCallbacks ¶
type PipelineCallbacks interface {
// contains filtered or unexported methods
}
type PolKV ¶
type PolKV struct { Key model.PolicyKey Value *model.Policy // contains filtered or unexported fields }
PolKV is really internal to the calc package. It is named with an initial capital so that the test package calc_test can also use it.
func (*PolKV) GovernsEgress ¶
func (*PolKV) GovernsIngress ¶
type PolicyMatchListener ¶
type PolicyResolver ¶
type PolicyResolver struct { Callbacks []PolicyResolverCallbacks InSync bool // contains filtered or unexported fields }
PolicyResolver marries up the active policies with local endpoints and calculates the complete, ordered set of policies that apply to each endpoint. As policies and endpoints are added/removed/updated, it emits events via the PolicyResolverCallbacks with the updated set of matching policies.
The PolicyResolver doesn't figure out which policies are currently active, it expects to be told via its OnPolicyMatch(Stopped) methods which policies match which endpoints. The ActiveRulesCalculator does that calculation.
func NewPolicyResolver ¶
func NewPolicyResolver() *PolicyResolver
func (*PolicyResolver) Flush ¶
func (pr *PolicyResolver) Flush()
func (*PolicyResolver) OnDatamodelStatus ¶
func (pr *PolicyResolver) OnDatamodelStatus(status api.SyncStatus)
func (*PolicyResolver) OnPolicyMatch ¶
func (pr *PolicyResolver) OnPolicyMatch(policyKey model.PolicyKey, endpointKey model.Key)
func (*PolicyResolver) OnPolicyMatchStopped ¶
func (pr *PolicyResolver) OnPolicyMatchStopped(policyKey model.PolicyKey, endpointKey model.Key)
func (*PolicyResolver) OnUpdate ¶
func (pr *PolicyResolver) OnUpdate(update api.Update) (filterOut bool)
func (*PolicyResolver) RegisterCallback ¶
func (pr *PolicyResolver) RegisterCallback(cb PolicyResolverCallbacks)
func (*PolicyResolver) RegisterWith ¶
func (pr *PolicyResolver) RegisterWith(allUpdDispatcher, localEndpointDispatcher *dispatcher.Dispatcher)
type PolicyResolverCallbacks ¶
type PolicySorter ¶
type PolicySorter struct {
// contains filtered or unexported fields
}
func NewPolicySorter ¶
func NewPolicySorter() *PolicySorter
func (*PolicySorter) Sorted ¶
func (poc *PolicySorter) Sorted() []*TierInfo
func (*PolicySorter) UpdatePolicy ¶
type Pool ¶
type Pool struct { Type proto.IPPoolType // Only set if this CIDR represents an IP pool NATOutgoing bool CrossSubnet bool }
type ProfileDecoder ¶
type ProfileDecoder struct {
// contains filtered or unexported fields
}
ProfileDecoder takes updates from a dispatcher, determines if the profile is a Kubernetes Service Account or Kubernetes Namespace, and if it is, generates a dataplane update or remove for it.
func NewProfileDecoder ¶
func NewProfileDecoder(callbacks passthruCallbacks) *ProfileDecoder
func (*ProfileDecoder) OnUpdate ¶
func (p *ProfileDecoder) OnUpdate(update api.Update) (filterOut bool)
func (*ProfileDecoder) RegisterWith ¶
func (p *ProfileDecoder) RegisterWith(d *dispatcher.Dispatcher)
type Ref ¶
type Ref struct { // Count of Refs that have this CIDR. Normally, for WEPs this will be 0 or 1 but Felix has to be tolerant // to bad data (two Refs with the same CIDR) so we do ref counting. For tunnel IPs, multiple tunnels may share the // same IP, so again ref counting is necessary here. RefCount int // The type of reference. RefType RefType // NodeName contains the nodename for this Ref / CIDR. NodeName string }
type RouteInfo ¶
type RouteInfo struct { // Pools contains information extracted from the local and remote IP pools that have this CIDR. // Since the datastore guarantees that pools have unique CIDRs within the cluster, we only expect one entry. Pools []Pool // Blocks contains route information extracted from local and remote IPAM blocks. // Since the datastore guarantees that blocks have unique CIDRs within the cluster, we only expect one entry. Blocks []Block // Host contains information extracted from the node/host config updates. Host struct { NodeNames []string // set if this CIDR _is_ a node's own IP. } // Refs contains information extracted from workload endpoints, or tunnel addresses extracted from the node. Refs []Ref // WasSent is set to true when the route is sent downstream. WasSent bool }
func (RouteInfo) Copy ¶
Copy returns a copy of the RouteInfo. Since some fields are pointers, we need to explicitly copy them so that they are not shared between the copies.
func (RouteInfo) IsValidRoute ¶
IsValidRoute returns true if the RouteInfo contains some information about a CIDR, i.e. if this route should be sent downstream. This _excludes_ the WasSent flag, which we use to track whether a route with this CIDR was previously sent. If IsValidRoute() returns false but WasSent is true then we need to withdraw the route.
type RouteTrie ¶
type RouteTrie struct { OnAlive func() // contains filtered or unexported fields }
RouteTrie stores the information that we've gleaned from various resources in a way that allows us to
- Look up a CIDR and find all the information that we know about the containing CIDRs. Example: if we look up a workload /32 CIDR then we'll also find the IP pool that contains it.
- Deal with collisions where resources from different sources share the same CIDR. Example: an IP pool and an IPAM block can share the same CIDR. When we do a lookup, we want to know about both the pool and the block.
More examples of nesting and collisions to be aware of:
- Disabled IPAM pools that contain no blocks, which are used for tagging "external" IPs as safe destinations that don't require SNAT and for adding IP ranges for BIRD to export.
- IPAM blocks that are /32s so they overlap with the pod IP inside them (and potentially with a misconfigured host IP).
- Transient misconfigurations during a resync where we may see things out of order (for example, two hosts sharing an IP).
- In future, /32s that we've learned from workload endpoints that are not contained within IP pools.
Approach: for each CIDR in the trie, we store a RouteInfo struct, which has a disjoint nested struct for tracking data from each source. All updates are done via the updateCIDR method, which handles cleaning up RouteInfo structs that are empty.
The RouteTrie maintains a set of dirty CIDRs. When an IPAM pool is updated, all the CIDRs under it are marked dirty.
func NewRouteTrie ¶
func NewRouteTrie() *RouteTrie
func (*RouteTrie) MarkCIDRDirty ¶
func (*RouteTrie) RemoveBlockRoute ¶
func (*RouteTrie) RemovePool ¶
func (*RouteTrie) UpdateBlockRoute ¶
func (*RouteTrie) UpdatePool ¶
type RuleScanner ¶
type RuleScanner struct { OnIPSetActive func(ipSet *IPSetData) OnIPSetInactive func(ipSet *IPSetData) RulesUpdateCallbacks rulesUpdateCallbacks // contains filtered or unexported fields }
RuleScanner scans the rules sent to it by the ActiveRulesCalculator, looking for selectors. It calculates the set of active selectors and emits events when they become active/inactive.
Previously, Felix tracked tags and selectors separately, with a separate tag and label index. However, we found that had a high occupancy cost. The current code uses a shared index and maps tags onto labels, so a tag named tagName, becomes a label tagName="". The RuleScanner maps tags to label selectors of the form "has(tagName)", taking advantage of the mapping. Such a selector is almost equivalent to having the tag; the only case where the behaviour would differ is if the user was using the same name for a tag and a label and the label and tags of the same name were applied to different endpoints. Since tags are being deprecated, we can live with that potential aliasing issue in return for a significant occupancy improvement at high scale.
The RuleScanner also emits events when rules are updated: since the input rule structs contain tags and selectors but downstream, we only care about IP sets, the RuleScanner converts rules from model.Rule objects to calc.ParsedRule objects. The latter share most fields, but the tags and selector fields are replaced by lists of IP sets.
The RuleScanner only calculates which selectors and tags are active/inactive. It doesn't match endpoints against tags/selectors. (That is done downstream in a labelindex.InheritIndex created in NewCalculationGraph.)
func NewRuleScanner ¶
func NewRuleScanner() *RuleScanner
func (*RuleScanner) OnPolicyActive ¶
func (rs *RuleScanner) OnPolicyActive(key model.PolicyKey, policy *model.Policy)
func (*RuleScanner) OnPolicyInactive ¶
func (rs *RuleScanner) OnPolicyInactive(key model.PolicyKey)
func (*RuleScanner) OnProfileActive ¶
func (rs *RuleScanner) OnProfileActive(key model.ProfileRulesKey, profile *model.ProfileRules)
func (*RuleScanner) OnProfileInactive ¶
func (rs *RuleScanner) OnProfileInactive(key model.ProfileRulesKey)
type StatsCollector ¶
type StatsCollector struct { Callback func(StatsUpdate) error // contains filtered or unexported fields }
func NewStatsCollector ¶
func NewStatsCollector(callback func(StatsUpdate) error) *StatsCollector
func (*StatsCollector) OnStatusUpdate ¶
func (s *StatsCollector) OnStatusUpdate(status api.SyncStatus)
func (*StatsCollector) OnUpdate ¶
func (s *StatsCollector) OnUpdate(update api.Update) (filterOut bool)
func (*StatsCollector) RegisterWith ¶
func (s *StatsCollector) RegisterWith(calcGraph *CalcGraph)
func (*StatsCollector) UpdatePolicyCounts ¶
func (s *StatsCollector) UpdatePolicyCounts(numTiers, numPolicies, numProfiles, numALPPolicies int)
type StatsUpdate ¶
type StatsUpdate struct { NumHosts int NumWorkloadEndpoints int NumHostEndpoints int NumTiers int NumPolicies int NumProfiles int NumALPPolicies int }
func (StatsUpdate) String ¶
func (s StatsUpdate) String() string
type SyncerCallbacksDecoupler ¶
type SyncerCallbacksDecoupler struct {
// contains filtered or unexported fields
}
func NewSyncerCallbacksDecoupler ¶
func NewSyncerCallbacksDecoupler() *SyncerCallbacksDecoupler
func (*SyncerCallbacksDecoupler) OnStatusUpdated ¶
func (a *SyncerCallbacksDecoupler) OnStatusUpdated(status api.SyncStatus)
func (*SyncerCallbacksDecoupler) OnUpdates ¶
func (a *SyncerCallbacksDecoupler) OnUpdates(updates []api.Update)
func (*SyncerCallbacksDecoupler) SendTo ¶
func (a *SyncerCallbacksDecoupler) SendTo(sink api.SyncerCallbacks)
type TierInfo ¶
type TierInfo struct { Name string Valid bool Order *float64 DefaultAction v3.Action Policies map[model.PolicyKey]*model.Policy SortedPolicies *btree.BTreeG[PolKV] OrderedPolicies []PolKV }
func NewTierInfo ¶
type VXLANResolver ¶
type VXLANResolver struct {
// contains filtered or unexported fields
}
VXLANResolver is responsible for resolving node IPs and node config to calculate the VTEP for each host. It registers for:
- model.HostIPKey
- model.HostConfigKey
VXLAN routes are calculated by the L3RouteResolver, and to be valid for the dataplane must target a VXLAN tunnel endpoint (VTEP) which comprises a node IP address, VXLAN tunnel address, and a deterministically calculated MAC address. The VXLAN resolver calculates the VTEPs. The dataplane is responsible for only programming routes once the VTEP is ready.
For each VTEP, this component will send a *proto.VXLANTunnelEndpointUpdate.
If a VTEP is no longer fully specified (e.g., due to a vxlan tunnel address removal), a *proto.VXLANTunnelEndpointRemove message is sent.
If a VTEP changes (e.g., due to a vxlan tunnel address changing), this component will treat it as a delete followed by an add.
func NewVXLANResolver ¶
func NewVXLANResolver(hostname string, callbacks vxlanCallbacks, useNodeResourceUpdates bool) *VXLANResolver
func (*VXLANResolver) OnHostConfigUpdate ¶
func (c *VXLANResolver) OnHostConfigUpdate(update api.Update) (_ bool)
OnHostConfigUpdate gets called whenever a node's host config changes. We only care about VXLAN tunnel IP/MAC address updates. On an add/update, we need to check if there are VTEPs which are now valid, and trigger programming of them to the data plane. On a delete, we need to withdraw any VTEPs associated with the node.
func (*VXLANResolver) OnHostIPUpdate ¶
func (c *VXLANResolver) OnHostIPUpdate(update api.Update) (_ bool)
OnHostIPUpdate gets called whenever a node IP address changes. On an add/update, we need to check if there is a VTEP which is now valid, and trigger programming of them to the data plane. On a delete, we need to withdraw the VTEP associated with the node.
func (*VXLANResolver) OnResourceUpdate ¶
func (c *VXLANResolver) OnResourceUpdate(update api.Update) (_ bool)
func (*VXLANResolver) RegisterWith ¶
func (c *VXLANResolver) RegisterWith(allUpdDispatcher *dispatcher.Dispatcher)
type ValidationFilter ¶
type ValidationFilter struct {
// contains filtered or unexported fields
}
func NewValidationFilter ¶
func NewValidationFilter(sink api.SyncerCallbacks, felixConfig *config.Config) *ValidationFilter
func (*ValidationFilter) OnStatusUpdated ¶
func (v *ValidationFilter) OnStatusUpdated(status api.SyncStatus)
func (*ValidationFilter) OnUpdates ¶
func (v *ValidationFilter) OnUpdates(updates []api.Update)
Source Files ¶
- active_rules_calculator.go
- async_calc_graph.go
- async_decoupler.go
- calc_graph.go
- config_batcher.go
- dataplane_passthru.go
- doc.go
- encapsulation_resolver.go
- event_sequencer.go
- l3_route_resolver.go
- policy_resolver.go
- policy_sorter.go
- profile_decoder.go
- rule_convert.go
- rule_scanner.go
- stats_collector.go
- validation_filter.go
- vxlan_resolver.go