diff --git a/api/pkg/apis/projectcalico/v3/felixconfig.go b/api/pkg/apis/projectcalico/v3/felixconfig.go
index 755212cd082..8d33bb105fb 100644
--- a/api/pkg/apis/projectcalico/v3/felixconfig.go
+++ b/api/pkg/apis/projectcalico/v3/felixconfig.go
@@ -63,6 +63,13 @@ const (
NFTablesModeDisabled = "Disabled"
)
+type ProgramRouteMode string
+
+const (
+ ProgramRouteModeNone ProgramRouteMode = "None"
+ ProgramRouteModeIPIP ProgramRouteMode = "IPIP"
+)
+
// +kubebuilder:validation:Enum=DoNothing;Enable;Disable
type AWSSrcDstCheckOption string
@@ -324,6 +331,8 @@ type FelixConfigurationSpec struct {
// IPIPMTU controls the MTU to set on the IPIP tunnel device. Optional as Felix auto-detects the MTU based on the
// MTU of the host's interfaces. [Default: 0 (auto-detect)]
IPIPMTU *int `json:"ipipMTU,omitempty" confignamev1:"IpInIpMtu"`
+ // ProgramRoutes specifies what type of routes Felix should program. [Default: None]. [Default: None]
+ ProgramRoutes *ProgramRouteMode `json:"programRoutes,omitempty" validate:"omitempty,oneof=None IPIP"`
// VXLANEnabled overrides whether Felix should create the VXLAN tunnel device for IPv4 VXLAN networking.
// Optional as Felix determines this based on the existing IP pools. [Default: nil (unset)]
diff --git a/api/pkg/apis/projectcalico/v3/zz_generated.deepcopy.go b/api/pkg/apis/projectcalico/v3/zz_generated.deepcopy.go
index 273d69857af..fe8273af68c 100644
--- a/api/pkg/apis/projectcalico/v3/zz_generated.deepcopy.go
+++ b/api/pkg/apis/projectcalico/v3/zz_generated.deepcopy.go
@@ -1211,6 +1211,11 @@ func (in *FelixConfigurationSpec) DeepCopyInto(out *FelixConfigurationSpec) {
*out = new(int)
**out = **in
}
+ if in.ProgramRoutes != nil {
+ in, out := &in.ProgramRoutes, &out.ProgramRoutes
+ *out = new(ProgramRouteMode)
+ **out = **in
+ }
if in.VXLANEnabled != nil {
in, out := &in.VXLANEnabled, &out.VXLANEnabled
*out = new(bool)
diff --git a/api/pkg/openapi/generated.openapi.go b/api/pkg/openapi/generated.openapi.go
index ef1ed3895c6..e6f4fad666c 100644
--- a/api/pkg/openapi/generated.openapi.go
+++ b/api/pkg/openapi/generated.openapi.go
@@ -2608,6 +2608,13 @@ func schema_pkg_apis_projectcalico_v3_FelixConfigurationSpec(ref common.Referenc
Format: "int32",
},
},
+ "programRoutes": {
+ SchemaProps: spec.SchemaProps{
+ Description: "ProgramRoutes specifies what type of routes Felix should program. [Default: None]. [Default: None]",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
"vxlanEnabled": {
SchemaProps: spec.SchemaProps{
Description: "VXLANEnabled overrides whether Felix should create the VXLAN tunnel device for IPv4 VXLAN networking. Optional as Felix determines this based on the existing IP pools. [Default: nil (unset)]",
diff --git a/charts/calico/templates/calico-config.yaml b/charts/calico/templates/calico-config.yaml
index 6b00f53649b..fd00e37a44d 100644
--- a/charts/calico/templates/calico-config.yaml
+++ b/charts/calico/templates/calico-config.yaml
@@ -41,6 +41,8 @@ data:
# Configure the backend to use.
{{- if or (.Values.flannel_migration) (.Values.vxlan) }}
calico_backend: "vxlan"
+{{- else if (.Values.ipip) }}
+ calico_backend: "ipip"
{{- else }}
calico_backend: "bird"
{{- end }}
diff --git a/charts/calico/templates/calico-node.yaml b/charts/calico/templates/calico-node.yaml
index 58b5e548d21..5200252d1bf 100644
--- a/charts/calico/templates/calico-node.yaml
+++ b/charts/calico/templates/calico-node.yaml
@@ -323,6 +323,9 @@ spec:
# Enable or Disable VXLAN on the default IPv6 IP pool.
- name: CALICO_IPV6POOL_VXLAN
value: "{{- if .Values.vxlan -}} CrossSubnet {{- else -}} Never {{- end -}}"
+ # Set if Felix should program IPIP routes or not.
+ - name: FELIX_PROGRAMROUTES
+ value: "{{ if .Values.ipip -}} IPIP {{- else -}} None {{- end -}}"
# Set MTU for tunnel device used if ipip is enabled
- name: FELIX_IPINIPMTU
valueFrom:
@@ -406,7 +409,7 @@ spec:
command:
- /bin/calico-node
- -felix-live
-{{- if and (eq .Values.network "calico") (not .Values.flannel_migration) (not .Values.vxlan) }}
+{{- if and (eq .Values.network "calico") (not .Values.flannel_migration) (not .Values.vxlan) (not .Values.ipip) }}
- -bird-live
{{- end }}
periodSeconds: 10
@@ -419,7 +422,7 @@ spec:
command:
- /bin/calico-node
- -felix-ready
-{{- if and (not .Values.flannel_migration) (not .Values.vxlan) }}
+{{- if and (not .Values.flannel_migration) (not .Values.vxlan) (not .Values.ipip) }}
- -bird-ready
{{- end }}
{{- else if eq .Values.network "flannel" }}
diff --git a/charts/values/calico-ipip.yaml b/charts/values/calico-ipip.yaml
new file mode 100644
index 00000000000..603289215e6
--- /dev/null
+++ b/charts/values/calico-ipip.yaml
@@ -0,0 +1,3 @@
+datastore: kubernetes
+network: calico
+ipip: true
diff --git a/felix/calc/calc_graph.go b/felix/calc/calc_graph.go
index 66c0053cbc3..47323940230 100644
--- a/felix/calc/calc_graph.go
+++ b/felix/calc/calc_graph.go
@@ -392,7 +392,8 @@ func NewCalculationGraph(
hostIPPassthru.RegisterWith(allUpdDispatcher)
cg.hostIPPassthru = hostIPPassthru
- if conf.BPFEnabled || conf.Encapsulation.VXLANEnabled || conf.Encapsulation.VXLANEnabledV6 || conf.WireguardEnabled || conf.WireguardEnabledV6 {
+ if conf.BPFEnabled || conf.Encapsulation.VXLANEnabled || conf.Encapsulation.VXLANEnabledV6 ||
+ conf.WireguardEnabled || conf.WireguardEnabledV6 || conf.ProgramIPIPRoutes() {
// Calculate simple node-ownership routes.
// ...
// Dispatcher (all updates)
diff --git a/felix/config/config_params.go b/felix/config/config_params.go
index 002b43718cd..cfab0e1d1cc 100644
--- a/felix/config/config_params.go
+++ b/felix/config/config_params.go
@@ -353,6 +353,7 @@ type Config struct {
IpInIpEnabled *bool `config:"*bool;"`
IpInIpMtu int `config:"int;0"`
IpInIpTunnelAddr net.IP `config:"ipv4;"`
+ ProgramRoutes string `config:"oneof(None,IPIP);None"`
// Feature enablement. Can be either "Enabled" or "Disabled". Note, this governs the
// programming of NAT mappings derived from Kubernetes pod annotations. OpenStack floating
@@ -1241,6 +1242,10 @@ func (config *Config) RouteTableIndices() []idalloc.IndexRange {
return config.RouteTableRanges
}
+func (config *Config) ProgramIPIPRoutes() bool {
+ return config.ProgramRoutes == string(v3.ProgramRouteModeIPIP)
+}
+
func New() *Config {
if knownParams == nil {
loadParams()
diff --git a/felix/dataplane/driver.go b/felix/dataplane/driver.go
index b49fb078191..69c3dece274 100644
--- a/felix/dataplane/driver.go
+++ b/felix/dataplane/driver.go
@@ -310,6 +310,7 @@ func StartDataplaneDriver(
RouteSyncDisabled: configParams.RouteSyncDisabled,
},
IPIPMTU: configParams.IpInIpMtu,
+ ProgramIPIPRoutes: configParams.ProgramIPIPRoutes(),
VXLANMTU: configParams.VXLANMTU,
VXLANMTUV6: configParams.VXLANMTUV6,
VXLANPort: configParams.VXLANPort,
diff --git a/felix/dataplane/linux/bpf_ep_mgr.go b/felix/dataplane/linux/bpf_ep_mgr.go
index fc60474fc05..32a122bdea9 100644
--- a/felix/dataplane/linux/bpf_ep_mgr.go
+++ b/felix/dataplane/linux/bpf_ep_mgr.go
@@ -549,7 +549,11 @@ func newBPFEndpointManager(
specialInterfaces := []string{"egress.calico"}
if config.RulesConfig.IPIPEnabled {
- specialInterfaces = append(specialInterfaces, dataplanedefs.IPIPIfaceName)
+ if config.ProgramIPIPRoutes {
+ specialInterfaces = append(specialInterfaces, dataplanedefs.IPIPIfaceNameV4)
+ } else {
+ specialInterfaces = append(specialInterfaces, dataplanedefs.IPIPDefaultIfaceNameV4)
+ }
}
if config.RulesConfig.VXLANEnabled {
specialInterfaces = append(specialInterfaces, dataplanedefs.VXLANIfaceNameV4)
diff --git a/felix/dataplane/linux/dataplanedefs/dataplane_defs.go b/felix/dataplane/linux/dataplanedefs/dataplane_defs.go
index 9c3ad4cc4a5..20eed7f729f 100644
--- a/felix/dataplane/linux/dataplanedefs/dataplane_defs.go
+++ b/felix/dataplane/linux/dataplanedefs/dataplane_defs.go
@@ -17,10 +17,13 @@ package dataplanedefs
import "github.com/vishvananda/netlink"
const (
- IPIPIfaceName = "tunl0"
- VXLANIfaceNameV4 = "vxlan.calico"
- VXLANIfaceNameV6 = "vxlan-v6.calico"
- VXLANDefaultProto netlink.RouteProtocol = 80
+ VXLANIfaceNameV4 = "vxlan.calico"
+ VXLANIfaceNameV6 = "vxlan-v6.calico"
+
+ IPIPIfaceNameV4 = "ipip.calico"
+ IPIPDefaultIfaceNameV4 = "tunl0"
+
+ DefaultRoutingProto netlink.RouteProtocol = 80
BPFInDev = "bpfin.cali"
BPFOutDev = "bpfout.cali"
diff --git a/felix/dataplane/linux/int_dataplane.go b/felix/dataplane/linux/int_dataplane.go
index 1bfd4fd4d79..be236f9e8d2 100644
--- a/felix/dataplane/linux/int_dataplane.go
+++ b/felix/dataplane/linux/int_dataplane.go
@@ -149,10 +149,13 @@ type Config struct {
NodeZone string
IPv6Enabled bool
RuleRendererOverride rules.RuleRenderer
- IPIPMTU int
- VXLANMTU int
- VXLANMTUV6 int
- VXLANPort int
+
+ IPIPMTU int
+ ProgramIPIPRoutes bool
+
+ VXLANMTU int
+ VXLANMTUV6 int
+ VXLANPort int
MaxIPSetSize int
@@ -319,6 +322,7 @@ type InternalDataplane struct {
ipSets []dpsets.IPSetsDataplane
ipipManager *ipipManager
+ ipipParentC chan string
vxlanManager *vxlanManager
vxlanParentC chan string
@@ -1035,10 +1039,33 @@ func NewIntDataplaneDriver(config Config) *InternalDataplane {
dp.RegisterManager(newFloatingIPManager(natTableV4, ruleRenderer, 4, config.FloatingIPsEnabled))
dp.RegisterManager(newMasqManager(ipSetsV4, natTableV4, ruleRenderer, config.MaxIPSetSize, 4))
if config.RulesConfig.IPIPEnabled {
- log.Info("IPIP enabled, starting thread to keep tunnel configuration in sync.")
- // Add a manager to keep the all-hosts IP set up to date.
- dp.ipipManager = newIPIPManager(ipSetsV4, config.MaxIPSetSize, config.ExternalNodesCidrs)
- go dp.ipipManager.KeepIPIPDeviceInSync(config.IPIPMTU, config.RulesConfig.IPIPTunnelAddress, dataplaneFeatures.ChecksumOffloadBroken)
+ if config.ProgramIPIPRoutes {
+ log.Info("IPIP enabled, starting thread to keep tunnel configuration in sync.")
+ // Add a manager to keep the all-hosts IP set up to date.
+ dp.ipipManager = newIPIPManager(
+ ipSetsV4,
+ routeTableV4,
+ dataplanedefs.IPIPIfaceNameV4,
+ config,
+ dp.loopSummarizer,
+ 4,
+ featureDetector,
+ )
+ dp.ipipParentC = make(chan string, 1)
+ go dp.ipipManager.KeepCalicoIPIPDeviceInSync(context.Background(), dataplaneFeatures.ChecksumOffloadBroken, 10*time.Second, dp.ipipParentC)
+ } else {
+ log.Info("IPIP using BGP enabled, starting thread to keep tunnel configuration in sync.")
+ dp.ipipManager = newIPIPManager(
+ ipSetsV4,
+ nil,
+ dataplanedefs.IPIPDefaultIfaceNameV4,
+ config,
+ dp.loopSummarizer,
+ 4,
+ featureDetector,
+ )
+ go dp.ipipManager.KeepIPIPDeviceInSync(dataplaneFeatures.ChecksumOffloadBroken)
+ }
dp.RegisterManager(dp.ipipManager) // IPv4-only
} else {
// Only clean up IPIP addresses if IPIP is implicitly disabled (no IPIP pools and not explicitly set in FelixConfig)
@@ -2078,6 +2105,8 @@ func (d *InternalDataplane) loopUpdatingDataplane() {
d.vxlanManager.OnParentNameUpdate(name)
case name := <-d.vxlanParentCV6:
d.vxlanManagerV6.OnParentNameUpdate(name)
+ case name := <-d.ipipParentC:
+ d.ipipManager.OnParentNameUpdate(name)
case <-ipSetsRefreshC:
log.Debug("Refreshing IP sets state")
d.forceIPSetsRefresh = true
diff --git a/felix/dataplane/linux/ipip_mgr.go b/felix/dataplane/linux/ipip_mgr.go
index 36ef82c543a..5f0933e5db8 100644
--- a/felix/dataplane/linux/ipip_mgr.go
+++ b/felix/dataplane/linux/ipip_mgr.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2021 Tigera, Inc. All rights reserved.
+// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,17 +15,28 @@
package intdataplane
import (
+ "context"
+ "errors"
"fmt"
"net"
+ "sync"
+ "syscall"
"time"
+ "github.com/sirupsen/logrus"
log "github.com/sirupsen/logrus"
"github.com/vishvananda/netlink"
dpsets "github.com/projectcalico/calico/felix/dataplane/ipsets"
+ "github.com/projectcalico/calico/felix/dataplane/linux/dataplanedefs"
+ "github.com/projectcalico/calico/felix/environment"
"github.com/projectcalico/calico/felix/ethtool"
+ "github.com/projectcalico/calico/felix/ip"
"github.com/projectcalico/calico/felix/ipsets"
+ "github.com/projectcalico/calico/felix/logutils"
+ "github.com/projectcalico/calico/felix/netlinkshim"
"github.com/projectcalico/calico/felix/proto"
+ "github.com/projectcalico/calico/felix/routetable"
"github.com/projectcalico/calico/felix/rules"
)
@@ -35,57 +46,434 @@ import (
//
// ipipManager also takes care of the configuration of the IPIP tunnel device.
type ipipManager struct {
- ipsetsDataplane dpsets.IPSetsDataplane
+ // Our dependencies.
+ routeTable routetable.Interface
+ parentIfaceName string
- // activeHostnameToIP maps hostname to string IP address. We don't bother to parse into
+ // activeHostnameToIP maps hostname to string IP address. We don't bother to parse into
// net.IPs because we're going to pass them directly to the IPSet API.
activeHostnameToIP map[string]string
- ipSetInSync bool
+ ipSetDirty bool
+ ipsetsDataplane dpsets.IPSetsDataplane
- // Config for creating/refreshing the IP set.
- ipSetMetadata ipsets.IPSetMetadata
+ // Hold pending updates.
+ routesByDest map[string]*proto.RouteUpdate
+ localIPAMBlocks map[string]*proto.RouteUpdate
+
+ // IPIP configuration.
+ ipipDevice string
+ ipVersion uint8
- // Dataplane shim.
- dataplane ipipDataplane
+ // Local information
+ hostname string
+ hostAddr string
+ myAddrLock sync.Mutex
+ myAddrChangedC chan struct{}
+ // Indicates if configuration has changed since the last apply.
+ routesDirty bool
+ // Config for creating/refreshing the IP set.
+ ipSetMetadata ipsets.IPSetMetadata
// Configured list of external node ip cidr's to be added to the ipset.
externalNodeCIDRs []string
+ nlHandle netlinkHandle
+ dpConfig Config
+ routeProtocol netlink.RouteProtocol
+
+ // Log context
+ logCtx *logrus.Entry
+ opRecorder logutils.OpRecorder
}
func newIPIPManager(
ipsetsDataplane dpsets.IPSetsDataplane,
- maxIPSetSize int,
- externalNodeCidrs []string,
+ mainRouteTable routetable.Interface,
+ deviceName string,
+ dpConfig Config,
+ opRecorder logutils.OpRecorder,
+ ipVersion uint8,
+ featureDetector environment.FeatureDetectorIface,
) *ipipManager {
- return newIPIPManagerWithShim(ipsetsDataplane, maxIPSetSize, realIPIPNetlink{}, externalNodeCidrs)
+ nlHandle, _ := netlinkshim.NewRealNetlink()
+ return newIPIPManagerWithShim(
+ ipsetsDataplane,
+ mainRouteTable,
+ deviceName,
+ dpConfig,
+ opRecorder,
+ nlHandle,
+ ipVersion,
+ )
}
func newIPIPManagerWithShim(
ipsetsDataplane dpsets.IPSetsDataplane,
- maxIPSetSize int,
- dataplane ipipDataplane,
- externalNodeCIDRs []string,
+ mainRouteTable routetable.Interface,
+ deviceName string,
+ dpConfig Config,
+ opRecorder logutils.OpRecorder,
+ nlHandle netlinkHandle,
+ ipVersion uint8,
) *ipipManager {
- ipipMgr := &ipipManager{
+ if ipVersion != 4 {
+ logrus.Errorf("IPIP manager only supports IPv4")
+ return nil
+ }
+ return &ipipManager{
ipsetsDataplane: ipsetsDataplane,
activeHostnameToIP: map[string]string{},
- dataplane: dataplane,
+ myAddrChangedC: make(chan struct{}, 1),
ipSetMetadata: ipsets.IPSetMetadata{
- MaxSize: maxIPSetSize,
+ MaxSize: dpConfig.MaxIPSetSize,
SetID: rules.IPSetIDAllHostNets,
Type: ipsets.IPSetTypeHashNet,
},
- externalNodeCIDRs: externalNodeCIDRs,
+ hostname: dpConfig.Hostname,
+ routeTable: mainRouteTable,
+ routesByDest: map[string]*proto.RouteUpdate{},
+ localIPAMBlocks: map[string]*proto.RouteUpdate{},
+ ipipDevice: deviceName,
+ ipVersion: ipVersion,
+ externalNodeCIDRs: dpConfig.ExternalNodesCidrs,
+ routesDirty: true,
+ ipSetDirty: true,
+ dpConfig: dpConfig,
+ nlHandle: nlHandle,
+ routeProtocol: calculateRouteProtocol(dpConfig),
+ logCtx: logrus.WithField("ipVersion", ipVersion),
+ opRecorder: opRecorder,
+ }
+}
+
+func (m *ipipManager) OnUpdate(msg interface{}) {
+ switch msg := msg.(type) {
+ case *proto.RouteUpdate:
+ cidr, err := ip.CIDRFromString(msg.Dst)
+ if err != nil {
+ m.logCtx.WithError(err).WithField("msg", msg).Warning("Unable to parse route update destination. Skipping update.")
+ return
+ }
+ if m.ipVersion != cidr.Version() {
+ // Skip since the update is for a mismatched IP version
+ return
+ }
+
+ // In case the route changes type to one we no longer care about...
+ m.deleteRoute(msg.Dst)
+
+ // Process remote IPAM blocks.
+ if msg.Type == proto.RouteType_REMOTE_WORKLOAD && msg.IpPoolType == proto.IPPoolType_IPIP {
+ m.logCtx.WithField("msg", msg).Debug("IPIP data plane received route update")
+ m.routesByDest[msg.Dst] = msg
+ m.routesDirty = true
+ }
+
+ // Process IPAM blocks that aren't associated to a single or /32 local workload
+ if routeIsLocalBlock(msg, proto.IPPoolType_IPIP) {
+ m.logCtx.WithField("msg", msg).Debug("IPIP data plane received route update for IPAM block")
+ m.localIPAMBlocks[msg.Dst] = msg
+ m.routesDirty = true
+ } else if _, ok := m.localIPAMBlocks[msg.Dst]; ok {
+ m.logCtx.WithField("msg", msg).Debug("IPIP data plane IPAM block changed to something else")
+ delete(m.localIPAMBlocks, msg.Dst)
+ m.routesDirty = true
+ }
+
+ case *proto.RouteRemove:
+ // Check to make sure that we are dealing with messages of the correct IP version.
+ cidr, err := ip.CIDRFromString(msg.Dst)
+ if err != nil {
+ m.logCtx.WithError(err).WithField("msg", msg).Warning("Unable to parse route removal destination. Skipping update.")
+ return
+ }
+ if m.ipVersion != cidr.Version() {
+ // Skip since the update is for a mismatched IP version
+ return
+ }
+ m.deleteRoute(msg.Dst)
+ case *proto.HostMetadataUpdate:
+ m.logCtx.WithField("hostname", msg.Hostname).Debug("Host update/create")
+ if msg.Hostname == m.hostname {
+ m.setLocalHostAddr(msg.Ipv4Addr)
+ }
+ m.activeHostnameToIP[msg.Hostname] = msg.Ipv4Addr
+ m.ipSetDirty = true
+ m.routesDirty = true
+ case *proto.HostMetadataRemove:
+ m.logCtx.WithField("hostname", msg.Hostname).Debug("Host removed")
+ if msg.Hostname == m.hostname {
+ m.setLocalHostAddr("")
+ }
+ delete(m.activeHostnameToIP, msg.Hostname)
+ m.ipSetDirty = true
+ m.routesDirty = true
+ }
+}
+
+func (m *ipipManager) deleteRoute(dst string) {
+ _, exists := m.routesByDest[dst]
+ if exists {
+ logrus.Debug("deleting route dst ", dst)
+ // In case the route changes type to one we no longer care about...
+ delete(m.routesByDest, dst)
+ m.routesDirty = true
+ }
+
+ if _, exists := m.localIPAMBlocks[dst]; exists {
+ logrus.Debug("deleting local ipam dst ", dst)
+ delete(m.localIPAMBlocks, dst)
+ m.routesDirty = true
+ }
+}
+
+func (m *ipipManager) setLocalHostAddr(address string) {
+ m.myAddrLock.Lock()
+ defer m.myAddrLock.Unlock()
+ m.hostAddr = address
+ select {
+ case m.myAddrChangedC <- struct{}{}:
+ default:
+ }
+}
+
+func (m *ipipManager) getLocalHostAddr() string {
+ m.myAddrLock.Lock()
+ defer m.myAddrLock.Unlock()
+ return m.hostAddr
+}
+
+func (m *ipipManager) CompleteDeferredWork() error {
+ if m.ipSetDirty {
+ m.updateAllHostsIPSet()
+ m.ipSetDirty = false
+ }
+ // Program IPIP routes, only if ProgramIPIPRoutes is true
+ if !m.dpConfig.ProgramIPIPRoutes {
+ m.routesDirty = false
+ return nil
+ }
+ if m.parentIfaceName == "" {
+ // Background goroutine hasn't sent us the parent interface name yet,
+ // but we can look it up synchronously. OnParentNameUpdate will handle
+ // any duplicate update when it arrives.
+ parent, err := m.getParentInterface()
+ if err != nil {
+ // If we can't look up the parent interface then we're in trouble.
+ // It likely means that our local address is missing or conflicting. We
+ // won't be able to program same-subnet routes at all, so we'll
+ // fall back to programming all tunnel routes. However, unless the
+ // ipip device happens to already exist, we won't be able to
+ // program tunnel routes either. The RouteTable will be the
+ // component that spots that the interface is missing.
+ //
+ // Note: this behaviour changed when we unified all the main
+ // RouteTable instances into one. Before that change, we chose to
+ // defer creation of our "no encap" RouteTable, so that the
+ // dataplane would stay untouched until the conflict was resolved.
+ // With only a single RouteTable, we need a different fallback.
+ m.logCtx.WithError(err).WithField("local address", m.getLocalHostAddr()).Error(
+ "Failed to find ipip tunnel device parent. Missing/conflicting local address? ipip route " +
+ "programming is likely to fail.")
+ } else {
+ m.parentIfaceName = parent.Attrs().Name
+ m.routesDirty = true
+ }
+ }
+ if m.routesDirty {
+ err := m.updateRoutes()
+ if err != nil {
+ return err
+ }
+ m.routesDirty = false
+ }
+ m.logCtx.Info("IPIP Manager completed deferred work")
+ return nil
+}
+
+func (m *ipipManager) updateAllHostsIPSet() {
+ // For simplicity (and on the assumption that host add/removes are rare) rewrite
+ // the whole IP set whenever we get a change. To replace this with delta handling
+ // would require reference counting the IPs because it's possible for two hosts
+ // to (at least transiently) share an IP. That would add occupancy and make the
+ // code more complex.
+ m.logCtx.Info("All-hosts IP set out-of sync, refreshing it.")
+ members := make([]string, 0, len(m.activeHostnameToIP)+len(m.externalNodeCIDRs))
+ for _, ip := range m.activeHostnameToIP {
+ members = append(members, ip)
+ }
+ members = append(members, m.externalNodeCIDRs...)
+ m.ipsetsDataplane.AddOrReplaceIPSet(m.ipSetMetadata, members)
+}
+
+func (m *ipipManager) updateRoutes() error {
+ // Iterate through all of our L3 routes and send them through to the
+ // RouteTable. It's a little wasteful to recalculate everything but the
+ // RouteTable will avoid making dataplane changes for routes that haven't
+ // changed.
+ m.opRecorder.RecordOperation("update-ipip-routes")
+
+ var ipipRoutes []routetable.Target
+ var noEncapRoutes []routetable.Target
+ for _, r := range m.routesByDest {
+ logCtx := m.logCtx.WithField("route", r)
+ cidr, err := ip.CIDRFromString(r.Dst)
+ if err != nil {
+ // Don't block programming of other routes if somehow we receive one with a bad dst.
+ logCtx.WithError(err).Warn("Failed to parse IPIP route destination")
+ continue
+ }
+
+ if noEncapRoute := noEncapRoute(m.parentIfaceName, cidr, r, m.routeProtocol); noEncapRoute != nil {
+ // We've got everything we need to program this route as a no-encap route.
+ noEncapRoutes = append(noEncapRoutes, *noEncapRoute)
+ logCtx.WithField("route", r).Debug("Destination in same subnet, using no-encap route.")
+ } else if ipipRoute := m.tunneledRoute(cidr, r); ipipRoute != nil {
+ ipipRoutes = append(ipipRoutes, *ipipRoute)
+ logCtx.WithField("route", ipipRoute).Debug("adding ipip route to list for addition")
+ } else {
+ logCtx.Debug("Not enough information to program route; missing target host address?")
+ }
+ }
+
+ m.logCtx.WithField("ipipRoutes", ipipRoutes).Debug("IPIP manager setting IPIP tunnled routes")
+ m.routeTable.SetRoutes(routetable.RouteClassIPIPTTunnel, m.ipipDevice, ipipRoutes)
+
+ bhRoutes := blackholeRoutes(m.localIPAMBlocks, m.routeProtocol)
+ m.logCtx.WithField("balckholes", bhRoutes).Debug("IPIP manager setting blackhole routes")
+ m.routeTable.SetRoutes(routetable.RouteClassIPAMBlockDrop, routetable.InterfaceNone, bhRoutes)
+
+ if m.parentIfaceName != "" {
+ m.logCtx.WithFields(logrus.Fields{
+ "noEncapDevice": m.parentIfaceName,
+ "routes": noEncapRoutes,
+ }).Debug("IPIP manager sending unencapsulated L3 updates")
+ m.routeTable.SetRoutes(routetable.RouteClassIPIPTSameSubnet, m.parentIfaceName, noEncapRoutes)
+ } else {
+ return errors.New("no encap route table not set, will defer adding routes")
+ }
+
+ return nil
+}
+
+func (m *ipipManager) tunneledRoute(cidr ip.CIDR, r *proto.RouteUpdate) *routetable.Target {
+ // Extract the gateway addr for this route based on its remote address.
+ remoteAddr, ok := m.activeHostnameToIP[r.DstNodeName]
+ if !ok {
+ // When the local address arrives, it'll set routesDirty=true so this loop will execute again.
+ return nil
}
- return ipipMgr
+
+ ipipRoute := routetable.Target{
+ Type: routetable.TargetTypeOnLink,
+ CIDR: cidr,
+ GW: ip.FromString(remoteAddr),
+ Protocol: m.routeProtocol,
+ }
+ return &ipipRoute
+}
+
+func (m *ipipManager) OnParentNameUpdate(name string) {
+ if name == "" {
+ m.logCtx.Warn("Empty parent interface name? Ignoring.")
+ return
+ }
+ if name == m.parentIfaceName {
+ return
+ }
+ if m.parentIfaceName != "" {
+ // We're changing parent interface, remove the old routes.
+ m.routeTable.SetRoutes(routetable.RouteClassIPIPTSameSubnet, m.parentIfaceName, nil)
+ }
+ m.parentIfaceName = name
+ m.routesDirty = true
}
// KeepIPIPDeviceInSync is a goroutine that configures the IPIP tunnel device, then periodically
// checks that it is still correctly configured.
-func (d *ipipManager) KeepIPIPDeviceInSync(mtu int, address net.IP, xsumBroken bool) {
- log.Info("IPIP thread started.")
+func (m *ipipManager) KeepCalicoIPIPDeviceInSync(
+ ctx context.Context,
+ xsumBroken bool,
+ wait time.Duration,
+ parentNameC chan string,
+) {
+ mtu := m.dpConfig.IPIPMTU
+ address := m.dpConfig.RulesConfig.IPIPTunnelAddress
+ m.logCtx.WithFields(logrus.Fields{
+ "device": m.ipipDevice,
+ "mtu": mtu,
+ "xsumBroken": xsumBroken,
+ "wait": wait,
+ }).Info("IPIP device thread started.")
+ logNextSuccess := true
+ parentName := ""
+
+ sleepMonitoringChans := func(maxDuration time.Duration) {
+ timer := time.NewTimer(maxDuration)
+ defer timer.Stop()
+ select {
+ case <-timer.C:
+ case <-ctx.Done():
+ logrus.Debug("Sleep returning early: context finished.")
+ case <-m.myAddrChangedC:
+ logrus.Debug("Sleep returning early: local address changed.")
+ }
+ }
+
+ for ctx.Err() == nil {
+ localAddr := m.getLocalHostAddr()
+ if localAddr == "" {
+ m.logCtx.Debug("Missing local address information, retrying...")
+ sleepMonitoringChans(10 * time.Second)
+ continue
+ }
+
+ parent, err := m.getParentInterface()
+ if err != nil {
+ m.logCtx.WithError(err).Warn("Failed to find IPIP tunnel device parent, retrying...")
+ sleepMonitoringChans(1 * time.Second)
+ continue
+ }
+
+ m.logCtx.WithField("localAddr", address).Debug("Configuring IPIP device")
+ err = m.configureIPIPDevice(mtu, address, xsumBroken)
+ if err != nil {
+ m.logCtx.WithError(err).Warn("Failed to configure IPIP tunnel device, retrying...")
+ logNextSuccess = true
+ sleepMonitoringChans(1 * time.Second)
+ continue
+ }
+
+ newParentName := parent.Attrs().Name
+ if newParentName != parentName {
+ // Send a message back to the main loop to tell it to update the
+ // routing tables.
+ m.logCtx.Infof("IPIP device parent changed from %q to %q", parentName, newParentName)
+ select {
+ case parentNameC <- newParentName:
+ parentName = newParentName
+ case <-m.myAddrChangedC:
+ m.logCtx.Info("My address changed; restarting configuration.")
+ continue
+ case <-ctx.Done():
+ continue
+ }
+ }
+
+ if logNextSuccess {
+ m.logCtx.Info("IPIP tunnel device configured")
+ logNextSuccess = false
+ }
+ sleepMonitoringChans(wait)
+ }
+ m.logCtx.Info("KeepIPIPDeviceInSync exiting due to context.")
+}
+
+// KeepIPIPDeviceInSync is a goroutine that configures the IPIP tunnel device, then periodically
+// checks that it is still correctly configured.
+func (m *ipipManager) KeepIPIPDeviceInSync(xsumBroken bool) {
+ log.WithField("device", m.ipipDevice).Info("IPIP device thread started.")
for {
- err := d.configureIPIPDevice(mtu, address, xsumBroken)
+ err := m.configureIPIPDevice(m.dpConfig.IPIPMTU, m.dpConfig.RulesConfig.IPIPTunnelAddress, xsumBroken)
if err != nil {
log.WithError(err).Warn("Failed configure IPIP tunnel device, retrying...")
time.Sleep(1 * time.Second)
@@ -95,27 +483,77 @@ func (d *ipipManager) KeepIPIPDeviceInSync(mtu int, address net.IP, xsumBroken b
}
}
+// getParentInterface returns the parent interface for the given local address. This link returned is nil
+// if, and only if, an error occurred
+func (m *ipipManager) getParentInterface() (netlink.Link, error) {
+ localAddr := m.getLocalHostAddr()
+ if localAddr == "" {
+ return nil, fmt.Errorf("local address not found")
+ }
+
+ m.logCtx.WithField("local address", localAddr).Debug("Getting parent interface")
+ links, err := m.nlHandle.LinkList()
+ if err != nil {
+ return nil, err
+ }
+
+ for _, link := range links {
+ addrs, err := m.nlHandle.AddrList(link, netlink.FAMILY_V4)
+ if err != nil {
+ return nil, err
+ }
+ for _, addr := range addrs {
+ if addr.IPNet.IP.String() == localAddr {
+ m.logCtx.Debugf("Found parent interface: %s", link)
+ return link, nil
+ }
+ }
+ }
+ return nil, fmt.Errorf("Unable to find parent interface with address %s", localAddr)
+}
+
// configureIPIPDevice ensures the IPIP tunnel device is up and configures correctly.
-func (d *ipipManager) configureIPIPDevice(mtu int, address net.IP, xsumBroken bool) error {
+func (m *ipipManager) configureIPIPDevice(mtu int, address net.IP, xsumBroken bool) error {
logCxt := log.WithFields(log.Fields{
"mtu": mtu,
"tunnelAddr": address,
+ "device": m.ipipDevice,
})
logCxt.Debug("Configuring IPIP tunnel")
- link, err := d.dataplane.LinkByName("tunl0")
+
+ la := netlink.NewLinkAttrs()
+ la.Name = m.ipipDevice
+ ipip := &netlink.Iptun{
+ LinkAttrs: la,
+ }
+
+ if m.ipipDevice == dataplanedefs.IPIPIfaceNameV4 {
+ localAddr := m.getLocalHostAddr()
+ localIP := net.ParseIP(localAddr)
+ if localIP == nil {
+ return fmt.Errorf("invalid address %v", localAddr)
+ }
+ ipip.Local = localIP
+ }
+
+ link, err := m.nlHandle.LinkByName(m.ipipDevice)
if err != nil {
- log.WithError(err).Info("Failed to get IPIP tunnel device, assuming it isn't present")
+ m.logCtx.WithError(err).Info("Failed to get IPIP tunnel device, assuming it isn't present")
+
// We call out to "ip tunnel", which takes care of loading the kernel module if
// needed. The tunl0 device is actually created automatically by the kernel
// module.
- err := d.dataplane.RunCmd("ip", "tunnel", "add", "tunl0", "mode", "ipip")
- if err != nil {
- log.WithError(err).Warning("Failed to add IPIP tunnel device")
+ if err := m.nlHandle.LinkAdd(ipip); err == syscall.EEXIST {
+ // Device already exists - likely a race.
+ m.logCtx.Debug("IPIP device already exists, likely created by someone else.")
+ } else if err != nil {
+ // Error other than "device exists" - return it.
return err
}
- link, err = d.dataplane.LinkByName("tunl0")
+
+ link, err = m.nlHandle.LinkByName(m.ipipDevice)
if err != nil {
- log.WithError(err).Warning("Failed to get tunnel device")
+ m.logCtx.WithError(err).Warning("Failed to get tunnel device")
return err
}
}
@@ -124,8 +562,8 @@ func (d *ipipManager) configureIPIPDevice(mtu int, address net.IP, xsumBroken bo
oldMTU := attrs.MTU
if oldMTU != mtu {
logCxt.WithField("oldMTU", oldMTU).Info("Tunnel device MTU needs to be updated")
- if err := d.dataplane.LinkSetMTU(link, mtu); err != nil {
- log.WithError(err).Warn("Failed to set tunnel device MTU")
+ if err := m.nlHandle.LinkSetMTU(link, mtu); err != nil {
+ m.logCtx.WithError(err).Warn("Failed to set tunnel device MTU")
return err
}
logCxt.Info("Updated tunnel MTU")
@@ -133,22 +571,26 @@ func (d *ipipManager) configureIPIPDevice(mtu int, address net.IP, xsumBroken bo
// If required, disable checksum offload.
if xsumBroken {
- if err := ethtool.EthtoolTXOff("tunl0"); err != nil {
+ if err := ethtool.EthtoolTXOff(m.ipipDevice); err != nil {
return fmt.Errorf("failed to disable checksum offload: %s", err)
}
}
if attrs.Flags&net.FlagUp == 0 {
logCxt.WithField("flags", attrs.Flags).Info("Tunnel wasn't admin up, enabling it")
- if err := d.dataplane.LinkSetUp(link); err != nil {
- log.WithError(err).Warn("Failed to set tunnel device up")
+ if err := m.nlHandle.LinkSetUp(link); err != nil {
+ m.logCtx.WithError(err).Warn("Failed to set tunnel device up")
return err
}
logCxt.Info("Set tunnel admin up")
}
+ // And the device is up.
+ /*if err := m.nlHandle.LinkSetUp(link); err != nil {
+ return fmt.Errorf("failed to set interface up: %s", err)
+ }*/
- if err := d.setLinkAddressV4("tunl0", address); err != nil {
- log.WithError(err).Warn("Failed to set tunnel device IP")
+ if err := m.setLinkAddressV4(m.ipipDevice, address); err != nil {
+ m.logCtx.WithError(err).Warn("Failed to set tunnel device IP")
return err
}
return nil
@@ -156,21 +598,21 @@ func (d *ipipManager) configureIPIPDevice(mtu int, address net.IP, xsumBroken bo
// setLinkAddressV4 updates the given link to set its local IP address. It removes any other
// addresses.
-func (d *ipipManager) setLinkAddressV4(linkName string, address net.IP) error {
- logCxt := log.WithFields(log.Fields{
+func (m *ipipManager) setLinkAddressV4(linkName string, address net.IP) error {
+ logCxt := m.logCtx.WithFields(logrus.Fields{
"link": linkName,
"addr": address,
})
logCxt.Debug("Setting local IPv4 address on link.")
- link, err := d.dataplane.LinkByName(linkName)
+ link, err := m.nlHandle.LinkByName(linkName)
if err != nil {
- log.WithError(err).WithField("name", linkName).Warning("Failed to get device")
+ m.logCtx.WithError(err).WithField("name", linkName).Warning("Failed to get device")
return err
}
- addrs, err := d.dataplane.AddrList(link, netlink.FAMILY_V4)
+ addrs, err := m.nlHandle.AddrList(link, netlink.FAMILY_V4)
if err != nil {
- log.WithError(err).Warn("Failed to list interface addresses")
+ m.logCtx.WithError(err).Warn("Failed to list interface addresses")
return err
}
@@ -182,8 +624,8 @@ func (d *ipipManager) setLinkAddressV4(linkName string, address net.IP) error {
continue
}
logCxt.WithField("oldAddr", oldAddr).Info("Removing old address")
- if err := d.dataplane.AddrDel(link, &oldAddr); err != nil {
- log.WithError(err).Warn("Failed to delete address")
+ if err := m.nlHandle.AddrDel(link, &oldAddr); err != nil {
+ m.logCtx.WithError(err).Warn("Failed to delete address")
return err
}
}
@@ -198,8 +640,8 @@ func (d *ipipManager) setLinkAddressV4(linkName string, address net.IP) error {
addr := &netlink.Addr{
IPNet: &ipNet,
}
- if err := d.dataplane.AddrAdd(link, addr); err != nil {
- log.WithError(err).WithField("addr", address).Warn("Failed to add address")
+ if err := m.nlHandle.AddrAdd(link, addr); err != nil {
+ m.logCtx.WithError(err).WithField("addr", address).Warn("Failed to add address")
return err
}
}
@@ -207,35 +649,3 @@ func (d *ipipManager) setLinkAddressV4(linkName string, address net.IP) error {
return nil
}
-
-func (d *ipipManager) OnUpdate(msg interface{}) {
- switch msg := msg.(type) {
- case *proto.HostMetadataUpdate:
- log.WithField("hostname", msg.Hostname).Debug("Host update/create")
- d.activeHostnameToIP[msg.Hostname] = msg.Ipv4Addr
- d.ipSetInSync = false
- case *proto.HostMetadataRemove:
- log.WithField("hostname", msg.Hostname).Debug("Host removed")
- delete(d.activeHostnameToIP, msg.Hostname)
- d.ipSetInSync = false
- }
-}
-
-func (m *ipipManager) CompleteDeferredWork() error {
- if !m.ipSetInSync {
- // For simplicity (and on the assumption that host add/removes are rare) rewrite
- // the whole IP set whenever we get a change. To replace this with delta handling
- // would require reference counting the IPs because it's possible for two hosts
- // to (at least transiently) share an IP. That would add occupancy and make the
- // code more complex.
- log.Info("All-hosts IP set out-of sync, refreshing it.")
- members := make([]string, 0, len(m.activeHostnameToIP)+len(m.externalNodeCIDRs))
- for _, ip := range m.activeHostnameToIP {
- members = append(members, ip)
- }
- members = append(members, m.externalNodeCIDRs...)
- m.ipsetsDataplane.AddOrReplaceIPSet(m.ipSetMetadata, members)
- m.ipSetInSync = true
- }
- return nil
-}
diff --git a/felix/dataplane/linux/ipip_mgr_netlink.go b/felix/dataplane/linux/ipip_mgr_netlink.go
deleted file mode 100644
index 6c7a6a0bc99..00000000000
--- a/felix/dataplane/linux/ipip_mgr_netlink.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2017 Tigera, Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package intdataplane
-
-import (
- "errors"
- "os/exec"
-
- "github.com/vishvananda/netlink"
- "golang.org/x/sys/unix"
-)
-
-// ipipDataplane is a shim interface for mocking netlink and os/exec in the IPIP manager.
-type ipipDataplane interface {
- LinkByName(name string) (netlink.Link, error)
- LinkSetMTU(link netlink.Link, mtu int) error
- LinkSetUp(link netlink.Link) error
- AddrList(link netlink.Link, family int) ([]netlink.Addr, error)
- AddrAdd(link netlink.Link, addr *netlink.Addr) error
- AddrDel(link netlink.Link, addr *netlink.Addr) error
- RunCmd(name string, args ...string) error
-}
-
-type realIPIPNetlink struct{}
-
-func (r realIPIPNetlink) LinkByName(name string) (netlink.Link, error) {
- return netlink.LinkByName(name)
-}
-func (r realIPIPNetlink) LinkSetMTU(link netlink.Link, mtu int) error {
- return netlink.LinkSetMTU(link, mtu)
-}
-
-func (r realIPIPNetlink) LinkSetUp(link netlink.Link) error {
- return netlink.LinkSetUp(link)
-}
-
-func (r realIPIPNetlink) AddrList(link netlink.Link, family int) ([]netlink.Addr, error) {
- retries := 3
- for {
- addrs, err := netlink.AddrList(link, family)
- if errors.Is(err, unix.EINTR) && retries > 0 {
- retries--
- continue
- }
- return addrs, err
- }
-}
-
-func (r realIPIPNetlink) AddrAdd(link netlink.Link, addr *netlink.Addr) error {
- return netlink.AddrAdd(link, addr)
-}
-
-func (r realIPIPNetlink) AddrDel(link netlink.Link, addr *netlink.Addr) error {
- return netlink.AddrDel(link, addr)
-}
-
-func (r realIPIPNetlink) RunCmd(name string, args ...string) error {
- cmd := exec.Command(name, args...)
- return cmd.Run()
-}
diff --git a/felix/dataplane/linux/ipip_mgr_test.go b/felix/dataplane/linux/ipip_mgr_test.go
index ffef1469712..1b668fecf0f 100644
--- a/felix/dataplane/linux/ipip_mgr_test.go
+++ b/felix/dataplane/linux/ipip_mgr_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2017-2021 Tigera, Inc. All rights reserved.
+// Copyright (c) 2017-2024 Tigera, Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,9 +15,11 @@
package intdataplane
import (
+ "context"
"errors"
"fmt"
"net"
+ "time"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@@ -25,7 +27,11 @@ import (
"github.com/vishvananda/netlink"
dpsets "github.com/projectcalico/calico/felix/dataplane/ipsets"
+ "github.com/projectcalico/calico/felix/dataplane/linux/dataplanedefs"
+ "github.com/projectcalico/calico/felix/logutils"
"github.com/projectcalico/calico/felix/proto"
+ "github.com/projectcalico/calico/felix/routetable"
+ "github.com/projectcalico/calico/felix/rules"
"github.com/projectcalico/calico/libcalico-go/lib/set"
)
@@ -39,6 +45,7 @@ var _ = Describe("IpipMgr (tunnel configuration)", func() {
ipipMgr *ipipManager
ipSets *dpsets.MockIPSets
dataplane *mockIPIPDataplane
+ rt *mockRouteTable
)
ip, _, err := net.ParseCIDR("10.0.0.1/32")
@@ -51,9 +58,25 @@ var _ = Describe("IpipMgr (tunnel configuration)", func() {
}
BeforeEach(func() {
- dataplane = &mockIPIPDataplane{}
+ dataplane = &mockIPIPDataplane{
+ tunnelLineName: dataplanedefs.IPIPDefaultIfaceNameV4,
+ }
ipSets = dpsets.NewMockIPSets()
- ipipMgr = newIPIPManagerWithShim(ipSets, 1024, dataplane, nil)
+ rt = &mockRouteTable{
+ currentRoutes: map[string][]routetable.Target{},
+ }
+ opRecorder := logutils.NewSummarizer("test")
+ ipipMgr = newIPIPManagerWithShim(
+ ipSets, rt, dataplanedefs.IPIPDefaultIfaceNameV4,
+ Config{
+ MaxIPSetSize: 1024,
+ Hostname: "node1",
+ ExternalNodesCidrs: nil,
+ },
+ opRecorder,
+ dataplane,
+ 4,
+ )
})
Describe("after calling configureIPIPDevice", func() {
@@ -63,6 +86,7 @@ var _ = Describe("IpipMgr (tunnel configuration)", func() {
}
BeforeEach(func() {
+ ipipMgr.OnParentNameUpdate("eth0")
err = ipipMgr.configureIPIPDevice(1400, ip, false)
Expect(err).ToNot(HaveOccurred())
})
@@ -88,7 +112,7 @@ var _ = Describe("IpipMgr (tunnel configuration)", func() {
Expect(err).ToNot(HaveOccurred())
})
It("should avoid creating the interface", func() {
- Expect(dataplane.RunCmdCalled).To(BeFalse())
+ Expect(dataplane.LinkAddCalled).To(BeFalse())
})
It("should avoid setting the interface UP again", func() {
Expect(dataplane.LinkSetUpCalled).To(BeFalse())
@@ -108,7 +132,7 @@ var _ = Describe("IpipMgr (tunnel configuration)", func() {
Expect(err).ToNot(HaveOccurred())
})
It("should avoid creating the interface", func() {
- Expect(dataplane.RunCmdCalled).To(BeFalse())
+ Expect(dataplane.LinkAddCalled).To(BeFalse())
})
It("should avoid setting the interface UP again", func() {
Expect(dataplane.LinkSetUpCalled).To(BeFalse())
@@ -129,7 +153,7 @@ var _ = Describe("IpipMgr (tunnel configuration)", func() {
Expect(err).ToNot(HaveOccurred())
})
It("should avoid creating the interface", func() {
- Expect(dataplane.RunCmdCalled).To(BeFalse())
+ Expect(dataplane.LinkAddCalled).To(BeFalse())
})
It("should avoid setting the interface UP again", func() {
Expect(dataplane.LinkSetUpCalled).To(BeFalse())
@@ -203,9 +227,9 @@ var _ = Describe("IpipMgr (tunnel configuration)", func() {
var _ = Describe("ipipManager IP set updates", func() {
var (
- ipipMgr *ipipManager
- ipSets *dpsets.MockIPSets
- dataplane *mockIPIPDataplane
+ ipipMgr *ipipManager
+ ipSets *dpsets.MockIPSets
+ rt *mockRouteTable
)
const (
@@ -213,9 +237,33 @@ var _ = Describe("ipipManager IP set updates", func() {
)
BeforeEach(func() {
- dataplane = &mockIPIPDataplane{}
ipSets = dpsets.NewMockIPSets()
- ipipMgr = newIPIPManagerWithShim(ipSets, 1024, dataplane, []string{externalCIDR})
+ rt = &mockRouteTable{
+ currentRoutes: map[string][]routetable.Target{},
+ }
+
+ la := netlink.NewLinkAttrs()
+ la.Name = "eth0"
+ opRecorder := logutils.NewSummarizer("test")
+ ipipMgr = newIPIPManagerWithShim(
+ ipSets, rt, dataplanedefs.IPIPDefaultIfaceNameV4,
+ Config{
+ MaxIPSetSize: 1024,
+ Hostname: "host1",
+ ExternalNodesCidrs: []string{externalCIDR},
+ },
+ opRecorder,
+ &mockIPIPDataplane{
+ links: []netlink.Link{&mockLink{attrs: la}},
+ tunnelLineName: dataplanedefs.IPIPDefaultIfaceNameV4,
+ },
+ 4,
+ )
+ ipipMgr.OnUpdate(&proto.HostMetadataUpdate{
+ Hostname: "host1",
+ Ipv4Addr: "10.0.0.1",
+ })
+ ipipMgr.OnParentNameUpdate("eth0")
})
It("should not create the IP set until first call to CompleteDeferredWork()", func() {
@@ -343,22 +391,176 @@ var _ = Describe("ipipManager IP set updates", func() {
})
})
+var _ = Describe("IPIPManager", func() {
+ var manager *ipipManager
+ var rt *mockRouteTable
+ var ipSets *dpsets.MockIPSets
+
+ BeforeEach(func() {
+ ipSets = dpsets.NewMockIPSets()
+ rt = &mockRouteTable{
+ currentRoutes: map[string][]routetable.Target{},
+ }
+
+ la := netlink.NewLinkAttrs()
+ la.Name = "eth0"
+ opRecorder := logutils.NewSummarizer("test")
+ manager = newIPIPManagerWithShim(
+ ipSets, rt, dataplanedefs.IPIPIfaceNameV4,
+ Config{
+ MaxIPSetSize: 1024,
+ Hostname: "host1",
+ ExternalNodesCidrs: []string{"10.10.10.0/24"},
+ RulesConfig: rules.Config{
+ IPIPTunnelAddress: net.ParseIP("192.168.0.1"),
+ },
+ ProgramIPIPRoutes: true,
+ IPIPMTU: 1400,
+ },
+ opRecorder,
+ &mockIPIPDataplane{
+ links: []netlink.Link{&mockLink{attrs: la}},
+ tunnelLineName: dataplanedefs.IPIPIfaceNameV4,
+ },
+ 4,
+ )
+ })
+
+ It("successfully adds a route to the parent interface", func() {
+ manager.OnUpdate(&proto.HostMetadataUpdate{
+ Hostname: "host1",
+ Ipv4Addr: "10.0.0.1",
+ })
+ manager.OnUpdate(&proto.HostMetadataUpdate{
+ Hostname: "host2",
+ Ipv4Addr: "10.0.1.1",
+ })
+
+ err := manager.configureIPIPDevice(50, manager.dpConfig.RulesConfig.IPIPTunnelAddress, false)
+ Expect(err).NotTo(HaveOccurred())
+ manager.OnParentNameUpdate("eth0")
+
+ Expect(manager.hostAddr).NotTo(BeZero())
+ Expect(manager.parentIfaceName).NotTo(BeEmpty())
+ parent, err := manager.getParentInterface()
+
+ Expect(parent).NotTo(BeNil())
+ Expect(err).NotTo(HaveOccurred())
+
+ manager.OnUpdate(&proto.RouteUpdate{
+ Type: proto.RouteType_REMOTE_WORKLOAD,
+ IpPoolType: proto.IPPoolType_IPIP,
+ Dst: "192.168.0.3/26",
+ DstNodeName: "host2",
+ DstNodeIp: "10.0.1.1",
+ SameSubnet: true,
+ })
+
+ manager.OnUpdate(&proto.RouteUpdate{
+ Type: proto.RouteType_REMOTE_WORKLOAD,
+ IpPoolType: proto.IPPoolType_IPIP,
+ Dst: "192.168.0.2/26",
+ DstNodeName: "host2",
+ DstNodeIp: "10.0.1.1",
+ })
+
+ manager.OnUpdate(&proto.RouteUpdate{
+ Type: proto.RouteType_LOCAL_WORKLOAD,
+ IpPoolType: proto.IPPoolType_IPIP,
+ Dst: "192.168.0.100/26",
+ DstNodeName: "host1",
+ DstNodeIp: "10.0.0.1",
+ SameSubnet: true,
+ })
+
+ // Borrowed /32 should not be programmed as blackhole.
+ manager.OnUpdate(&proto.RouteUpdate{
+ Type: proto.RouteType_LOCAL_WORKLOAD,
+ IpPoolType: proto.IPPoolType_IPIP,
+ Dst: "192.168.0.10/32",
+ DstNodeName: "host1",
+ DstNodeIp: "10.0.0.7",
+ SameSubnet: true,
+ })
+
+ Expect(rt.currentRoutes[dataplanedefs.IPIPIfaceNameV4]).To(HaveLen(0))
+ Expect(rt.currentRoutes[routetable.InterfaceNone]).To(HaveLen(0))
+
+ err = manager.CompleteDeferredWork()
+
+ Expect(err).NotTo(HaveOccurred())
+ Expect(rt.currentRoutes[dataplanedefs.IPIPIfaceNameV4]).To(HaveLen(1))
+ Expect(rt.currentRoutes[routetable.InterfaceNone]).To(HaveLen(1))
+ Expect(rt.currentRoutes["eth0"]).NotTo(BeNil())
+ })
+
+ It("adds the route to the default table on next try when the parent route table is not immediately found", func() {
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+ parentNameC := make(chan string)
+ go manager.KeepCalicoIPIPDeviceInSync(ctx, false, 1*time.Second, parentNameC)
+
+ manager.OnUpdate(&proto.HostMetadataUpdate{
+ Hostname: "host2",
+ Ipv4Addr: "10.0.1.1/32",
+ })
+
+ manager.OnUpdate(&proto.RouteUpdate{
+ Type: proto.RouteType_REMOTE_WORKLOAD,
+ IpPoolType: proto.IPPoolType_IPIP,
+ Dst: "172.0.0.1/26",
+ DstNodeName: "host2",
+ DstNodeIp: "172.8.8.8",
+ SameSubnet: true,
+ })
+
+ err := manager.CompleteDeferredWork()
+ Expect(err).NotTo(BeNil())
+ Expect(err.Error()).To(Equal("no encap route table not set, will defer adding routes"))
+ Expect(manager.routesDirty).To(BeTrue())
+
+ manager.OnUpdate(&proto.HostMetadataUpdate{
+ Hostname: "host1",
+ Ipv4Addr: "10.0.0.1",
+ })
+
+ Expect(manager.hostAddr).NotTo(BeZero())
+
+ // Note: parent name is sent after configuration so this receive
+ // ensures we don't race.
+ Eventually(parentNameC, "2s").Should(Receive(Equal("eth0")))
+ manager.OnParentNameUpdate("eth0")
+
+ err = manager.configureIPIPDevice(50, manager.dpConfig.RulesConfig.IPIPTunnelAddress, false)
+ Expect(err).NotTo(HaveOccurred())
+
+ Expect(rt.currentRoutes["eth0"]).To(HaveLen(0))
+ err = manager.CompleteDeferredWork()
+ Expect(err).NotTo(HaveOccurred())
+ Expect(manager.routesDirty).To(BeFalse())
+ Expect(rt.currentRoutes["eth0"]).To(HaveLen(1))
+ })
+})
+
type mockIPIPDataplane struct {
tunnelLink *mockLink
tunnelLinkAttrs *netlink.LinkAttrs
+ tunnelLineName string
addrs []netlink.Addr
- RunCmdCalled bool
+ LinkAddCalled bool
LinkSetMTUCalled bool
LinkSetUpCalled bool
AddrUpdated bool
NumCalls int
ErrorAtCall int
+
+ links []netlink.Link
}
func (d *mockIPIPDataplane) ResetCalls() {
- d.RunCmdCalled = false
+ d.LinkAddCalled = false
d.LinkSetMTUCalled = false
d.LinkSetUpCalled = false
d.AddrUpdated = false
@@ -380,7 +582,7 @@ func (d *mockIPIPDataplane) LinkByName(name string) (netlink.Link, error) {
return nil, err
}
- Expect(name).To(Equal("tunl0"))
+ Expect(name).To(Equal(d.tunnelLineName))
if d.tunnelLink == nil {
return nil, notFound
}
@@ -392,7 +594,7 @@ func (d *mockIPIPDataplane) LinkSetMTU(link netlink.Link, mtu int) error {
if err := d.incCallCount(); err != nil {
return err
}
- Expect(link.Attrs().Name).To(Equal("tunl0"))
+ Expect(link.Attrs().Name).To(Equal(d.tunnelLineName))
d.tunnelLinkAttrs.MTU = mtu
return nil
}
@@ -402,7 +604,7 @@ func (d *mockIPIPDataplane) LinkSetUp(link netlink.Link) error {
if err := d.incCallCount(); err != nil {
return err
}
- Expect(link.Attrs().Name).To(Equal("tunl0"))
+ Expect(link.Attrs().Name).To(Equal(d.tunnelLineName))
d.tunnelLinkAttrs.Flags |= net.FlagUp
return nil
}
@@ -411,7 +613,16 @@ func (d *mockIPIPDataplane) AddrList(link netlink.Link, family int) ([]netlink.A
if err := d.incCallCount(); err != nil {
return nil, err
}
- Expect(link.Attrs().Name).To(Equal("tunl0"))
+
+ name := link.Attrs().Name
+ Expect(name).Should(BeElementOf(d.tunnelLineName, "eth0"))
+ if name == "eth0" {
+ return []netlink.Addr{{
+ IPNet: &net.IPNet{
+ IP: net.IPv4(10, 0, 0, 1),
+ }},
+ }, nil
+ }
return d.addrs, nil
}
@@ -436,25 +647,30 @@ func (d *mockIPIPDataplane) AddrDel(link netlink.Link, addr *netlink.Addr) error
return nil
}
-func (d *mockIPIPDataplane) RunCmd(name string, args ...string) error {
- d.RunCmdCalled = true
+func (d *mockIPIPDataplane) LinkList() ([]netlink.Link, error) {
+ return d.links, nil
+}
+
+func (d *mockIPIPDataplane) LinkAdd(l netlink.Link) error {
+ d.LinkAddCalled = true
if err := d.incCallCount(); err != nil {
return err
}
- log.WithFields(log.Fields{"name": name, "args": args}).Info("RunCmd called")
- Expect(name).To(Equal("ip"))
- Expect(args).To(Equal([]string{"tunnel", "add", "tunl0", "mode", "ipip"}))
-
+ Expect(l.Attrs().Name).To(Equal(d.tunnelLineName))
if d.tunnelLink == nil {
log.Info("Creating tunnel link")
link := &mockLink{}
- link.attrs.Name = "tunl0"
+ link.attrs.Name = d.tunnelLineName
d.tunnelLinkAttrs = &link.attrs
d.tunnelLink = link
}
return nil
}
+func (d *mockIPIPDataplane) LinkDel(_ netlink.Link) error {
+ return nil
+}
+
type mockLink struct {
attrs netlink.LinkAttrs
typ string
diff --git a/felix/dataplane/linux/routing_utility.go b/felix/dataplane/linux/routing_utility.go
new file mode 100644
index 00000000000..8cc0d731e21
--- /dev/null
+++ b/felix/dataplane/linux/routing_utility.go
@@ -0,0 +1,128 @@
+// Copyright (c) 2024 Tigera, Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package intdataplane
+
+import (
+ "strings"
+ "syscall"
+
+ "github.com/sirupsen/logrus"
+ "github.com/vishvananda/netlink"
+
+ "github.com/projectcalico/calico/felix/dataplane/linux/dataplanedefs"
+ "github.com/projectcalico/calico/felix/ip"
+ "github.com/projectcalico/calico/felix/proto"
+ "github.com/projectcalico/calico/felix/routetable"
+)
+
+// added so that we can shim netlink for tests
+type netlinkHandle interface {
+ LinkByName(name string) (netlink.Link, error)
+ LinkSetMTU(link netlink.Link, mtu int) error
+ LinkSetUp(link netlink.Link) error
+ AddrList(link netlink.Link, family int) ([]netlink.Addr, error)
+ AddrAdd(link netlink.Link, addr *netlink.Addr) error
+ AddrDel(link netlink.Link, addr *netlink.Addr) error
+ LinkList() ([]netlink.Link, error)
+ LinkAdd(netlink.Link) error
+ LinkDel(netlink.Link) error
+}
+
+func routeIsLocalBlock(msg *proto.RouteUpdate, routeProto proto.IPPoolType) bool {
+ // RouteType_LOCAL_WORKLOAD means "local IPAM block _or_ /32 of workload" in IPv4.
+ // It means "local IPAM block _or_ /128 of workload" in IPv6.
+ if msg.Type != proto.RouteType_LOCAL_WORKLOAD {
+ return false
+ }
+ // Only care about a specific ippool
+ if msg.IpPoolType != routeProto {
+ return false
+ }
+ // Ignore routes that we know are from local workload endpoints.
+ if msg.LocalWorkload {
+ return false
+ }
+
+ // Check the valid suffix depending on IP version.
+ cidr, err := ip.CIDRFromString(msg.Dst)
+ if err != nil {
+ logrus.WithError(err).WithField("msg", msg).Warning("Unable to parse destination into a CIDR. Treating block as external.")
+ }
+ // Ignore exact routes, i.e. /32 (ipv4) or /128 (ipv6) routes in any case for two reasons:
+ // * If we have a /32 or /128 block then our blackhole route would stop the CNI plugin from
+ // programming its /32 or /128 for a newly added workload.
+ // * If this isn't a /32 or /128 block then it must be a borrowed /32 or /128 from another
+ // block. In that case, we know we're racing with CNI, adding a new workload.
+ // We've received the borrowed IP but not the workload endpoint yet.
+ exactRoute := "/32"
+ if cidr.Version() == 6 {
+ exactRoute = "/128"
+ }
+ return !strings.HasSuffix(msg.Dst, exactRoute)
+}
+
+func blackholeRoutes(localIPAMBlocks map[string]*proto.RouteUpdate, proto netlink.RouteProtocol) []routetable.Target {
+ var rtt []routetable.Target
+ for dst := range localIPAMBlocks {
+ cidr, err := ip.CIDRFromString(dst)
+ if err != nil {
+ logrus.WithError(err).Warning(
+ "Error processing IPAM block CIDR: ", dst,
+ )
+ continue
+ }
+ rtt = append(rtt, routetable.Target{
+ Type: routetable.TargetTypeBlackhole,
+ CIDR: cidr,
+ Protocol: proto,
+ })
+ }
+ return rtt
+}
+
+func noEncapRoute(parentIface string, cidr ip.CIDR, r *proto.RouteUpdate, proto netlink.RouteProtocol) *routetable.Target {
+ if parentIface == "" {
+ return nil
+ }
+ if !r.GetSameSubnet() {
+ return nil
+ }
+ if r.DstNodeIp == "" {
+ return nil
+ }
+ noEncapRoute := routetable.Target{
+ Type: routetable.TargetTypeNoEncap,
+ CIDR: cidr,
+ GW: ip.FromString(r.DstNodeIp),
+ Protocol: proto,
+ }
+ return &noEncapRoute
+}
+
+func calculateRouteProtocol(dpConfig Config) netlink.RouteProtocol {
+ // For same-subnet and blackhole routes, we need a unique protocol
+ // to attach to the routes. If the global DeviceRouteProtocol is set to
+ // a usable value, use that; otherwise, pick a safer default. (For back
+ // compatibility, our DeviceRouteProtocol defaults to RTPROT_BOOT, which
+ // can also be used by other processes.)
+ //
+ // Routes to the VXLAN tunnel device itself are identified by their target
+ // interface. We don't need to worry about their protocol.
+ noEncapProtocol := dataplanedefs.DefaultRoutingProto
+ if dpConfig.DeviceRouteProtocol != syscall.RTPROT_BOOT {
+ noEncapProtocol = dpConfig.DeviceRouteProtocol
+ }
+ return noEncapProtocol
+}
diff --git a/felix/dataplane/linux/vxlan_mgr.go b/felix/dataplane/linux/vxlan_mgr.go
index 997b4cfcca9..7a6c420afaf 100644
--- a/felix/dataplane/linux/vxlan_mgr.go
+++ b/felix/dataplane/linux/vxlan_mgr.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2021 Tigera, Inc. All rights reserved.
+// Copyright (c) 2016-2024 Tigera, Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@ import (
"fmt"
"net"
"reflect"
- "strings"
"sync"
"syscall"
"time"
@@ -29,7 +28,6 @@ import (
"github.com/vishvananda/netlink"
dpsets "github.com/projectcalico/calico/felix/dataplane/ipsets"
- "github.com/projectcalico/calico/felix/dataplane/linux/dataplanedefs"
"github.com/projectcalico/calico/felix/ethtool"
"github.com/projectcalico/calico/felix/ip"
"github.com/projectcalico/calico/felix/ipsets"
@@ -41,19 +39,6 @@ import (
"github.com/projectcalico/calico/felix/vxlanfdb"
)
-// added so that we can shim netlink for tests
-type netlinkHandle interface {
- LinkByName(name string) (netlink.Link, error)
- LinkSetMTU(link netlink.Link, mtu int) error
- LinkSetUp(link netlink.Link) error
- AddrList(link netlink.Link, family int) ([]netlink.Addr, error)
- AddrAdd(link netlink.Link, addr *netlink.Addr) error
- AddrDel(link netlink.Link, addr *netlink.Addr) error
- LinkList() ([]netlink.Link, error)
- LinkAdd(netlink.Link) error
- LinkDel(netlink.Link) error
-}
-
type vxlanManager struct {
// Our dependencies.
hostname string
@@ -85,7 +70,7 @@ type vxlanManager struct {
vtepsDirty bool
nlHandle netlinkHandle
dpConfig Config
- noEncapProtocol netlink.RouteProtocol
+ routeProtocol netlink.RouteProtocol
// Log context
logCtx *logrus.Entry
@@ -128,7 +113,6 @@ func newVXLANManagerWithShims(
nlHandle netlinkHandle,
ipVersion uint8,
) *vxlanManager {
- logCtx := logrus.WithField("ipVersion", ipVersion)
return &vxlanManager{
ipsetsDataplane: ipsetsDataplane,
ipSetMetadata: ipsets.IPSetMetadata{
@@ -152,28 +136,12 @@ func newVXLANManagerWithShims(
vtepsDirty: true,
dpConfig: dpConfig,
nlHandle: nlHandle,
- noEncapProtocol: calculateNonEncapRouteProtocol(dpConfig),
- logCtx: logCtx,
+ routeProtocol: calculateRouteProtocol(dpConfig),
+ logCtx: logrus.WithField("ipVersion", ipVersion),
opRecorder: opRecorder,
}
}
-func calculateNonEncapRouteProtocol(dpConfig Config) netlink.RouteProtocol {
- // For same-subnet and blackhole routes, we need a unique protocol
- // to attach to the routes. If the global DeviceRouteProtocol is set to
- // a usable value, use that; otherwise, pick a safer default. (For back
- // compatibility, our DeviceRouteProtocol defaults to RTPROT_BOOT, which
- // can also be used by other processes.)
- //
- // Routes to the VXLAN tunnel device itself are identified by their target
- // interface. We don't need to worry about their protocol.
- noEncapProtocol := dataplanedefs.VXLANDefaultProto
- if dpConfig.DeviceRouteProtocol != syscall.RTPROT_BOOT {
- noEncapProtocol = dpConfig.DeviceRouteProtocol
- }
- return noEncapProtocol
-}
-
func (m *vxlanManager) OnUpdate(protoBufMsg interface{}) {
switch msg := protoBufMsg.(type) {
case *proto.RouteUpdate:
@@ -207,7 +175,7 @@ func (m *vxlanManager) OnUpdate(protoBufMsg interface{}) {
}
// Process IPAM blocks that aren't associated to a single or /32 local workload
- if routeIsLocalVXLANBlock(msg) {
+ if routeIsLocalBlock(msg, proto.IPPoolType_VXLAN) {
m.logCtx.WithField("msg", msg).Debug("VXLAN data plane received route update for IPAM block")
m.localIPAMBlocks[msg.Dst] = msg
m.routesDirty = true
@@ -257,50 +225,6 @@ func (m *vxlanManager) OnUpdate(protoBufMsg interface{}) {
}
}
-func routeIsLocalVXLANBlock(msg *proto.RouteUpdate) bool {
- // RouteType_LOCAL_WORKLOAD means "local IPAM block _or_ /32 of workload" in IPv4.
- // It means "local IPAM block _or_ /128 of workload" in IPv6.
- if msg.Type != proto.RouteType_LOCAL_WORKLOAD {
- return false
- }
- // Only care about VXLAN blocks.
- if msg.IpPoolType != proto.IPPoolType_VXLAN {
- return false
- }
- // Ignore routes that we know are from local workload endpoints.
- if msg.LocalWorkload {
- return false
- }
-
- // Check the valid suffix depending on IP version.
- cidr, err := ip.CIDRFromString(msg.Dst)
- if err != nil {
- logrus.WithError(err).WithField("msg", msg).Warning("Unable to parse destination into a CIDR. Treating block as external.")
- }
- if cidr.Version() == 4 {
- // This is an IPv4 route.
- // Ignore /32 routes in any case for two reasons:
- // * If we have a /32 block then our blackhole route would stop the CNI plugin from programming its /32 for a
- // newly added workload.
- // * If this isn't a /32 block then it must be a borrowed /32 from another block. In that case, we know we're
- // racing with CNI, adding a new workload. We've received the borrowed IP but not the workload endpoint yet.
- if strings.HasSuffix(msg.Dst, "/32") {
- return false
- }
- } else {
- // This is an IPv6 route.
- // Ignore /128 routes in any case for two reasons:
- // * If we have a /128 block then our blackhole route would stop the CNI plugin from programming its /128 for a
- // newly added workload.
- // * If this isn't a /128 block then it must be a borrowed /128 from another block. In that case, we know we're
- // racing with CNI, adding a new workload. We've received the borrowed IP but not the workload endpoint yet.
- if strings.HasSuffix(msg.Dst, "/128") {
- return false
- }
- }
- return true
-}
-
func (m *vxlanManager) deleteRoute(dst string) {
_, exists := m.routesByDest[dst]
if exists {
@@ -337,26 +261,6 @@ func (m *vxlanManager) getLocalVTEPParent() (netlink.Link, error) {
return m.getParentInterface(m.getLocalVTEP())
}
-func (m *vxlanManager) blackholeRoutes() []routetable.Target {
- var rtt []routetable.Target
- for dst := range m.localIPAMBlocks {
- cidr, err := ip.CIDRFromString(dst)
- if err != nil {
- m.logCtx.WithError(err).Warning(
- "Error processing IPAM block CIDR: ", dst,
- )
- continue
- }
- rtt = append(rtt, routetable.Target{
- Type: routetable.TargetTypeBlackhole,
- CIDR: cidr,
- Protocol: m.noEncapProtocol,
- })
- }
- m.logCtx.Debug("calculated blackholes ", rtt)
- return rtt
-}
-
func (m *vxlanManager) CompleteDeferredWork() error {
if m.parentIfaceName == "" {
// Background goroutine hasn't sent us the parent interface name yet,
@@ -390,12 +294,11 @@ func (m *vxlanManager) CompleteDeferredWork() error {
m.updateNeighborsAndAllowedSources()
m.vtepsDirty = false
}
-
if m.routesDirty {
m.updateRoutes()
m.routesDirty = false
}
-
+ m.logCtx.Info("VXLAN Manager completed deferred work")
return nil
}
@@ -452,7 +355,7 @@ func (m *vxlanManager) updateRoutes() {
continue
}
- if noEncapRoute := m.noEncapRoute(cidr, r); noEncapRoute != nil {
+ if noEncapRoute := noEncapRoute(m.parentIfaceName, cidr, r, m.routeProtocol); noEncapRoute != nil {
// We've got everything we need to program this route as a no-encap route.
noEncapRoutes = append(noEncapRoutes, *noEncapRoute)
logCtx.WithField("route", r).Debug("Destination in same subnet, using no-encap route.")
@@ -466,7 +369,10 @@ func (m *vxlanManager) updateRoutes() {
m.logCtx.WithField("vxlanRoutes", vxlanRoutes).Debug("VXLAN manager setting VXLAN tunneled routes")
m.routeTable.SetRoutes(routetable.RouteClassVXLANTunnel, m.vxlanDevice, vxlanRoutes)
- m.routeTable.SetRoutes(routetable.RouteClassIPAMBlockDrop, routetable.InterfaceNone, m.blackholeRoutes())
+
+ bhRoutes := blackholeRoutes(m.localIPAMBlocks, m.routeProtocol)
+ m.logCtx.WithField("balckholes", bhRoutes).Debug("VXLAN manager setting blackhole routes")
+ m.routeTable.SetRoutes(routetable.RouteClassIPAMBlockDrop, routetable.InterfaceNone, bhRoutes)
if m.parentIfaceName != "" {
m.logCtx.WithFields(logrus.Fields{
@@ -479,25 +385,6 @@ func (m *vxlanManager) updateRoutes() {
}
}
-func (m *vxlanManager) noEncapRoute(cidr ip.CIDR, r *proto.RouteUpdate) *routetable.Target {
- if !r.GetSameSubnet() {
- return nil
- }
- if m.parentIfaceName == "" {
- return nil
- }
- if r.DstNodeIp == "" {
- return nil
- }
- noEncapRoute := routetable.Target{
- Type: routetable.TargetTypeNoEncap,
- CIDR: cidr,
- GW: ip.FromString(r.DstNodeIp),
- Protocol: m.noEncapProtocol,
- }
- return &noEncapRoute
-}
-
func (m *vxlanManager) tunneledRoute(cidr ip.CIDR, r *proto.RouteUpdate) *routetable.Target {
if r.Type == proto.RouteType_REMOTE_TUNNEL {
// We treat remote tunnel routes as directly connected. They don't have a gateway of
@@ -516,9 +403,10 @@ func (m *vxlanManager) tunneledRoute(cidr ip.CIDR, r *proto.RouteUpdate) *routet
vtepAddr = vtep.Ipv6Addr
}
return &routetable.Target{
- Type: routetable.TargetTypeVXLAN,
- CIDR: cidr,
- GW: ip.FromString(vtepAddr),
+ Type: routetable.TargetTypeVXLAN,
+ CIDR: cidr,
+ GW: ip.FromString(vtepAddr),
+ Protocol: m.routeProtocol,
}
}
diff --git a/felix/docs/config-params.json b/felix/docs/config-params.json
index b05f190afe2..6190b371195 100644
--- a/felix/docs/config-params.json
+++ b/felix/docs/config-params.json
@@ -1785,6 +1785,32 @@
"UserEditable": true,
"GoType": "string"
},
+ {
+ "Group": "Dataplane: Common",
+ "GroupWithSortPrefix": "10 Dataplane: Common",
+ "NameConfigFile": "ProgramRoutes",
+ "NameEnvVar": "FELIX_ProgramRoutes",
+ "NameYAML": "programRoutes",
+ "NameGoAPI": "ProgramRoutes",
+ "StringSchema": "One of: `IPIP`, `None` (case insensitive)",
+ "StringSchemaHTML": "One of: IPIP
, None
(case insensitive)",
+ "StringDefault": "None",
+ "ParsedDefault": "None",
+ "ParsedDefaultJSON": "\"None\"",
+ "ParsedType": "string",
+ "YAMLType": "string",
+ "YAMLSchema": "",
+ "YAMLEnumValues": null,
+ "YAMLSchemaHTML": "",
+ "YAMLDefault": "None",
+ "Required": false,
+ "OnParseFailure": "ReplaceWithDefault",
+ "AllowedConfigSources": "All",
+ "Description": "Specifies what type of routes Felix should program. .",
+ "DescriptionHTML": "
Specifies what type of routes Felix should program. .
",
+ "UserEditable": true,
+ "GoType": "*v3.ProgramRouteMode"
+ },
{
"Group": "Dataplane: Common",
"GroupWithSortPrefix": "10 Dataplane: Common",
diff --git a/felix/docs/config-params.md b/felix/docs/config-params.md
index 79e80b69006..82cbb52319d 100644
--- a/felix/docs/config-params.md
+++ b/felix/docs/config-params.md
@@ -962,6 +962,19 @@ like Application layer policy.
| `FelixConfiguration` schema | String. |
| Default value (YAML) | none |
+### `ProgramRoutes` (config file) / `programRoutes` (YAML)
+
+Specifies what type of routes Felix should program. .
+
+| Detail | |
+| --- | --- |
+| Environment variable | `FELIX_ProgramRoutes` |
+| Encoding (env var/config file) | One of: IPIP
, None
(case insensitive) |
+| Default value (above encoding) | `None` |
+| `FelixConfiguration` field | `programRoutes` (YAML) `ProgramRoutes` (Go API) |
+| `FelixConfiguration` schema | `string` |
+| Default value (YAML) | `None` |
+
### `RemoveExternalRoutes` (config file) / `removeExternalRoutes` (YAML)
Controls whether Felix will remove unexpected routes to workload interfaces. Felix will
diff --git a/felix/fv/apply_on_forward_test.go b/felix/fv/apply_on_forward_test.go
index cb5309669f4..74271842a57 100644
--- a/felix/fv/apply_on_forward_test.go
+++ b/felix/fv/apply_on_forward_test.go
@@ -54,7 +54,7 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ apply on forward tests; wit
infra = getInfra()
options := infrastructure.DefaultTopologyOptions()
- options.IPIPEnabled = false
+ options.IPIPMode = api.IPIPModeNever
tc, client = infrastructure.StartNNodeTopology(2, options, infra)
// Install a default profile that allows all ingress and egress, in the absence of any Policy.
diff --git a/felix/fv/bpf_dual_stack_test.go b/felix/fv/bpf_dual_stack_test.go
index 17ca764b932..25796693e89 100644
--- a/felix/fv/bpf_dual_stack_test.go
+++ b/felix/fv/bpf_dual_stack_test.go
@@ -92,8 +92,8 @@ func describeBPFDualStackTests(ctlbEnabled, ipv6Dataplane bool) bool {
opts.EnableIPv6 = true
opts.NATOutgoingEnabled = true
opts.AutoHEPsEnabled = false
- opts.IPIPEnabled = false
- opts.IPIPRoutesEnabled = false
+ opts.IPIPMode = api.IPIPModeNever
+ opts.SimulateRoutes = false
opts.DelayFelixStart = true
if ipv6Dataplane {
diff --git a/felix/fv/bpf_test.go b/felix/fv/bpf_test.go
index 7326cbddc5c..ef09257d2e9 100644
--- a/felix/fv/bpf_test.go
+++ b/felix/fv/bpf_test.go
@@ -375,14 +375,14 @@ func describeBPFTests(opts ...bpfTestOpt) bool {
options.NATOutgoingEnabled = true
options.AutoHEPsEnabled = true
// override IPIP being enabled by default
- options.IPIPEnabled = false
- options.IPIPRoutesEnabled = false
+ options.IPIPMode = api.IPIPModeNever
+ options.SimulateRoutes = false
switch testOpts.tunnel {
case "none":
// nothing
case "ipip":
- options.IPIPEnabled = true
- options.IPIPRoutesEnabled = true
+ options.IPIPMode = api.IPIPModeAlways
+ options.SimulateRoutes = true
case "vxlan":
options.VXLANMode = api.VXLANModeAlways
case "wireguard":
@@ -5427,7 +5427,7 @@ func ensureBPFProgramsAttached(felix *infrastructure.Felix, ifacesExtra ...strin
func ensureBPFProgramsAttachedOffset(offset int, felix *infrastructure.Felix, ifacesExtra ...string) {
expectedIfaces := []string{"eth0"}
if felix.ExpectedIPIPTunnelAddr != "" {
- expectedIfaces = append(expectedIfaces, "tunl0")
+ expectedIfaces = append(expectedIfaces, felix.TopologyOptions.IPIPDevice)
}
if felix.ExpectedVXLANTunnelAddr != "" {
expectedIfaces = append(expectedIfaces, "vxlan.calico")
diff --git a/felix/fv/donottrack_test.go b/felix/fv/donottrack_test.go
index 99fab9b21af..54e0b150a3b 100644
--- a/felix/fv/donottrack_test.go
+++ b/felix/fv/donottrack_test.go
@@ -63,7 +63,7 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ do-not-track policy tests;
if BPFMode() {
options.EnableIPv6 = true
options.ExtraEnvVars["FELIX_BPFLogLevel"] = "debug"
- options.IPIPEnabled = false
+ options.IPIPMode = api.IPIPModeNever
}
tc, client = infrastructure.StartNNodeTopology(2, options, infra)
cc = &Checker{}
diff --git a/felix/fv/ep_to_host_action_test.go b/felix/fv/ep_to_host_action_test.go
index a98759cb3fc..f053124fb7c 100644
--- a/felix/fv/ep_to_host_action_test.go
+++ b/felix/fv/ep_to_host_action_test.go
@@ -51,7 +51,7 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ endpoint-to-host-action tes
}
infra = getInfra()
options := infrastructure.DefaultTopologyOptions()
- options.IPIPEnabled = false
+ options.IPIPMode = api.IPIPModeNever
options.DelayFelixStart = true
options.FelixLogSeverity = "Debug"
tc, client = infrastructure.StartNNodeTopology(2, options, infra)
diff --git a/felix/fv/flow_logs_goladmane_test.go b/felix/fv/flow_logs_goladmane_test.go
index ab687d429ee..d673a9b45a1 100644
--- a/felix/fv/flow_logs_goladmane_test.go
+++ b/felix/fv/flow_logs_goladmane_test.go
@@ -125,7 +125,7 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ flow log goldmane tests", [
BeforeEach(func() {
infra = getInfra()
opts = infrastructure.DefaultTopologyOptions()
- opts.IPIPEnabled = false
+ opts.IPIPMode = api.IPIPModeNever
opts.FlowLogSource = infrastructure.FlowLogSourceGoldmane
opts.ExtraEnvVars["FELIX_BPFCONNTRACKTIMEOUTS"] = "TCPFinsSeen=30s"
@@ -583,10 +583,11 @@ var _ = infrastructure.DatastoreDescribe("ipv6 flow log tests", []apiconfig.Data
opts.FlowLogSource = infrastructure.FlowLogSourceGoldmane
opts.EnableIPv6 = true
- opts.IPIPEnabled = false
+ //opts.IPIPEnabled = false
+ opts.IPIPMode = api.IPIPModeNever
opts.NATOutgoingEnabled = true
opts.AutoHEPsEnabled = false
- opts.IPIPRoutesEnabled = false
+ opts.SimulateRoutes = false
opts.ExtraEnvVars["FELIX_FLOWLOGSFLUSHINTERVAL"] = "2"
opts.ExtraEnvVars["FELIX_IPV6SUPPORT"] = "true"
opts.ExtraEnvVars["FELIX_DefaultEndpointToHostAction"] = "RETURN"
diff --git a/felix/fv/hostendpoints_test.go b/felix/fv/hostendpoints_test.go
index e9615777305..b296b283e12 100644
--- a/felix/fv/hostendpoints_test.go
+++ b/felix/fv/hostendpoints_test.go
@@ -62,7 +62,7 @@ func describeHostEndpointTests(getInfra infrastructure.InfraFactory, allInterfac
BeforeEach(func() {
infra = getInfra()
options := infrastructure.DefaultTopologyOptions()
- options.IPIPEnabled = false
+ options.IPIPMode = api.IPIPModeNever
options.WithTypha = true
tc, client = infrastructure.StartNNodeTopology(2, options, infra)
@@ -600,7 +600,7 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ with IP forwarding disabled
infra = getInfra()
options := infrastructure.DefaultTopologyOptions()
options.DelayFelixStart = true
- options.IPIPEnabled = false
+ options.IPIPMode = api.IPIPModeNever
options.WithTypha = true
options.ExtraEnvVars["FELIX_IPFORWARDING"] = "Disabled"
tc, client = infrastructure.StartNNodeTopology(2, options, infra)
diff --git a/felix/fv/infrastructure/topology.go b/felix/fv/infrastructure/topology.go
index bae702d901d..fe15e40f3b2 100644
--- a/felix/fv/infrastructure/topology.go
+++ b/felix/fv/infrastructure/topology.go
@@ -26,9 +26,11 @@ import (
"github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
api "github.com/projectcalico/api/pkg/apis/projectcalico/v3"
+ v3 "github.com/projectcalico/api/pkg/apis/projectcalico/v3"
log "github.com/sirupsen/logrus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "github.com/projectcalico/calico/felix/dataplane/linux/dataplanedefs"
"github.com/projectcalico/calico/felix/fv/containers"
client "github.com/projectcalico/calico/libcalico-go/lib/clientv3"
"github.com/projectcalico/calico/libcalico-go/lib/errors"
@@ -49,16 +51,19 @@ type TopologyOptions struct {
EnableIPv6 bool
// Temporary flag to implement and test IPv6 in bpf dataplane.
// TODO: Remove it when IPv6 implementation in BPF mode is complete.
- BPFEnableIPv6 bool
- ExtraEnvVars map[string]string
- ExtraVolumes map[string]string
- WithTypha bool
- WithFelixTyphaTLS bool
- TestManagesBPF bool
- TyphaLogSeverity string
- IPIPEnabled bool
- IPIPRoutesEnabled bool
+ BPFEnableIPv6 bool
+ ExtraEnvVars map[string]string
+ ExtraVolumes map[string]string
+ WithTypha bool
+ WithFelixTyphaTLS bool
+ TestManagesBPF bool
+ TyphaLogSeverity string
+ //IPIPEnabled bool
+ //IPIPRoutesEnabled bool
+ IPIPMode api.IPIPMode
+ IPIPDevice string
VXLANMode api.VXLANMode
+ SimulateRoutes bool
WireguardEnabled bool
WireguardEnabledV6 bool
InitialFelixConfiguration *api.FelixConfiguration
@@ -112,11 +117,14 @@ func DefaultTopologyOptions() TopologyOptions {
WithTypha: false,
WithFelixTyphaTLS: false,
TyphaLogSeverity: "info",
- IPIPEnabled: true,
- IPIPRoutesEnabled: true,
- IPPoolCIDR: DefaultIPPoolCIDR,
- IPv6PoolCIDR: DefaultIPv6PoolCIDR,
- UseIPPools: true,
+ //IPIPEnabled: true,
+ //IPIPRoutesEnabled: true,
+ IPIPMode: v3.IPIPModeAlways,
+ IPIPDevice: dataplanedefs.IPIPDefaultIfaceNameV4,
+ SimulateRoutes: true,
+ IPPoolCIDR: DefaultIPPoolCIDR,
+ IPv6PoolCIDR: DefaultIPv6PoolCIDR,
+ UseIPPools: true,
}
}
@@ -139,16 +147,21 @@ func CreateDefaultIPPoolFromOpts(
case 4:
ipPool.Name = DefaultIPPoolName
ipPool.Spec.CIDR = opts.IPPoolCIDR
-
// IPIP is only supported on IPv4
- if opts.IPIPEnabled {
- ipPool.Spec.IPIPMode = api.IPIPModeAlways
+ /*if opts.IPIPEnabled {
+ if opts.IPIPRoutesEnabled {
+ ipPool.Spec.IPIPMode = api.IPIPModeAlways
+ } else {
+ ipPool.Spec.IPIPMode = opts.IPIPMode
+ }
} else {
ipPool.Spec.IPIPMode = api.IPIPModeNever
- }
+ }*/
+ ipPool.Spec.IPIPMode = opts.IPIPMode
case 6:
ipPool.Name = DefaultIPv6PoolName
ipPool.Spec.CIDR = opts.IPv6PoolCIDR
+ ipPool.Spec.IPIPMode = api.IPIPModeNever
default:
log.WithField("ipVersion", ipVersion).Panic("Unknown IP version")
}
@@ -224,7 +237,7 @@ func StartNNodeTopology(
success := false
var err error
- if opts.EnableIPv6 && opts.IPIPEnabled && os.Getenv("FELIX_FV_ENABLE_BPF") == "true" {
+ if opts.EnableIPv6 && opts.IPIPMode != api.IPIPModeNever && os.Getenv("FELIX_FV_ENABLE_BPF") == "true" {
log.Errorf("IPIP not supported in BPF with ipv6!")
return
}
@@ -244,6 +257,10 @@ func StartNNodeTopology(
opts.VXLANMode = api.VXLANModeNever
}
+ if opts.IPIPMode == "" {
+ opts.IPIPMode = api.IPIPModeNever
+ }
+
// Get client.
client = infra.GetCalicoClient()
mustInitDatastore(client)
@@ -360,7 +377,7 @@ func StartNNodeTopology(
}
setUpBGPNodeIPAndIPIPTunnelIP := n > 1 || opts.NeedNodeIP
- if opts.IPIPEnabled {
+ if opts.IPIPMode != api.IPIPModeNever {
infra.SetExpectedIPIPTunnelAddr(felix, IPv4CIDR, i, setUpBGPNodeIPAndIPIPTunnelIP)
expectedIPs = append(expectedIPs, felix.ExpectedIPIPTunnelAddr)
}
@@ -443,27 +460,19 @@ func StartNNodeTopology(
defer wg.Done()
defer ginkgo.GinkgoRecover()
jBlock := fmt.Sprintf("%d.%d.%d.0/24", IPv4CIDR.IP[0], IPv4CIDR.IP[1], j)
- if opts.IPIPEnabled && opts.IPIPRoutesEnabled {
- // Can get "Nexthop device is not up" error here if tunl0 device is
- // not ready yet, which can happen especially if Felix start was
- // delayed.
- Eventually(func() error {
- return iFelix.ExecMayFail("ip", "route", "add", jBlock, "via", jFelix.IP, "dev", "tunl0", "onlink")
- }, "10s", "1s").ShouldNot(HaveOccurred())
- } else if opts.VXLANMode == api.VXLANModeNever {
- // If VXLAN is enabled, Felix will program these routes itself.
- err := iFelix.ExecMayFail("ip", "route", "add", jBlock, "via", jFelix.IP, "dev", "eth0")
- Expect(err).ToNot(HaveOccurred())
+ log.Infof("Marva simulating routes: %v %v %v", opts.VXLANMode, opts.IPIPMode, opts.SimulateRoutes)
+ if needToSimulateIPIPRoutes(&opts) {
+ programIPIPRouts(iFelix, jBlock, jFelix.IP)
+ } else if needToSimulateNoEncapRoutes(&opts) {
+ programNoEncapRoutes(iFelix, jBlock, jFelix.IP, false)
}
if opts.EnableIPv6 {
- jBlockV6 := fmt.Sprintf("%x%x:%x%x:%x%x:%x%x:%x%x:0:%d:0/112", IPv6CIDR.IP[0], IPv6CIDR.IP[1], IPv6CIDR.IP[2], IPv6CIDR.IP[3], IPv6CIDR.IP[4], IPv6CIDR.IP[5], IPv6CIDR.IP[6], IPv6CIDR.IP[7], IPv6CIDR.IP[8], IPv6CIDR.IP[9], j)
- if opts.VXLANMode == api.VXLANModeNever {
- // If VXLAN is enabled, Felix will program these routes itself.
- // If IPIP routes are enabled, these routes will conflict with configured ones and a 'RTNETLINK answers: File exists' error would occur.
- err := iFelix.ExecMayFail("ip", "-6", "route", "add", jBlockV6, "via", jFelix.IPv6, "dev", "eth0")
- Expect(err).ToNot(HaveOccurred())
+ if needToSimulateNoEncapRoutes(&opts) {
+ jBlockV6 := fmt.Sprintf("%x%x:%x%x:%x%x:%x%x:%x%x:0:%d:0/112",
+ IPv6CIDR.IP[0], IPv6CIDR.IP[1], IPv6CIDR.IP[2], IPv6CIDR.IP[3], IPv6CIDR.IP[4],
+ IPv6CIDR.IP[5], IPv6CIDR.IP[6], IPv6CIDR.IP[7], IPv6CIDR.IP[8], IPv6CIDR.IP[9], j)
+ programNoEncapRoutes(iFelix, jBlockV6, jFelix.IPv6, true)
}
-
}
}(i, j, iFelix, jFelix)
}
@@ -474,6 +483,36 @@ func StartNNodeTopology(
return
}
+func needToSimulateIPIPRoutes(opts *TopologyOptions) bool {
+ return opts.IPIPMode == api.IPIPModeAlways && opts.SimulateRoutes
+}
+
+func needToSimulateNoEncapRoutes(opts *TopologyOptions) bool {
+ log.Infof("Marva simulating routes: %v %v %v", opts.VXLANMode, opts.IPIPMode, opts.SimulateRoutes)
+ return opts.VXLANMode == api.VXLANModeNever && opts.IPIPMode == api.IPIPModeNever && opts.SimulateRoutes
+ //return opts.VXLANMode == api.VXLANModeNever
+}
+
+func programIPIPRouts(felix *Felix, dest, gw string) {
+ // Can get "Nexthop device is not up" error here if tunl0 device is
+ // not ready yet, which can happen especially if Felix start was delayed.
+ Eventually(func() error {
+ return felix.ExecMayFail("ip", "route", "add", dest, "via", gw, "dev", "tunl0", "onlink", "proto", "100")
+ }, "10s", "1s").ShouldNot(HaveOccurred())
+}
+
+func programNoEncapRoutes(felix *Felix, dest, gw string, ipv6 bool) {
+ // If VXLAN is enabled, Felix will program these routes itself.
+ // If IPIP routes are enabled, these routes will conflict with configured ones and a 'RTNETLINK answers: File exists' error would occur.
+ if ipv6 {
+ err := felix.ExecMayFail("ip", "-6", "route", "add", dest, "via", gw, "dev", "eth0")
+ Expect(err).ToNot(HaveOccurred())
+ } else {
+ err := felix.ExecMayFail("ip", "route", "add", dest, "via", gw, "dev", "eth0")
+ Expect(err).ToNot(HaveOccurred())
+ }
+}
+
func mustInitDatastore(client client.Interface) {
Eventually(func() error {
log.Info("Initializing the datastore...")
diff --git a/felix/fv/ip6tables_test.go b/felix/fv/ip6tables_test.go
index 10183e5c95f..cd4591bf953 100644
--- a/felix/fv/ip6tables_test.go
+++ b/felix/fv/ip6tables_test.go
@@ -56,7 +56,7 @@ var _ = infrastructure.DatastoreDescribe("IPv6 iptables/nftables tests", []apico
options = infrastructure.DefaultTopologyOptions()
options.EnableIPv6 = true
options.FelixLogSeverity = "Debug"
- options.IPIPEnabled = false
+ options.IPIPMode = api.IPIPModeNever
iOpts := []infrastructure.CreateOption{
infrastructure.K8sWithIPv6(),
diff --git a/felix/fv/ipip_test.go b/felix/fv/ipip_test.go
index c17d36271b5..5dc3d73a761 100644
--- a/felix/fv/ipip_test.go
+++ b/felix/fv/ipip_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2020-2021 Tigera, Inc. All rights reserved.
+// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -33,6 +33,7 @@ import (
"github.com/vishvananda/netlink"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ dpdefs "github.com/projectcalico/calico/felix/dataplane/linux/dataplanedefs"
"github.com/projectcalico/calico/felix/fv/connectivity"
"github.com/projectcalico/calico/felix/fv/containers"
"github.com/projectcalico/calico/felix/fv/infrastructure"
@@ -41,11 +42,13 @@ import (
"github.com/projectcalico/calico/libcalico-go/lib/apiconfig"
client "github.com/projectcalico/calico/libcalico-go/lib/clientv3"
cerrors "github.com/projectcalico/calico/libcalico-go/lib/errors"
+ "github.com/projectcalico/calico/libcalico-go/lib/ipam"
+ "github.com/projectcalico/calico/libcalico-go/lib/net"
"github.com/projectcalico/calico/libcalico-go/lib/netlinkutils"
"github.com/projectcalico/calico/libcalico-go/lib/options"
)
-var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ IPIP topology before adding host IPs to IP sets", []apiconfig.DatastoreType{apiconfig.EtcdV3, apiconfig.Kubernetes}, func(getInfra infrastructure.InfraFactory) {
+var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ IPIP topology with BIRD programming routes before adding host IPs to IP sets", []apiconfig.DatastoreType{apiconfig.EtcdV3, apiconfig.Kubernetes}, func(getInfra infrastructure.InfraFactory) {
var (
bpfEnabled = os.Getenv("FELIX_FV_ENABLE_BPF") == "true"
infra infrastructure.DatastoreInfra
@@ -492,6 +495,683 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ IPIP topology before adding
})
})
+var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ IPIP topology with Felix programming routes before adding host IPs to IP sets", []apiconfig.DatastoreType{apiconfig.EtcdV3, apiconfig.Kubernetes}, func(getInfra infrastructure.InfraFactory) {
+ type testConf struct {
+ IPIPMode api.IPIPMode
+ RouteSource string
+ BrokenXSum bool
+ }
+ for _, testConfig := range []testConf{
+ {api.IPIPModeCrossSubnet, "CalicoIPAM", true},
+ {api.IPIPModeCrossSubnet, "WorkloadIPs", false},
+
+ {api.IPIPModeAlways, "CalicoIPAM", true},
+ {api.IPIPModeAlways, "WorkloadIPs", false},
+ } {
+ ipipMode := testConfig.IPIPMode
+ routeSource := testConfig.RouteSource
+ brokenXSum := testConfig.BrokenXSum
+
+ Describe(fmt.Sprintf("IPIP mode set to %s, routeSource %s, brokenXSum: %v", ipipMode, routeSource, brokenXSum), func() {
+ var (
+ infra infrastructure.DatastoreInfra
+ tc infrastructure.TopologyContainers
+ felixes []*infrastructure.Felix
+ client client.Interface
+ w [3]*workload.Workload
+ hostW [3]*workload.Workload
+ cc *connectivity.Checker
+ topologyOptions infrastructure.TopologyOptions
+ )
+
+ BeforeEach(func() {
+ infra = getInfra()
+ if (NFTMode() || BPFMode()) && getDataStoreType(infra) == "etcdv3" {
+ Skip("Skipping NFT / BPF test for etcdv3 backend.")
+ }
+
+ topologyOptions = createIPIPBaseTopologyOptions(ipipMode, routeSource, brokenXSum)
+ tc, client = infrastructure.StartNNodeTopology(3, topologyOptions, infra)
+
+ w, hostW = setupIPIPWorkloads(infra, tc, topologyOptions, client)
+ felixes = tc.Felixes
+
+ cc = &connectivity.Checker{}
+ })
+
+ AfterEach(func() {
+ if CurrentGinkgoTestDescription().Failed {
+ for _, felix := range tc.Felixes {
+ if NFTMode() {
+ logNFTDiags(felix)
+ } else {
+ felix.Exec("iptables-save", "-c")
+ felix.Exec("ipset", "list")
+ }
+ felix.Exec("ip", "r")
+ felix.Exec("ip", "a")
+ if BPFMode() {
+ felix.Exec("calico-bpf", "policy", "dump", "eth0", "all", "--asm")
+ }
+ }
+ }
+
+ for _, wl := range w {
+ wl.Stop()
+ }
+ for _, wl := range hostW {
+ wl.Stop()
+ }
+ tc.Stop()
+
+ if CurrentGinkgoTestDescription().Failed {
+ infra.DumpErrorData()
+ }
+ infra.Stop()
+ })
+
+ if brokenXSum {
+ It("should disable checksum offload", func() {
+ Eventually(func() string {
+ out, err := felixes[0].ExecOutput("ethtool", "-k", dpdefs.IPIPIfaceNameV4)
+ if err != nil {
+ return fmt.Sprintf("ERROR: %v", err)
+ }
+ return out
+ }, "10s", "100ms").Should(ContainSubstring("tx-checksumming: off"))
+ })
+ } else {
+ It("should not disable checksum offload", func() {
+ Eventually(func() string {
+ out, err := felixes[0].ExecOutput("ethtool", "-k", dpdefs.IPIPIfaceNameV4)
+ if err != nil {
+ return fmt.Sprintf("ERROR: %v", err)
+ }
+ return out
+ }, "10s", "100ms").Should(ContainSubstring("tx-checksumming: on"))
+ })
+ }
+
+ It("should fully randomize MASQUERADE rules", func() {
+ for _, felix := range tc.Felixes {
+ if NFTMode() {
+ Eventually(func() string {
+ out, _ := felix.ExecOutput("nft", "list", "table", "calico")
+ return out
+ }, "10s", "100ms").Should(ContainSubstring("fully-random"))
+ } else {
+ Eventually(func() string {
+ out, _ := felix.ExecOutput("iptables-save", "-c")
+ return out
+ }, "10s", "100ms").Should(ContainSubstring("--random-fully"))
+ }
+ }
+ })
+
+ It("should have workload to workload connectivity", func() {
+ cc.ExpectSome(w[0], w[1])
+ cc.ExpectSome(w[1], w[0])
+ cc.CheckConnectivity()
+ })
+
+ It("should have some blackhole routes installed", func() {
+ if routeSource == "WorkloadIPs" {
+ Skip("not applicable for workload ips")
+ return
+ }
+
+ nodes := []string{
+ "blackhole 10.65.0.0/26 proto 80",
+ "blackhole 10.65.1.0/26 proto 80",
+ "blackhole 10.65.2.0/26 proto 80",
+ }
+
+ for n, result := range nodes {
+ Eventually(func() string {
+ o, _ := felixes[n].ExecOutput("ip", "r", "s", "type", "blackhole")
+ return o
+ }, "10s", "100ms").Should(ContainSubstring(result))
+ wName := fmt.Sprintf("w%d", n)
+
+ err := client.IPAM().ReleaseByHandle(context.TODO(), wName)
+ Expect(err).NotTo(HaveOccurred())
+
+ affinityCfg := ipam.AffinityConfig{
+ AffinityType: ipam.AffinityTypeHost,
+ Host: felixes[n].Hostname,
+ }
+ err = client.IPAM().ReleaseHostAffinities(context.TODO(), affinityCfg, true)
+ Expect(err).NotTo(HaveOccurred())
+
+ Eventually(func() string {
+ o, _ := felixes[n].ExecOutput("ip", "r", "s", "type", "blackhole")
+ return o
+ }, "10s", "100ms").Should(BeEmpty())
+ }
+ })
+
+ if ipipMode == api.IPIPModeCrossSubnet && routeSource == "CalicoIPAM" {
+ It("should move same-subnet routes when the node IP moves to a new interface", func() {
+ // Routes should look like this:
+ //
+ // default via 172.17.0.1 dev eth0
+ // blackhole 10.65.0.0/26 proto 80
+ // 10.65.0.2 dev cali29f56ea1abf scope link
+ // 10.65.1.0/26 via 172.17.0.6 dev eth0 proto 80 onlink
+ // 10.65.2.0/26 via 172.17.0.5 dev eth0 proto 80 onlink
+ // 172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.7
+ felix := tc.Felixes[0]
+ Eventually(felix.ExecOutputFn("ip", "route", "show"), "10s").Should(ContainSubstring(
+ fmt.Sprintf("10.65.1.0/26 via %s dev eth0 proto 80 onlink", tc.Felixes[1].IP)))
+
+ // Find the default and subnet routes, we'll need to
+ // recreate those after moving the IP.
+ defaultRoute, err := felix.ExecOutput("ip", "route", "show", "default")
+ Expect(err).NotTo(HaveOccurred())
+ lines := strings.Split(strings.Trim(defaultRoute, "\n "), "\n")
+ Expect(lines).To(HaveLen(1))
+ defaultRouteArgs := strings.Split(strings.Replace(lines[0], "eth0", "bond0", -1), " ")
+
+ // Assuming the subnet route will be "proto kernel" and that will be the only such route.
+ subnetRoute, err := felix.ExecOutput("ip", "route", "show", "proto", "kernel")
+ Expect(err).NotTo(HaveOccurred())
+ lines = strings.Split(strings.Trim(subnetRoute, "\n "), "\n")
+ Expect(lines).To(HaveLen(1), "expected only one proto kernel route, has docker's routing set-up changed?")
+ subnetArgs := strings.Split(strings.Replace(lines[0], "eth0", "bond0", -1), " ")
+
+ // Add the bond, replacing eth0.
+ felix.Exec("ip", "addr", "del", felix.IP, "dev", "eth0")
+ felix.Exec("ip", "link", "add", "dev", "bond0", "type", "bond")
+ felix.Exec("ip", "link", "set", "dev", "eth0", "down")
+ felix.Exec("ip", "link", "set", "dev", "eth0", "master", "bond0")
+ felix.Exec("ip", "link", "set", "dev", "eth0", "up")
+ felix.Exec("ip", "link", "set", "dev", "bond0", "up")
+
+ // Move IP to bond0. We don't actually set up more than one
+ // bonded interface in this test, we just want to know that
+ // felix spots the IP move.
+ ipWithSubnet := felix.IP + "/" + felix.GetIPPrefix()
+ felix.Exec("ip", "addr", "add", ipWithSubnet, "dev", "bond0")
+
+ // Re-add the default routes, via bond0 (one gets removed when
+ // eth0 goes down, the other gets stuck on eth0).
+ felix.Exec(append([]string{"ip", "r", "add"}, defaultRouteArgs...)...)
+ felix.Exec(append([]string{"ip", "r", "replace"}, subnetArgs...)...)
+
+ expCrossSubRoute := fmt.Sprintf("10.65.1.0/26 via %s dev bond0 proto 80 onlink", tc.Felixes[1].IP)
+ Eventually(felix.ExecOutputFn("ip", "route", "show"), "60s").Should(
+ ContainSubstring(expCrossSubRoute),
+ "Cross-subnet route should move from eth0 to bond0.",
+ )
+ })
+ }
+
+ It("should have host to workload connectivity", func() {
+ if ipipMode == api.IPIPModeAlways && routeSource == "WorkloadIPs" {
+ Skip("Skipping due to known issue with tunnel IPs not being programmed in WEP mode")
+ }
+ cc.ExpectSome(tc.Felixes[0], w[1])
+ cc.ExpectSome(tc.Felixes[0], w[0])
+ cc.CheckConnectivity()
+ })
+
+ It("should have host to host connectivity", func() {
+ cc.ExpectSome(tc.Felixes[0], hostW[1])
+ cc.ExpectSome(tc.Felixes[1], hostW[0])
+ cc.CheckConnectivity()
+ })
+
+ Context("with host protection policy in place", func() {
+ BeforeEach(func() {
+ // Make sure our new host endpoints don't cut felix off from the datastore.
+ err := infra.AddAllowToDatastore("host-endpoint=='true'")
+ Expect(err).NotTo(HaveOccurred())
+
+ ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
+ defer cancel()
+
+ for _, f := range tc.Felixes {
+ hep := api.NewHostEndpoint()
+ hep.Name = "eth0-" + f.Name
+ hep.Labels = map[string]string{
+ "host-endpoint": "true",
+ }
+ hep.Spec.Node = f.Hostname
+ hep.Spec.ExpectedIPs = []string{f.IP}
+ _, err := client.HostEndpoints().Create(ctx, hep, options.SetOptions{})
+ Expect(err).NotTo(HaveOccurred())
+ }
+ })
+
+ It("should have workload connectivity but not host connectivity", func() {
+ // Host endpoints (with no policies) block host-host traffic due to default drop.
+ cc.ExpectNone(tc.Felixes[0], hostW[1])
+ cc.ExpectNone(tc.Felixes[1], hostW[0])
+ // But the rules to allow IPIP between our hosts let the workload traffic through.
+ cc.ExpectSome(w[0], w[1])
+ cc.ExpectSome(w[1], w[0])
+ cc.CheckConnectivity()
+ })
+ })
+
+ Context("with all-interfaces host protection policy in place", func() {
+ BeforeEach(func() {
+ // Make sure our new host endpoints don't cut felix off from the datastore.
+ err := infra.AddAllowToDatastore("host-endpoint=='true'")
+ Expect(err).NotTo(HaveOccurred())
+
+ ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
+ defer cancel()
+
+ // Create host endpoints for each node.
+ for _, f := range tc.Felixes {
+ hep := api.NewHostEndpoint()
+ hep.Name = "all-interfaces-" + f.Name
+ hep.Labels = map[string]string{
+ "host-endpoint": "true",
+ "hostname": f.Hostname,
+ }
+ hep.Spec.Node = f.Hostname
+ hep.Spec.ExpectedIPs = []string{f.IP}
+ hep.Spec.InterfaceName = "*"
+ _, err := client.HostEndpoints().Create(ctx, hep, options.SetOptions{})
+ Expect(err).NotTo(HaveOccurred())
+ }
+ })
+
+ It("should block host-to-host traffic in the absence of policy allowing it", func() {
+ cc.ExpectNone(tc.Felixes[0], hostW[1])
+ cc.ExpectNone(tc.Felixes[1], hostW[0])
+ cc.ExpectSome(w[0], w[1])
+ cc.ExpectSome(w[1], w[0])
+ cc.CheckConnectivity()
+ })
+
+ It("should allow host-to-own-pod traffic in the absence of policy allowing it but not host to other-pods", func() {
+ cc.ExpectSome(tc.Felixes[0], w[0])
+ cc.ExpectSome(tc.Felixes[1], w[1])
+ cc.ExpectNone(tc.Felixes[0], w[1])
+ cc.ExpectNone(tc.Felixes[1], w[0])
+ cc.CheckConnectivity()
+ })
+
+ It("should allow felixes[0] to reach felixes[1] if ingress and egress policies are in place", func() {
+ // Create a policy selecting felix[1] that allows egress.
+ policy := api.NewGlobalNetworkPolicy()
+ policy.Name = "f0-egress"
+ policy.Spec.Egress = []api.Rule{{Action: api.Allow}}
+ policy.Spec.Selector = fmt.Sprintf("hostname == '%s'", tc.Felixes[0].Hostname)
+ _, err := client.GlobalNetworkPolicies().Create(utils.Ctx, policy, utils.NoOptions)
+ Expect(err).NotTo(HaveOccurred())
+
+ // But there is no policy allowing ingress into felix[1].
+ cc.ExpectNone(tc.Felixes[0], hostW[1])
+ cc.ExpectNone(tc.Felixes[1], hostW[0])
+
+ // Workload connectivity is unchanged.
+ cc.ExpectSome(w[0], w[1])
+ cc.ExpectSome(w[1], w[0])
+ cc.CheckConnectivity()
+ cc.ResetExpectations()
+
+ // Now add a policy selecting felix[1] that allows ingress.
+ policy = api.NewGlobalNetworkPolicy()
+ policy.Name = "f1-ingress"
+ policy.Spec.Ingress = []api.Rule{{Action: api.Allow}}
+ policy.Spec.Selector = fmt.Sprintf("hostname == '%s'", tc.Felixes[1].Hostname)
+ _, err = client.GlobalNetworkPolicies().Create(utils.Ctx, policy, utils.NoOptions)
+ Expect(err).NotTo(HaveOccurred())
+
+ // Now testContainers.Felix[0] can reach testContainers.Felix[1].
+ cc.ExpectSome(tc.Felixes[0], hostW[1])
+ cc.ExpectNone(tc.Felixes[1], hostW[0])
+
+ // Workload connectivity is unchanged.
+ cc.ExpectSome(w[0], w[1])
+ cc.ExpectSome(w[1], w[0])
+ cc.CheckConnectivity()
+ })
+
+ Context("with policy allowing port 8055", func() {
+ BeforeEach(func() {
+ tcp := numorstring.ProtocolFromString("tcp")
+ udp := numorstring.ProtocolFromString("udp")
+ p8055 := numorstring.SinglePort(8055)
+ policy := api.NewGlobalNetworkPolicy()
+ policy.Name = "allow-8055"
+ policy.Spec.Ingress = []api.Rule{
+ {
+ Protocol: &udp,
+ Destination: api.EntityRule{
+ Ports: []numorstring.Port{p8055},
+ },
+ Action: api.Allow,
+ },
+ {
+ Protocol: &tcp,
+ Destination: api.EntityRule{
+ Ports: []numorstring.Port{p8055},
+ },
+ Action: api.Allow,
+ },
+ }
+ policy.Spec.Egress = []api.Rule{
+ {
+ Protocol: &udp,
+ Destination: api.EntityRule{
+ Ports: []numorstring.Port{p8055},
+ },
+ Action: api.Allow,
+ },
+ {
+ Protocol: &tcp,
+ Destination: api.EntityRule{
+ Ports: []numorstring.Port{p8055},
+ },
+ Action: api.Allow,
+ },
+ }
+ policy.Spec.Selector = fmt.Sprintf("has(host-endpoint)")
+ _, err := client.GlobalNetworkPolicies().Create(utils.Ctx, policy, utils.NoOptions)
+ Expect(err).NotTo(HaveOccurred())
+ })
+
+ // Please take care if adding other connectivity checks into this case, to
+ // avoid those other checks setting up conntrack state that allows the
+ // existing case to pass for a different reason.
+ It("allows host0 to remote Calico-networked workload via service IP", func() {
+ if ipipMode == api.IPIPModeAlways && routeSource == "WorkloadIPs" {
+ Skip("Skipping due to known issue with tunnel IPs not being programmed in WEP mode")
+ }
+ // Allocate a service IP.
+ serviceIP := "10.101.0.11"
+ port := 8055
+ tgtPort := 8055
+
+ createK8sServiceWithoutKubeProxy(createK8sServiceWithoutKubeProxyArgs{
+ infra: infra,
+ felix: tc.Felixes[0],
+ w: w[1],
+ svcName: "test-svc",
+ serviceIP: serviceIP,
+ targetIP: w[1].IP,
+ port: port,
+ tgtPort: tgtPort,
+ chain: "OUTPUT",
+ })
+ // Expect to connect to the service IP.
+ cc.ExpectSome(felixes[0], connectivity.TargetIP(serviceIP), uint16(port))
+ cc.CheckConnectivity()
+ })
+ })
+ })
+
+ Context("after removing BGP address from third node", func() {
+ // Simulate having a host send VXLAN traffic from an unknown source, should get blocked.
+ BeforeEach(func() {
+ for _, f := range felixes {
+ if BPFMode() {
+ Eventually(func() int {
+ return strings.Count(f.BPFRoutes(), "host")
+ }).Should(Equal(len(felixes)*2),
+ "Expected one host and one host tunneled route per node")
+ } else if NFTMode() {
+ Eventually(f.NFTSetSizeFn("cali40all-hosts-net"), "10s", "200ms").Should(Equal(len(felixes)))
+ } else {
+ Eventually(f.IPSetSizeFn("cali40all-hosts-net"), "10s", "200ms").Should(Equal(len(felixes)))
+ }
+ }
+
+ // Pause felix[2], so it can't touch the dataplane; we want to
+ // test that felix[0] blocks the traffic.
+ pid := felixes[2].GetFelixPID()
+ felixes[2].Exec("kill", "-STOP", fmt.Sprint(pid))
+
+ ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
+ defer cancel()
+ infra.RemoveNodeAddresses(felixes[2])
+ node, err := client.Nodes().Get(ctx, felixes[2].Hostname, options.GetOptions{})
+ Expect(err).NotTo(HaveOccurred())
+
+ node.Spec.BGP = nil
+ _, err = client.Nodes().Update(ctx, node, options.SetOptions{})
+ })
+
+ It("should have no connectivity from third felix and expected number of IPs in allow list", func() {
+ if BPFMode() {
+ Eventually(func() int {
+ return strings.Count(felixes[0].BPFRoutes(), "host")
+ }).Should(Equal((len(felixes)-1)*2),
+ "Expected one host and one host tunneled route per node, not: "+felixes[0].BPFRoutes())
+ } else if NFTMode() {
+ Eventually(felixes[0].NFTSetSizeFn("cali40all-hosts-net"), "5s", "200ms").Should(Equal(len(felixes) - 1))
+ } else {
+ Eventually(felixes[0].IPSetSizeFn("cali40all-hosts-net"), "5s", "200ms").Should(Equal(len(felixes) - 1))
+ }
+
+ cc.ExpectSome(w[0], w[1])
+ cc.ExpectSome(w[1], w[0])
+ cc.ExpectNone(w[0], w[2])
+ cc.ExpectNone(w[1], w[2])
+ cc.ExpectNone(w[2], w[0])
+ cc.ExpectNone(w[2], w[1])
+ cc.CheckConnectivity()
+ })
+ })
+
+ // Explicitly verify that the IPIP allow-list IP set is doing its job (since Felix makes multiple dataplane
+ // changes when the BGP IP disappears, and we want to make sure that it's the rule that's causing the
+ // connectivity to drop).
+ Context("after removing BGP address from third node, all felixes paused", func() {
+ // Simulate having a host send IPIP traffic from an unknown source, should get blocked.
+ BeforeEach(func() {
+ if BPFMode() {
+ Skip("Skipping due to manual removal of host from ipset not breaking connectivity in BPF mode")
+ return
+ }
+
+ // Check we initially have the expected number of entries.
+ for _, f := range felixes {
+ // Wait for Felix to set up the allow list.
+ if NFTMode() {
+ Eventually(f.NFTSetSizeFn("cali40all-hosts-net"), "5s", "200ms").Should(Equal(len(felixes)))
+ } else {
+ Eventually(f.IPSetSizeFn("cali40all-hosts-net"), "5s", "200ms").Should(Equal(len(felixes)))
+ }
+ }
+
+ // Wait until dataplane has settled.
+ cc.ExpectSome(w[0], w[1])
+ cc.ExpectSome(w[0], w[2])
+ cc.ExpectSome(w[1], w[2])
+ cc.CheckConnectivity()
+ cc.ResetExpectations()
+
+ // Then pause all the felixes.
+ for _, f := range felixes {
+ pid := f.GetFelixPID()
+ f.Exec("kill", "-STOP", fmt.Sprint(pid))
+ }
+ })
+
+ // BPF mode doesn't use the IP set.
+ if ipipMode == api.IPIPModeAlways && !BPFMode() {
+ It("after manually removing third node from allow list should have expected connectivity", func() {
+ if NFTMode() {
+ felixes[0].Exec("nft", "delete", "element", "ip", "calico", "cali40all-hosts-net", fmt.Sprintf("{ %s }", felixes[2].IP))
+ } else {
+ felixes[0].Exec("ipset", "del", "cali40all-hosts-net", felixes[2].IP)
+ }
+
+ cc.ExpectSome(w[0], w[1])
+ cc.ExpectSome(w[1], w[0])
+ cc.ExpectSome(w[1], w[2])
+ cc.ExpectNone(w[2], w[0])
+ cc.CheckConnectivity()
+ })
+ }
+ })
+
+ It("should configure the ipip device correctly", func() {
+ // The ipip device should appear with default MTU, etc. FV environment uses MTU 1500,
+ // which means that we should expect 1480 after subtracting IPIP overhead for IPv4.
+ mtuStr := "mtu 1480"
+ for _, felix := range felixes {
+ Eventually(func() string {
+ out, _ := felix.ExecOutput("ip", "-d", "link", "show", dpdefs.IPIPIfaceNameV4)
+ return out
+ }, "60s", "500ms").Should(ContainSubstring(mtuStr))
+ }
+
+ // Change the host device's MTU, and expect the IPIP device to be updated.
+ for _, felix := range felixes {
+ Eventually(func() error {
+ _, err := felix.ExecOutput("ip", "link", "set", "eth0", "mtu", "1400")
+ return err
+ }, "10s", "100ms").Should(BeNil())
+ }
+
+ // MTU should be auto-detected, and updated to the host MTU minus 20 bytes overhead IPIP.
+ mtuStr = "mtu 1380"
+ mtuValue := "1380"
+ for _, felix := range felixes {
+ // Felix checks host MTU every 30s
+ Eventually(func() string {
+ out, _ := felix.ExecOutput("ip", "-d", "link", "show", dpdefs.IPIPIfaceNameV4)
+ return out
+ }, "60s", "500ms").Should(ContainSubstring(mtuStr))
+
+ // And expect the MTU file on disk to be updated.
+ Eventually(func() string {
+ out, _ := felix.ExecOutput("cat", "/var/lib/calico/mtu")
+ return out
+ }, "30s", "100ms").Should(ContainSubstring(mtuValue))
+ }
+
+ // Explicitly configure the MTU.
+ felixConfig := api.NewFelixConfiguration() // Create a default FelixConfiguration
+ felixConfig.Name = "default"
+ mtu := 1300
+ felixConfig.Spec.IPIPMTU = &mtu
+ _, err := client.FelixConfigurations().Create(context.Background(), felixConfig, options.SetOptions{})
+ Expect(err).NotTo(HaveOccurred())
+
+ // Expect the settings to be changed on the device.
+ for _, felix := range felixes {
+ // Felix checks host MTU every 30s
+ Eventually(func() string {
+ out, _ := felix.ExecOutput("ip", "-d", "link", "show", dpdefs.IPIPIfaceNameV4)
+ return out
+ }, "60s", "500ms").Should(ContainSubstring("mtu 1300"))
+ }
+ })
+
+ Context("external nodes configured", func() {
+ var externalClient *containers.Container
+
+ BeforeEach(func() {
+ externalClient = infrastructure.RunExtClient("ext-client")
+
+ Eventually(func() error {
+ err := externalClient.ExecMayFail("ip", "tunnel", "add", "tunl0", "mode", "ipip")
+ if err != nil && strings.Contains(err.Error(), "SIOCADDTUNNEL: File exists") {
+ return nil
+ }
+ return err
+ }).Should(Succeed())
+
+ externalClient.Exec("ip", "link", "set", "tunl0", "up")
+ externalClient.Exec("ip", "addr", "add", "dev", "tunl0", "10.65.222.1")
+ externalClient.Exec("ip", "route", "add", "10.65.0.0/24", "via",
+ tc.Felixes[0].IP, "dev", "tunl0", "onlink")
+ })
+
+ JustAfterEach(func() {
+ if CurrentGinkgoTestDescription().Failed {
+ externalClient.Exec("ip", "r")
+ externalClient.Exec("ip", "l")
+ externalClient.Exec("ip", "a")
+ }
+ })
+
+ AfterEach(func() {
+ externalClient.Stop()
+ })
+
+ It("should allow IPIP to external client if it is in ExternalNodesCIDRList", func() {
+ By("testing that ext client ipip does not work if not part of ExternalNodesCIDRList")
+
+ for _, f := range tc.Felixes {
+ // Make sure that only the internal nodes are present in the ipset
+ if BPFMode() {
+ Eventually(f.BPFRoutes, "10s").Should(ContainSubstring(f.IP))
+ Consistently(f.BPFRoutes).ShouldNot(ContainSubstring(externalClient.IP))
+ } else if NFTMode() {
+ Eventually(f.NFTSetSizeFn("cali40all-hosts-net"), "5s", "200ms").Should(Equal(3))
+ } else {
+ Eventually(f.IPSetSizeFn("cali40all-hosts-net"), "5s", "200ms").Should(Equal(3))
+ }
+ }
+
+ cc.ExpectNone(externalClient, w[0])
+ cc.CheckConnectivity()
+
+ By("changing configuration to include the external client")
+
+ updateConfig := func(addr string) {
+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+ c, err := client.FelixConfigurations().Get(ctx, "default", options.GetOptions{})
+ if err != nil {
+ // Create the default config if it doesn't already exist.
+ if _, ok := err.(cerrors.ErrorResourceDoesNotExist); ok {
+ c = api.NewFelixConfiguration()
+ c.Name = "default"
+ c, err = client.FelixConfigurations().Create(ctx, c, options.SetOptions{})
+ Expect(err).NotTo(HaveOccurred())
+ } else {
+ Expect(err).NotTo(HaveOccurred())
+ }
+ }
+ c.Spec.ExternalNodesCIDRList = &[]string{addr}
+ log.WithFields(log.Fields{"felixconfiguration": c, "adding Addr": addr}).Info("Updating FelixConfiguration ")
+ _, err = client.FelixConfigurations().Update(ctx, c, options.SetOptions{})
+ Expect(err).NotTo(HaveOccurred())
+ }
+
+ updateConfig(externalClient.IP)
+
+ // Wait for the config to take
+ for _, f := range tc.Felixes {
+ if BPFMode() {
+ Eventually(f.BPFRoutes, "10s").Should(ContainSubstring(externalClient.IP))
+ Expect(f.IPSetSize("cali40all-hosts-net")).To(BeZero(),
+ "BPF mode shouldn't program IP sets")
+ } else if NFTMode() {
+ Eventually(f.NFTSetSizeFn("cali40all-hosts-net"), "15s", "200ms").Should(Equal(4))
+ } else {
+ Eventually(f.IPSetSizeFn("cali40all-hosts-net"), "15s", "200ms").Should(Equal(4))
+ }
+ }
+
+ // Pause felix[0], so it can't touch the dataplane; we want to
+ // test that felix[0] blocks the traffic.
+ pid := felixes[0].GetFelixPID()
+ felixes[0].Exec("kill", "-STOP", fmt.Sprint(pid))
+
+ tc.Felixes[0].Exec("ip", "route", "add", "10.65.222.1", "via",
+ externalClient.IP, "dev", dpdefs.IPIPIfaceNameV4, "onlink", "proto", "90")
+
+ By("testing that the ext client can connect via ipip")
+ cc.ResetExpectations()
+ cc.ExpectSome(externalClient, w[0])
+ cc.CheckConnectivity()
+ })
+ })
+ })
+ }
+})
+
type createK8sServiceWithoutKubeProxyArgs struct {
infra infrastructure.DatastoreInfra
felix *infrastructure.Felix
@@ -533,3 +1213,72 @@ func getDataStoreType(infra infrastructure.DatastoreInfra) string {
return "kubernetes"
}
}
+
+func createIPIPBaseTopologyOptions(
+ ipipMode api.IPIPMode,
+ routeSource string,
+ brokenXSum bool,
+) infrastructure.TopologyOptions {
+ topologyOptions := infrastructure.DefaultTopologyOptions()
+ //topologyOptions.IPIPEnabled = true
+ topologyOptions.IPIPMode = ipipMode
+ topologyOptions.VXLANMode = api.VXLANModeNever
+ topologyOptions.IPIPDevice = dpdefs.IPIPIfaceNameV4
+ topologyOptions.SimulateRoutes = false
+ topologyOptions.ExtraEnvVars["FELIX_ProgramRoutes"] = "IPIP"
+ topologyOptions.ExtraEnvVars["FELIX_ROUTESOURCE"] = routeSource
+ // We force the broken checksum handling on or off so that we're not dependent on kernel version
+ // for these tests. Since we're testing in containers anyway, checksum offload can't really be
+ // tested but we can verify the state with ethtool.
+ topologyOptions.ExtraEnvVars["FELIX_FeatureDetectOverride"] = fmt.Sprintf("ChecksumOffloadBroken=%t", brokenXSum)
+ topologyOptions.FelixDebugFilenameRegex = "ipip|route_table|l3_route_resolver|int_dataplane"
+ return topologyOptions
+}
+
+func setupIPIPWorkloads(infra infrastructure.DatastoreInfra, tc infrastructure.TopologyContainers, to infrastructure.TopologyOptions, client client.Interface) (w, hostW [3]*workload.Workload) {
+ // Install a default profile that allows all ingress and egress, in the absence of any Policy.
+ infra.AddDefaultAllow()
+
+ // Wait until the ipip device appears; it is created when felix inserts the ipip module
+ // into the kernel.
+ Eventually(func() error {
+ links, err := netlink.LinkList()
+ if err != nil {
+ return err
+ }
+ for _, link := range links {
+ if link.Attrs().Name == "tunl0" {
+ return nil
+ }
+ }
+ return errors.New("tunl0 wasn't auto-created")
+ }).Should(BeNil())
+
+ // Create workloads, using that profile. One on each "host".
+ _, IPv4CIDR, err := net.ParseCIDR(to.IPPoolCIDR)
+ Expect(err).To(BeNil())
+ for ii := range w {
+ wIP := fmt.Sprintf("%d.%d.%d.2", IPv4CIDR.IP[0], IPv4CIDR.IP[1], ii)
+ wName := fmt.Sprintf("w%d", ii)
+ err := client.IPAM().AssignIP(context.Background(), ipam.AssignIPArgs{
+ IP: net.MustParseIP(wIP),
+ HandleID: &wName,
+ Attrs: map[string]string{
+ ipam.AttributeNode: tc.Felixes[ii].Hostname,
+ },
+ Hostname: tc.Felixes[ii].Hostname,
+ })
+ Expect(err).NotTo(HaveOccurred())
+
+ w[ii] = workload.Run(tc.Felixes[ii], wName, "default", wIP, "8055", "tcp")
+ w[ii].ConfigureInInfra(infra)
+
+ hostW[ii] = workload.Run(tc.Felixes[ii], fmt.Sprintf("host%d", ii), "", tc.Felixes[ii].IP, "8055", "tcp")
+ }
+
+ if BPFMode() {
+ ensureAllNodesBPFProgramsAttached(tc.Felixes)
+ }
+
+ return
+}
diff --git a/felix/fv/latency_test.go b/felix/fv/latency_test.go
index 103c58fcf29..58cc7f1a3f3 100644
--- a/felix/fv/latency_test.go
+++ b/felix/fv/latency_test.go
@@ -62,7 +62,7 @@ var _ = Context("_BPF-SAFE_ Latency tests with initialized Felix and etcd datast
BeforeEach(func() {
topologyOptions := infrastructure.DefaultTopologyOptions()
- topologyOptions.IPIPEnabled = false
+ topologyOptions.IPIPMode = api.IPIPModeNever
topologyOptions.ExtraEnvVars["FELIX_BPFLOGLEVEL"] = "off" // For best perf.
tc, etcd, client, infra = infrastructure.StartSingleNodeEtcdTopology(topologyOptions)
diff --git a/felix/fv/mtu_test.go b/felix/fv/mtu_test.go
index 24903d2b039..68bf2ea16d0 100644
--- a/felix/fv/mtu_test.go
+++ b/felix/fv/mtu_test.go
@@ -88,7 +88,7 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ VXLAN topology before addin
topologyOptions := infrastructure.DefaultTopologyOptions()
topologyOptions.DelayFelixStart = true
topologyOptions.VXLANMode = api.VXLANModeAlways
- topologyOptions.IPIPEnabled = false
+ topologyOptions.IPIPMode = api.IPIPModeNever
topologyOptions.EnableIPv6 = enableIPv6
// Need n>1 or the infra won't set up IP pools!
@@ -137,7 +137,7 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ VXLAN topology before addin
infra = getInfra()
topologyOptions := infrastructure.DefaultTopologyOptions()
topologyOptions.VXLANMode = api.VXLANModeAlways
- topologyOptions.IPIPEnabled = false
+ topologyOptions.IPIPMode = api.IPIPModeNever
topologyOptions.EnableIPv6 = enableIPv6
// Configure the interface pattern so that it doesn't match any host interfaces.
diff --git a/felix/fv/routes_test.go b/felix/fv/routes_test.go
index d06af021032..5a174f73067 100644
--- a/felix/fv/routes_test.go
+++ b/felix/fv/routes_test.go
@@ -53,7 +53,7 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ routing table tests", []api
topologyOptions := infrastructure.DefaultTopologyOptions()
topologyOptions.VXLANMode = api.VXLANModeAlways
- topologyOptions.IPIPEnabled = false
+ topologyOptions.IPIPMode = api.IPIPModeNever
topologyOptions.EnableIPv6 = false
topologyOptions.ExtraEnvVars["FELIX_ROUTESOURCE"] = "WorkloadIPs"
topologyOptions.FelixDebugFilenameRegex = "route_table.go|vxlan_fdb"
diff --git a/felix/fv/service_loop_prevention_test.go b/felix/fv/service_loop_prevention_test.go
index d567fce84eb..b3c1a09fef6 100644
--- a/felix/fv/service_loop_prevention_test.go
+++ b/felix/fv/service_loop_prevention_test.go
@@ -50,7 +50,7 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ service loop prevention; wi
if BPFMode() {
options.EnableIPv6 = true
}
- options.IPIPEnabled = false
+ options.IPIPMode = api.IPIPModeNever
tc, client = infrastructure.StartNNodeTopology(2, options, infra)
if BPFMode() {
ensureAllNodesBPFProgramsAttached(tc.Felixes)
diff --git a/felix/fv/spoof_test.go b/felix/fv/spoof_test.go
index 6a1b796e3c4..8a381a24c06 100644
--- a/felix/fv/spoof_test.go
+++ b/felix/fv/spoof_test.go
@@ -169,7 +169,7 @@ var _ = Describe("Spoof tests", func() {
Expect(err).NotTo(HaveOccurred())
opts := infrastructure.DefaultTopologyOptions()
opts.EnableIPv6 = true
- opts.IPIPEnabled = false
+ opts.IPIPMode = api.IPIPModeNever
opts.ExtraEnvVars["FELIX_BPFConnectTimeLoadBalancing"] = string(api.BPFConnectTimeLBDisabled)
opts.ExtraEnvVars["FELIX_BPFHostNetworkedNATWithoutCTLB"] = string(api.BPFHostNetworkedNATEnabled)
opts.ExtraEnvVars["FELIX_IPV6SUPPORT"] = "true"
diff --git a/felix/fv/status_report_test.go b/felix/fv/status_report_test.go
index 1ecfe78fbfd..2c13a817cad 100644
--- a/felix/fv/status_report_test.go
+++ b/felix/fv/status_report_test.go
@@ -49,7 +49,7 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ openstack status-reporting"
topologyOptions := infrastructure.DefaultTopologyOptions()
topologyOptions.VXLANMode = api.VXLANModeAlways
- topologyOptions.IPIPEnabled = false
+ topologyOptions.IPIPMode = api.IPIPModeNever
topologyOptions.EnableIPv6 = false
topologyOptions.ExtraEnvVars["FELIX_ENDPOINTREPORTINGENABLED"] = "true"
topologyOptions.ExtraEnvVars["FELIX_OPENSTACKREGION"] = "r0"
diff --git a/felix/fv/tiered_policy_test.go b/felix/fv/tiered_policy_test.go
index 23c3c3770e5..e4203e46572 100644
--- a/felix/fv/tiered_policy_test.go
+++ b/felix/fv/tiered_policy_test.go
@@ -81,7 +81,7 @@ var _ = infrastructure.DatastoreDescribe("connectivity tests with policy tiers _
BeforeEach(func() {
infra = getInfra()
opts = infrastructure.DefaultTopologyOptions()
- opts.IPIPEnabled = false
+ opts.IPIPMode = api.IPIPModeNever
// Start felix instances.
tc, client = infrastructure.StartNNodeTopology(2, opts, infra)
diff --git a/felix/fv/vxlan_test.go b/felix/fv/vxlan_test.go
index f5bf6e46d67..3ea43021f08 100644
--- a/felix/fv/vxlan_test.go
+++ b/felix/fv/vxlan_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2020-2021 Tigera, Inc. All rights reserved.
+// Copyright (c) 2020-2024 Tigera, Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -83,7 +83,7 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ VXLAN topology before addin
Skip("Skipping NFT / BPF tests for etcdv3 backend.")
}
- topologyOptions = createBaseTopologyOptions(vxlanMode, enableIPv6, routeSource, brokenXSum)
+ topologyOptions = createVXLANBaseTopologyOptions(vxlanMode, enableIPv6, routeSource, brokenXSum)
topologyOptions.FelixLogSeverity = "Debug"
tc, client = infrastructure.StartNNodeTopology(3, topologyOptions, infra)
@@ -875,10 +875,10 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ VXLAN topology before addin
}
})
-func createBaseTopologyOptions(vxlanMode api.VXLANMode, enableIPv6 bool, routeSource string, brokenXSum bool) infrastructure.TopologyOptions {
+func createVXLANBaseTopologyOptions(vxlanMode api.VXLANMode, enableIPv6 bool, routeSource string, brokenXSum bool) infrastructure.TopologyOptions {
topologyOptions := infrastructure.DefaultTopologyOptions()
topologyOptions.VXLANMode = vxlanMode
- topologyOptions.IPIPEnabled = false
+ topologyOptions.IPIPMode = api.IPIPModeNever
topologyOptions.EnableIPv6 = enableIPv6
topologyOptions.ExtraEnvVars["FELIX_ROUTESOURCE"] = routeSource
// We force the broken checksum handling on or off so that we're not dependent on kernel version
diff --git a/felix/fv/wireguard_test.go b/felix/fv/wireguard_test.go
index 8f97f06dff5..34b98c1650a 100644
--- a/felix/fv/wireguard_test.go
+++ b/felix/fv/wireguard_test.go
@@ -17,12 +17,10 @@
package fv_test
import (
- "bytes"
"context"
"errors"
"fmt"
"os"
- "os/exec"
"regexp"
"strconv"
"strings"
@@ -75,9 +73,9 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ WireGuard-Supported", []api
cc *connectivity.Checker
routeEntriesV4 [nodeCount]string
routeEntriesV6 [nodeCount]string
- dmesgCmd *exec.Cmd
- dmesgBuf bytes.Buffer
- dmesgKill func()
+ //dmesgCmd *exec.Cmd
+ //dmesgBuf bytes.Buffer
+ //dmesgKill func()
wgBootstrapEvents chan struct{}
)
@@ -108,17 +106,17 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ WireGuard-Supported", []api
}
// Enable Wireguard module debugging.
- utils.Run("sudo", "sh", "-c", "echo module wireguard +p > /sys/kernel/debug/dynamic_debug/control")
+ //utils.Run("sudo", "sh", "-c", "echo module wireguard +p > /sys/kernel/debug/dynamic_debug/control")
// Start a process tailing the dmesg log.
- ctx, cancel := context.WithCancel(context.Background())
+ /*ctx, cancel := context.WithCancel(context.Background())
dmesgCmd = exec.CommandContext(ctx, "sudo", "dmesg", "-wH")
dmesgCmd.Stdout = &dmesgBuf
dmesgCmd.Stderr = &dmesgBuf
err := dmesgCmd.Start()
Expect(err).NotTo(HaveOccurred())
dmesgKill = cancel
- log.Info("Started dmesg log capture")
+ log.Info("Started dmesg log capture")*/
infra = getInfra()
ipipEnabled := !BPFMode() || !wireguardEnabledV6
@@ -188,11 +186,11 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ WireGuard-Supported", []api
})
AfterEach(func() {
- if dmesgKill != nil {
+ /*if dmesgKill != nil {
log.Info("Stop dmesg log capture")
dmesgKill()
log.Infof("Captured dmesg log:\n%v", dmesgBuf.String())
- }
+ }*/
if CurrentGinkgoTestDescription().Failed {
for _, felix := range topologyContainers.Felixes {
@@ -1057,7 +1055,7 @@ var _ = infrastructure.DatastoreDescribe("_BPF-SAFE_ WireGuard-Supported", []api
}
})
- It("workload connectivity remains but uses un-encrypted tunnel", func() {
+ It("nina workload connectivity remains but uses un-encrypted tunnel", func() {
if wireguardEnabledV4 {
cc.ExpectSome(wlsV4[0], wlsV4[1])
cc.ExpectSome(wlsV4[1], wlsV4[0])
@@ -1765,7 +1763,8 @@ func wireguardTopologyOptions(routeSource string, ipipEnabled, wireguardIPv4Enab
// Enable IPv6 if IPv6 Wireguard will be enabled.
topologyOptions.EnableIPv6 = wireguardIPv6Enabled
// Assigning workload IPs using IPAM API.
- topologyOptions.IPIPRoutesEnabled = false
+ //topologyOptions.SimulateRoutes = true
+ topologyOptions.IPIPMode = api.IPIPModeNever
// Indicate wireguard is enabled
topologyOptions.WireguardEnabled = wireguardIPv4Enabled
topologyOptions.WireguardEnabledV6 = wireguardIPv6Enabled
@@ -1775,7 +1774,10 @@ func wireguardTopologyOptions(routeSource string, ipipEnabled, wireguardIPv4Enab
}
topologyOptions.ExtraEnvVars["FELIX_ROUTESOURCE"] = routeSource
topologyOptions.ExtraEnvVars["FELIX_PROMETHEUSMETRICSENABLED"] = "true"
- topologyOptions.IPIPEnabled = ipipEnabled
+ if !ipipEnabled {
+ topologyOptions.IPIPMode = api.IPIPModeNever
+ topologyOptions.SimulateRoutes = true
+ }
// With Wireguard and BPF mode the default IptablesMarkMask of 0xffff0000 isn't enough.
topologyOptions.ExtraEnvVars["FELIX_IPTABLESMARKMASK"] = "4294934528" // 0xffff8000
diff --git a/felix/routetable/defs.go b/felix/routetable/defs.go
index 094203e5908..2c9e256377f 100644
--- a/felix/routetable/defs.go
+++ b/felix/routetable/defs.go
@@ -38,6 +38,8 @@ const (
RouteClassWireguard
RouteClassVXLANSameSubnet
RouteClassVXLANTunnel
+ RouteClassIPIPTSameSubnet
+ RouteClassIPIPTTunnel
RouteClassIPAMBlockDrop
RouteClassMax
@@ -45,7 +47,8 @@ const (
func (c RouteClass) IsRemote() bool {
switch c {
- case RouteClassVXLANTunnel, RouteClassVXLANSameSubnet, RouteClassWireguard:
+ case RouteClassVXLANTunnel, RouteClassVXLANSameSubnet, RouteClassWireguard,
+ RouteClassIPIPTTunnel, RouteClassIPIPTSameSubnet:
return true
default:
return false
@@ -115,7 +118,7 @@ func (t Target) RouteScope() netlink.Scope {
case TargetTypeProhibit:
return netlink.SCOPE_UNIVERSE
case TargetTypeOnLink:
- return netlink.SCOPE_LINK
+ return netlink.SCOPE_UNIVERSE
default:
return netlink.SCOPE_LINK
}
diff --git a/felix/routetable/ownershippol/main_route_table_policy.go b/felix/routetable/ownershippol/main_route_table_policy.go
index 4480ade8d03..11f1d2dd95e 100644
--- a/felix/routetable/ownershippol/main_route_table_policy.go
+++ b/felix/routetable/ownershippol/main_route_table_policy.go
@@ -46,8 +46,8 @@ func NewMainTable(
// So, if we see RTPROTO_BOOT on a route, it's ours if it's also
// associated with one of our interfaces. But, if we see a route with
// defaultVXLANProto, we know it's ours.
- allRouteProtos = []netlink.RouteProtocol{unix.RTPROT_BOOT, dataplanedefs.VXLANDefaultProto}
- exclusiveRouteProtos = []netlink.RouteProtocol{dataplanedefs.VXLANDefaultProto}
+ allRouteProtos = []netlink.RouteProtocol{unix.RTPROT_BOOT, dataplanedefs.DefaultRoutingProto}
+ exclusiveRouteProtos = []netlink.RouteProtocol{dataplanedefs.DefaultRoutingProto}
} else {
// If DeviceRouteProtocol is not RTPROTO_BOOT, then we use that value
// for all our routes and we don't need to worry about RTPROTO_BOOT.
@@ -62,6 +62,7 @@ func NewMainTable(
// we'll clean up the routes if VXLAN is disabled.
vxlanIfaceName,
dataplanedefs.BPFInDev,
+ dataplanedefs.IPIPIfaceNameV4,
// Not including routetable.InterfaceNone because MainTableOwnershipPolicy
// automatically handles it.
// Not including tunl0, it is managed by BIRD.
diff --git a/felix/routetable/routeclass_string.go b/felix/routetable/routeclass_string.go
index 7a3e95e94d6..c876191573f 100644
--- a/felix/routetable/routeclass_string.go
+++ b/felix/routetable/routeclass_string.go
@@ -13,13 +13,15 @@ func _() {
_ = x[RouteClassWireguard-2]
_ = x[RouteClassVXLANSameSubnet-3]
_ = x[RouteClassVXLANTunnel-4]
- _ = x[RouteClassIPAMBlockDrop-5]
- _ = x[RouteClassMax-6]
+ _ = x[RouteClassIPIPTSameSubnet-5]
+ _ = x[RouteClassIPIPTTunnel-6]
+ _ = x[RouteClassIPAMBlockDrop-7]
+ _ = x[RouteClassMax-8]
}
-const _RouteClass_name = "RouteClassLocalWorkloadRouteClassBPFSpecialRouteClassWireguardRouteClassVXLANSameSubnetRouteClassVXLANTunnelRouteClassIPAMBlockDropRouteClassMax"
+const _RouteClass_name = "RouteClassLocalWorkloadRouteClassBPFSpecialRouteClassWireguardRouteClassVXLANSameSubnetRouteClassVXLANTunnelRouteClassIPIPTSameSubnetRouteClassIPIPTTunnelRouteClassIPAMBlockDropRouteClassMax"
-var _RouteClass_index = [...]uint8{0, 23, 43, 62, 87, 108, 131, 144}
+var _RouteClass_index = [...]uint8{0, 23, 43, 62, 87, 108, 133, 154, 177, 190}
func (i RouteClass) String() string {
if i < 0 || i >= RouteClass(len(_RouteClass_index)-1) {
diff --git a/libcalico-go/config/crd/crd.projectcalico.org_felixconfigurations.yaml b/libcalico-go/config/crd/crd.projectcalico.org_felixconfigurations.yaml
index 8e54bd87a2f..c97d09864ff 100644
--- a/libcalico-go/config/crd/crd.projectcalico.org_felixconfigurations.yaml
+++ b/libcalico-go/config/crd/crd.projectcalico.org_felixconfigurations.yaml
@@ -962,6 +962,10 @@ spec:
PolicySyncPathPrefix is used to by Felix to communicate policy changes to external services,
like Application layer policy. [Default: Empty]
type: string
+ programRoutes:
+ description: 'ProgramRoutes specifies what type of routes Felix should
+ program. [Default: None]. [Default: None]'
+ type: string
prometheusGoMetricsEnabled:
description: |-
PrometheusGoMetricsEnabled disables Go runtime metrics collection, which the Prometheus client does by default, when
diff --git a/libcalico-go/lib/backend/syncersv1/updateprocessors/configurationprocessor_test.go b/libcalico-go/lib/backend/syncersv1/updateprocessors/configurationprocessor_test.go
index 27d3c9d4c6c..51dfe623111 100644
--- a/libcalico-go/lib/backend/syncersv1/updateprocessors/configurationprocessor_test.go
+++ b/libcalico-go/lib/backend/syncersv1/updateprocessors/configurationprocessor_test.go
@@ -43,7 +43,7 @@ const (
)
const (
- numBaseFelixConfigs = 161
+ numBaseFelixConfigs = 162
)
var _ = Describe("Test the generic configuration update processor and the concrete implementations", func() {
diff --git a/manifests/calico-bpf.yaml b/manifests/calico-bpf.yaml
index 2d6cb2f8c9c..99a7ee6998c 100644
--- a/manifests/calico-bpf.yaml
+++ b/manifests/calico-bpf.yaml
@@ -1974,6 +1974,10 @@ spec:
PolicySyncPathPrefix is used to by Felix to communicate policy changes to external services,
like Application layer policy. [Default: Empty]
type: string
+ programRoutes:
+ description: 'ProgramRoutes specifies what type of routes Felix should
+ program. [Default: None]. [Default: None]'
+ type: string
prometheusGoMetricsEnabled:
description: |-
PrometheusGoMetricsEnabled disables Go runtime metrics collection, which the Prometheus client does by default, when
@@ -7638,6 +7642,9 @@ spec:
# Enable or Disable VXLAN on the default IPv6 IP pool.
- name: CALICO_IPV6POOL_VXLAN
value: "Never"
+ # Set if Felix should program IPIP routes or not.
+ - name: FELIX_PROGRAMROUTES
+ value: "None"
# Set MTU for tunnel device used if ipip is enabled
- name: FELIX_IPINIPMTU
valueFrom:
diff --git a/manifests/calico-etcd.yaml b/manifests/calico-etcd.yaml
index 77f3598794e..1883ccdc947 100644
--- a/manifests/calico-etcd.yaml
+++ b/manifests/calico-etcd.yaml
@@ -435,6 +435,9 @@ spec:
# Enable or Disable VXLAN on the default IPv6 IP pool.
- name: CALICO_IPV6POOL_VXLAN
value: "Never"
+ # Set if Felix should program IPIP routes or not.
+ - name: FELIX_PROGRAMROUTES
+ value: "None"
# Set MTU for tunnel device used if ipip is enabled
- name: FELIX_IPINIPMTU
valueFrom:
diff --git a/manifests/calico-ipip.yaml b/manifests/calico-ipip.yaml
new file mode 100644
index 00000000000..86c1a936a50
--- /dev/null
+++ b/manifests/calico-ipip.yaml
@@ -0,0 +1,7812 @@
+---
+# Source: calico/templates/calico-kube-controllers.yaml
+# This manifest creates a Pod Disruption Budget for Controller to allow K8s Cluster Autoscaler to evict
+
+apiVersion: policy/v1
+kind: PodDisruptionBudget
+metadata:
+ name: calico-kube-controllers
+ namespace: kube-system
+ labels:
+ k8s-app: calico-kube-controllers
+spec:
+ maxUnavailable: 1
+ selector:
+ matchLabels:
+ k8s-app: calico-kube-controllers
+---
+# Source: calico/templates/calico-kube-controllers.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: calico-kube-controllers
+ namespace: kube-system
+---
+# Source: calico/templates/calico-node.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: calico-node
+ namespace: kube-system
+---
+# Source: calico/templates/calico-node.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: calico-cni-plugin
+ namespace: kube-system
+---
+# Source: calico/templates/calico-config.yaml
+# This ConfigMap is used to configure a self-hosted Calico installation.
+kind: ConfigMap
+apiVersion: v1
+metadata:
+ name: calico-config
+ namespace: kube-system
+data:
+ # Typha is disabled.
+ typha_service_name: "none"
+ # Configure the backend to use.
+ calico_backend: "ipip"
+
+ # Configure the MTU to use for workload interfaces and tunnels.
+ # By default, MTU is auto-detected, and explicitly setting this field should not be required.
+ # You can override auto-detection by providing a non-zero value.
+ veth_mtu: "0"
+
+ # The CNI network configuration to install on each node. The special
+ # values in this config will be automatically populated.
+ cni_network_config: |-
+ {
+ "name": "k8s-pod-network",
+ "cniVersion": "0.3.1",
+ "plugins": [
+ {
+ "type": "calico",
+ "log_level": "info",
+ "log_file_path": "/var/log/calico/cni/cni.log",
+ "datastore_type": "kubernetes",
+ "nodename": "__KUBERNETES_NODE_NAME__",
+ "mtu": __CNI_MTU__,
+ "ipam": {
+ "type": "calico-ipam"
+ },
+ "policy": {
+ "type": "k8s"
+ },
+ "kubernetes": {
+ "kubeconfig": "__KUBECONFIG_FILEPATH__"
+ }
+ },
+ {
+ "type": "portmap",
+ "snat": true,
+ "capabilities": {"portMappings": true}
+ },
+ {
+ "type": "bandwidth",
+ "capabilities": {"bandwidth": true}
+ }
+ ]
+ }
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: bgpconfigurations.crd.projectcalico.org
+spec:
+ group: crd.projectcalico.org
+ names:
+ kind: BGPConfiguration
+ listKind: BGPConfigurationList
+ plural: bgpconfigurations
+ singular: bgpconfiguration
+ preserveUnknownFields: false
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ description: BGPConfiguration contains the configuration for any BGP routing.
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: BGPConfigurationSpec contains the values of the BGP configuration.
+ properties:
+ asNumber:
+ description: 'ASNumber is the default AS number used by a node. [Default:
+ 64512]'
+ format: int32
+ type: integer
+ bindMode:
+ description: |-
+ BindMode indicates whether to listen for BGP connections on all addresses (None)
+ or only on the node's canonical IP address Node.Spec.BGP.IPvXAddress (NodeIP).
+ Default behaviour is to listen for BGP connections on all addresses.
+ type: string
+ communities:
+ description: Communities is a list of BGP community values and their
+ arbitrary names for tagging routes.
+ items:
+ description: Community contains standard or large community value
+ and its name.
+ properties:
+ name:
+ description: Name given to community value.
+ type: string
+ value:
+ description: |-
+ Value must be of format `aa:nn` or `aa:nn:mm`.
+ For standard community use `aa:nn` format, where `aa` and `nn` are 16 bit number.
+ For large community use `aa:nn:mm` format, where `aa`, `nn` and `mm` are 32 bit number.
+ Where, `aa` is an AS Number, `nn` and `mm` are per-AS identifier.
+ pattern: ^(\d+):(\d+)$|^(\d+):(\d+):(\d+)$
+ type: string
+ type: object
+ type: array
+ ignoredInterfaces:
+ description: IgnoredInterfaces indicates the network interfaces that
+ needs to be excluded when reading device routes.
+ items:
+ type: string
+ type: array
+ listenPort:
+ description: ListenPort is the port where BGP protocol should listen.
+ Defaults to 179
+ maximum: 65535
+ minimum: 1
+ type: integer
+ logSeverityScreen:
+ description: 'LogSeverityScreen is the log severity above which logs
+ are sent to the stdout. [Default: INFO]'
+ type: string
+ nodeMeshMaxRestartTime:
+ description: |-
+ Time to allow for software restart for node-to-mesh peerings. When specified, this is configured
+ as the graceful restart timeout. When not specified, the BIRD default of 120s is used.
+ This field can only be set on the default BGPConfiguration instance and requires that NodeMesh is enabled
+ type: string
+ nodeMeshPassword:
+ description: |-
+ Optional BGP password for full node-to-mesh peerings.
+ This field can only be set on the default BGPConfiguration instance and requires that NodeMesh is enabled
+ properties:
+ secretKeyRef:
+ description: Selects a key of a secret in the node pod's namespace.
+ properties:
+ key:
+ description: The key of the secret to select from. Must be
+ a valid secret key.
+ type: string
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must be
+ defined
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ type: object
+ nodeToNodeMeshEnabled:
+ description: 'NodeToNodeMeshEnabled sets whether full node to node
+ BGP mesh is enabled. [Default: true]'
+ type: boolean
+ prefixAdvertisements:
+ description: PrefixAdvertisements contains per-prefix advertisement
+ configuration.
+ items:
+ description: PrefixAdvertisement configures advertisement properties
+ for the specified CIDR.
+ properties:
+ cidr:
+ description: CIDR for which properties should be advertised.
+ type: string
+ communities:
+ description: |-
+ Communities can be list of either community names already defined in `Specs.Communities` or community value of format `aa:nn` or `aa:nn:mm`.
+ For standard community use `aa:nn` format, where `aa` and `nn` are 16 bit number.
+ For large community use `aa:nn:mm` format, where `aa`, `nn` and `mm` are 32 bit number.
+ Where,`aa` is an AS Number, `nn` and `mm` are per-AS identifier.
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ serviceClusterIPs:
+ description: |-
+ ServiceClusterIPs are the CIDR blocks from which service cluster IPs are allocated.
+ If specified, Calico will advertise these blocks, as well as any cluster IPs within them.
+ items:
+ description: ServiceClusterIPBlock represents a single allowed ClusterIP
+ CIDR block.
+ properties:
+ cidr:
+ type: string
+ type: object
+ type: array
+ serviceExternalIPs:
+ description: |-
+ ServiceExternalIPs are the CIDR blocks for Kubernetes Service External IPs.
+ Kubernetes Service ExternalIPs will only be advertised if they are within one of these blocks.
+ items:
+ description: ServiceExternalIPBlock represents a single allowed
+ External IP CIDR block.
+ properties:
+ cidr:
+ type: string
+ type: object
+ type: array
+ serviceLoadBalancerIPs:
+ description: |-
+ ServiceLoadBalancerIPs are the CIDR blocks for Kubernetes Service LoadBalancer IPs.
+ Kubernetes Service status.LoadBalancer.Ingress IPs will only be advertised if they are within one of these blocks.
+ items:
+ description: ServiceLoadBalancerIPBlock represents a single allowed
+ LoadBalancer IP CIDR block.
+ properties:
+ cidr:
+ type: string
+ type: object
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: true
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: bgpfilters.crd.projectcalico.org
+spec:
+ group: crd.projectcalico.org
+ names:
+ kind: BGPFilter
+ listKind: BGPFilterList
+ plural: bgpfilters
+ singular: bgpfilter
+ preserveUnknownFields: false
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: BGPFilterSpec contains the IPv4 and IPv6 filter rules of
+ the BGP Filter.
+ properties:
+ exportV4:
+ description: The ordered set of IPv4 BGPFilter rules acting on exporting
+ routes to a peer.
+ items:
+ description: BGPFilterRuleV4 defines a BGP filter rule consisting
+ a single IPv4 CIDR block and a filter action for this CIDR.
+ properties:
+ action:
+ type: string
+ cidr:
+ type: string
+ interface:
+ type: string
+ matchOperator:
+ type: string
+ prefixLength:
+ properties:
+ max:
+ format: int32
+ maximum: 32
+ minimum: 0
+ type: integer
+ min:
+ format: int32
+ maximum: 32
+ minimum: 0
+ type: integer
+ type: object
+ source:
+ type: string
+ required:
+ - action
+ type: object
+ type: array
+ exportV6:
+ description: The ordered set of IPv6 BGPFilter rules acting on exporting
+ routes to a peer.
+ items:
+ description: BGPFilterRuleV6 defines a BGP filter rule consisting
+ a single IPv6 CIDR block and a filter action for this CIDR.
+ properties:
+ action:
+ type: string
+ cidr:
+ type: string
+ interface:
+ type: string
+ matchOperator:
+ type: string
+ prefixLength:
+ properties:
+ max:
+ format: int32
+ maximum: 128
+ minimum: 0
+ type: integer
+ min:
+ format: int32
+ maximum: 128
+ minimum: 0
+ type: integer
+ type: object
+ source:
+ type: string
+ required:
+ - action
+ type: object
+ type: array
+ importV4:
+ description: The ordered set of IPv4 BGPFilter rules acting on importing
+ routes from a peer.
+ items:
+ description: BGPFilterRuleV4 defines a BGP filter rule consisting
+ a single IPv4 CIDR block and a filter action for this CIDR.
+ properties:
+ action:
+ type: string
+ cidr:
+ type: string
+ interface:
+ type: string
+ matchOperator:
+ type: string
+ prefixLength:
+ properties:
+ max:
+ format: int32
+ maximum: 32
+ minimum: 0
+ type: integer
+ min:
+ format: int32
+ maximum: 32
+ minimum: 0
+ type: integer
+ type: object
+ source:
+ type: string
+ required:
+ - action
+ type: object
+ type: array
+ importV6:
+ description: The ordered set of IPv6 BGPFilter rules acting on importing
+ routes from a peer.
+ items:
+ description: BGPFilterRuleV6 defines a BGP filter rule consisting
+ a single IPv6 CIDR block and a filter action for this CIDR.
+ properties:
+ action:
+ type: string
+ cidr:
+ type: string
+ interface:
+ type: string
+ matchOperator:
+ type: string
+ prefixLength:
+ properties:
+ max:
+ format: int32
+ maximum: 128
+ minimum: 0
+ type: integer
+ min:
+ format: int32
+ maximum: 128
+ minimum: 0
+ type: integer
+ type: object
+ source:
+ type: string
+ required:
+ - action
+ type: object
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: true
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: bgppeers.crd.projectcalico.org
+spec:
+ group: crd.projectcalico.org
+ names:
+ kind: BGPPeer
+ listKind: BGPPeerList
+ plural: bgppeers
+ singular: bgppeer
+ preserveUnknownFields: false
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: BGPPeerSpec contains the specification for a BGPPeer resource.
+ properties:
+ asNumber:
+ description: The AS Number of the peer.
+ format: int32
+ type: integer
+ filters:
+ description: The ordered set of BGPFilters applied on this BGP peer.
+ items:
+ type: string
+ type: array
+ keepOriginalNextHop:
+ description: |-
+ Option to keep the original nexthop field when routes are sent to a BGP Peer.
+ Setting "true" configures the selected BGP Peers node to use the "next hop keep;"
+ instead of "next hop self;"(default) in the specific branch of the Node on "bird.cfg".
+ type: boolean
+ maxRestartTime:
+ description: |-
+ Time to allow for software restart. When specified, this is configured as the graceful
+ restart timeout. When not specified, the BIRD default of 120s is used.
+ type: string
+ node:
+ description: |-
+ The node name identifying the Calico node instance that is targeted by this peer.
+ If this is not set, and no nodeSelector is specified, then this BGP peer selects all
+ nodes in the cluster.
+ type: string
+ nodeSelector:
+ description: |-
+ Selector for the nodes that should have this peering. When this is set, the Node
+ field must be empty.
+ type: string
+ numAllowedLocalASNumbers:
+ description: |-
+ Maximum number of local AS numbers that are allowed in the AS path for received routes.
+ This removes BGP loop prevention and should only be used if absolutely necessary.
+ format: int32
+ type: integer
+ password:
+ description: Optional BGP password for the peerings generated by this
+ BGPPeer resource.
+ properties:
+ secretKeyRef:
+ description: Selects a key of a secret in the node pod's namespace.
+ properties:
+ key:
+ description: The key of the secret to select from. Must be
+ a valid secret key.
+ type: string
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ optional:
+ description: Specify whether the Secret or its key must be
+ defined
+ type: boolean
+ required:
+ - key
+ type: object
+ x-kubernetes-map-type: atomic
+ type: object
+ peerIP:
+ description: |-
+ The IP address of the peer followed by an optional port number to peer with.
+ If port number is given, format should be `[]:port` or `:` for IPv4.
+ If optional port number is not set, and this peer IP and ASNumber belongs to a calico/node
+ with ListenPort set in BGPConfiguration, then we use that port to peer.
+ type: string
+ peerSelector:
+ description: |-
+ Selector for the remote nodes to peer with. When this is set, the PeerIP and
+ ASNumber fields must be empty. For each peering between the local node and
+ selected remote nodes, we configure an IPv4 peering if both ends have
+ NodeBGPSpec.IPv4Address specified, and an IPv6 peering if both ends have
+ NodeBGPSpec.IPv6Address specified. The remote AS number comes from the remote
+ node's NodeBGPSpec.ASNumber, or the global default if that is not set.
+ type: string
+ reachableBy:
+ description: |-
+ Add an exact, i.e. /32, static route toward peer IP in order to prevent route flapping.
+ ReachableBy contains the address of the gateway which peer can be reached by.
+ type: string
+ sourceAddress:
+ description: |-
+ Specifies whether and how to configure a source address for the peerings generated by
+ this BGPPeer resource. Default value "UseNodeIP" means to configure the node IP as the
+ source address. "None" means not to configure a source address.
+ type: string
+ ttlSecurity:
+ description: |-
+ TTLSecurity enables the generalized TTL security mechanism (GTSM) which protects against spoofed packets by
+ ignoring received packets with a smaller than expected TTL value. The provided value is the number of hops
+ (edges) between the peers.
+ type: integer
+ type: object
+ type: object
+ served: true
+ storage: true
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: blockaffinities.crd.projectcalico.org
+spec:
+ group: crd.projectcalico.org
+ names:
+ kind: BlockAffinity
+ listKind: BlockAffinityList
+ plural: blockaffinities
+ singular: blockaffinity
+ preserveUnknownFields: false
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: BlockAffinitySpec contains the specification for a BlockAffinity
+ resource.
+ properties:
+ cidr:
+ type: string
+ deleted:
+ description: |-
+ Deleted indicates that this block affinity is being deleted.
+ This field is a string for compatibility with older releases that
+ mistakenly treat this field as a string.
+ type: string
+ node:
+ type: string
+ state:
+ type: string
+ type:
+ type: string
+ required:
+ - cidr
+ - deleted
+ - node
+ - state
+ type: object
+ type: object
+ served: true
+ storage: true
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: caliconodestatuses.crd.projectcalico.org
+spec:
+ group: crd.projectcalico.org
+ names:
+ kind: CalicoNodeStatus
+ listKind: CalicoNodeStatusList
+ plural: caliconodestatuses
+ singular: caliconodestatus
+ preserveUnknownFields: false
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: CalicoNodeStatusSpec contains the specification for a CalicoNodeStatus
+ resource.
+ properties:
+ classes:
+ description: |-
+ Classes declares the types of information to monitor for this calico/node,
+ and allows for selective status reporting about certain subsets of information.
+ items:
+ type: string
+ type: array
+ node:
+ description: The node name identifies the Calico node instance for
+ node status.
+ type: string
+ updatePeriodSeconds:
+ description: |-
+ UpdatePeriodSeconds is the period at which CalicoNodeStatus should be updated.
+ Set to 0 to disable CalicoNodeStatus refresh. Maximum update period is one day.
+ format: int32
+ type: integer
+ type: object
+ status:
+ description: |-
+ CalicoNodeStatusStatus defines the observed state of CalicoNodeStatus.
+ No validation needed for status since it is updated by Calico.
+ properties:
+ agent:
+ description: Agent holds agent status on the node.
+ properties:
+ birdV4:
+ description: BIRDV4 represents the latest observed status of bird4.
+ properties:
+ lastBootTime:
+ description: LastBootTime holds the value of lastBootTime
+ from bird.ctl output.
+ type: string
+ lastReconfigurationTime:
+ description: LastReconfigurationTime holds the value of lastReconfigTime
+ from bird.ctl output.
+ type: string
+ routerID:
+ description: Router ID used by bird.
+ type: string
+ state:
+ description: The state of the BGP Daemon.
+ type: string
+ version:
+ description: Version of the BGP daemon
+ type: string
+ type: object
+ birdV6:
+ description: BIRDV6 represents the latest observed status of bird6.
+ properties:
+ lastBootTime:
+ description: LastBootTime holds the value of lastBootTime
+ from bird.ctl output.
+ type: string
+ lastReconfigurationTime:
+ description: LastReconfigurationTime holds the value of lastReconfigTime
+ from bird.ctl output.
+ type: string
+ routerID:
+ description: Router ID used by bird.
+ type: string
+ state:
+ description: The state of the BGP Daemon.
+ type: string
+ version:
+ description: Version of the BGP daemon
+ type: string
+ type: object
+ type: object
+ bgp:
+ description: BGP holds node BGP status.
+ properties:
+ numberEstablishedV4:
+ description: The total number of IPv4 established bgp sessions.
+ type: integer
+ numberEstablishedV6:
+ description: The total number of IPv6 established bgp sessions.
+ type: integer
+ numberNotEstablishedV4:
+ description: The total number of IPv4 non-established bgp sessions.
+ type: integer
+ numberNotEstablishedV6:
+ description: The total number of IPv6 non-established bgp sessions.
+ type: integer
+ peersV4:
+ description: PeersV4 represents IPv4 BGP peers status on the node.
+ items:
+ description: CalicoNodePeer contains the status of BGP peers
+ on the node.
+ properties:
+ peerIP:
+ description: IP address of the peer whose condition we are
+ reporting.
+ type: string
+ since:
+ description: Since the state or reason last changed.
+ type: string
+ state:
+ description: State is the BGP session state.
+ type: string
+ type:
+ description: |-
+ Type indicates whether this peer is configured via the node-to-node mesh,
+ or via en explicit global or per-node BGPPeer object.
+ type: string
+ type: object
+ type: array
+ peersV6:
+ description: PeersV6 represents IPv6 BGP peers status on the node.
+ items:
+ description: CalicoNodePeer contains the status of BGP peers
+ on the node.
+ properties:
+ peerIP:
+ description: IP address of the peer whose condition we are
+ reporting.
+ type: string
+ since:
+ description: Since the state or reason last changed.
+ type: string
+ state:
+ description: State is the BGP session state.
+ type: string
+ type:
+ description: |-
+ Type indicates whether this peer is configured via the node-to-node mesh,
+ or via en explicit global or per-node BGPPeer object.
+ type: string
+ type: object
+ type: array
+ required:
+ - numberEstablishedV4
+ - numberEstablishedV6
+ - numberNotEstablishedV4
+ - numberNotEstablishedV6
+ type: object
+ lastUpdated:
+ description: |-
+ LastUpdated is a timestamp representing the server time when CalicoNodeStatus object
+ last updated. It is represented in RFC3339 form and is in UTC.
+ format: date-time
+ nullable: true
+ type: string
+ routes:
+ description: Routes reports routes known to the Calico BGP daemon
+ on the node.
+ properties:
+ routesV4:
+ description: RoutesV4 represents IPv4 routes on the node.
+ items:
+ description: CalicoNodeRoute contains the status of BGP routes
+ on the node.
+ properties:
+ destination:
+ description: Destination of the route.
+ type: string
+ gateway:
+ description: Gateway for the destination.
+ type: string
+ interface:
+ description: Interface for the destination
+ type: string
+ learnedFrom:
+ description: LearnedFrom contains information regarding
+ where this route originated.
+ properties:
+ peerIP:
+ description: If sourceType is NodeMesh or BGPPeer, IP
+ address of the router that sent us this route.
+ type: string
+ sourceType:
+ description: Type of the source where a route is learned
+ from.
+ type: string
+ type: object
+ type:
+ description: Type indicates if the route is being used for
+ forwarding or not.
+ type: string
+ type: object
+ type: array
+ routesV6:
+ description: RoutesV6 represents IPv6 routes on the node.
+ items:
+ description: CalicoNodeRoute contains the status of BGP routes
+ on the node.
+ properties:
+ destination:
+ description: Destination of the route.
+ type: string
+ gateway:
+ description: Gateway for the destination.
+ type: string
+ interface:
+ description: Interface for the destination
+ type: string
+ learnedFrom:
+ description: LearnedFrom contains information regarding
+ where this route originated.
+ properties:
+ peerIP:
+ description: If sourceType is NodeMesh or BGPPeer, IP
+ address of the router that sent us this route.
+ type: string
+ sourceType:
+ description: Type of the source where a route is learned
+ from.
+ type: string
+ type: object
+ type:
+ description: Type indicates if the route is being used for
+ forwarding or not.
+ type: string
+ type: object
+ type: array
+ type: object
+ type: object
+ type: object
+ served: true
+ storage: true
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: clusterinformations.crd.projectcalico.org
+spec:
+ group: crd.projectcalico.org
+ names:
+ kind: ClusterInformation
+ listKind: ClusterInformationList
+ plural: clusterinformations
+ singular: clusterinformation
+ preserveUnknownFields: false
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ description: ClusterInformation contains the cluster specific information.
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: ClusterInformationSpec contains the values of describing
+ the cluster.
+ properties:
+ calicoVersion:
+ description: CalicoVersion is the version of Calico that the cluster
+ is running
+ type: string
+ clusterGUID:
+ description: ClusterGUID is the GUID of the cluster
+ type: string
+ clusterType:
+ description: ClusterType describes the type of the cluster
+ type: string
+ datastoreReady:
+ description: |-
+ DatastoreReady is used during significant datastore migrations to signal to components
+ such as Felix that it should wait before accessing the datastore.
+ type: boolean
+ variant:
+ description: Variant declares which variant of Calico should be active.
+ type: string
+ type: object
+ type: object
+ served: true
+ storage: true
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: felixconfigurations.crd.projectcalico.org
+spec:
+ group: crd.projectcalico.org
+ names:
+ kind: FelixConfiguration
+ listKind: FelixConfigurationList
+ plural: felixconfigurations
+ singular: felixconfiguration
+ preserveUnknownFields: false
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ description: Felix Configuration contains the configuration for Felix.
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: FelixConfigurationSpec contains the values of the Felix configuration.
+ properties:
+ allowIPIPPacketsFromWorkloads:
+ description: |-
+ AllowIPIPPacketsFromWorkloads controls whether Felix will add a rule to drop IPIP encapsulated traffic
+ from workloads. [Default: false]
+ type: boolean
+ allowVXLANPacketsFromWorkloads:
+ description: |-
+ AllowVXLANPacketsFromWorkloads controls whether Felix will add a rule to drop VXLAN encapsulated traffic
+ from workloads. [Default: false]
+ type: boolean
+ awsSrcDstCheck:
+ description: |-
+ AWSSrcDstCheck controls whether Felix will try to change the "source/dest check" setting on the EC2 instance
+ on which it is running. A value of "Disable" will try to disable the source/dest check. Disabling the check
+ allows for sending workload traffic without encapsulation within the same AWS subnet.
+ [Default: DoNothing]
+ enum:
+ - DoNothing
+ - Enable
+ - Disable
+ type: string
+ bpfCTLBLogFilter:
+ description: |-
+ BPFCTLBLogFilter specifies, what is logged by connect time load balancer when BPFLogLevel is
+ debug. Currently has to be specified as 'all' when BPFLogFilters is set
+ to see CTLB logs.
+ [Default: unset - means logs are emitted when BPFLogLevel id debug and BPFLogFilters not set.]
+ type: string
+ bpfConnectTimeLoadBalancing:
+ description: |-
+ BPFConnectTimeLoadBalancing when in BPF mode, controls whether Felix installs the connect-time load
+ balancer. The connect-time load balancer is required for the host to be able to reach Kubernetes services
+ and it improves the performance of pod-to-service connections.When set to TCP, connect time load balancing
+ is available only for services with TCP ports. [Default: TCP]
+ enum:
+ - TCP
+ - Enabled
+ - Disabled
+ type: string
+ bpfConnectTimeLoadBalancingEnabled:
+ description: |-
+ BPFConnectTimeLoadBalancingEnabled when in BPF mode, controls whether Felix installs the connection-time load
+ balancer. The connect-time load balancer is required for the host to be able to reach Kubernetes services
+ and it improves the performance of pod-to-service connections. The only reason to disable it is for debugging
+ purposes.
+
+ Deprecated: Use BPFConnectTimeLoadBalancing [Default: true]
+ type: boolean
+ bpfConntrackLogLevel:
+ description: |-
+ BPFConntrackLogLevel controls the log level of the BPF conntrack cleanup program, which runs periodically
+ to clean up expired BPF conntrack entries.
+ [Default: Off].
+ enum:
+ - "Off"
+ - Debug
+ type: string
+ bpfConntrackMode:
+ description: |-
+ BPFConntrackCleanupMode controls how BPF conntrack entries are cleaned up. `Auto` will use a BPF program if supported,
+ falling back to userspace if not. `Userspace` will always use the userspace cleanup code. `BPFProgram` will
+ always use the BPF program (failing if not supported).
+ [Default: Auto]
+ enum:
+ - Auto
+ - Userspace
+ - BPFProgram
+ type: string
+ bpfConntrackTimeouts:
+ description: |-
+ BPFConntrackTimers overrides the default values for the specified conntrack timer if
+ set. Each value can be either a duration or `Auto` to pick the value from
+ a Linux conntrack timeout.
+
+ Configurable timers are: CreationGracePeriod, TCPSynSent,
+ TCPEstablished, TCPFinsSeen, TCPResetSeen, UDPTimeout, GenericTimeout,
+ ICMPTimeout.
+
+ Unset values are replaced by the default values with a warning log for
+ incorrect values.
+ properties:
+ creationGracePeriod:
+ description: |2-
+ CreationGracePeriod gives a generic grace period to new connection
+ before they are considered for cleanup [Default: 10s].
+ pattern: ^(([0-9]*(\.[0-9]*)?(ms|s|h|m|us)+)+|Auto)$
+ type: string
+ genericTimeout:
+ description: |-
+ GenericTimeout controls how long it takes before considering this
+ entry for cleanup after the connection became idle. If set to 'Auto', the
+ value from nf_conntrack_generic_timeout is used. If nil, Calico uses its
+ own default value. [Default: 10m].
+ pattern: ^(([0-9]*(\.[0-9]*)?(ms|s|h|m|us)+)+|Auto)$
+ type: string
+ icmpTimeout:
+ description: |-
+ ICMPTimeout controls how long it takes before considering this
+ entry for cleanup after the connection became idle. If set to 'Auto', the
+ value from nf_conntrack_icmp_timeout is used. If nil, Calico uses its
+ own default value. [Default: 5s].
+ pattern: ^(([0-9]*(\.[0-9]*)?(ms|s|h|m|us)+)+|Auto)$
+ type: string
+ tcpEstablished:
+ description: |-
+ TCPEstablished controls how long it takes before considering this entry for
+ cleanup after the connection became idle. If set to 'Auto', the
+ value from nf_conntrack_tcp_timeout_established is used. If nil, Calico uses
+ its own default value. [Default: 1h].
+ pattern: ^(([0-9]*(\.[0-9]*)?(ms|s|h|m|us)+)+|Auto)$
+ type: string
+ tcpFinsSeen:
+ description: |-
+ TCPFinsSeen controls how long it takes before considering this entry for
+ cleanup after the connection was closed gracefully. If set to 'Auto', the
+ value from nf_conntrack_tcp_timeout_time_wait is used. If nil, Calico uses
+ its own default value. [Default: Auto].
+ pattern: ^(([0-9]*(\.[0-9]*)?(ms|s|h|m|us)+)+|Auto)$
+ type: string
+ tcpResetSeen:
+ description: |-
+ TCPFinsSeen controls how long it takes before considering this entry for
+ cleanup after the connection was aborted. If nil, Calico uses its own
+ default value. [Default: 40s].
+ pattern: ^(([0-9]*(\.[0-9]*)?(ms|s|h|m|us)+)+|Auto)$
+ type: string
+ tcpSynSent:
+ description: |-
+ TCPSynSent controls how long it takes before considering this entry for
+ cleanup after the last SYN without a response. If set to 'Auto', the
+ value from nf_conntrack_tcp_timeout_syn_sent is used. If nil, Calico uses
+ its own default value. [Default: 20s].
+ pattern: ^(([0-9]*(\.[0-9]*)?(ms|s|h|m|us)+)+|Auto)$
+ type: string
+ udpTimeout:
+ description: |-
+ UDPTimeout controls how long it takes before considering this entry for
+ cleanup after the connection became idle. If nil, Calico uses its own
+ default value. [Default: 60s].
+ pattern: ^(([0-9]*(\.[0-9]*)?(ms|s|h|m|us)+)+|Auto)$
+ type: string
+ type: object
+ bpfDSROptoutCIDRs:
+ description: |-
+ BPFDSROptoutCIDRs is a list of CIDRs which are excluded from DSR. That is, clients
+ in those CIDRs will access service node ports as if BPFExternalServiceMode was set to
+ Tunnel.
+ items:
+ type: string
+ type: array
+ bpfDataIfacePattern:
+ description: |-
+ BPFDataIfacePattern is a regular expression that controls which interfaces Felix should attach BPF programs to
+ in order to catch traffic to/from the network. This needs to match the interfaces that Calico workload traffic
+ flows over as well as any interfaces that handle incoming traffic to nodeports and services from outside the
+ cluster. It should not match the workload interfaces (usually named cali...) or any other special device managed
+ by Calico itself (e.g., tunnels).
+ type: string
+ bpfDisableGROForIfaces:
+ description: |-
+ BPFDisableGROForIfaces is a regular expression that controls which interfaces Felix should disable the
+ Generic Receive Offload [GRO] option. It should not match the workload interfaces (usually named cali...).
+ type: string
+ bpfDisableUnprivileged:
+ description: |-
+ BPFDisableUnprivileged, if enabled, Felix sets the kernel.unprivileged_bpf_disabled sysctl to disable
+ unprivileged use of BPF. This ensures that unprivileged users cannot access Calico's BPF maps and
+ cannot insert their own BPF programs to interfere with Calico's. [Default: true]
+ type: boolean
+ bpfEnabled:
+ description: 'BPFEnabled, if enabled Felix will use the BPF dataplane.
+ [Default: false]'
+ type: boolean
+ bpfEnforceRPF:
+ description: |-
+ BPFEnforceRPF enforce strict RPF on all host interfaces with BPF programs regardless of
+ what is the per-interfaces or global setting. Possible values are Disabled, Strict
+ or Loose. [Default: Loose]
+ pattern: ^(?i)(Disabled|Strict|Loose)?$
+ type: string
+ bpfExcludeCIDRsFromNAT:
+ description: |-
+ BPFExcludeCIDRsFromNAT is a list of CIDRs that are to be excluded from NAT
+ resolution so that host can handle them. A typical usecase is node local
+ DNS cache.
+ items:
+ type: string
+ type: array
+ bpfExportBufferSizeMB:
+ description: |-
+ BPFExportBufferSizeMB in BPF mode, controls the buffer size used for sending BPF events to felix.
+ [Default: 1]
+ type: integer
+ bpfExtToServiceConnmark:
+ description: |-
+ BPFExtToServiceConnmark in BPF mode, controls a 32bit mark that is set on connections from an
+ external client to a local service. This mark allows us to control how packets of that
+ connection are routed within the host and how is routing interpreted by RPF check. [Default: 0]
+ type: integer
+ bpfExternalServiceMode:
+ description: |-
+ BPFExternalServiceMode in BPF mode, controls how connections from outside the cluster to services (node ports
+ and cluster IPs) are forwarded to remote workloads. If set to "Tunnel" then both request and response traffic
+ is tunneled to the remote node. If set to "DSR", the request traffic is tunneled but the response traffic
+ is sent directly from the remote node. In "DSR" mode, the remote node appears to use the IP of the ingress
+ node; this requires a permissive L2 network. [Default: Tunnel]
+ pattern: ^(?i)(Tunnel|DSR)?$
+ type: string
+ bpfForceTrackPacketsFromIfaces:
+ description: |-
+ BPFForceTrackPacketsFromIfaces in BPF mode, forces traffic from these interfaces
+ to skip Calico's iptables NOTRACK rule, allowing traffic from those interfaces to be
+ tracked by Linux conntrack. Should only be used for interfaces that are not used for
+ the Calico fabric. For example, a docker bridge device for non-Calico-networked
+ containers. [Default: docker+]
+ items:
+ type: string
+ type: array
+ bpfHostConntrackBypass:
+ description: |-
+ BPFHostConntrackBypass Controls whether to bypass Linux conntrack in BPF mode for
+ workloads and services. [Default: true - bypass Linux conntrack]
+ type: boolean
+ bpfHostNetworkedNATWithoutCTLB:
+ description: |-
+ BPFHostNetworkedNATWithoutCTLB when in BPF mode, controls whether Felix does a NAT without CTLB. This along with BPFConnectTimeLoadBalancing
+ determines the CTLB behavior. [Default: Enabled]
+ enum:
+ - Enabled
+ - Disabled
+ type: string
+ bpfKubeProxyEndpointSlicesEnabled:
+ description: |-
+ BPFKubeProxyEndpointSlicesEnabled is deprecated and has no effect. BPF
+ kube-proxy always accepts endpoint slices. This option will be removed in
+ the next release.
+ type: boolean
+ bpfKubeProxyIptablesCleanupEnabled:
+ description: |-
+ BPFKubeProxyIptablesCleanupEnabled, if enabled in BPF mode, Felix will proactively clean up the upstream
+ Kubernetes kube-proxy's iptables chains. Should only be enabled if kube-proxy is not running. [Default: true]
+ type: boolean
+ bpfKubeProxyMinSyncPeriod:
+ description: |-
+ BPFKubeProxyMinSyncPeriod, in BPF mode, controls the minimum time between updates to the dataplane for Felix's
+ embedded kube-proxy. Lower values give reduced set-up latency. Higher values reduce Felix CPU usage by
+ batching up more work. [Default: 1s]
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ bpfL3IfacePattern:
+ description: |-
+ BPFL3IfacePattern is a regular expression that allows to list tunnel devices like wireguard or vxlan (i.e., L3 devices)
+ in addition to BPFDataIfacePattern. That is, tunnel interfaces not created by Calico, that Calico workload traffic flows
+ over as well as any interfaces that handle incoming traffic to nodeports and services from outside the cluster.
+ type: string
+ bpfLogFilters:
+ additionalProperties:
+ type: string
+ description: |-
+ BPFLogFilters is a map of key=values where the value is
+ a pcap filter expression and the key is an interface name with 'all'
+ denoting all interfaces, 'weps' all workload endpoints and 'heps' all host
+ endpoints.
+
+ When specified as an env var, it accepts a comma-separated list of
+ key=values.
+ [Default: unset - means all debug logs are emitted]
+ type: object
+ bpfLogLevel:
+ description: |-
+ BPFLogLevel controls the log level of the BPF programs when in BPF dataplane mode. One of "Off", "Info", or
+ "Debug". The logs are emitted to the BPF trace pipe, accessible with the command `tc exec bpf debug`.
+ [Default: Off].
+ pattern: ^(?i)(Off|Info|Debug)?$
+ type: string
+ bpfMapSizeConntrack:
+ description: |-
+ BPFMapSizeConntrack sets the size for the conntrack map. This map must be large enough to hold
+ an entry for each active connection. Warning: changing the size of the conntrack map can cause disruption.
+ type: integer
+ bpfMapSizeConntrackCleanupQueue:
+ description: |-
+ BPFMapSizeConntrackCleanupQueue sets the size for the map used to hold NAT conntrack entries that are queued
+ for cleanup. This should be big enough to hold all the NAT entries that expire within one cleanup interval.
+ minimum: 1
+ type: integer
+ bpfMapSizeConntrackScaling:
+ description: |-
+ BPFMapSizeConntrackScaling controls whether and how we scale the conntrack map size depending
+ on its usage. 'Disabled' make the size stay at the default or whatever is set by
+ BPFMapSizeConntrack*. 'DoubleIfFull' doubles the size when the map is pretty much full even
+ after cleanups. [Default: DoubleIfFull]
+ pattern: ^(?i)(Disabled|DoubleIfFull)?$
+ type: string
+ bpfMapSizeIPSets:
+ description: |-
+ BPFMapSizeIPSets sets the size for ipsets map. The IP sets map must be large enough to hold an entry
+ for each endpoint matched by every selector in the source/destination matches in network policy. Selectors
+ such as "all()" can result in large numbers of entries (one entry per endpoint in that case).
+ type: integer
+ bpfMapSizeIfState:
+ description: |-
+ BPFMapSizeIfState sets the size for ifstate map. The ifstate map must be large enough to hold an entry
+ for each device (host + workloads) on a host.
+ type: integer
+ bpfMapSizeNATAffinity:
+ description: |-
+ BPFMapSizeNATAffinity sets the size of the BPF map that stores the affinity of a connection (for services that
+ enable that feature.
+ type: integer
+ bpfMapSizeNATBackend:
+ description: |-
+ BPFMapSizeNATBackend sets the size for NAT back end map.
+ This is the total number of endpoints. This is mostly
+ more than the size of the number of services.
+ type: integer
+ bpfMapSizeNATFrontend:
+ description: |-
+ BPFMapSizeNATFrontend sets the size for NAT front end map.
+ FrontendMap should be large enough to hold an entry for each nodeport,
+ external IP and each port in each service.
+ type: integer
+ bpfMapSizePerCpuConntrack:
+ description: |-
+ BPFMapSizePerCPUConntrack determines the size of conntrack map based on the number of CPUs. If set to a
+ non-zero value, overrides BPFMapSizeConntrack with `BPFMapSizePerCPUConntrack * (Number of CPUs)`.
+ This map must be large enough to hold an entry for each active connection. Warning: changing the size of the
+ conntrack map can cause disruption.
+ type: integer
+ bpfMapSizeRoute:
+ description: |-
+ BPFMapSizeRoute sets the size for the routes map. The routes map should be large enough
+ to hold one entry per workload and a handful of entries per host (enough to cover its own IPs and
+ tunnel IPs).
+ type: integer
+ bpfPSNATPorts:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ BPFPSNATPorts sets the range from which we randomly pick a port if there is a source port
+ collision. This should be within the ephemeral range as defined by RFC 6056 (1024–65535) and
+ preferably outside the ephemeral ranges used by common operating systems. Linux uses
+ 32768–60999, while others mostly use the IANA defined range 49152–65535. It is not necessarily
+ a problem if this range overlaps with the operating systems. Both ends of the range are
+ inclusive. [Default: 20000:29999]
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ bpfPolicyDebugEnabled:
+ description: |-
+ BPFPolicyDebugEnabled when true, Felix records detailed information
+ about the BPF policy programs, which can be examined with the calico-bpf command-line tool.
+ type: boolean
+ bpfProfiling:
+ description: |-
+ BPFProfiling controls profiling of BPF programs. At the monent, it can be
+ Disabled or Enabled. [Default: Disabled]
+ enum:
+ - Enabled
+ - Disabled
+ type: string
+ bpfRedirectToPeer:
+ description: |-
+ BPFRedirectToPeer controls which whether it is allowed to forward straight to the
+ peer side of the workload devices. It is allowed for any host L2 devices by default
+ (L2Only), but it breaks TCP dump on the host side of workload device as it bypasses
+ it on ingress. Value of Enabled also allows redirection from L3 host devices like
+ IPIP tunnel or Wireguard directly to the peer side of the workload's device. This
+ makes redirection faster, however, it breaks tools like tcpdump on the peer side.
+ Use Enabled with caution. [Default: L2Only]
+ enum:
+ - Enabled
+ - Disabled
+ - L2Only
+ type: string
+ chainInsertMode:
+ description: |-
+ ChainInsertMode controls whether Felix hooks the kernel's top-level iptables chains by inserting a rule
+ at the top of the chain or by appending a rule at the bottom. insert is the safe default since it prevents
+ Calico's rules from being bypassed. If you switch to append mode, be sure that the other rules in the chains
+ signal acceptance by falling through to the Calico rules, otherwise the Calico policy will be bypassed.
+ [Default: insert]
+ pattern: ^(?i)(Insert|Append)?$
+ type: string
+ dataplaneDriver:
+ description: |-
+ DataplaneDriver filename of the external dataplane driver to use. Only used if UseInternalDataplaneDriver
+ is set to false.
+ type: string
+ dataplaneWatchdogTimeout:
+ description: |-
+ DataplaneWatchdogTimeout is the readiness/liveness timeout used for Felix's (internal) dataplane driver.
+ Deprecated: replaced by the generic HealthTimeoutOverrides.
+ type: string
+ debugDisableLogDropping:
+ description: |-
+ DebugDisableLogDropping disables the dropping of log messages when the log buffer is full. This can
+ significantly impact performance if log write-out is a bottleneck. [Default: false]
+ type: boolean
+ debugHost:
+ description: |-
+ DebugHost is the host IP or hostname to bind the debug port to. Only used
+ if DebugPort is set. [Default:localhost]
+ type: string
+ debugMemoryProfilePath:
+ description: DebugMemoryProfilePath is the path to write the memory
+ profile to when triggered by signal.
+ type: string
+ debugPort:
+ description: |-
+ DebugPort if set, enables Felix's debug HTTP port, which allows memory and CPU profiles
+ to be retrieved. The debug port is not secure, it should not be exposed to the internet.
+ type: integer
+ debugSimulateCalcGraphHangAfter:
+ description: |-
+ DebugSimulateCalcGraphHangAfter is used to simulate a hang in the calculation graph after the specified duration.
+ This is useful in tests of the watchdog system only!
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ debugSimulateDataplaneApplyDelay:
+ description: |-
+ DebugSimulateDataplaneApplyDelay adds an artificial delay to every dataplane operation. This is useful for
+ simulating a heavily loaded system for test purposes only.
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ debugSimulateDataplaneHangAfter:
+ description: |-
+ DebugSimulateDataplaneHangAfter is used to simulate a hang in the dataplane after the specified duration.
+ This is useful in tests of the watchdog system only!
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ defaultEndpointToHostAction:
+ description: |-
+ DefaultEndpointToHostAction controls what happens to traffic that goes from a workload endpoint to the host
+ itself (after the endpoint's egress policy is applied). By default, Calico blocks traffic from workload
+ endpoints to the host itself with an iptables "DROP" action. If you want to allow some or all traffic from
+ endpoint to host, set this parameter to RETURN or ACCEPT. Use RETURN if you have your own rules in the iptables
+ "INPUT" chain; Calico will insert its rules at the top of that chain, then "RETURN" packets to the "INPUT" chain
+ once it has completed processing workload endpoint egress policy. Use ACCEPT to unconditionally accept packets
+ from workloads after processing workload endpoint egress policy. [Default: Drop]
+ pattern: ^(?i)(Drop|Accept|Return)?$
+ type: string
+ deviceRouteProtocol:
+ description: |-
+ DeviceRouteProtocol controls the protocol to set on routes programmed by Felix. The protocol is an 8-bit label
+ used to identify the owner of the route.
+ type: integer
+ deviceRouteSourceAddress:
+ description: |-
+ DeviceRouteSourceAddress IPv4 address to set as the source hint for routes programmed by Felix. When not set
+ the source address for local traffic from host to workload will be determined by the kernel.
+ type: string
+ deviceRouteSourceAddressIPv6:
+ description: |-
+ DeviceRouteSourceAddressIPv6 IPv6 address to set as the source hint for routes programmed by Felix. When not set
+ the source address for local traffic from host to workload will be determined by the kernel.
+ type: string
+ disableConntrackInvalidCheck:
+ description: |-
+ DisableConntrackInvalidCheck disables the check for invalid connections in conntrack. While the conntrack
+ invalid check helps to detect malicious traffic, it can also cause issues with certain multi-NIC scenarios.
+ type: boolean
+ endpointReportingDelay:
+ description: |-
+ EndpointReportingDelay is the delay before Felix reports endpoint status to the datastore. This is only used
+ by the OpenStack integration. [Default: 1s]
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ endpointReportingEnabled:
+ description: |-
+ EndpointReportingEnabled controls whether Felix reports endpoint status to the datastore. This is only used
+ by the OpenStack integration. [Default: false]
+ type: boolean
+ endpointStatusPathPrefix:
+ description: |-
+ EndpointStatusPathPrefix is the path to the directory where endpoint status will be written. Endpoint status
+ file reporting is disabled if field is left empty.
+
+ Chosen directory should match the directory used by the CNI plugin for PodStartupDelay.
+ [Default: /var/run/calico]
+ type: string
+ externalNodesList:
+ description: |-
+ ExternalNodesCIDRList is a list of CIDR's of external, non-Calico nodes from which VXLAN/IPIP overlay traffic
+ will be allowed. By default, external tunneled traffic is blocked to reduce attack surface.
+ items:
+ type: string
+ type: array
+ failsafeInboundHostPorts:
+ description: |-
+ FailsafeInboundHostPorts is a list of ProtoPort struct objects including UDP/TCP/SCTP ports and CIDRs that Felix will
+ allow incoming traffic to host endpoints on irrespective of the security policy. This is useful to avoid accidentally
+ cutting off a host with incorrect configuration. For backwards compatibility, if the protocol is not specified,
+ it defaults to "tcp". If a CIDR is not specified, it will allow traffic from all addresses. To disable all inbound host ports,
+ use the value "[]". The default value allows ssh access, DHCP, BGP, etcd and the Kubernetes API.
+ [Default: tcp:22, udp:68, tcp:179, tcp:2379, tcp:2380, tcp:5473, tcp:6443, tcp:6666, tcp:6667 ]
+ items:
+ description: ProtoPort is combination of protocol, port, and CIDR.
+ Protocol and port must be specified.
+ properties:
+ net:
+ type: string
+ port:
+ type: integer
+ protocol:
+ type: string
+ required:
+ - port
+ type: object
+ type: array
+ failsafeOutboundHostPorts:
+ description: |-
+ FailsafeOutboundHostPorts is a list of PortProto struct objects including UDP/TCP/SCTP ports and CIDRs that Felix
+ will allow outgoing traffic from host endpoints to irrespective of the security policy. This is useful to avoid accidentally
+ cutting off a host with incorrect configuration. For backwards compatibility, if the protocol is not specified, it defaults
+ to "tcp". If a CIDR is not specified, it will allow traffic from all addresses. To disable all outbound host ports,
+ use the value "[]". The default value opens etcd's standard ports to ensure that Felix does not get cut off from etcd
+ as well as allowing DHCP, DNS, BGP and the Kubernetes API.
+ [Default: udp:53, udp:67, tcp:179, tcp:2379, tcp:2380, tcp:5473, tcp:6443, tcp:6666, tcp:6667 ]
+ items:
+ description: ProtoPort is combination of protocol, port, and CIDR.
+ Protocol and port must be specified.
+ properties:
+ net:
+ type: string
+ port:
+ type: integer
+ protocol:
+ type: string
+ required:
+ - port
+ type: object
+ type: array
+ featureDetectOverride:
+ description: |-
+ FeatureDetectOverride is used to override feature detection based on auto-detected platform
+ capabilities. Values are specified in a comma separated list with no spaces, example;
+ "SNATFullyRandom=true,MASQFullyRandom=false,RestoreSupportsLock=". A value of "true" or "false" will
+ force enable/disable feature, empty or omitted values fall back to auto-detection.
+ pattern: ^([a-zA-Z0-9-_]+=(true|false|),)*([a-zA-Z0-9-_]+=(true|false|))?$
+ type: string
+ featureGates:
+ description: |-
+ FeatureGates is used to enable or disable tech-preview Calico features.
+ Values are specified in a comma separated list with no spaces, example;
+ "BPFConnectTimeLoadBalancingWorkaround=enabled,XyZ=false". This is
+ used to enable features that are not fully production ready.
+ pattern: ^([a-zA-Z0-9-_]+=([^=]+),)*([a-zA-Z0-9-_]+=([^=]+))?$
+ type: string
+ floatingIPs:
+ description: |-
+ FloatingIPs configures whether or not Felix will program non-OpenStack floating IP addresses. (OpenStack-derived
+ floating IPs are always programmed, regardless of this setting.)
+ enum:
+ - Enabled
+ - Disabled
+ type: string
+ flowLogsCollectorDebugTrace:
+ description: |-
+ When FlowLogsCollectorDebugTrace is set to true, enables the logs in the collector to be
+ printed in their entirety.
+ type: boolean
+ flowLogsFlushInterval:
+ description: FlowLogsFlushInterval configures the interval at which
+ Felix exports flow logs.
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ flowLogsGoldmaneServer:
+ description: FlowLogGoldmaneServer is the flow server endpoint to
+ which flow data should be published.
+ type: string
+ flowLogsMaxOriginalIPsIncluded:
+ description: FlowLogsMaxOriginalIPsIncluded specifies the number of
+ unique IP addresses (if relevant) that should be included in Flow
+ logs.
+ type: integer
+ genericXDPEnabled:
+ description: |-
+ GenericXDPEnabled enables Generic XDP so network cards that don't support XDP offload or driver
+ modes can use XDP. This is not recommended since it doesn't provide better performance than
+ iptables. [Default: false]
+ type: boolean
+ goGCThreshold:
+ description: |-
+ GoGCThreshold Sets the Go runtime's garbage collection threshold. I.e. the percentage that the heap is
+ allowed to grow before garbage collection is triggered. In general, doubling the value halves the CPU time
+ spent doing GC, but it also doubles peak GC memory overhead. A special value of -1 can be used
+ to disable GC entirely; this should only be used in conjunction with the GoMemoryLimitMB setting.
+
+ This setting is overridden by the GOGC environment variable.
+
+ [Default: 40]
+ type: integer
+ goMaxProcs:
+ description: |-
+ GoMaxProcs sets the maximum number of CPUs that the Go runtime will use concurrently. A value of -1 means
+ "use the system default"; typically the number of real CPUs on the system.
+
+ this setting is overridden by the GOMAXPROCS environment variable.
+
+ [Default: -1]
+ type: integer
+ goMemoryLimitMB:
+ description: |-
+ GoMemoryLimitMB sets a (soft) memory limit for the Go runtime in MB. The Go runtime will try to keep its memory
+ usage under the limit by triggering GC as needed. To avoid thrashing, it will exceed the limit if GC starts to
+ take more than 50% of the process's CPU time. A value of -1 disables the memory limit.
+
+ Note that the memory limit, if used, must be considerably less than any hard resource limit set at the container
+ or pod level. This is because felix is not the only process that must run in the container or pod.
+
+ This setting is overridden by the GOMEMLIMIT environment variable.
+
+ [Default: -1]
+ type: integer
+ healthEnabled:
+ description: |-
+ HealthEnabled if set to true, enables Felix's health port, which provides readiness and liveness endpoints.
+ [Default: false]
+ type: boolean
+ healthHost:
+ description: 'HealthHost is the host that the health server should
+ bind to. [Default: localhost]'
+ type: string
+ healthPort:
+ description: 'HealthPort is the TCP port that the health server should
+ bind to. [Default: 9099]'
+ type: integer
+ healthTimeoutOverrides:
+ description: |-
+ HealthTimeoutOverrides allows the internal watchdog timeouts of individual subcomponents to be
+ overridden. This is useful for working around "false positive" liveness timeouts that can occur
+ in particularly stressful workloads or if CPU is constrained. For a list of active
+ subcomponents, see Felix's logs.
+ items:
+ properties:
+ name:
+ type: string
+ timeout:
+ type: string
+ required:
+ - name
+ - timeout
+ type: object
+ type: array
+ interfaceExclude:
+ description: |-
+ InterfaceExclude A comma-separated list of interface names that should be excluded when Felix is resolving
+ host endpoints. The default value ensures that Felix ignores Kubernetes' internal `kube-ipvs0` device. If you
+ want to exclude multiple interface names using a single value, the list supports regular expressions. For
+ regular expressions you must wrap the value with `/`. For example having values `/^kube/,veth1` will exclude
+ all interfaces that begin with `kube` and also the interface `veth1`. [Default: kube-ipvs0]
+ type: string
+ interfacePrefix:
+ description: |-
+ InterfacePrefix is the interface name prefix that identifies workload endpoints and so distinguishes
+ them from host endpoint interfaces. Note: in environments other than bare metal, the orchestrators
+ configure this appropriately. For example our Kubernetes and Docker integrations set the 'cali' value,
+ and our OpenStack integration sets the 'tap' value. [Default: cali]
+ type: string
+ interfaceRefreshInterval:
+ description: |-
+ InterfaceRefreshInterval is the period at which Felix rescans local interfaces to verify their state.
+ The rescan can be disabled by setting the interval to 0.
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ ipForwarding:
+ description: |-
+ IPForwarding controls whether Felix sets the host sysctls to enable IP forwarding. IP forwarding is required
+ when using Calico for workload networking. This should be disabled only on hosts where Calico is used solely for
+ host protection. In BPF mode, due to a kernel interaction, either IPForwarding must be enabled or BPFEnforceRPF
+ must be disabled. [Default: Enabled]
+ enum:
+ - Enabled
+ - Disabled
+ type: string
+ ipipEnabled:
+ description: |-
+ IPIPEnabled overrides whether Felix should configure an IPIP interface on the host. Optional as Felix
+ determines this based on the existing IP pools. [Default: nil (unset)]
+ type: boolean
+ ipipMTU:
+ description: |-
+ IPIPMTU controls the MTU to set on the IPIP tunnel device. Optional as Felix auto-detects the MTU based on the
+ MTU of the host's interfaces. [Default: 0 (auto-detect)]
+ type: integer
+ ipsetsRefreshInterval:
+ description: |-
+ IpsetsRefreshInterval controls the period at which Felix re-checks all IP sets to look for discrepancies.
+ Set to 0 to disable the periodic refresh. [Default: 90s]
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ iptablesBackend:
+ description: |-
+ IptablesBackend controls which backend of iptables will be used. The default is `Auto`.
+
+ Warning: changing this on a running system can leave "orphaned" rules in the "other" backend. These
+ should be cleaned up to avoid confusing interactions.
+ pattern: ^(?i)(Auto|Legacy|NFT)?$
+ type: string
+ iptablesFilterAllowAction:
+ description: |-
+ IptablesFilterAllowAction controls what happens to traffic that is accepted by a Felix policy chain in the
+ iptables filter table (which is used for "normal" policy). The default will immediately `Accept` the traffic. Use
+ `Return` to send the traffic back up to the system chains for further processing.
+ pattern: ^(?i)(Accept|Return)?$
+ type: string
+ iptablesFilterDenyAction:
+ description: |-
+ IptablesFilterDenyAction controls what happens to traffic that is denied by network policy. By default Calico blocks traffic
+ with an iptables "DROP" action. If you want to use "REJECT" action instead you can configure it in here.
+ pattern: ^(?i)(Drop|Reject)?$
+ type: string
+ iptablesLockFilePath:
+ description: |-
+ IptablesLockFilePath is the location of the iptables lock file. You may need to change this
+ if the lock file is not in its standard location (for example if you have mapped it into Felix's
+ container at a different path). [Default: /run/xtables.lock]
+ type: string
+ iptablesLockProbeInterval:
+ description: |-
+ IptablesLockProbeInterval when IptablesLockTimeout is enabled: the time that Felix will wait between
+ attempts to acquire the iptables lock if it is not available. Lower values make Felix more
+ responsive when the lock is contended, but use more CPU. [Default: 50ms]
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ iptablesLockTimeout:
+ description: |-
+ IptablesLockTimeout is the time that Felix itself will wait for the iptables lock (rather than delegating the
+ lock handling to the `iptables` command).
+
+ Deprecated: `iptables-restore` v1.8+ always takes the lock, so enabling this feature results in deadlock.
+ [Default: 0s disabled]
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ iptablesMangleAllowAction:
+ description: |-
+ IptablesMangleAllowAction controls what happens to traffic that is accepted by a Felix policy chain in the
+ iptables mangle table (which is used for "pre-DNAT" policy). The default will immediately `Accept` the traffic.
+ Use `Return` to send the traffic back up to the system chains for further processing.
+ pattern: ^(?i)(Accept|Return)?$
+ type: string
+ iptablesMarkMask:
+ description: |-
+ IptablesMarkMask is the mask that Felix selects its IPTables Mark bits from. Should be a 32 bit hexadecimal
+ number with at least 8 bits set, none of which clash with any other mark bits in use on the system.
+ [Default: 0xffff0000]
+ format: int32
+ type: integer
+ iptablesNATOutgoingInterfaceFilter:
+ description: |-
+ This parameter can be used to limit the host interfaces on which Calico will apply SNAT to traffic leaving a
+ Calico IPAM pool with "NAT outgoing" enabled. This can be useful if you have a main data interface, where
+ traffic should be SNATted and a secondary device (such as the docker bridge) which is local to the host and
+ doesn't require SNAT. This parameter uses the iptables interface matching syntax, which allows + as a
+ wildcard. Most users will not need to set this. Example: if your data interfaces are eth0 and eth1 and you
+ want to exclude the docker bridge, you could set this to eth+
+ type: string
+ iptablesPostWriteCheckInterval:
+ description: |-
+ IptablesPostWriteCheckInterval is the period after Felix has done a write
+ to the dataplane that it schedules an extra read back in order to check the write was not
+ clobbered by another process. This should only occur if another application on the system
+ doesn't respect the iptables lock. [Default: 1s]
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ iptablesRefreshInterval:
+ description: |-
+ IptablesRefreshInterval is the period at which Felix re-checks the IP sets
+ in the dataplane to ensure that no other process has accidentally broken Calico's rules.
+ Set to 0 to disable IP sets refresh. Note: the default for this value is lower than the
+ other refresh intervals as a workaround for a Linux kernel bug that was fixed in kernel
+ version 4.11. If you are using v4.11 or greater you may want to set this to, a higher value
+ to reduce Felix CPU usage. [Default: 10s]
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ ipv6Support:
+ description: IPv6Support controls whether Felix enables support for
+ IPv6 (if supported by the in-use dataplane).
+ type: boolean
+ kubeNodePortRanges:
+ description: |-
+ KubeNodePortRanges holds list of port ranges used for service node ports. Only used if felix detects kube-proxy running in ipvs mode.
+ Felix uses these ranges to separate host and workload traffic. [Default: 30000:32767].
+ items:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ type: array
+ logDebugFilenameRegex:
+ description: |-
+ LogDebugFilenameRegex controls which source code files have their Debug log output included in the logs.
+ Only logs from files with names that match the given regular expression are included. The filter only applies
+ to Debug level logs.
+ type: string
+ logFilePath:
+ description: 'LogFilePath is the full path to the Felix log. Set to
+ none to disable file logging. [Default: /var/log/calico/felix.log]'
+ type: string
+ logPrefix:
+ description: 'LogPrefix is the log prefix that Felix uses when rendering
+ LOG rules. [Default: calico-packet]'
+ type: string
+ logSeverityFile:
+ description: 'LogSeverityFile is the log severity above which logs
+ are sent to the log file. [Default: Info]'
+ pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$
+ type: string
+ logSeverityScreen:
+ description: 'LogSeverityScreen is the log severity above which logs
+ are sent to the stdout. [Default: Info]'
+ pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$
+ type: string
+ logSeveritySys:
+ description: |-
+ LogSeveritySys is the log severity above which logs are sent to the syslog. Set to None for no logging to syslog.
+ [Default: Info]
+ pattern: ^(?i)(Debug|Info|Warning|Error|Fatal)?$
+ type: string
+ maxIpsetSize:
+ description: |-
+ MaxIpsetSize is the maximum number of IP addresses that can be stored in an IP set. Not applicable
+ if using the nftables backend.
+ type: integer
+ metadataAddr:
+ description: |-
+ MetadataAddr is the IP address or domain name of the server that can answer VM queries for
+ cloud-init metadata. In OpenStack, this corresponds to the machine running nova-api (or in
+ Ubuntu, nova-api-metadata). A value of none (case-insensitive) means that Felix should not
+ set up any NAT rule for the metadata path. [Default: 127.0.0.1]
+ type: string
+ metadataPort:
+ description: |-
+ MetadataPort is the port of the metadata server. This, combined with global.MetadataAddr (if
+ not 'None'), is used to set up a NAT rule, from 169.254.169.254:80 to MetadataAddr:MetadataPort.
+ In most cases this should not need to be changed [Default: 8775].
+ type: integer
+ mtuIfacePattern:
+ description: |-
+ MTUIfacePattern is a regular expression that controls which interfaces Felix should scan in order
+ to calculate the host's MTU.
+ This should not match workload interfaces (usually named cali...).
+ type: string
+ natOutgoingAddress:
+ description: |-
+ NATOutgoingAddress specifies an address to use when performing source NAT for traffic in a natOutgoing pool that
+ is leaving the network. By default the address used is an address on the interface the traffic is leaving on
+ (i.e. it uses the iptables MASQUERADE target).
+ type: string
+ natPortRange:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ NATPortRange specifies the range of ports that is used for port mapping when doing outgoing NAT. When unset the default behavior of the
+ network stack is used.
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ netlinkTimeout:
+ description: |-
+ NetlinkTimeout is the timeout when talking to the kernel over the netlink protocol, used for programming
+ routes, rules, and other kernel objects. [Default: 10s]
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ nfNetlinkBufSize:
+ description: |-
+ NfNetlinkBufSize controls the size of NFLOG messages that the kernel will try to send to Felix. NFLOG messages
+ are used to report flow verdicts from the kernel. Warning: currently increasing the value may cause errors
+ due to a bug in the netlink library.
+ type: string
+ nftablesFilterAllowAction:
+ description: |-
+ NftablesFilterAllowAction controls the nftables action that Felix uses to represent the "allow" policy verdict
+ in the filter table. The default is to `ACCEPT` the traffic, which is a terminal action. Alternatively,
+ `RETURN` can be used to return the traffic back to the top-level chain for further processing by your rules.
+ pattern: ^(?i)(Accept|Return)?$
+ type: string
+ nftablesFilterDenyAction:
+ description: |-
+ NftablesFilterDenyAction controls what happens to traffic that is denied by network policy. By default, Calico
+ blocks traffic with a "drop" action. If you want to use a "reject" action instead you can configure it here.
+ pattern: ^(?i)(Drop|Reject)?$
+ type: string
+ nftablesMangleAllowAction:
+ description: |-
+ NftablesMangleAllowAction controls the nftables action that Felix uses to represent the "allow" policy verdict
+ in the mangle table. The default is to `ACCEPT` the traffic, which is a terminal action. Alternatively,
+ `RETURN` can be used to return the traffic back to the top-level chain for further processing by your rules.
+ pattern: ^(?i)(Accept|Return)?$
+ type: string
+ nftablesMarkMask:
+ description: |-
+ NftablesMarkMask is the mask that Felix selects its nftables Mark bits from. Should be a 32 bit hexadecimal
+ number with at least 8 bits set, none of which clash with any other mark bits in use on the system.
+ [Default: 0xffff0000]
+ format: int32
+ type: integer
+ nftablesMode:
+ description: 'NFTablesMode configures nftables support in Felix. [Default:
+ Disabled]'
+ enum:
+ - Disabled
+ - Enabled
+ - Auto
+ type: string
+ nftablesRefreshInterval:
+ description: 'NftablesRefreshInterval controls the interval at which
+ Felix periodically refreshes the nftables rules. [Default: 90s]'
+ type: string
+ openstackRegion:
+ description: |-
+ OpenstackRegion is the name of the region that a particular Felix belongs to. In a multi-region
+ Calico/OpenStack deployment, this must be configured somehow for each Felix (here in the datamodel,
+ or in felix.cfg or the environment on each compute node), and must match the [calico]
+ openstack_region value configured in neutron.conf on each node. [Default: Empty]
+ type: string
+ policySyncPathPrefix:
+ description: |-
+ PolicySyncPathPrefix is used to by Felix to communicate policy changes to external services,
+ like Application layer policy. [Default: Empty]
+ type: string
+ programRoutes:
+ description: 'ProgramRoutes specifies what type of routes Felix should
+ program. [Default: None]. [Default: None]'
+ type: string
+ prometheusGoMetricsEnabled:
+ description: |-
+ PrometheusGoMetricsEnabled disables Go runtime metrics collection, which the Prometheus client does by default, when
+ set to false. This reduces the number of metrics reported, reducing Prometheus load. [Default: true]
+ type: boolean
+ prometheusMetricsEnabled:
+ description: 'PrometheusMetricsEnabled enables the Prometheus metrics
+ server in Felix if set to true. [Default: false]'
+ type: boolean
+ prometheusMetricsHost:
+ description: 'PrometheusMetricsHost is the host that the Prometheus
+ metrics server should bind to. [Default: empty]'
+ type: string
+ prometheusMetricsPort:
+ description: 'PrometheusMetricsPort is the TCP port that the Prometheus
+ metrics server should bind to. [Default: 9091]'
+ type: integer
+ prometheusProcessMetricsEnabled:
+ description: |-
+ PrometheusProcessMetricsEnabled disables process metrics collection, which the Prometheus client does by default, when
+ set to false. This reduces the number of metrics reported, reducing Prometheus load. [Default: true]
+ type: boolean
+ prometheusWireGuardMetricsEnabled:
+ description: |-
+ PrometheusWireGuardMetricsEnabled disables wireguard metrics collection, which the Prometheus client does by default, when
+ set to false. This reduces the number of metrics reported, reducing Prometheus load. [Default: true]
+ type: boolean
+ removeExternalRoutes:
+ description: |-
+ RemoveExternalRoutes Controls whether Felix will remove unexpected routes to workload interfaces. Felix will
+ always clean up expected routes that use the configured DeviceRouteProtocol. To add your own routes, you must
+ use a distinct protocol (in addition to setting this field to false).
+ type: boolean
+ reportingInterval:
+ description: |-
+ ReportingInterval is the interval at which Felix reports its status into the datastore or 0 to disable.
+ Must be non-zero in OpenStack deployments. [Default: 30s]
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ reportingTTL:
+ description: 'ReportingTTL is the time-to-live setting for process-wide
+ status reports. [Default: 90s]'
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ routeRefreshInterval:
+ description: |-
+ RouteRefreshInterval is the period at which Felix re-checks the routes
+ in the dataplane to ensure that no other process has accidentally broken Calico's rules.
+ Set to 0 to disable route refresh. [Default: 90s]
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ routeSource:
+ description: |-
+ RouteSource configures where Felix gets its routing information.
+ - WorkloadIPs: use workload endpoints to construct routes.
+ - CalicoIPAM: the default - use IPAM data to construct routes.
+ pattern: ^(?i)(WorkloadIPs|CalicoIPAM)?$
+ type: string
+ routeSyncDisabled:
+ description: |-
+ RouteSyncDisabled will disable all operations performed on the route table. Set to true to
+ run in network-policy mode only.
+ type: boolean
+ routeTableRange:
+ description: |-
+ Deprecated in favor of RouteTableRanges.
+ Calico programs additional Linux route tables for various purposes.
+ RouteTableRange specifies the indices of the route tables that Calico should use.
+ properties:
+ max:
+ type: integer
+ min:
+ type: integer
+ required:
+ - max
+ - min
+ type: object
+ routeTableRanges:
+ description: |-
+ Calico programs additional Linux route tables for various purposes.
+ RouteTableRanges specifies a set of table index ranges that Calico should use.
+ Deprecates`RouteTableRange`, overrides `RouteTableRange`.
+ items:
+ properties:
+ max:
+ type: integer
+ min:
+ type: integer
+ required:
+ - max
+ - min
+ type: object
+ type: array
+ serviceLoopPrevention:
+ description: |-
+ When service IP advertisement is enabled, prevent routing loops to service IPs that are
+ not in use, by dropping or rejecting packets that do not get DNAT'd by kube-proxy.
+ Unless set to "Disabled", in which case such routing loops continue to be allowed.
+ [Default: Drop]
+ pattern: ^(?i)(Drop|Reject|Disabled)?$
+ type: string
+ sidecarAccelerationEnabled:
+ description: 'SidecarAccelerationEnabled enables experimental sidecar
+ acceleration [Default: false]'
+ type: boolean
+ usageReportingEnabled:
+ description: |-
+ UsageReportingEnabled reports anonymous Calico version number and cluster size to projectcalico.org. Logs warnings returned by the usage
+ server. For example, if a significant security vulnerability has been discovered in the version of Calico being used. [Default: true]
+ type: boolean
+ usageReportingInitialDelay:
+ description: 'UsageReportingInitialDelay controls the minimum delay
+ before Felix makes a report. [Default: 300s]'
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ usageReportingInterval:
+ description: 'UsageReportingInterval controls the interval at which
+ Felix makes reports. [Default: 86400s]'
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ useInternalDataplaneDriver:
+ description: |-
+ UseInternalDataplaneDriver, if true, Felix will use its internal dataplane programming logic. If false, it
+ will launch an external dataplane driver and communicate with it over protobuf.
+ type: boolean
+ vxlanEnabled:
+ description: |-
+ VXLANEnabled overrides whether Felix should create the VXLAN tunnel device for IPv4 VXLAN networking.
+ Optional as Felix determines this based on the existing IP pools. [Default: nil (unset)]
+ type: boolean
+ vxlanMTU:
+ description: |-
+ VXLANMTU is the MTU to set on the IPv4 VXLAN tunnel device. Optional as Felix auto-detects the MTU based on the
+ MTU of the host's interfaces. [Default: 0 (auto-detect)]
+ type: integer
+ vxlanMTUV6:
+ description: |-
+ VXLANMTUV6 is the MTU to set on the IPv6 VXLAN tunnel device. Optional as Felix auto-detects the MTU based on the
+ MTU of the host's interfaces. [Default: 0 (auto-detect)]
+ type: integer
+ vxlanPort:
+ description: 'VXLANPort is the UDP port number to use for VXLAN traffic.
+ [Default: 4789]'
+ type: integer
+ vxlanVNI:
+ description: |-
+ VXLANVNI is the VXLAN VNI to use for VXLAN traffic. You may need to change this if the default value is
+ in use on your system. [Default: 4096]
+ type: integer
+ windowsManageFirewallRules:
+ description: 'WindowsManageFirewallRules configures whether or not
+ Felix will program Windows Firewall rules (to allow inbound access
+ to its own metrics ports). [Default: Disabled]'
+ enum:
+ - Enabled
+ - Disabled
+ type: string
+ wireguardEnabled:
+ description: 'WireguardEnabled controls whether Wireguard is enabled
+ for IPv4 (encapsulating IPv4 traffic over an IPv4 underlay network).
+ [Default: false]'
+ type: boolean
+ wireguardEnabledV6:
+ description: 'WireguardEnabledV6 controls whether Wireguard is enabled
+ for IPv6 (encapsulating IPv6 traffic over an IPv6 underlay network).
+ [Default: false]'
+ type: boolean
+ wireguardHostEncryptionEnabled:
+ description: 'WireguardHostEncryptionEnabled controls whether Wireguard
+ host-to-host encryption is enabled. [Default: false]'
+ type: boolean
+ wireguardInterfaceName:
+ description: 'WireguardInterfaceName specifies the name to use for
+ the IPv4 Wireguard interface. [Default: wireguard.cali]'
+ type: string
+ wireguardInterfaceNameV6:
+ description: 'WireguardInterfaceNameV6 specifies the name to use for
+ the IPv6 Wireguard interface. [Default: wg-v6.cali]'
+ type: string
+ wireguardKeepAlive:
+ description: 'WireguardPersistentKeepAlive controls Wireguard PersistentKeepalive
+ option. Set 0 to disable. [Default: 0]'
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ wireguardListeningPort:
+ description: 'WireguardListeningPort controls the listening port used
+ by IPv4 Wireguard. [Default: 51820]'
+ type: integer
+ wireguardListeningPortV6:
+ description: 'WireguardListeningPortV6 controls the listening port
+ used by IPv6 Wireguard. [Default: 51821]'
+ type: integer
+ wireguardMTU:
+ description: 'WireguardMTU controls the MTU on the IPv4 Wireguard
+ interface. See Configuring MTU [Default: 1440]'
+ type: integer
+ wireguardMTUV6:
+ description: 'WireguardMTUV6 controls the MTU on the IPv6 Wireguard
+ interface. See Configuring MTU [Default: 1420]'
+ type: integer
+ wireguardRoutingRulePriority:
+ description: 'WireguardRoutingRulePriority controls the priority value
+ to use for the Wireguard routing rule. [Default: 99]'
+ type: integer
+ wireguardThreadingEnabled:
+ description: |-
+ WireguardThreadingEnabled controls whether Wireguard has Threaded NAPI enabled. [Default: false]
+ This increases the maximum number of packets a Wireguard interface can process.
+ Consider threaded NAPI only if you have high packets per second workloads that are causing dropping packets due to a saturated `softirq` CPU core.
+ There is a [known issue](https://lore.kernel.org/netdev/CALrw=nEoT2emQ0OAYCjM1d_6Xe_kNLSZ6dhjb5FxrLFYh4kozA@mail.gmail.com/T/) with this setting
+ that may cause NAPI to get stuck holding the global `rtnl_mutex` when a peer is removed.
+ Workaround: Make sure your Linux kernel [includes this patch](https://github.com/torvalds/linux/commit/56364c910691f6d10ba88c964c9041b9ab777bd6) to unwedge NAPI.
+ type: boolean
+ workloadSourceSpoofing:
+ description: |-
+ WorkloadSourceSpoofing controls whether pods can use the allowedSourcePrefixes annotation to send traffic with a source IP
+ address that is not theirs. This is disabled by default. When set to "Any", pods can request any prefix.
+ pattern: ^(?i)(Disabled|Any)?$
+ type: string
+ xdpEnabled:
+ description: 'XDPEnabled enables XDP acceleration for suitable untracked
+ incoming deny rules. [Default: true]'
+ type: boolean
+ xdpRefreshInterval:
+ description: |-
+ XDPRefreshInterval is the period at which Felix re-checks all XDP state to ensure that no
+ other process has accidentally broken Calico's BPF maps or attached programs. Set to 0 to
+ disable XDP refresh. [Default: 90s]
+ pattern: ^([0-9]+(\\.[0-9]+)?(ms|s|m|h))*$
+ type: string
+ type: object
+ type: object
+ served: true
+ storage: true
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: globalnetworkpolicies.crd.projectcalico.org
+spec:
+ group: crd.projectcalico.org
+ names:
+ kind: GlobalNetworkPolicy
+ listKind: GlobalNetworkPolicyList
+ plural: globalnetworkpolicies
+ singular: globalnetworkpolicy
+ preserveUnknownFields: false
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ properties:
+ applyOnForward:
+ description: ApplyOnForward indicates to apply the rules in this policy
+ on forward traffic.
+ type: boolean
+ doNotTrack:
+ description: |-
+ DoNotTrack indicates whether packets matched by the rules in this policy should go through
+ the data plane's connection tracking, such as Linux conntrack. If True, the rules in
+ this policy are applied before any data plane connection tracking, and packets allowed by
+ this policy are marked as not to be tracked.
+ type: boolean
+ egress:
+ description: |-
+ The ordered set of egress rules. Each rule contains a set of packet match criteria and
+ a corresponding action to apply.
+ items:
+ description: |-
+ A Rule encapsulates a set of match criteria and an action. Both selector-based security Policy
+ and security Profiles reference rules - separated out as a list of rules for both
+ ingress and egress packet matching.
+
+ Each positive match criteria has a negated version, prefixed with "Not". All the match
+ criteria within a rule must be satisfied for a packet to match. A single rule can contain
+ the positive and negative version of a match and both must be satisfied for the rule to match.
+ properties:
+ action:
+ type: string
+ destination:
+ description: Destination contains the match criteria that apply
+ to destination entity.
+ properties:
+ namespaceSelector:
+ description: |-
+ NamespaceSelector is an optional field that contains a selector expression. Only traffic
+ that originates from (or terminates at) endpoints within the selected namespaces will be
+ matched. When both NamespaceSelector and another selector are defined on the same rule, then only
+ workload endpoints that are matched by both selectors will be selected by the rule.
+
+ For NetworkPolicy, an empty NamespaceSelector implies that the Selector is limited to selecting
+ only workload endpoints in the same namespace as the NetworkPolicy.
+
+ For NetworkPolicy, `global()` NamespaceSelector implies that the Selector is limited to selecting
+ only GlobalNetworkSet or HostEndpoint.
+
+ For GlobalNetworkPolicy, an empty NamespaceSelector implies the Selector applies to workload
+ endpoints across all namespaces.
+ type: string
+ nets:
+ description: |-
+ Nets is an optional field that restricts the rule to only apply to traffic that
+ originates from (or terminates at) IP addresses in any of the given subnets.
+ items:
+ type: string
+ type: array
+ notNets:
+ description: NotNets is the negated version of the Nets
+ field.
+ items:
+ type: string
+ type: array
+ notPorts:
+ description: |-
+ NotPorts is the negated version of the Ports field.
+ Since only some protocols have ports, if any ports are specified it requires the
+ Protocol match in the Rule to be set to "TCP" or "UDP".
+ items:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ type: array
+ notSelector:
+ description: |-
+ NotSelector is the negated version of the Selector field. See Selector field for
+ subtleties with negated selectors.
+ type: string
+ ports:
+ description: |-
+ Ports is an optional field that restricts the rule to only apply to traffic that has a
+ source (destination) port that matches one of these ranges/values. This value is a
+ list of integers or strings that represent ranges of ports.
+
+ Since only some protocols have ports, if any ports are specified it requires the
+ Protocol match in the Rule to be set to "TCP" or "UDP".
+ items:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ type: array
+ selector:
+ description: "Selector is an optional field that contains
+ a selector expression (see Policy for\nsample syntax).
+ \ Only traffic that originates from (terminates at) endpoints
+ matching\nthe selector will be matched.\n\nNote that:
+ in addition to the negated version of the Selector (see
+ NotSelector below), the\nselector expression syntax itself
+ supports negation. The two types of negation are subtly\ndifferent.
+ One negates the set of matched endpoints, the other negates
+ the whole match:\n\n\tSelector = \"!has(my_label)\" matches
+ packets that are from other Calico-controlled\n\tendpoints
+ that do not have the label \"my_label\".\n\n\tNotSelector
+ = \"has(my_label)\" matches packets that are not from
+ Calico-controlled\n\tendpoints that do have the label
+ \"my_label\".\n\nThe effect is that the latter will accept
+ packets from non-Calico sources whereas the\nformer is
+ limited to packets from Calico-controlled endpoints."
+ type: string
+ serviceAccounts:
+ description: |-
+ ServiceAccounts is an optional field that restricts the rule to only apply to traffic that originates from (or
+ terminates at) a pod running as a matching service account.
+ properties:
+ names:
+ description: |-
+ Names is an optional field that restricts the rule to only apply to traffic that originates from (or terminates
+ at) a pod running as a service account whose name is in the list.
+ items:
+ type: string
+ type: array
+ selector:
+ description: |-
+ Selector is an optional field that restricts the rule to only apply to traffic that originates from
+ (or terminates at) a pod running as a service account that matches the given label selector.
+ If both Names and Selector are specified then they are AND'ed.
+ type: string
+ type: object
+ services:
+ description: |-
+ Services is an optional field that contains options for matching Kubernetes Services.
+ If specified, only traffic that originates from or terminates at endpoints within the selected
+ service(s) will be matched, and only to/from each endpoint's port.
+
+ Services cannot be specified on the same rule as Selector, NotSelector, NamespaceSelector, Nets,
+ NotNets or ServiceAccounts.
+
+ Ports and NotPorts can only be specified with Services on ingress rules.
+ properties:
+ name:
+ description: Name specifies the name of a Kubernetes
+ Service to match.
+ type: string
+ namespace:
+ description: |-
+ Namespace specifies the namespace of the given Service. If left empty, the rule
+ will match within this policy's namespace.
+ type: string
+ type: object
+ type: object
+ http:
+ description: HTTP contains match criteria that apply to HTTP
+ requests.
+ properties:
+ methods:
+ description: |-
+ Methods is an optional field that restricts the rule to apply only to HTTP requests that use one of the listed
+ HTTP Methods (e.g. GET, PUT, etc.)
+ Multiple methods are OR'd together.
+ items:
+ type: string
+ type: array
+ paths:
+ description: |-
+ Paths is an optional field that restricts the rule to apply to HTTP requests that use one of the listed
+ HTTP Paths.
+ Multiple paths are OR'd together.
+ e.g:
+ - exact: /foo
+ - prefix: /bar
+ NOTE: Each entry may ONLY specify either a `exact` or a `prefix` match. The validator will check for it.
+ items:
+ description: |-
+ HTTPPath specifies an HTTP path to match. It may be either of the form:
+ exact: : which matches the path exactly or
+ prefix: : which matches the path prefix
+ properties:
+ exact:
+ type: string
+ prefix:
+ type: string
+ type: object
+ type: array
+ type: object
+ icmp:
+ description: |-
+ ICMP is an optional field that restricts the rule to apply to a specific type and
+ code of ICMP traffic. This should only be specified if the Protocol field is set to
+ "ICMP" or "ICMPv6".
+ properties:
+ code:
+ description: |-
+ Match on a specific ICMP code. If specified, the Type value must also be specified.
+ This is a technical limitation imposed by the kernel's iptables firewall, which
+ Calico uses to enforce the rule.
+ type: integer
+ type:
+ description: |-
+ Match on a specific ICMP type. For example a value of 8 refers to ICMP Echo Request
+ (i.e. pings).
+ type: integer
+ type: object
+ ipVersion:
+ description: |-
+ IPVersion is an optional field that restricts the rule to only match a specific IP
+ version.
+ type: integer
+ metadata:
+ description: Metadata contains additional information for this
+ rule
+ properties:
+ annotations:
+ additionalProperties:
+ type: string
+ description: Annotations is a set of key value pairs that
+ give extra information about the rule
+ type: object
+ type: object
+ notICMP:
+ description: NotICMP is the negated version of the ICMP field.
+ properties:
+ code:
+ description: |-
+ Match on a specific ICMP code. If specified, the Type value must also be specified.
+ This is a technical limitation imposed by the kernel's iptables firewall, which
+ Calico uses to enforce the rule.
+ type: integer
+ type:
+ description: |-
+ Match on a specific ICMP type. For example a value of 8 refers to ICMP Echo Request
+ (i.e. pings).
+ type: integer
+ type: object
+ notProtocol:
+ anyOf:
+ - type: integer
+ - type: string
+ description: NotProtocol is the negated version of the Protocol
+ field.
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ protocol:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ Protocol is an optional field that restricts the rule to only apply to traffic of
+ a specific IP protocol. Required if any of the EntityRules contain Ports
+ (because ports only apply to certain protocols).
+
+ Must be one of these string values: "TCP", "UDP", "ICMP", "ICMPv6", "SCTP", "UDPLite"
+ or an integer in the range 1-255.
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ source:
+ description: Source contains the match criteria that apply to
+ source entity.
+ properties:
+ namespaceSelector:
+ description: |-
+ NamespaceSelector is an optional field that contains a selector expression. Only traffic
+ that originates from (or terminates at) endpoints within the selected namespaces will be
+ matched. When both NamespaceSelector and another selector are defined on the same rule, then only
+ workload endpoints that are matched by both selectors will be selected by the rule.
+
+ For NetworkPolicy, an empty NamespaceSelector implies that the Selector is limited to selecting
+ only workload endpoints in the same namespace as the NetworkPolicy.
+
+ For NetworkPolicy, `global()` NamespaceSelector implies that the Selector is limited to selecting
+ only GlobalNetworkSet or HostEndpoint.
+
+ For GlobalNetworkPolicy, an empty NamespaceSelector implies the Selector applies to workload
+ endpoints across all namespaces.
+ type: string
+ nets:
+ description: |-
+ Nets is an optional field that restricts the rule to only apply to traffic that
+ originates from (or terminates at) IP addresses in any of the given subnets.
+ items:
+ type: string
+ type: array
+ notNets:
+ description: NotNets is the negated version of the Nets
+ field.
+ items:
+ type: string
+ type: array
+ notPorts:
+ description: |-
+ NotPorts is the negated version of the Ports field.
+ Since only some protocols have ports, if any ports are specified it requires the
+ Protocol match in the Rule to be set to "TCP" or "UDP".
+ items:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ type: array
+ notSelector:
+ description: |-
+ NotSelector is the negated version of the Selector field. See Selector field for
+ subtleties with negated selectors.
+ type: string
+ ports:
+ description: |-
+ Ports is an optional field that restricts the rule to only apply to traffic that has a
+ source (destination) port that matches one of these ranges/values. This value is a
+ list of integers or strings that represent ranges of ports.
+
+ Since only some protocols have ports, if any ports are specified it requires the
+ Protocol match in the Rule to be set to "TCP" or "UDP".
+ items:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ type: array
+ selector:
+ description: "Selector is an optional field that contains
+ a selector expression (see Policy for\nsample syntax).
+ \ Only traffic that originates from (terminates at) endpoints
+ matching\nthe selector will be matched.\n\nNote that:
+ in addition to the negated version of the Selector (see
+ NotSelector below), the\nselector expression syntax itself
+ supports negation. The two types of negation are subtly\ndifferent.
+ One negates the set of matched endpoints, the other negates
+ the whole match:\n\n\tSelector = \"!has(my_label)\" matches
+ packets that are from other Calico-controlled\n\tendpoints
+ that do not have the label \"my_label\".\n\n\tNotSelector
+ = \"has(my_label)\" matches packets that are not from
+ Calico-controlled\n\tendpoints that do have the label
+ \"my_label\".\n\nThe effect is that the latter will accept
+ packets from non-Calico sources whereas the\nformer is
+ limited to packets from Calico-controlled endpoints."
+ type: string
+ serviceAccounts:
+ description: |-
+ ServiceAccounts is an optional field that restricts the rule to only apply to traffic that originates from (or
+ terminates at) a pod running as a matching service account.
+ properties:
+ names:
+ description: |-
+ Names is an optional field that restricts the rule to only apply to traffic that originates from (or terminates
+ at) a pod running as a service account whose name is in the list.
+ items:
+ type: string
+ type: array
+ selector:
+ description: |-
+ Selector is an optional field that restricts the rule to only apply to traffic that originates from
+ (or terminates at) a pod running as a service account that matches the given label selector.
+ If both Names and Selector are specified then they are AND'ed.
+ type: string
+ type: object
+ services:
+ description: |-
+ Services is an optional field that contains options for matching Kubernetes Services.
+ If specified, only traffic that originates from or terminates at endpoints within the selected
+ service(s) will be matched, and only to/from each endpoint's port.
+
+ Services cannot be specified on the same rule as Selector, NotSelector, NamespaceSelector, Nets,
+ NotNets or ServiceAccounts.
+
+ Ports and NotPorts can only be specified with Services on ingress rules.
+ properties:
+ name:
+ description: Name specifies the name of a Kubernetes
+ Service to match.
+ type: string
+ namespace:
+ description: |-
+ Namespace specifies the namespace of the given Service. If left empty, the rule
+ will match within this policy's namespace.
+ type: string
+ type: object
+ type: object
+ required:
+ - action
+ type: object
+ type: array
+ ingress:
+ description: |-
+ The ordered set of ingress rules. Each rule contains a set of packet match criteria and
+ a corresponding action to apply.
+ items:
+ description: |-
+ A Rule encapsulates a set of match criteria and an action. Both selector-based security Policy
+ and security Profiles reference rules - separated out as a list of rules for both
+ ingress and egress packet matching.
+
+ Each positive match criteria has a negated version, prefixed with "Not". All the match
+ criteria within a rule must be satisfied for a packet to match. A single rule can contain
+ the positive and negative version of a match and both must be satisfied for the rule to match.
+ properties:
+ action:
+ type: string
+ destination:
+ description: Destination contains the match criteria that apply
+ to destination entity.
+ properties:
+ namespaceSelector:
+ description: |-
+ NamespaceSelector is an optional field that contains a selector expression. Only traffic
+ that originates from (or terminates at) endpoints within the selected namespaces will be
+ matched. When both NamespaceSelector and another selector are defined on the same rule, then only
+ workload endpoints that are matched by both selectors will be selected by the rule.
+
+ For NetworkPolicy, an empty NamespaceSelector implies that the Selector is limited to selecting
+ only workload endpoints in the same namespace as the NetworkPolicy.
+
+ For NetworkPolicy, `global()` NamespaceSelector implies that the Selector is limited to selecting
+ only GlobalNetworkSet or HostEndpoint.
+
+ For GlobalNetworkPolicy, an empty NamespaceSelector implies the Selector applies to workload
+ endpoints across all namespaces.
+ type: string
+ nets:
+ description: |-
+ Nets is an optional field that restricts the rule to only apply to traffic that
+ originates from (or terminates at) IP addresses in any of the given subnets.
+ items:
+ type: string
+ type: array
+ notNets:
+ description: NotNets is the negated version of the Nets
+ field.
+ items:
+ type: string
+ type: array
+ notPorts:
+ description: |-
+ NotPorts is the negated version of the Ports field.
+ Since only some protocols have ports, if any ports are specified it requires the
+ Protocol match in the Rule to be set to "TCP" or "UDP".
+ items:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ type: array
+ notSelector:
+ description: |-
+ NotSelector is the negated version of the Selector field. See Selector field for
+ subtleties with negated selectors.
+ type: string
+ ports:
+ description: |-
+ Ports is an optional field that restricts the rule to only apply to traffic that has a
+ source (destination) port that matches one of these ranges/values. This value is a
+ list of integers or strings that represent ranges of ports.
+
+ Since only some protocols have ports, if any ports are specified it requires the
+ Protocol match in the Rule to be set to "TCP" or "UDP".
+ items:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ type: array
+ selector:
+ description: "Selector is an optional field that contains
+ a selector expression (see Policy for\nsample syntax).
+ \ Only traffic that originates from (terminates at) endpoints
+ matching\nthe selector will be matched.\n\nNote that:
+ in addition to the negated version of the Selector (see
+ NotSelector below), the\nselector expression syntax itself
+ supports negation. The two types of negation are subtly\ndifferent.
+ One negates the set of matched endpoints, the other negates
+ the whole match:\n\n\tSelector = \"!has(my_label)\" matches
+ packets that are from other Calico-controlled\n\tendpoints
+ that do not have the label \"my_label\".\n\n\tNotSelector
+ = \"has(my_label)\" matches packets that are not from
+ Calico-controlled\n\tendpoints that do have the label
+ \"my_label\".\n\nThe effect is that the latter will accept
+ packets from non-Calico sources whereas the\nformer is
+ limited to packets from Calico-controlled endpoints."
+ type: string
+ serviceAccounts:
+ description: |-
+ ServiceAccounts is an optional field that restricts the rule to only apply to traffic that originates from (or
+ terminates at) a pod running as a matching service account.
+ properties:
+ names:
+ description: |-
+ Names is an optional field that restricts the rule to only apply to traffic that originates from (or terminates
+ at) a pod running as a service account whose name is in the list.
+ items:
+ type: string
+ type: array
+ selector:
+ description: |-
+ Selector is an optional field that restricts the rule to only apply to traffic that originates from
+ (or terminates at) a pod running as a service account that matches the given label selector.
+ If both Names and Selector are specified then they are AND'ed.
+ type: string
+ type: object
+ services:
+ description: |-
+ Services is an optional field that contains options for matching Kubernetes Services.
+ If specified, only traffic that originates from or terminates at endpoints within the selected
+ service(s) will be matched, and only to/from each endpoint's port.
+
+ Services cannot be specified on the same rule as Selector, NotSelector, NamespaceSelector, Nets,
+ NotNets or ServiceAccounts.
+
+ Ports and NotPorts can only be specified with Services on ingress rules.
+ properties:
+ name:
+ description: Name specifies the name of a Kubernetes
+ Service to match.
+ type: string
+ namespace:
+ description: |-
+ Namespace specifies the namespace of the given Service. If left empty, the rule
+ will match within this policy's namespace.
+ type: string
+ type: object
+ type: object
+ http:
+ description: HTTP contains match criteria that apply to HTTP
+ requests.
+ properties:
+ methods:
+ description: |-
+ Methods is an optional field that restricts the rule to apply only to HTTP requests that use one of the listed
+ HTTP Methods (e.g. GET, PUT, etc.)
+ Multiple methods are OR'd together.
+ items:
+ type: string
+ type: array
+ paths:
+ description: |-
+ Paths is an optional field that restricts the rule to apply to HTTP requests that use one of the listed
+ HTTP Paths.
+ Multiple paths are OR'd together.
+ e.g:
+ - exact: /foo
+ - prefix: /bar
+ NOTE: Each entry may ONLY specify either a `exact` or a `prefix` match. The validator will check for it.
+ items:
+ description: |-
+ HTTPPath specifies an HTTP path to match. It may be either of the form:
+ exact: : which matches the path exactly or
+ prefix: : which matches the path prefix
+ properties:
+ exact:
+ type: string
+ prefix:
+ type: string
+ type: object
+ type: array
+ type: object
+ icmp:
+ description: |-
+ ICMP is an optional field that restricts the rule to apply to a specific type and
+ code of ICMP traffic. This should only be specified if the Protocol field is set to
+ "ICMP" or "ICMPv6".
+ properties:
+ code:
+ description: |-
+ Match on a specific ICMP code. If specified, the Type value must also be specified.
+ This is a technical limitation imposed by the kernel's iptables firewall, which
+ Calico uses to enforce the rule.
+ type: integer
+ type:
+ description: |-
+ Match on a specific ICMP type. For example a value of 8 refers to ICMP Echo Request
+ (i.e. pings).
+ type: integer
+ type: object
+ ipVersion:
+ description: |-
+ IPVersion is an optional field that restricts the rule to only match a specific IP
+ version.
+ type: integer
+ metadata:
+ description: Metadata contains additional information for this
+ rule
+ properties:
+ annotations:
+ additionalProperties:
+ type: string
+ description: Annotations is a set of key value pairs that
+ give extra information about the rule
+ type: object
+ type: object
+ notICMP:
+ description: NotICMP is the negated version of the ICMP field.
+ properties:
+ code:
+ description: |-
+ Match on a specific ICMP code. If specified, the Type value must also be specified.
+ This is a technical limitation imposed by the kernel's iptables firewall, which
+ Calico uses to enforce the rule.
+ type: integer
+ type:
+ description: |-
+ Match on a specific ICMP type. For example a value of 8 refers to ICMP Echo Request
+ (i.e. pings).
+ type: integer
+ type: object
+ notProtocol:
+ anyOf:
+ - type: integer
+ - type: string
+ description: NotProtocol is the negated version of the Protocol
+ field.
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ protocol:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ Protocol is an optional field that restricts the rule to only apply to traffic of
+ a specific IP protocol. Required if any of the EntityRules contain Ports
+ (because ports only apply to certain protocols).
+
+ Must be one of these string values: "TCP", "UDP", "ICMP", "ICMPv6", "SCTP", "UDPLite"
+ or an integer in the range 1-255.
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ source:
+ description: Source contains the match criteria that apply to
+ source entity.
+ properties:
+ namespaceSelector:
+ description: |-
+ NamespaceSelector is an optional field that contains a selector expression. Only traffic
+ that originates from (or terminates at) endpoints within the selected namespaces will be
+ matched. When both NamespaceSelector and another selector are defined on the same rule, then only
+ workload endpoints that are matched by both selectors will be selected by the rule.
+
+ For NetworkPolicy, an empty NamespaceSelector implies that the Selector is limited to selecting
+ only workload endpoints in the same namespace as the NetworkPolicy.
+
+ For NetworkPolicy, `global()` NamespaceSelector implies that the Selector is limited to selecting
+ only GlobalNetworkSet or HostEndpoint.
+
+ For GlobalNetworkPolicy, an empty NamespaceSelector implies the Selector applies to workload
+ endpoints across all namespaces.
+ type: string
+ nets:
+ description: |-
+ Nets is an optional field that restricts the rule to only apply to traffic that
+ originates from (or terminates at) IP addresses in any of the given subnets.
+ items:
+ type: string
+ type: array
+ notNets:
+ description: NotNets is the negated version of the Nets
+ field.
+ items:
+ type: string
+ type: array
+ notPorts:
+ description: |-
+ NotPorts is the negated version of the Ports field.
+ Since only some protocols have ports, if any ports are specified it requires the
+ Protocol match in the Rule to be set to "TCP" or "UDP".
+ items:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ type: array
+ notSelector:
+ description: |-
+ NotSelector is the negated version of the Selector field. See Selector field for
+ subtleties with negated selectors.
+ type: string
+ ports:
+ description: |-
+ Ports is an optional field that restricts the rule to only apply to traffic that has a
+ source (destination) port that matches one of these ranges/values. This value is a
+ list of integers or strings that represent ranges of ports.
+
+ Since only some protocols have ports, if any ports are specified it requires the
+ Protocol match in the Rule to be set to "TCP" or "UDP".
+ items:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ type: array
+ selector:
+ description: "Selector is an optional field that contains
+ a selector expression (see Policy for\nsample syntax).
+ \ Only traffic that originates from (terminates at) endpoints
+ matching\nthe selector will be matched.\n\nNote that:
+ in addition to the negated version of the Selector (see
+ NotSelector below), the\nselector expression syntax itself
+ supports negation. The two types of negation are subtly\ndifferent.
+ One negates the set of matched endpoints, the other negates
+ the whole match:\n\n\tSelector = \"!has(my_label)\" matches
+ packets that are from other Calico-controlled\n\tendpoints
+ that do not have the label \"my_label\".\n\n\tNotSelector
+ = \"has(my_label)\" matches packets that are not from
+ Calico-controlled\n\tendpoints that do have the label
+ \"my_label\".\n\nThe effect is that the latter will accept
+ packets from non-Calico sources whereas the\nformer is
+ limited to packets from Calico-controlled endpoints."
+ type: string
+ serviceAccounts:
+ description: |-
+ ServiceAccounts is an optional field that restricts the rule to only apply to traffic that originates from (or
+ terminates at) a pod running as a matching service account.
+ properties:
+ names:
+ description: |-
+ Names is an optional field that restricts the rule to only apply to traffic that originates from (or terminates
+ at) a pod running as a service account whose name is in the list.
+ items:
+ type: string
+ type: array
+ selector:
+ description: |-
+ Selector is an optional field that restricts the rule to only apply to traffic that originates from
+ (or terminates at) a pod running as a service account that matches the given label selector.
+ If both Names and Selector are specified then they are AND'ed.
+ type: string
+ type: object
+ services:
+ description: |-
+ Services is an optional field that contains options for matching Kubernetes Services.
+ If specified, only traffic that originates from or terminates at endpoints within the selected
+ service(s) will be matched, and only to/from each endpoint's port.
+
+ Services cannot be specified on the same rule as Selector, NotSelector, NamespaceSelector, Nets,
+ NotNets or ServiceAccounts.
+
+ Ports and NotPorts can only be specified with Services on ingress rules.
+ properties:
+ name:
+ description: Name specifies the name of a Kubernetes
+ Service to match.
+ type: string
+ namespace:
+ description: |-
+ Namespace specifies the namespace of the given Service. If left empty, the rule
+ will match within this policy's namespace.
+ type: string
+ type: object
+ type: object
+ required:
+ - action
+ type: object
+ type: array
+ namespaceSelector:
+ description: NamespaceSelector is an optional field for an expression
+ used to select a pod based on namespaces.
+ type: string
+ order:
+ description: |-
+ Order is an optional field that specifies the order in which the policy is applied.
+ Policies with higher "order" are applied after those with lower
+ order within the same tier. If the order is omitted, it may be considered to be "infinite" - i.e. the
+ policy will be applied last. Policies with identical order will be applied in
+ alphanumerical order based on the Policy "Name" within the tier.
+ type: number
+ performanceHints:
+ description: |-
+ PerformanceHints contains a list of hints to Calico's policy engine to
+ help process the policy more efficiently. Hints never change the
+ enforcement behaviour of the policy.
+
+ Currently, the only available hint is "AssumeNeededOnEveryNode". When
+ that hint is set on a policy, Felix will act as if the policy matches
+ a local endpoint even if it does not. This is useful for "preloading"
+ any large static policies that are known to be used on every node.
+ If the policy is _not_ used on a particular node then the work
+ done to preload the policy (and to maintain it) is wasted.
+ items:
+ type: string
+ type: array
+ preDNAT:
+ description: PreDNAT indicates to apply the rules in this policy before
+ any DNAT.
+ type: boolean
+ selector:
+ description: "The selector is an expression used to pick out the endpoints
+ that the policy should\nbe applied to.\n\nSelector expressions follow
+ this syntax:\n\n\tlabel == \"string_literal\" -> comparison, e.g.
+ my_label == \"foo bar\"\n\tlabel != \"string_literal\" -> not
+ equal; also matches if label is not present\n\tlabel in { \"a\",
+ \"b\", \"c\", ... } -> true if the value of label X is one of
+ \"a\", \"b\", \"c\"\n\tlabel not in { \"a\", \"b\", \"c\", ... }
+ \ -> true if the value of label X is not one of \"a\", \"b\", \"c\"\n\thas(label_name)
+ \ -> True if that label is present\n\t! expr -> negation of expr\n\texpr
+ && expr -> Short-circuit and\n\texpr || expr -> Short-circuit
+ or\n\t( expr ) -> parens for grouping\n\tall() or the empty selector
+ -> matches all endpoints.\n\nLabel names are allowed to contain
+ alphanumerics, -, _ and /. String literals are more permissive\nbut
+ they do not support escape characters.\n\nExamples (with made-up
+ labels):\n\n\ttype == \"webserver\" && deployment == \"prod\"\n\ttype
+ in {\"frontend\", \"backend\"}\n\tdeployment != \"dev\"\n\t! has(label_name)"
+ type: string
+ serviceAccountSelector:
+ description: ServiceAccountSelector is an optional field for an expression
+ used to select a pod based on service accounts.
+ type: string
+ tier:
+ description: |-
+ The name of the tier that this policy belongs to. If this is omitted, the default
+ tier (name is "default") is assumed. The specified tier must exist in order to create
+ security policies within the tier, the "default" tier is created automatically if it
+ does not exist, this means for deployments requiring only a single Tier, the tier name
+ may be omitted on all policy management requests.
+ type: string
+ types:
+ description: |-
+ Types indicates whether this policy applies to ingress, or to egress, or to both. When
+ not explicitly specified (and so the value on creation is empty or nil), Calico defaults
+ Types according to what Ingress and Egress rules are present in the policy. The
+ default is:
+
+ - [ PolicyTypeIngress ], if there are no Egress rules (including the case where there are
+ also no Ingress rules)
+
+ - [ PolicyTypeEgress ], if there are Egress rules but no Ingress rules
+
+ - [ PolicyTypeIngress, PolicyTypeEgress ], if there are both Ingress and Egress rules.
+
+ When the policy is read back again, Types will always be one of these values, never empty
+ or nil.
+ items:
+ description: PolicyType enumerates the possible values of the PolicySpec
+ Types field.
+ type: string
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: true
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: globalnetworksets.crd.projectcalico.org
+spec:
+ group: crd.projectcalico.org
+ names:
+ kind: GlobalNetworkSet
+ listKind: GlobalNetworkSetList
+ plural: globalnetworksets
+ singular: globalnetworkset
+ preserveUnknownFields: false
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ description: |-
+ GlobalNetworkSet contains a set of arbitrary IP sub-networks/CIDRs that share labels to
+ allow rules to refer to them via selectors. The labels of GlobalNetworkSet are not namespaced.
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: GlobalNetworkSetSpec contains the specification for a NetworkSet
+ resource.
+ properties:
+ nets:
+ description: The list of IP networks that belong to this set.
+ items:
+ type: string
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: true
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: hostendpoints.crd.projectcalico.org
+spec:
+ group: crd.projectcalico.org
+ names:
+ kind: HostEndpoint
+ listKind: HostEndpointList
+ plural: hostendpoints
+ singular: hostendpoint
+ preserveUnknownFields: false
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: HostEndpointSpec contains the specification for a HostEndpoint
+ resource.
+ properties:
+ expectedIPs:
+ description: "The expected IP addresses (IPv4 and IPv6) of the endpoint.\nIf
+ \"InterfaceName\" is not present, Calico will look for an interface
+ matching any\nof the IPs in the list and apply policy to that.\nNote:\n\tWhen
+ using the selector match criteria in an ingress or egress security
+ Policy\n\tor Profile, Calico converts the selector into a set of
+ IP addresses. For host\n\tendpoints, the ExpectedIPs field is used
+ for that purpose. (If only the interface\n\tname is specified, Calico
+ does not learn the IPs of the interface for use in match\n\tcriteria.)"
+ items:
+ type: string
+ type: array
+ interfaceName:
+ description: |-
+ Either "*", or the name of a specific Linux interface to apply policy to; or empty. "*"
+ indicates that this HostEndpoint governs all traffic to, from or through the default
+ network namespace of the host named by the "Node" field; entering and leaving that
+ namespace via any interface, including those from/to non-host-networked local workloads.
+
+ If InterfaceName is not "*", this HostEndpoint only governs traffic that enters or leaves
+ the host through the specific interface named by InterfaceName, or - when InterfaceName
+ is empty - through the specific interface that has one of the IPs in ExpectedIPs.
+ Therefore, when InterfaceName is empty, at least one expected IP must be specified. Only
+ external interfaces (such as "eth0") are supported here; it isn't possible for a
+ HostEndpoint to protect traffic through a specific local workload interface.
+
+ Note: Only some kinds of policy are implemented for "*" HostEndpoints; initially just
+ pre-DNAT policy. Please check Calico documentation for the latest position.
+ type: string
+ node:
+ description: The node name identifying the Calico node instance.
+ type: string
+ ports:
+ description: Ports contains the endpoint's named ports, which may
+ be referenced in security policy rules.
+ items:
+ properties:
+ name:
+ type: string
+ port:
+ type: integer
+ protocol:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ required:
+ - name
+ - port
+ - protocol
+ type: object
+ type: array
+ profiles:
+ description: |-
+ A list of identifiers of security Profile objects that apply to this endpoint. Each
+ profile is applied in the order that they appear in this list. Profile rules are applied
+ after the selector-based security policy.
+ items:
+ type: string
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: true
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: ipamblocks.crd.projectcalico.org
+spec:
+ group: crd.projectcalico.org
+ names:
+ kind: IPAMBlock
+ listKind: IPAMBlockList
+ plural: ipamblocks
+ singular: ipamblock
+ preserveUnknownFields: false
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: IPAMBlockSpec contains the specification for an IPAMBlock
+ resource.
+ properties:
+ affinity:
+ description: |-
+ Affinity of the block, if this block has one. If set, it will be of the form
+ "host:". If not set, this block is not affine to a host.
+ type: string
+ allocations:
+ description: |-
+ Array of allocations in-use within this block. nil entries mean the allocation is free.
+ For non-nil entries at index i, the index is the ordinal of the allocation within this block
+ and the value is the index of the associated attributes in the Attributes array.
+ items:
+ type: integer
+ # TODO: This nullable is manually added in. We should update controller-gen
+ # to handle []*int properly itself.
+ nullable: true
+ type: array
+ attributes:
+ description: |-
+ Attributes is an array of arbitrary metadata associated with allocations in the block. To find
+ attributes for a given allocation, use the value of the allocation's entry in the Allocations array
+ as the index of the element in this array.
+ items:
+ properties:
+ handle_id:
+ type: string
+ secondary:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ type: array
+ cidr:
+ description: The block's CIDR.
+ type: string
+ deleted:
+ description: |-
+ Deleted is an internal boolean used to workaround a limitation in the Kubernetes API whereby
+ deletion will not return a conflict error if the block has been updated. It should not be set manually.
+ type: boolean
+ sequenceNumber:
+ default: 0
+ description: |-
+ We store a sequence number that is updated each time the block is written.
+ Each allocation will also store the sequence number of the block at the time of its creation.
+ When releasing an IP, passing the sequence number associated with the allocation allows us
+ to protect against a race condition and ensure the IP hasn't been released and re-allocated
+ since the release request.
+ format: int64
+ type: integer
+ sequenceNumberForAllocation:
+ additionalProperties:
+ format: int64
+ type: integer
+ description: |-
+ Map of allocated ordinal within the block to sequence number of the block at
+ the time of allocation. Kubernetes does not allow numerical keys for maps, so
+ the key is cast to a string.
+ type: object
+ strictAffinity:
+ description: StrictAffinity on the IPAMBlock is deprecated and no
+ longer used by the code. Use IPAMConfig StrictAffinity instead.
+ type: boolean
+ unallocated:
+ description: Unallocated is an ordered list of allocations which are
+ free in the block.
+ items:
+ type: integer
+ type: array
+ required:
+ - allocations
+ - attributes
+ - cidr
+ - strictAffinity
+ - unallocated
+ type: object
+ type: object
+ served: true
+ storage: true
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: ipamconfigs.crd.projectcalico.org
+spec:
+ group: crd.projectcalico.org
+ names:
+ kind: IPAMConfig
+ listKind: IPAMConfigList
+ plural: ipamconfigs
+ singular: ipamconfig
+ preserveUnknownFields: false
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: IPAMConfigSpec contains the specification for an IPAMConfig
+ resource.
+ properties:
+ autoAllocateBlocks:
+ type: boolean
+ maxBlocksPerHost:
+ description: |-
+ MaxBlocksPerHost, if non-zero, is the max number of blocks that can be
+ affine to each host.
+ maximum: 2147483647
+ minimum: 0
+ type: integer
+ strictAffinity:
+ type: boolean
+ required:
+ - autoAllocateBlocks
+ - strictAffinity
+ type: object
+ type: object
+ served: true
+ storage: true
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: ipamhandles.crd.projectcalico.org
+spec:
+ group: crd.projectcalico.org
+ names:
+ kind: IPAMHandle
+ listKind: IPAMHandleList
+ plural: ipamhandles
+ singular: ipamhandle
+ preserveUnknownFields: false
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: IPAMHandleSpec contains the specification for an IPAMHandle
+ resource.
+ properties:
+ block:
+ additionalProperties:
+ type: integer
+ type: object
+ deleted:
+ type: boolean
+ handleID:
+ type: string
+ required:
+ - block
+ - handleID
+ type: object
+ type: object
+ served: true
+ storage: true
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: ippools.crd.projectcalico.org
+spec:
+ group: crd.projectcalico.org
+ names:
+ kind: IPPool
+ listKind: IPPoolList
+ plural: ippools
+ singular: ippool
+ preserveUnknownFields: false
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: IPPoolSpec contains the specification for an IPPool resource.
+ properties:
+ allowedUses:
+ description: |-
+ AllowedUse controls what the IP pool will be used for. If not specified or empty, defaults to
+ ["Tunnel", "Workload"] for back-compatibility
+ items:
+ type: string
+ type: array
+ assignmentMode:
+ description: Determines the mode how IP addresses should be assigned
+ from this pool
+ enum:
+ - Automatic
+ - Manual
+ type: string
+ blockSize:
+ description: The block size to use for IP address assignments from
+ this pool. Defaults to 26 for IPv4 and 122 for IPv6.
+ type: integer
+ cidr:
+ description: The pool CIDR.
+ type: string
+ disableBGPExport:
+ description: 'Disable exporting routes from this IP Pool''s CIDR over
+ BGP. [Default: false]'
+ type: boolean
+ disabled:
+ description: When disabled is true, Calico IPAM will not assign addresses
+ from this pool.
+ type: boolean
+ ipip:
+ description: |-
+ Deprecated: this field is only used for APIv1 backwards compatibility.
+ Setting this field is not allowed, this field is for internal use only.
+ properties:
+ enabled:
+ description: |-
+ When enabled is true, ipip tunneling will be used to deliver packets to
+ destinations within this pool.
+ type: boolean
+ mode:
+ description: |-
+ The IPIP mode. This can be one of "always" or "cross-subnet". A mode
+ of "always" will also use IPIP tunneling for routing to destination IP
+ addresses within this pool. A mode of "cross-subnet" will only use IPIP
+ tunneling when the destination node is on a different subnet to the
+ originating node. The default value (if not specified) is "always".
+ type: string
+ type: object
+ ipipMode:
+ description: |-
+ Contains configuration for IPIP tunneling for this pool. If not specified,
+ then this is defaulted to "Never" (i.e. IPIP tunneling is disabled).
+ type: string
+ nat-outgoing:
+ description: |-
+ Deprecated: this field is only used for APIv1 backwards compatibility.
+ Setting this field is not allowed, this field is for internal use only.
+ type: boolean
+ natOutgoing:
+ description: |-
+ When natOutgoing is true, packets sent from Calico networked containers in
+ this pool to destinations outside of this pool will be masqueraded.
+ type: boolean
+ nodeSelector:
+ description: Allows IPPool to allocate for a specific node by label
+ selector.
+ type: string
+ vxlanMode:
+ description: |-
+ Contains configuration for VXLAN tunneling for this pool. If not specified,
+ then this is defaulted to "Never" (i.e. VXLAN tunneling is disabled).
+ type: string
+ required:
+ - cidr
+ type: object
+ type: object
+ served: true
+ storage: true
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: ipreservations.crd.projectcalico.org
+spec:
+ group: crd.projectcalico.org
+ names:
+ kind: IPReservation
+ listKind: IPReservationList
+ plural: ipreservations
+ singular: ipreservation
+ preserveUnknownFields: false
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: IPReservationSpec contains the specification for an IPReservation
+ resource.
+ properties:
+ reservedCIDRs:
+ description: ReservedCIDRs is a list of CIDRs and/or IP addresses
+ that Calico IPAM will exclude from new allocations.
+ items:
+ type: string
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: true
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: kubecontrollersconfigurations.crd.projectcalico.org
+spec:
+ group: crd.projectcalico.org
+ names:
+ kind: KubeControllersConfiguration
+ listKind: KubeControllersConfigurationList
+ plural: kubecontrollersconfigurations
+ singular: kubecontrollersconfiguration
+ preserveUnknownFields: false
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: KubeControllersConfigurationSpec contains the values of the
+ Kubernetes controllers configuration.
+ properties:
+ controllers:
+ description: Controllers enables and configures individual Kubernetes
+ controllers
+ properties:
+ loadBalancer:
+ description: LoadBalancer enables and configures the LoadBalancer
+ controller. Enabled by default, set to nil to disable.
+ properties:
+ assignIPs:
+ type: string
+ type: object
+ namespace:
+ description: Namespace enables and configures the namespace controller.
+ Enabled by default, set to nil to disable.
+ properties:
+ reconcilerPeriod:
+ description: 'ReconcilerPeriod is the period to perform reconciliation
+ with the Calico datastore. [Default: 5m]'
+ type: string
+ type: object
+ node:
+ description: Node enables and configures the node controller.
+ Enabled by default, set to nil to disable.
+ properties:
+ hostEndpoint:
+ description: HostEndpoint controls syncing nodes to host endpoints.
+ Disabled by default, set to nil to disable.
+ properties:
+ autoCreate:
+ description: 'AutoCreate enables automatic creation of
+ host endpoints for every node. [Default: Disabled]'
+ type: string
+ type: object
+ leakGracePeriod:
+ description: |-
+ LeakGracePeriod is the period used by the controller to determine if an IP address has been leaked.
+ Set to 0 to disable IP garbage collection. [Default: 15m]
+ type: string
+ reconcilerPeriod:
+ description: 'ReconcilerPeriod is the period to perform reconciliation
+ with the Calico datastore. [Default: 5m]'
+ type: string
+ syncLabels:
+ description: 'SyncLabels controls whether to copy Kubernetes
+ node labels to Calico nodes. [Default: Enabled]'
+ type: string
+ type: object
+ policy:
+ description: Policy enables and configures the policy controller.
+ Enabled by default, set to nil to disable.
+ properties:
+ reconcilerPeriod:
+ description: 'ReconcilerPeriod is the period to perform reconciliation
+ with the Calico datastore. [Default: 5m]'
+ type: string
+ type: object
+ serviceAccount:
+ description: ServiceAccount enables and configures the service
+ account controller. Enabled by default, set to nil to disable.
+ properties:
+ reconcilerPeriod:
+ description: 'ReconcilerPeriod is the period to perform reconciliation
+ with the Calico datastore. [Default: 5m]'
+ type: string
+ type: object
+ workloadEndpoint:
+ description: WorkloadEndpoint enables and configures the workload
+ endpoint controller. Enabled by default, set to nil to disable.
+ properties:
+ reconcilerPeriod:
+ description: 'ReconcilerPeriod is the period to perform reconciliation
+ with the Calico datastore. [Default: 5m]'
+ type: string
+ type: object
+ type: object
+ debugProfilePort:
+ description: |-
+ DebugProfilePort configures the port to serve memory and cpu profiles on. If not specified, profiling
+ is disabled.
+ format: int32
+ type: integer
+ etcdV3CompactionPeriod:
+ description: 'EtcdV3CompactionPeriod is the period between etcdv3
+ compaction requests. Set to 0 to disable. [Default: 10m]'
+ type: string
+ healthChecks:
+ description: 'HealthChecks enables or disables support for health
+ checks [Default: Enabled]'
+ type: string
+ logSeverityScreen:
+ description: 'LogSeverityScreen is the log severity above which logs
+ are sent to the stdout. [Default: Info]'
+ type: string
+ prometheusMetricsPort:
+ description: 'PrometheusMetricsPort is the TCP port that the Prometheus
+ metrics server should bind to. Set to 0 to disable. [Default: 9094]'
+ type: integer
+ required:
+ - controllers
+ type: object
+ status:
+ description: |-
+ KubeControllersConfigurationStatus represents the status of the configuration. It's useful for admins to
+ be able to see the actual config that was applied, which can be modified by environment variables on the
+ kube-controllers process.
+ properties:
+ environmentVars:
+ additionalProperties:
+ type: string
+ description: |-
+ EnvironmentVars contains the environment variables on the kube-controllers that influenced
+ the RunningConfig.
+ type: object
+ runningConfig:
+ description: |-
+ RunningConfig contains the effective config that is running in the kube-controllers pod, after
+ merging the API resource with any environment variables.
+ properties:
+ controllers:
+ description: Controllers enables and configures individual Kubernetes
+ controllers
+ properties:
+ loadBalancer:
+ description: LoadBalancer enables and configures the LoadBalancer
+ controller. Enabled by default, set to nil to disable.
+ properties:
+ assignIPs:
+ type: string
+ type: object
+ namespace:
+ description: Namespace enables and configures the namespace
+ controller. Enabled by default, set to nil to disable.
+ properties:
+ reconcilerPeriod:
+ description: 'ReconcilerPeriod is the period to perform
+ reconciliation with the Calico datastore. [Default:
+ 5m]'
+ type: string
+ type: object
+ node:
+ description: Node enables and configures the node controller.
+ Enabled by default, set to nil to disable.
+ properties:
+ hostEndpoint:
+ description: HostEndpoint controls syncing nodes to host
+ endpoints. Disabled by default, set to nil to disable.
+ properties:
+ autoCreate:
+ description: 'AutoCreate enables automatic creation
+ of host endpoints for every node. [Default: Disabled]'
+ type: string
+ type: object
+ leakGracePeriod:
+ description: |-
+ LeakGracePeriod is the period used by the controller to determine if an IP address has been leaked.
+ Set to 0 to disable IP garbage collection. [Default: 15m]
+ type: string
+ reconcilerPeriod:
+ description: 'ReconcilerPeriod is the period to perform
+ reconciliation with the Calico datastore. [Default:
+ 5m]'
+ type: string
+ syncLabels:
+ description: 'SyncLabels controls whether to copy Kubernetes
+ node labels to Calico nodes. [Default: Enabled]'
+ type: string
+ type: object
+ policy:
+ description: Policy enables and configures the policy controller.
+ Enabled by default, set to nil to disable.
+ properties:
+ reconcilerPeriod:
+ description: 'ReconcilerPeriod is the period to perform
+ reconciliation with the Calico datastore. [Default:
+ 5m]'
+ type: string
+ type: object
+ serviceAccount:
+ description: ServiceAccount enables and configures the service
+ account controller. Enabled by default, set to nil to disable.
+ properties:
+ reconcilerPeriod:
+ description: 'ReconcilerPeriod is the period to perform
+ reconciliation with the Calico datastore. [Default:
+ 5m]'
+ type: string
+ type: object
+ workloadEndpoint:
+ description: WorkloadEndpoint enables and configures the workload
+ endpoint controller. Enabled by default, set to nil to disable.
+ properties:
+ reconcilerPeriod:
+ description: 'ReconcilerPeriod is the period to perform
+ reconciliation with the Calico datastore. [Default:
+ 5m]'
+ type: string
+ type: object
+ type: object
+ debugProfilePort:
+ description: |-
+ DebugProfilePort configures the port to serve memory and cpu profiles on. If not specified, profiling
+ is disabled.
+ format: int32
+ type: integer
+ etcdV3CompactionPeriod:
+ description: 'EtcdV3CompactionPeriod is the period between etcdv3
+ compaction requests. Set to 0 to disable. [Default: 10m]'
+ type: string
+ healthChecks:
+ description: 'HealthChecks enables or disables support for health
+ checks [Default: Enabled]'
+ type: string
+ logSeverityScreen:
+ description: 'LogSeverityScreen is the log severity above which
+ logs are sent to the stdout. [Default: Info]'
+ type: string
+ prometheusMetricsPort:
+ description: 'PrometheusMetricsPort is the TCP port that the Prometheus
+ metrics server should bind to. Set to 0 to disable. [Default:
+ 9094]'
+ type: integer
+ required:
+ - controllers
+ type: object
+ type: object
+ type: object
+ served: true
+ storage: true
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: networkpolicies.crd.projectcalico.org
+spec:
+ group: crd.projectcalico.org
+ names:
+ kind: NetworkPolicy
+ listKind: NetworkPolicyList
+ plural: networkpolicies
+ singular: networkpolicy
+ preserveUnknownFields: false
+ scope: Namespaced
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ properties:
+ egress:
+ description: |-
+ The ordered set of egress rules. Each rule contains a set of packet match criteria and
+ a corresponding action to apply.
+ items:
+ description: |-
+ A Rule encapsulates a set of match criteria and an action. Both selector-based security Policy
+ and security Profiles reference rules - separated out as a list of rules for both
+ ingress and egress packet matching.
+
+ Each positive match criteria has a negated version, prefixed with "Not". All the match
+ criteria within a rule must be satisfied for a packet to match. A single rule can contain
+ the positive and negative version of a match and both must be satisfied for the rule to match.
+ properties:
+ action:
+ type: string
+ destination:
+ description: Destination contains the match criteria that apply
+ to destination entity.
+ properties:
+ namespaceSelector:
+ description: |-
+ NamespaceSelector is an optional field that contains a selector expression. Only traffic
+ that originates from (or terminates at) endpoints within the selected namespaces will be
+ matched. When both NamespaceSelector and another selector are defined on the same rule, then only
+ workload endpoints that are matched by both selectors will be selected by the rule.
+
+ For NetworkPolicy, an empty NamespaceSelector implies that the Selector is limited to selecting
+ only workload endpoints in the same namespace as the NetworkPolicy.
+
+ For NetworkPolicy, `global()` NamespaceSelector implies that the Selector is limited to selecting
+ only GlobalNetworkSet or HostEndpoint.
+
+ For GlobalNetworkPolicy, an empty NamespaceSelector implies the Selector applies to workload
+ endpoints across all namespaces.
+ type: string
+ nets:
+ description: |-
+ Nets is an optional field that restricts the rule to only apply to traffic that
+ originates from (or terminates at) IP addresses in any of the given subnets.
+ items:
+ type: string
+ type: array
+ notNets:
+ description: NotNets is the negated version of the Nets
+ field.
+ items:
+ type: string
+ type: array
+ notPorts:
+ description: |-
+ NotPorts is the negated version of the Ports field.
+ Since only some protocols have ports, if any ports are specified it requires the
+ Protocol match in the Rule to be set to "TCP" or "UDP".
+ items:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ type: array
+ notSelector:
+ description: |-
+ NotSelector is the negated version of the Selector field. See Selector field for
+ subtleties with negated selectors.
+ type: string
+ ports:
+ description: |-
+ Ports is an optional field that restricts the rule to only apply to traffic that has a
+ source (destination) port that matches one of these ranges/values. This value is a
+ list of integers or strings that represent ranges of ports.
+
+ Since only some protocols have ports, if any ports are specified it requires the
+ Protocol match in the Rule to be set to "TCP" or "UDP".
+ items:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ type: array
+ selector:
+ description: "Selector is an optional field that contains
+ a selector expression (see Policy for\nsample syntax).
+ \ Only traffic that originates from (terminates at) endpoints
+ matching\nthe selector will be matched.\n\nNote that:
+ in addition to the negated version of the Selector (see
+ NotSelector below), the\nselector expression syntax itself
+ supports negation. The two types of negation are subtly\ndifferent.
+ One negates the set of matched endpoints, the other negates
+ the whole match:\n\n\tSelector = \"!has(my_label)\" matches
+ packets that are from other Calico-controlled\n\tendpoints
+ that do not have the label \"my_label\".\n\n\tNotSelector
+ = \"has(my_label)\" matches packets that are not from
+ Calico-controlled\n\tendpoints that do have the label
+ \"my_label\".\n\nThe effect is that the latter will accept
+ packets from non-Calico sources whereas the\nformer is
+ limited to packets from Calico-controlled endpoints."
+ type: string
+ serviceAccounts:
+ description: |-
+ ServiceAccounts is an optional field that restricts the rule to only apply to traffic that originates from (or
+ terminates at) a pod running as a matching service account.
+ properties:
+ names:
+ description: |-
+ Names is an optional field that restricts the rule to only apply to traffic that originates from (or terminates
+ at) a pod running as a service account whose name is in the list.
+ items:
+ type: string
+ type: array
+ selector:
+ description: |-
+ Selector is an optional field that restricts the rule to only apply to traffic that originates from
+ (or terminates at) a pod running as a service account that matches the given label selector.
+ If both Names and Selector are specified then they are AND'ed.
+ type: string
+ type: object
+ services:
+ description: |-
+ Services is an optional field that contains options for matching Kubernetes Services.
+ If specified, only traffic that originates from or terminates at endpoints within the selected
+ service(s) will be matched, and only to/from each endpoint's port.
+
+ Services cannot be specified on the same rule as Selector, NotSelector, NamespaceSelector, Nets,
+ NotNets or ServiceAccounts.
+
+ Ports and NotPorts can only be specified with Services on ingress rules.
+ properties:
+ name:
+ description: Name specifies the name of a Kubernetes
+ Service to match.
+ type: string
+ namespace:
+ description: |-
+ Namespace specifies the namespace of the given Service. If left empty, the rule
+ will match within this policy's namespace.
+ type: string
+ type: object
+ type: object
+ http:
+ description: HTTP contains match criteria that apply to HTTP
+ requests.
+ properties:
+ methods:
+ description: |-
+ Methods is an optional field that restricts the rule to apply only to HTTP requests that use one of the listed
+ HTTP Methods (e.g. GET, PUT, etc.)
+ Multiple methods are OR'd together.
+ items:
+ type: string
+ type: array
+ paths:
+ description: |-
+ Paths is an optional field that restricts the rule to apply to HTTP requests that use one of the listed
+ HTTP Paths.
+ Multiple paths are OR'd together.
+ e.g:
+ - exact: /foo
+ - prefix: /bar
+ NOTE: Each entry may ONLY specify either a `exact` or a `prefix` match. The validator will check for it.
+ items:
+ description: |-
+ HTTPPath specifies an HTTP path to match. It may be either of the form:
+ exact: : which matches the path exactly or
+ prefix: : which matches the path prefix
+ properties:
+ exact:
+ type: string
+ prefix:
+ type: string
+ type: object
+ type: array
+ type: object
+ icmp:
+ description: |-
+ ICMP is an optional field that restricts the rule to apply to a specific type and
+ code of ICMP traffic. This should only be specified if the Protocol field is set to
+ "ICMP" or "ICMPv6".
+ properties:
+ code:
+ description: |-
+ Match on a specific ICMP code. If specified, the Type value must also be specified.
+ This is a technical limitation imposed by the kernel's iptables firewall, which
+ Calico uses to enforce the rule.
+ type: integer
+ type:
+ description: |-
+ Match on a specific ICMP type. For example a value of 8 refers to ICMP Echo Request
+ (i.e. pings).
+ type: integer
+ type: object
+ ipVersion:
+ description: |-
+ IPVersion is an optional field that restricts the rule to only match a specific IP
+ version.
+ type: integer
+ metadata:
+ description: Metadata contains additional information for this
+ rule
+ properties:
+ annotations:
+ additionalProperties:
+ type: string
+ description: Annotations is a set of key value pairs that
+ give extra information about the rule
+ type: object
+ type: object
+ notICMP:
+ description: NotICMP is the negated version of the ICMP field.
+ properties:
+ code:
+ description: |-
+ Match on a specific ICMP code. If specified, the Type value must also be specified.
+ This is a technical limitation imposed by the kernel's iptables firewall, which
+ Calico uses to enforce the rule.
+ type: integer
+ type:
+ description: |-
+ Match on a specific ICMP type. For example a value of 8 refers to ICMP Echo Request
+ (i.e. pings).
+ type: integer
+ type: object
+ notProtocol:
+ anyOf:
+ - type: integer
+ - type: string
+ description: NotProtocol is the negated version of the Protocol
+ field.
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ protocol:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ Protocol is an optional field that restricts the rule to only apply to traffic of
+ a specific IP protocol. Required if any of the EntityRules contain Ports
+ (because ports only apply to certain protocols).
+
+ Must be one of these string values: "TCP", "UDP", "ICMP", "ICMPv6", "SCTP", "UDPLite"
+ or an integer in the range 1-255.
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ source:
+ description: Source contains the match criteria that apply to
+ source entity.
+ properties:
+ namespaceSelector:
+ description: |-
+ NamespaceSelector is an optional field that contains a selector expression. Only traffic
+ that originates from (or terminates at) endpoints within the selected namespaces will be
+ matched. When both NamespaceSelector and another selector are defined on the same rule, then only
+ workload endpoints that are matched by both selectors will be selected by the rule.
+
+ For NetworkPolicy, an empty NamespaceSelector implies that the Selector is limited to selecting
+ only workload endpoints in the same namespace as the NetworkPolicy.
+
+ For NetworkPolicy, `global()` NamespaceSelector implies that the Selector is limited to selecting
+ only GlobalNetworkSet or HostEndpoint.
+
+ For GlobalNetworkPolicy, an empty NamespaceSelector implies the Selector applies to workload
+ endpoints across all namespaces.
+ type: string
+ nets:
+ description: |-
+ Nets is an optional field that restricts the rule to only apply to traffic that
+ originates from (or terminates at) IP addresses in any of the given subnets.
+ items:
+ type: string
+ type: array
+ notNets:
+ description: NotNets is the negated version of the Nets
+ field.
+ items:
+ type: string
+ type: array
+ notPorts:
+ description: |-
+ NotPorts is the negated version of the Ports field.
+ Since only some protocols have ports, if any ports are specified it requires the
+ Protocol match in the Rule to be set to "TCP" or "UDP".
+ items:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ type: array
+ notSelector:
+ description: |-
+ NotSelector is the negated version of the Selector field. See Selector field for
+ subtleties with negated selectors.
+ type: string
+ ports:
+ description: |-
+ Ports is an optional field that restricts the rule to only apply to traffic that has a
+ source (destination) port that matches one of these ranges/values. This value is a
+ list of integers or strings that represent ranges of ports.
+
+ Since only some protocols have ports, if any ports are specified it requires the
+ Protocol match in the Rule to be set to "TCP" or "UDP".
+ items:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ type: array
+ selector:
+ description: "Selector is an optional field that contains
+ a selector expression (see Policy for\nsample syntax).
+ \ Only traffic that originates from (terminates at) endpoints
+ matching\nthe selector will be matched.\n\nNote that:
+ in addition to the negated version of the Selector (see
+ NotSelector below), the\nselector expression syntax itself
+ supports negation. The two types of negation are subtly\ndifferent.
+ One negates the set of matched endpoints, the other negates
+ the whole match:\n\n\tSelector = \"!has(my_label)\" matches
+ packets that are from other Calico-controlled\n\tendpoints
+ that do not have the label \"my_label\".\n\n\tNotSelector
+ = \"has(my_label)\" matches packets that are not from
+ Calico-controlled\n\tendpoints that do have the label
+ \"my_label\".\n\nThe effect is that the latter will accept
+ packets from non-Calico sources whereas the\nformer is
+ limited to packets from Calico-controlled endpoints."
+ type: string
+ serviceAccounts:
+ description: |-
+ ServiceAccounts is an optional field that restricts the rule to only apply to traffic that originates from (or
+ terminates at) a pod running as a matching service account.
+ properties:
+ names:
+ description: |-
+ Names is an optional field that restricts the rule to only apply to traffic that originates from (or terminates
+ at) a pod running as a service account whose name is in the list.
+ items:
+ type: string
+ type: array
+ selector:
+ description: |-
+ Selector is an optional field that restricts the rule to only apply to traffic that originates from
+ (or terminates at) a pod running as a service account that matches the given label selector.
+ If both Names and Selector are specified then they are AND'ed.
+ type: string
+ type: object
+ services:
+ description: |-
+ Services is an optional field that contains options for matching Kubernetes Services.
+ If specified, only traffic that originates from or terminates at endpoints within the selected
+ service(s) will be matched, and only to/from each endpoint's port.
+
+ Services cannot be specified on the same rule as Selector, NotSelector, NamespaceSelector, Nets,
+ NotNets or ServiceAccounts.
+
+ Ports and NotPorts can only be specified with Services on ingress rules.
+ properties:
+ name:
+ description: Name specifies the name of a Kubernetes
+ Service to match.
+ type: string
+ namespace:
+ description: |-
+ Namespace specifies the namespace of the given Service. If left empty, the rule
+ will match within this policy's namespace.
+ type: string
+ type: object
+ type: object
+ required:
+ - action
+ type: object
+ type: array
+ ingress:
+ description: |-
+ The ordered set of ingress rules. Each rule contains a set of packet match criteria and
+ a corresponding action to apply.
+ items:
+ description: |-
+ A Rule encapsulates a set of match criteria and an action. Both selector-based security Policy
+ and security Profiles reference rules - separated out as a list of rules for both
+ ingress and egress packet matching.
+
+ Each positive match criteria has a negated version, prefixed with "Not". All the match
+ criteria within a rule must be satisfied for a packet to match. A single rule can contain
+ the positive and negative version of a match and both must be satisfied for the rule to match.
+ properties:
+ action:
+ type: string
+ destination:
+ description: Destination contains the match criteria that apply
+ to destination entity.
+ properties:
+ namespaceSelector:
+ description: |-
+ NamespaceSelector is an optional field that contains a selector expression. Only traffic
+ that originates from (or terminates at) endpoints within the selected namespaces will be
+ matched. When both NamespaceSelector and another selector are defined on the same rule, then only
+ workload endpoints that are matched by both selectors will be selected by the rule.
+
+ For NetworkPolicy, an empty NamespaceSelector implies that the Selector is limited to selecting
+ only workload endpoints in the same namespace as the NetworkPolicy.
+
+ For NetworkPolicy, `global()` NamespaceSelector implies that the Selector is limited to selecting
+ only GlobalNetworkSet or HostEndpoint.
+
+ For GlobalNetworkPolicy, an empty NamespaceSelector implies the Selector applies to workload
+ endpoints across all namespaces.
+ type: string
+ nets:
+ description: |-
+ Nets is an optional field that restricts the rule to only apply to traffic that
+ originates from (or terminates at) IP addresses in any of the given subnets.
+ items:
+ type: string
+ type: array
+ notNets:
+ description: NotNets is the negated version of the Nets
+ field.
+ items:
+ type: string
+ type: array
+ notPorts:
+ description: |-
+ NotPorts is the negated version of the Ports field.
+ Since only some protocols have ports, if any ports are specified it requires the
+ Protocol match in the Rule to be set to "TCP" or "UDP".
+ items:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ type: array
+ notSelector:
+ description: |-
+ NotSelector is the negated version of the Selector field. See Selector field for
+ subtleties with negated selectors.
+ type: string
+ ports:
+ description: |-
+ Ports is an optional field that restricts the rule to only apply to traffic that has a
+ source (destination) port that matches one of these ranges/values. This value is a
+ list of integers or strings that represent ranges of ports.
+
+ Since only some protocols have ports, if any ports are specified it requires the
+ Protocol match in the Rule to be set to "TCP" or "UDP".
+ items:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ type: array
+ selector:
+ description: "Selector is an optional field that contains
+ a selector expression (see Policy for\nsample syntax).
+ \ Only traffic that originates from (terminates at) endpoints
+ matching\nthe selector will be matched.\n\nNote that:
+ in addition to the negated version of the Selector (see
+ NotSelector below), the\nselector expression syntax itself
+ supports negation. The two types of negation are subtly\ndifferent.
+ One negates the set of matched endpoints, the other negates
+ the whole match:\n\n\tSelector = \"!has(my_label)\" matches
+ packets that are from other Calico-controlled\n\tendpoints
+ that do not have the label \"my_label\".\n\n\tNotSelector
+ = \"has(my_label)\" matches packets that are not from
+ Calico-controlled\n\tendpoints that do have the label
+ \"my_label\".\n\nThe effect is that the latter will accept
+ packets from non-Calico sources whereas the\nformer is
+ limited to packets from Calico-controlled endpoints."
+ type: string
+ serviceAccounts:
+ description: |-
+ ServiceAccounts is an optional field that restricts the rule to only apply to traffic that originates from (or
+ terminates at) a pod running as a matching service account.
+ properties:
+ names:
+ description: |-
+ Names is an optional field that restricts the rule to only apply to traffic that originates from (or terminates
+ at) a pod running as a service account whose name is in the list.
+ items:
+ type: string
+ type: array
+ selector:
+ description: |-
+ Selector is an optional field that restricts the rule to only apply to traffic that originates from
+ (or terminates at) a pod running as a service account that matches the given label selector.
+ If both Names and Selector are specified then they are AND'ed.
+ type: string
+ type: object
+ services:
+ description: |-
+ Services is an optional field that contains options for matching Kubernetes Services.
+ If specified, only traffic that originates from or terminates at endpoints within the selected
+ service(s) will be matched, and only to/from each endpoint's port.
+
+ Services cannot be specified on the same rule as Selector, NotSelector, NamespaceSelector, Nets,
+ NotNets or ServiceAccounts.
+
+ Ports and NotPorts can only be specified with Services on ingress rules.
+ properties:
+ name:
+ description: Name specifies the name of a Kubernetes
+ Service to match.
+ type: string
+ namespace:
+ description: |-
+ Namespace specifies the namespace of the given Service. If left empty, the rule
+ will match within this policy's namespace.
+ type: string
+ type: object
+ type: object
+ http:
+ description: HTTP contains match criteria that apply to HTTP
+ requests.
+ properties:
+ methods:
+ description: |-
+ Methods is an optional field that restricts the rule to apply only to HTTP requests that use one of the listed
+ HTTP Methods (e.g. GET, PUT, etc.)
+ Multiple methods are OR'd together.
+ items:
+ type: string
+ type: array
+ paths:
+ description: |-
+ Paths is an optional field that restricts the rule to apply to HTTP requests that use one of the listed
+ HTTP Paths.
+ Multiple paths are OR'd together.
+ e.g:
+ - exact: /foo
+ - prefix: /bar
+ NOTE: Each entry may ONLY specify either a `exact` or a `prefix` match. The validator will check for it.
+ items:
+ description: |-
+ HTTPPath specifies an HTTP path to match. It may be either of the form:
+ exact: : which matches the path exactly or
+ prefix: : which matches the path prefix
+ properties:
+ exact:
+ type: string
+ prefix:
+ type: string
+ type: object
+ type: array
+ type: object
+ icmp:
+ description: |-
+ ICMP is an optional field that restricts the rule to apply to a specific type and
+ code of ICMP traffic. This should only be specified if the Protocol field is set to
+ "ICMP" or "ICMPv6".
+ properties:
+ code:
+ description: |-
+ Match on a specific ICMP code. If specified, the Type value must also be specified.
+ This is a technical limitation imposed by the kernel's iptables firewall, which
+ Calico uses to enforce the rule.
+ type: integer
+ type:
+ description: |-
+ Match on a specific ICMP type. For example a value of 8 refers to ICMP Echo Request
+ (i.e. pings).
+ type: integer
+ type: object
+ ipVersion:
+ description: |-
+ IPVersion is an optional field that restricts the rule to only match a specific IP
+ version.
+ type: integer
+ metadata:
+ description: Metadata contains additional information for this
+ rule
+ properties:
+ annotations:
+ additionalProperties:
+ type: string
+ description: Annotations is a set of key value pairs that
+ give extra information about the rule
+ type: object
+ type: object
+ notICMP:
+ description: NotICMP is the negated version of the ICMP field.
+ properties:
+ code:
+ description: |-
+ Match on a specific ICMP code. If specified, the Type value must also be specified.
+ This is a technical limitation imposed by the kernel's iptables firewall, which
+ Calico uses to enforce the rule.
+ type: integer
+ type:
+ description: |-
+ Match on a specific ICMP type. For example a value of 8 refers to ICMP Echo Request
+ (i.e. pings).
+ type: integer
+ type: object
+ notProtocol:
+ anyOf:
+ - type: integer
+ - type: string
+ description: NotProtocol is the negated version of the Protocol
+ field.
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ protocol:
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ Protocol is an optional field that restricts the rule to only apply to traffic of
+ a specific IP protocol. Required if any of the EntityRules contain Ports
+ (because ports only apply to certain protocols).
+
+ Must be one of these string values: "TCP", "UDP", "ICMP", "ICMPv6", "SCTP", "UDPLite"
+ or an integer in the range 1-255.
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ source:
+ description: Source contains the match criteria that apply to
+ source entity.
+ properties:
+ namespaceSelector:
+ description: |-
+ NamespaceSelector is an optional field that contains a selector expression. Only traffic
+ that originates from (or terminates at) endpoints within the selected namespaces will be
+ matched. When both NamespaceSelector and another selector are defined on the same rule, then only
+ workload endpoints that are matched by both selectors will be selected by the rule.
+
+ For NetworkPolicy, an empty NamespaceSelector implies that the Selector is limited to selecting
+ only workload endpoints in the same namespace as the NetworkPolicy.
+
+ For NetworkPolicy, `global()` NamespaceSelector implies that the Selector is limited to selecting
+ only GlobalNetworkSet or HostEndpoint.
+
+ For GlobalNetworkPolicy, an empty NamespaceSelector implies the Selector applies to workload
+ endpoints across all namespaces.
+ type: string
+ nets:
+ description: |-
+ Nets is an optional field that restricts the rule to only apply to traffic that
+ originates from (or terminates at) IP addresses in any of the given subnets.
+ items:
+ type: string
+ type: array
+ notNets:
+ description: NotNets is the negated version of the Nets
+ field.
+ items:
+ type: string
+ type: array
+ notPorts:
+ description: |-
+ NotPorts is the negated version of the Ports field.
+ Since only some protocols have ports, if any ports are specified it requires the
+ Protocol match in the Rule to be set to "TCP" or "UDP".
+ items:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ type: array
+ notSelector:
+ description: |-
+ NotSelector is the negated version of the Selector field. See Selector field for
+ subtleties with negated selectors.
+ type: string
+ ports:
+ description: |-
+ Ports is an optional field that restricts the rule to only apply to traffic that has a
+ source (destination) port that matches one of these ranges/values. This value is a
+ list of integers or strings that represent ranges of ports.
+
+ Since only some protocols have ports, if any ports are specified it requires the
+ Protocol match in the Rule to be set to "TCP" or "UDP".
+ items:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^.*
+ x-kubernetes-int-or-string: true
+ type: array
+ selector:
+ description: "Selector is an optional field that contains
+ a selector expression (see Policy for\nsample syntax).
+ \ Only traffic that originates from (terminates at) endpoints
+ matching\nthe selector will be matched.\n\nNote that:
+ in addition to the negated version of the Selector (see
+ NotSelector below), the\nselector expression syntax itself
+ supports negation. The two types of negation are subtly\ndifferent.
+ One negates the set of matched endpoints, the other negates
+ the whole match:\n\n\tSelector = \"!has(my_label)\" matches
+ packets that are from other Calico-controlled\n\tendpoints
+ that do not have the label \"my_label\".\n\n\tNotSelector
+ = \"has(my_label)\" matches packets that are not from
+ Calico-controlled\n\tendpoints that do have the label
+ \"my_label\".\n\nThe effect is that the latter will accept
+ packets from non-Calico sources whereas the\nformer is
+ limited to packets from Calico-controlled endpoints."
+ type: string
+ serviceAccounts:
+ description: |-
+ ServiceAccounts is an optional field that restricts the rule to only apply to traffic that originates from (or
+ terminates at) a pod running as a matching service account.
+ properties:
+ names:
+ description: |-
+ Names is an optional field that restricts the rule to only apply to traffic that originates from (or terminates
+ at) a pod running as a service account whose name is in the list.
+ items:
+ type: string
+ type: array
+ selector:
+ description: |-
+ Selector is an optional field that restricts the rule to only apply to traffic that originates from
+ (or terminates at) a pod running as a service account that matches the given label selector.
+ If both Names and Selector are specified then they are AND'ed.
+ type: string
+ type: object
+ services:
+ description: |-
+ Services is an optional field that contains options for matching Kubernetes Services.
+ If specified, only traffic that originates from or terminates at endpoints within the selected
+ service(s) will be matched, and only to/from each endpoint's port.
+
+ Services cannot be specified on the same rule as Selector, NotSelector, NamespaceSelector, Nets,
+ NotNets or ServiceAccounts.
+
+ Ports and NotPorts can only be specified with Services on ingress rules.
+ properties:
+ name:
+ description: Name specifies the name of a Kubernetes
+ Service to match.
+ type: string
+ namespace:
+ description: |-
+ Namespace specifies the namespace of the given Service. If left empty, the rule
+ will match within this policy's namespace.
+ type: string
+ type: object
+ type: object
+ required:
+ - action
+ type: object
+ type: array
+ order:
+ description: |-
+ Order is an optional field that specifies the order in which the policy is applied.
+ Policies with higher "order" are applied after those with lower
+ order within the same tier. If the order is omitted, it may be considered to be "infinite" - i.e. the
+ policy will be applied last. Policies with identical order will be applied in
+ alphanumerical order based on the Policy "Name" within the tier.
+ type: number
+ performanceHints:
+ description: |-
+ PerformanceHints contains a list of hints to Calico's policy engine to
+ help process the policy more efficiently. Hints never change the
+ enforcement behaviour of the policy.
+
+ Currently, the only available hint is "AssumeNeededOnEveryNode". When
+ that hint is set on a policy, Felix will act as if the policy matches
+ a local endpoint even if it does not. This is useful for "preloading"
+ any large static policies that are known to be used on every node.
+ If the policy is _not_ used on a particular node then the work
+ done to preload the policy (and to maintain it) is wasted.
+ items:
+ type: string
+ type: array
+ selector:
+ description: "The selector is an expression used to pick out the endpoints
+ that the policy should\nbe applied to.\n\nSelector expressions follow
+ this syntax:\n\n\tlabel == \"string_literal\" -> comparison, e.g.
+ my_label == \"foo bar\"\n\tlabel != \"string_literal\" -> not
+ equal; also matches if label is not present\n\tlabel in { \"a\",
+ \"b\", \"c\", ... } -> true if the value of label X is one of
+ \"a\", \"b\", \"c\"\n\tlabel not in { \"a\", \"b\", \"c\", ... }
+ \ -> true if the value of label X is not one of \"a\", \"b\", \"c\"\n\thas(label_name)
+ \ -> True if that label is present\n\t! expr -> negation of expr\n\texpr
+ && expr -> Short-circuit and\n\texpr || expr -> Short-circuit
+ or\n\t( expr ) -> parens for grouping\n\tall() or the empty selector
+ -> matches all endpoints.\n\nLabel names are allowed to contain
+ alphanumerics, -, _ and /. String literals are more permissive\nbut
+ they do not support escape characters.\n\nExamples (with made-up
+ labels):\n\n\ttype == \"webserver\" && deployment == \"prod\"\n\ttype
+ in {\"frontend\", \"backend\"}\n\tdeployment != \"dev\"\n\t! has(label_name)"
+ type: string
+ serviceAccountSelector:
+ description: ServiceAccountSelector is an optional field for an expression
+ used to select a pod based on service accounts.
+ type: string
+ tier:
+ description: |-
+ The name of the tier that this policy belongs to. If this is omitted, the default
+ tier (name is "default") is assumed. The specified tier must exist in order to create
+ security policies within the tier, the "default" tier is created automatically if it
+ does not exist, this means for deployments requiring only a single Tier, the tier name
+ may be omitted on all policy management requests.
+ type: string
+ types:
+ description: |-
+ Types indicates whether this policy applies to ingress, or to egress, or to both. When
+ not explicitly specified (and so the value on creation is empty or nil), Calico defaults
+ Types according to what Ingress and Egress are present in the policy. The
+ default is:
+
+ - [ PolicyTypeIngress ], if there are no Egress rules (including the case where there are
+ also no Ingress rules)
+
+ - [ PolicyTypeEgress ], if there are Egress rules but no Ingress rules
+
+ - [ PolicyTypeIngress, PolicyTypeEgress ], if there are both Ingress and Egress rules.
+
+ When the policy is read back again, Types will always be one of these values, never empty
+ or nil.
+ items:
+ description: PolicyType enumerates the possible values of the PolicySpec
+ Types field.
+ type: string
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: true
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: networksets.crd.projectcalico.org
+spec:
+ group: crd.projectcalico.org
+ names:
+ kind: NetworkSet
+ listKind: NetworkSetList
+ plural: networksets
+ singular: networkset
+ preserveUnknownFields: false
+ scope: Namespaced
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ description: NetworkSet is the Namespaced-equivalent of the GlobalNetworkSet.
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: NetworkSetSpec contains the specification for a NetworkSet
+ resource.
+ properties:
+ nets:
+ description: The list of IP networks that belong to this set.
+ items:
+ type: string
+ type: array
+ type: object
+ type: object
+ served: true
+ storage: true
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: tiers.crd.projectcalico.org
+spec:
+ group: crd.projectcalico.org
+ names:
+ kind: Tier
+ listKind: TierList
+ plural: tiers
+ singular: tier
+ preserveUnknownFields: false
+ scope: Cluster
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: TierSpec contains the specification for a security policy
+ tier resource.
+ properties:
+ defaultAction:
+ description: |-
+ DefaultAction specifies the action applied to workloads selected by a policy in the tier,
+ but not rule matched the workload's traffic.
+ [Default: Deny]
+ enum:
+ - Pass
+ - Deny
+ type: string
+ order:
+ description: |-
+ Order is an optional field that specifies the order in which the tier is applied.
+ Tiers with higher "order" are applied after those with lower order. If the order
+ is omitted, it may be considered to be "infinite" - i.e. the tier will be applied
+ last. Tiers with identical order will be applied in alphanumerical order based
+ on the Tier "Name".
+ type: number
+ type: object
+ type: object
+ served: true
+ storage: true
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ api-approved.kubernetes.io: https://github.com/kubernetes-sigs/network-policy-api/pull/30
+ policy.networking.k8s.io/bundle-version: v0.1.1
+ policy.networking.k8s.io/channel: experimental
+ creationTimestamp: null
+ name: adminnetworkpolicies.policy.networking.k8s.io
+spec:
+ group: policy.networking.k8s.io
+ names:
+ kind: AdminNetworkPolicy
+ listKind: AdminNetworkPolicyList
+ plural: adminnetworkpolicies
+ shortNames:
+ - anp
+ singular: adminnetworkpolicy
+ scope: Cluster
+ versions:
+ - additionalPrinterColumns:
+ - jsonPath: .spec.priority
+ name: Priority
+ type: string
+ - jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
+ name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: |-
+ AdminNetworkPolicy is a cluster level resource that is part of the
+ AdminNetworkPolicy API.
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: Specification of the desired behavior of AdminNetworkPolicy.
+ properties:
+ egress:
+ description: |-
+ Egress is the list of Egress rules to be applied to the selected pods.
+ A total of 100 rules will be allowed in each ANP instance.
+ The relative precedence of egress rules within a single ANP object (all of
+ which share the priority) will be determined by the order in which the rule
+ is written. Thus, a rule that appears at the top of the egress rules
+ would take the highest precedence.
+ ANPs with no egress rules do not affect egress traffic.
+
+
+ Support: Core
+ items:
+ description: |-
+ AdminNetworkPolicyEgressRule describes an action to take on a particular
+ set of traffic originating from pods selected by a AdminNetworkPolicy's
+ Subject field.
+
+ properties:
+ action:
+ description: |-
+ Action specifies the effect this rule will have on matching traffic.
+ Currently the following actions are supported:
+ Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy)
+ Deny: denies the selected traffic
+ Pass: instructs the selected traffic to skip any remaining ANP rules, and
+ then pass execution to any NetworkPolicies that select the pod.
+ If the pod is not selected by any NetworkPolicies then execution
+ is passed to any BaselineAdminNetworkPolicies that select the pod.
+
+
+ Support: Core
+ enum:
+ - Allow
+ - Deny
+ - Pass
+ type: string
+ name:
+ description: |-
+ Name is an identifier for this rule, that may be no more than 100 characters
+ in length. This field should be used by the implementation to help
+ improve observability, readability and error-reporting for any applied
+ AdminNetworkPolicies.
+
+
+ Support: Core
+ maxLength: 100
+ type: string
+ ports:
+ description: |-
+ Ports allows for matching traffic based on port and protocols.
+ This field is a list of destination ports for the outgoing egress traffic.
+ If Ports is not set then the rule does not filter traffic via port.
+
+
+ Support: Core
+ items:
+ description: |-
+ AdminNetworkPolicyPort describes how to select network ports on pod(s).
+ Exactly one field must be set.
+ maxProperties: 1
+ minProperties: 1
+ properties:
+ namedPort:
+ description: |-
+ NamedPort selects a port on a pod(s) based on name.
+
+
+ Support: Extended
+
+
+
+ type: string
+ portNumber:
+ description: |-
+ Port selects a port on a pod(s) based on number.
+
+
+ Support: Core
+ properties:
+ port:
+ description: |-
+ Number defines a network port value.
+
+
+ Support: Core
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ protocol:
+ default: TCP
+ description: |-
+ Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must
+ match. If not specified, this field defaults to TCP.
+
+
+ Support: Core
+ type: string
+ required:
+ - port
+ - protocol
+ type: object
+ portRange:
+ description: |-
+ PortRange selects a port range on a pod(s) based on provided start and end
+ values.
+
+
+ Support: Core
+ properties:
+ end:
+ description: |-
+ End defines a network port that is the end of a port range, the End value
+ must be greater than Start.
+
+
+ Support: Core
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ protocol:
+ default: TCP
+ description: |-
+ Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must
+ match. If not specified, this field defaults to TCP.
+
+
+ Support: Core
+ type: string
+ start:
+ description: |-
+ Start defines a network port that is the start of a port range, the Start
+ value must be less than End.
+
+
+ Support: Core
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - end
+ - start
+ type: object
+ type: object
+ maxItems: 100
+ type: array
+ to:
+ description: |-
+ To is the List of destinations whose traffic this rule applies to.
+ If any AdminNetworkPolicyEgressPeer matches the destination of outgoing
+ traffic then the specified action is applied.
+ This field must be defined and contain at least one item.
+
+
+ Support: Core
+ items:
+ description: |-
+ AdminNetworkPolicyEgressPeer defines a peer to allow traffic to.
+ Exactly one of the selector pointers must be set for a given peer. If a
+ consumer observes none of its fields are set, they must assume an unknown
+ option has been specified and fail closed.
+ maxProperties: 1
+ minProperties: 1
+ properties:
+ namespaces:
+ description: |-
+ Namespaces defines a way to select all pods within a set of Namespaces.
+ Note that host-networked pods are not included in this type of peer.
+
+
+ Support: Core
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ networks:
+ description: |-
+ Networks defines a way to select peers via CIDR blocks.
+ This is intended for representing entities that live outside the cluster,
+ which can't be selected by pods, namespaces and nodes peers, but note
+ that cluster-internal traffic will be checked against the rule as
+ well. So if you Allow or Deny traffic to `"0.0.0.0/0"`, that will allow
+ or deny all IPv4 pod-to-pod traffic as well. If you don't want that,
+ add a rule that Passes all pod traffic before the Networks rule.
+
+
+ Each item in Networks should be provided in the CIDR format and should be
+ IPv4 or IPv6, for example "10.0.0.0/8" or "fd00::/8".
+
+
+ Networks can have upto 25 CIDRs specified.
+
+
+ Support: Extended
+
+
+
+ items:
+ description: |-
+ CIDR is an IP address range in CIDR notation (for example, "10.0.0.0/8" or "fd00::/8").
+ This string must be validated by implementations using net.ParseCIDR
+ TODO: Introduce CEL CIDR validation regex isCIDR() in Kube 1.31 when it is available.
+ maxLength: 43
+ type: string
+ x-kubernetes-validations:
+ - message: CIDR must be either an IPv4 or IPv6 address.
+ IPv4 address embedded in IPv6 addresses are not
+ supported
+ rule: self.contains(':') != self.contains('.')
+ maxItems: 25
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: set
+ nodes:
+ description: |-
+ Nodes defines a way to select a set of nodes in
+ the cluster. This field follows standard label selector
+ semantics; if present but empty, it selects all Nodes.
+
+
+ Support: Extended
+
+
+
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ pods:
+ description: |-
+ Pods defines a way to select a set of pods in
+ a set of namespaces. Note that host-networked pods
+ are not included in this type of peer.
+
+
+ Support: Core
+ properties:
+ namespaceSelector:
+ description: |-
+ NamespaceSelector follows standard label selector semantics; if empty,
+ it selects all Namespaces.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are
+ ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the
+ selector applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ podSelector:
+ description: |-
+ PodSelector is used to explicitly select pods within a namespace; if empty,
+ it selects all Pods.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are
+ ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the
+ selector applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - namespaceSelector
+ - podSelector
+ type: object
+ type: object
+ maxItems: 100
+ minItems: 1
+ type: array
+ required:
+ - action
+ - to
+ type: object
+ x-kubernetes-validations:
+ - message: networks/nodes peer cannot be set with namedPorts since
+ there are no namedPorts for networks/nodes
+ rule: '!(self.to.exists(peer, has(peer.networks) || has(peer.nodes))
+ && has(self.ports) && self.ports.exists(port, has(port.namedPort)))'
+ maxItems: 100
+ type: array
+ ingress:
+ description: |-
+ Ingress is the list of Ingress rules to be applied to the selected pods.
+ A total of 100 rules will be allowed in each ANP instance.
+ The relative precedence of ingress rules within a single ANP object (all of
+ which share the priority) will be determined by the order in which the rule
+ is written. Thus, a rule that appears at the top of the ingress rules
+ would take the highest precedence.
+ ANPs with no ingress rules do not affect ingress traffic.
+
+
+ Support: Core
+ items:
+ description: |-
+ AdminNetworkPolicyIngressRule describes an action to take on a particular
+ set of traffic destined for pods selected by an AdminNetworkPolicy's
+ Subject field.
+ properties:
+ action:
+ description: |-
+ Action specifies the effect this rule will have on matching traffic.
+ Currently the following actions are supported:
+ Allow: allows the selected traffic (even if it would otherwise have been denied by NetworkPolicy)
+ Deny: denies the selected traffic
+ Pass: instructs the selected traffic to skip any remaining ANP rules, and
+ then pass execution to any NetworkPolicies that select the pod.
+ If the pod is not selected by any NetworkPolicies then execution
+ is passed to any BaselineAdminNetworkPolicies that select the pod.
+
+
+ Support: Core
+ enum:
+ - Allow
+ - Deny
+ - Pass
+ type: string
+ from:
+ description: |-
+ From is the list of sources whose traffic this rule applies to.
+ If any AdminNetworkPolicyIngressPeer matches the source of incoming
+ traffic then the specified action is applied.
+ This field must be defined and contain at least one item.
+
+
+ Support: Core
+ items:
+ description: |-
+ AdminNetworkPolicyIngressPeer defines an in-cluster peer to allow traffic from.
+ Exactly one of the selector pointers must be set for a given peer. If a
+ consumer observes none of its fields are set, they must assume an unknown
+ option has been specified and fail closed.
+ maxProperties: 1
+ minProperties: 1
+ properties:
+ namespaces:
+ description: |-
+ Namespaces defines a way to select all pods within a set of Namespaces.
+ Note that host-networked pods are not included in this type of peer.
+
+
+ Support: Core
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ pods:
+ description: |-
+ Pods defines a way to select a set of pods in
+ a set of namespaces. Note that host-networked pods
+ are not included in this type of peer.
+
+
+ Support: Core
+ properties:
+ namespaceSelector:
+ description: |-
+ NamespaceSelector follows standard label selector semantics; if empty,
+ it selects all Namespaces.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are
+ ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the
+ selector applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ podSelector:
+ description: |-
+ PodSelector is used to explicitly select pods within a namespace; if empty,
+ it selects all Pods.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are
+ ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the
+ selector applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - namespaceSelector
+ - podSelector
+ type: object
+ type: object
+ maxItems: 100
+ minItems: 1
+ type: array
+ name:
+ description: |-
+ Name is an identifier for this rule, that may be no more than 100 characters
+ in length. This field should be used by the implementation to help
+ improve observability, readability and error-reporting for any applied
+ AdminNetworkPolicies.
+
+
+ Support: Core
+ maxLength: 100
+ type: string
+ ports:
+ description: |-
+ Ports allows for matching traffic based on port and protocols.
+ This field is a list of ports which should be matched on
+ the pods selected for this policy i.e the subject of the policy.
+ So it matches on the destination port for the ingress traffic.
+ If Ports is not set then the rule does not filter traffic via port.
+
+
+ Support: Core
+ items:
+ description: |-
+ AdminNetworkPolicyPort describes how to select network ports on pod(s).
+ Exactly one field must be set.
+ maxProperties: 1
+ minProperties: 1
+ properties:
+ namedPort:
+ description: |-
+ NamedPort selects a port on a pod(s) based on name.
+
+
+ Support: Extended
+
+
+
+ type: string
+ portNumber:
+ description: |-
+ Port selects a port on a pod(s) based on number.
+
+
+ Support: Core
+ properties:
+ port:
+ description: |-
+ Number defines a network port value.
+
+
+ Support: Core
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ protocol:
+ default: TCP
+ description: |-
+ Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must
+ match. If not specified, this field defaults to TCP.
+
+
+ Support: Core
+ type: string
+ required:
+ - port
+ - protocol
+ type: object
+ portRange:
+ description: |-
+ PortRange selects a port range on a pod(s) based on provided start and end
+ values.
+
+
+ Support: Core
+ properties:
+ end:
+ description: |-
+ End defines a network port that is the end of a port range, the End value
+ must be greater than Start.
+
+
+ Support: Core
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ protocol:
+ default: TCP
+ description: |-
+ Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must
+ match. If not specified, this field defaults to TCP.
+
+
+ Support: Core
+ type: string
+ start:
+ description: |-
+ Start defines a network port that is the start of a port range, the Start
+ value must be less than End.
+
+
+ Support: Core
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - end
+ - start
+ type: object
+ type: object
+ maxItems: 100
+ type: array
+ required:
+ - action
+ - from
+ type: object
+ maxItems: 100
+ type: array
+ priority:
+ description: |-
+ Priority is a value from 0 to 1000. Rules with lower priority values have
+ higher precedence, and are checked before rules with higher priority values.
+ All AdminNetworkPolicy rules have higher precedence than NetworkPolicy or
+ BaselineAdminNetworkPolicy rules
+ The behavior is undefined if two ANP objects have same priority.
+
+
+ Support: Core
+ format: int32
+ maximum: 1000
+ minimum: 0
+ type: integer
+ subject:
+ description: |-
+ Subject defines the pods to which this AdminNetworkPolicy applies.
+ Note that host-networked pods are not included in subject selection.
+
+
+ Support: Core
+ maxProperties: 1
+ minProperties: 1
+ properties:
+ namespaces:
+ description: Namespaces is used to select pods via namespace selectors.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ pods:
+ description: Pods is used to select pods via namespace AND pod
+ selectors.
+ properties:
+ namespaceSelector:
+ description: |-
+ NamespaceSelector follows standard label selector semantics; if empty,
+ it selects all Namespaces.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ podSelector:
+ description: |-
+ PodSelector is used to explicitly select pods within a namespace; if empty,
+ it selects all Pods.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - namespaceSelector
+ - podSelector
+ type: object
+ type: object
+ required:
+ - priority
+ - subject
+ type: object
+ status:
+ description: Status is the status to be reported by the implementation.
+ properties:
+ conditions:
+ items:
+ description: "Condition contains details for one aspect of the current
+ state of this API Resource.\n---\nThis struct is intended for
+ direct use as an array at the field path .status.conditions. For
+ example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
+ observations of a foo's current state.\n\t // Known .status.conditions.type
+ are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
+ +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
+ \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
+ patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
+ \ // other fields\n\t}"
+ properties:
+ lastTransitionTime:
+ description: |-
+ lastTransitionTime is the last time the condition transitioned from one status to another.
+ This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ format: date-time
+ type: string
+ message:
+ description: |-
+ message is a human readable message indicating details about the transition.
+ This may be an empty string.
+ maxLength: 32768
+ type: string
+ observedGeneration:
+ description: |-
+ observedGeneration represents the .metadata.generation that the condition was set based upon.
+ For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
+ with respect to the current state of the instance.
+ format: int64
+ minimum: 0
+ type: integer
+ reason:
+ description: |-
+ reason contains a programmatic identifier indicating the reason for the condition's last transition.
+ Producers of specific condition types may define expected values and meanings for this field,
+ and whether the values are considered a guaranteed API.
+ The value should be a CamelCase string.
+ This field may not be empty.
+ maxLength: 1024
+ minLength: 1
+ pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+ type: string
+ status:
+ description: status of the condition, one of True, False, Unknown.
+ enum:
+ - "True"
+ - "False"
+ - Unknown
+ type: string
+ type:
+ description: |-
+ type of condition in CamelCase or in foo.example.com/CamelCase.
+ ---
+ Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
+ useful (see .node.status.conditions), the ability to deconflict is important.
+ The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ maxLength: 316
+ pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+ type: string
+ required:
+ - lastTransitionTime
+ - message
+ - reason
+ - status
+ - type
+ type: object
+ type: array
+ x-kubernetes-list-map-keys:
+ - type
+ x-kubernetes-list-type: map
+ required:
+ - conditions
+ type: object
+ required:
+ - metadata
+ - spec
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
+status:
+ acceptedNames:
+ kind: ""
+ plural: ""
+ conditions: null
+ storedVersions: null
+---
+# Source: calico/templates/kdd-crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ api-approved.kubernetes.io: https://github.com/kubernetes-sigs/network-policy-api/pull/30
+ policy.networking.k8s.io/bundle-version: v0.1.1
+ policy.networking.k8s.io/channel: experimental
+ creationTimestamp: null
+ name: baselineadminnetworkpolicies.policy.networking.k8s.io
+spec:
+ group: policy.networking.k8s.io
+ names:
+ kind: BaselineAdminNetworkPolicy
+ listKind: BaselineAdminNetworkPolicyList
+ plural: baselineadminnetworkpolicies
+ shortNames:
+ - banp
+ singular: baselineadminnetworkpolicy
+ scope: Cluster
+ versions:
+ - additionalPrinterColumns:
+ - jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
+ name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: |-
+ BaselineAdminNetworkPolicy is a cluster level resource that is part of the
+ AdminNetworkPolicy API.
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: Specification of the desired behavior of BaselineAdminNetworkPolicy.
+ properties:
+ egress:
+ description: |-
+ Egress is the list of Egress rules to be applied to the selected pods if
+ they are not matched by any AdminNetworkPolicy or NetworkPolicy rules.
+ A total of 100 Egress rules will be allowed in each BANP instance.
+ The relative precedence of egress rules within a single BANP object
+ will be determined by the order in which the rule is written.
+ Thus, a rule that appears at the top of the egress rules
+ would take the highest precedence.
+ BANPs with no egress rules do not affect egress traffic.
+
+
+ Support: Core
+ items:
+ description: |-
+ BaselineAdminNetworkPolicyEgressRule describes an action to take on a particular
+ set of traffic originating from pods selected by a BaselineAdminNetworkPolicy's
+ Subject field.
+
+ properties:
+ action:
+ description: |-
+ Action specifies the effect this rule will have on matching traffic.
+ Currently the following actions are supported:
+ Allow: allows the selected traffic
+ Deny: denies the selected traffic
+
+
+ Support: Core
+ enum:
+ - Allow
+ - Deny
+ type: string
+ name:
+ description: |-
+ Name is an identifier for this rule, that may be no more than 100 characters
+ in length. This field should be used by the implementation to help
+ improve observability, readability and error-reporting for any applied
+ BaselineAdminNetworkPolicies.
+
+
+ Support: Core
+ maxLength: 100
+ type: string
+ ports:
+ description: |-
+ Ports allows for matching traffic based on port and protocols.
+ This field is a list of destination ports for the outgoing egress traffic.
+ If Ports is not set then the rule does not filter traffic via port.
+ items:
+ description: |-
+ AdminNetworkPolicyPort describes how to select network ports on pod(s).
+ Exactly one field must be set.
+ maxProperties: 1
+ minProperties: 1
+ properties:
+ namedPort:
+ description: |-
+ NamedPort selects a port on a pod(s) based on name.
+
+
+ Support: Extended
+
+
+
+ type: string
+ portNumber:
+ description: |-
+ Port selects a port on a pod(s) based on number.
+
+
+ Support: Core
+ properties:
+ port:
+ description: |-
+ Number defines a network port value.
+
+
+ Support: Core
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ protocol:
+ default: TCP
+ description: |-
+ Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must
+ match. If not specified, this field defaults to TCP.
+
+
+ Support: Core
+ type: string
+ required:
+ - port
+ - protocol
+ type: object
+ portRange:
+ description: |-
+ PortRange selects a port range on a pod(s) based on provided start and end
+ values.
+
+
+ Support: Core
+ properties:
+ end:
+ description: |-
+ End defines a network port that is the end of a port range, the End value
+ must be greater than Start.
+
+
+ Support: Core
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ protocol:
+ default: TCP
+ description: |-
+ Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must
+ match. If not specified, this field defaults to TCP.
+
+
+ Support: Core
+ type: string
+ start:
+ description: |-
+ Start defines a network port that is the start of a port range, the Start
+ value must be less than End.
+
+
+ Support: Core
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - end
+ - start
+ type: object
+ type: object
+ maxItems: 100
+ type: array
+ to:
+ description: |-
+ To is the list of destinations whose traffic this rule applies to.
+ If any AdminNetworkPolicyEgressPeer matches the destination of outgoing
+ traffic then the specified action is applied.
+ This field must be defined and contain at least one item.
+
+
+ Support: Core
+ items:
+ description: |-
+ AdminNetworkPolicyEgressPeer defines a peer to allow traffic to.
+ Exactly one of the selector pointers must be set for a given peer. If a
+ consumer observes none of its fields are set, they must assume an unknown
+ option has been specified and fail closed.
+ maxProperties: 1
+ minProperties: 1
+ properties:
+ namespaces:
+ description: |-
+ Namespaces defines a way to select all pods within a set of Namespaces.
+ Note that host-networked pods are not included in this type of peer.
+
+
+ Support: Core
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ networks:
+ description: |-
+ Networks defines a way to select peers via CIDR blocks.
+ This is intended for representing entities that live outside the cluster,
+ which can't be selected by pods, namespaces and nodes peers, but note
+ that cluster-internal traffic will be checked against the rule as
+ well. So if you Allow or Deny traffic to `"0.0.0.0/0"`, that will allow
+ or deny all IPv4 pod-to-pod traffic as well. If you don't want that,
+ add a rule that Passes all pod traffic before the Networks rule.
+
+
+ Each item in Networks should be provided in the CIDR format and should be
+ IPv4 or IPv6, for example "10.0.0.0/8" or "fd00::/8".
+
+
+ Networks can have upto 25 CIDRs specified.
+
+
+ Support: Extended
+
+
+
+ items:
+ description: |-
+ CIDR is an IP address range in CIDR notation (for example, "10.0.0.0/8" or "fd00::/8").
+ This string must be validated by implementations using net.ParseCIDR
+ TODO: Introduce CEL CIDR validation regex isCIDR() in Kube 1.31 when it is available.
+ maxLength: 43
+ type: string
+ x-kubernetes-validations:
+ - message: CIDR must be either an IPv4 or IPv6 address.
+ IPv4 address embedded in IPv6 addresses are not
+ supported
+ rule: self.contains(':') != self.contains('.')
+ maxItems: 25
+ minItems: 1
+ type: array
+ x-kubernetes-list-type: set
+ nodes:
+ description: |-
+ Nodes defines a way to select a set of nodes in
+ the cluster. This field follows standard label selector
+ semantics; if present but empty, it selects all Nodes.
+
+
+ Support: Extended
+
+
+
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ pods:
+ description: |-
+ Pods defines a way to select a set of pods in
+ a set of namespaces. Note that host-networked pods
+ are not included in this type of peer.
+
+
+ Support: Core
+ properties:
+ namespaceSelector:
+ description: |-
+ NamespaceSelector follows standard label selector semantics; if empty,
+ it selects all Namespaces.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are
+ ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the
+ selector applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ podSelector:
+ description: |-
+ PodSelector is used to explicitly select pods within a namespace; if empty,
+ it selects all Pods.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are
+ ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the
+ selector applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - namespaceSelector
+ - podSelector
+ type: object
+ type: object
+ maxItems: 100
+ minItems: 1
+ type: array
+ required:
+ - action
+ - to
+ type: object
+ x-kubernetes-validations:
+ - message: networks/nodes peer cannot be set with namedPorts since
+ there are no namedPorts for networks/nodes
+ rule: '!(self.to.exists(peer, has(peer.networks) || has(peer.nodes))
+ && has(self.ports) && self.ports.exists(port, has(port.namedPort)))'
+ maxItems: 100
+ type: array
+ ingress:
+ description: |-
+ Ingress is the list of Ingress rules to be applied to the selected pods
+ if they are not matched by any AdminNetworkPolicy or NetworkPolicy rules.
+ A total of 100 Ingress rules will be allowed in each BANP instance.
+ The relative precedence of ingress rules within a single BANP object
+ will be determined by the order in which the rule is written.
+ Thus, a rule that appears at the top of the ingress rules
+ would take the highest precedence.
+ BANPs with no ingress rules do not affect ingress traffic.
+
+
+ Support: Core
+ items:
+ description: |-
+ BaselineAdminNetworkPolicyIngressRule describes an action to take on a particular
+ set of traffic destined for pods selected by a BaselineAdminNetworkPolicy's
+ Subject field.
+ properties:
+ action:
+ description: |-
+ Action specifies the effect this rule will have on matching traffic.
+ Currently the following actions are supported:
+ Allow: allows the selected traffic
+ Deny: denies the selected traffic
+
+
+ Support: Core
+ enum:
+ - Allow
+ - Deny
+ type: string
+ from:
+ description: |-
+ From is the list of sources whose traffic this rule applies to.
+ If any AdminNetworkPolicyIngressPeer matches the source of incoming
+ traffic then the specified action is applied.
+ This field must be defined and contain at least one item.
+
+
+ Support: Core
+ items:
+ description: |-
+ AdminNetworkPolicyIngressPeer defines an in-cluster peer to allow traffic from.
+ Exactly one of the selector pointers must be set for a given peer. If a
+ consumer observes none of its fields are set, they must assume an unknown
+ option has been specified and fail closed.
+ maxProperties: 1
+ minProperties: 1
+ properties:
+ namespaces:
+ description: |-
+ Namespaces defines a way to select all pods within a set of Namespaces.
+ Note that host-networked pods are not included in this type of peer.
+
+
+ Support: Core
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ pods:
+ description: |-
+ Pods defines a way to select a set of pods in
+ a set of namespaces. Note that host-networked pods
+ are not included in this type of peer.
+
+
+ Support: Core
+ properties:
+ namespaceSelector:
+ description: |-
+ NamespaceSelector follows standard label selector semantics; if empty,
+ it selects all Namespaces.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are
+ ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the
+ selector applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ podSelector:
+ description: |-
+ PodSelector is used to explicitly select pods within a namespace; if empty,
+ it selects all Pods.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are
+ ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the
+ selector applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - namespaceSelector
+ - podSelector
+ type: object
+ type: object
+ maxItems: 100
+ minItems: 1
+ type: array
+ name:
+ description: |-
+ Name is an identifier for this rule, that may be no more than 100 characters
+ in length. This field should be used by the implementation to help
+ improve observability, readability and error-reporting for any applied
+ BaselineAdminNetworkPolicies.
+
+
+ Support: Core
+ maxLength: 100
+ type: string
+ ports:
+ description: |-
+ Ports allows for matching traffic based on port and protocols.
+ This field is a list of ports which should be matched on
+ the pods selected for this policy i.e the subject of the policy.
+ So it matches on the destination port for the ingress traffic.
+ If Ports is not set then the rule does not filter traffic via port.
+
+
+ Support: Core
+ items:
+ description: |-
+ AdminNetworkPolicyPort describes how to select network ports on pod(s).
+ Exactly one field must be set.
+ maxProperties: 1
+ minProperties: 1
+ properties:
+ namedPort:
+ description: |-
+ NamedPort selects a port on a pod(s) based on name.
+
+
+ Support: Extended
+
+
+
+ type: string
+ portNumber:
+ description: |-
+ Port selects a port on a pod(s) based on number.
+
+
+ Support: Core
+ properties:
+ port:
+ description: |-
+ Number defines a network port value.
+
+
+ Support: Core
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ protocol:
+ default: TCP
+ description: |-
+ Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must
+ match. If not specified, this field defaults to TCP.
+
+
+ Support: Core
+ type: string
+ required:
+ - port
+ - protocol
+ type: object
+ portRange:
+ description: |-
+ PortRange selects a port range on a pod(s) based on provided start and end
+ values.
+
+
+ Support: Core
+ properties:
+ end:
+ description: |-
+ End defines a network port that is the end of a port range, the End value
+ must be greater than Start.
+
+
+ Support: Core
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ protocol:
+ default: TCP
+ description: |-
+ Protocol is the network protocol (TCP, UDP, or SCTP) which traffic must
+ match. If not specified, this field defaults to TCP.
+
+
+ Support: Core
+ type: string
+ start:
+ description: |-
+ Start defines a network port that is the start of a port range, the Start
+ value must be less than End.
+
+
+ Support: Core
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - end
+ - start
+ type: object
+ type: object
+ maxItems: 100
+ type: array
+ required:
+ - action
+ - from
+ type: object
+ maxItems: 100
+ type: array
+ subject:
+ description: |-
+ Subject defines the pods to which this BaselineAdminNetworkPolicy applies.
+ Note that host-networked pods are not included in subject selection.
+
+
+ Support: Core
+ maxProperties: 1
+ minProperties: 1
+ properties:
+ namespaces:
+ description: Namespaces is used to select pods via namespace selectors.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ pods:
+ description: Pods is used to select pods via namespace AND pod
+ selectors.
+ properties:
+ namespaceSelector:
+ description: |-
+ NamespaceSelector follows standard label selector semantics; if empty,
+ it selects all Namespaces.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ podSelector:
+ description: |-
+ PodSelector is used to explicitly select pods within a namespace; if empty,
+ it selects all Pods.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
+ required:
+ - namespaceSelector
+ - podSelector
+ type: object
+ type: object
+ required:
+ - subject
+ type: object
+ status:
+ description: Status is the status to be reported by the implementation.
+ properties:
+ conditions:
+ items:
+ description: "Condition contains details for one aspect of the current
+ state of this API Resource.\n---\nThis struct is intended for
+ direct use as an array at the field path .status.conditions. For
+ example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
+ observations of a foo's current state.\n\t // Known .status.conditions.type
+ are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
+ +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
+ \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
+ patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
+ \ // other fields\n\t}"
+ properties:
+ lastTransitionTime:
+ description: |-
+ lastTransitionTime is the last time the condition transitioned from one status to another.
+ This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ format: date-time
+ type: string
+ message:
+ description: |-
+ message is a human readable message indicating details about the transition.
+ This may be an empty string.
+ maxLength: 32768
+ type: string
+ observedGeneration:
+ description: |-
+ observedGeneration represents the .metadata.generation that the condition was set based upon.
+ For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
+ with respect to the current state of the instance.
+ format: int64
+ minimum: 0
+ type: integer
+ reason:
+ description: |-
+ reason contains a programmatic identifier indicating the reason for the condition's last transition.
+ Producers of specific condition types may define expected values and meanings for this field,
+ and whether the values are considered a guaranteed API.
+ The value should be a CamelCase string.
+ This field may not be empty.
+ maxLength: 1024
+ minLength: 1
+ pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+ type: string
+ status:
+ description: status of the condition, one of True, False, Unknown.
+ enum:
+ - "True"
+ - "False"
+ - Unknown
+ type: string
+ type:
+ description: |-
+ type of condition in CamelCase or in foo.example.com/CamelCase.
+ ---
+ Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
+ useful (see .node.status.conditions), the ability to deconflict is important.
+ The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ maxLength: 316
+ pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+ type: string
+ required:
+ - lastTransitionTime
+ - message
+ - reason
+ - status
+ - type
+ type: object
+ type: array
+ x-kubernetes-list-map-keys:
+ - type
+ x-kubernetes-list-type: map
+ required:
+ - conditions
+ type: object
+ required:
+ - metadata
+ - spec
+ type: object
+ x-kubernetes-validations:
+ - message: Only one baseline admin network policy with metadata.name="default"
+ can be created in the cluster
+ rule: self.metadata.name == 'default'
+ served: true
+ storage: true
+ subresources:
+ status: {}
+status:
+ acceptedNames:
+ kind: ""
+ plural: ""
+ conditions: null
+ storedVersions: null
+---
+# Source: calico/templates/calico-kube-controllers-rbac.yaml
+# Include a clusterrole for the kube-controllers component,
+# and bind it to the calico-kube-controllers serviceaccount.
+kind: ClusterRole
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+ name: calico-kube-controllers
+rules:
+ # Nodes are watched to monitor for deletions.
+ - apiGroups: [""]
+ resources:
+ - nodes
+ verbs:
+ - watch
+ - list
+ - get
+ # Pods are watched to check for existence as part of IPAM controller.
+ - apiGroups: [""]
+ resources:
+ - pods
+ verbs:
+ - get
+ - list
+ - watch
+ # Services are monitored for service LoadBalancer IP allocation
+ - apiGroups: [""]
+ resources:
+ - services
+ - services/status
+ verbs:
+ - get
+ - list
+ - update
+ - watch
+ # IPAM resources are manipulated in response to node and block updates, as well as periodic triggers.
+ - apiGroups: ["crd.projectcalico.org"]
+ resources:
+ - ipreservations
+ verbs:
+ - list
+ - apiGroups: ["crd.projectcalico.org"]
+ resources:
+ - blockaffinities
+ - ipamblocks
+ - ipamhandles
+ - ipamconfigs
+ - tiers
+ verbs:
+ - get
+ - list
+ - create
+ - update
+ - delete
+ - watch
+ # Pools are watched to maintain a mapping of blocks to IP pools.
+ - apiGroups: ["crd.projectcalico.org"]
+ resources:
+ - ippools
+ verbs:
+ - list
+ - watch
+ # kube-controllers manages hostendpoints.
+ - apiGroups: ["crd.projectcalico.org"]
+ resources:
+ - hostendpoints
+ verbs:
+ - get
+ - list
+ - create
+ - update
+ - delete
+ # Needs access to update clusterinformations.
+ - apiGroups: ["crd.projectcalico.org"]
+ resources:
+ - clusterinformations
+ verbs:
+ - get
+ - list
+ - create
+ - update
+ - watch
+ # KubeControllersConfiguration is where it gets its config
+ - apiGroups: ["crd.projectcalico.org"]
+ resources:
+ - kubecontrollersconfigurations
+ verbs:
+ # read its own config
+ - get
+ # create a default if none exists
+ - create
+ # update status
+ - update
+ # watch for changes
+ - watch
+---
+# Source: calico/templates/calico-node-rbac.yaml
+# Include a clusterrole for the calico-node DaemonSet,
+# and bind it to the calico-node serviceaccount.
+kind: ClusterRole
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+ name: calico-node
+rules:
+ # Used for creating service account tokens to be used by the CNI plugin
+ - apiGroups: [""]
+ resources:
+ - serviceaccounts/token
+ resourceNames:
+ - calico-cni-plugin
+ verbs:
+ - create
+ # The CNI plugin needs to get pods, nodes, and namespaces.
+ - apiGroups: [""]
+ resources:
+ - pods
+ - nodes
+ - namespaces
+ verbs:
+ - get
+ # EndpointSlices are used for Service-based network policy rule
+ # enforcement.
+ - apiGroups: ["discovery.k8s.io"]
+ resources:
+ - endpointslices
+ verbs:
+ - watch
+ - list
+ - apiGroups: [""]
+ resources:
+ - endpoints
+ - services
+ verbs:
+ # Used to discover service IPs for advertisement.
+ - watch
+ - list
+ # Used to discover Typhas.
+ - get
+ # Pod CIDR auto-detection on kubeadm needs access to config maps.
+ - apiGroups: [""]
+ resources:
+ - configmaps
+ verbs:
+ - get
+ - apiGroups: [""]
+ resources:
+ - nodes/status
+ verbs:
+ # Needed for clearing NodeNetworkUnavailable flag.
+ - patch
+ # Calico stores some configuration information in node annotations.
+ - update
+ # Watch for changes to Kubernetes NetworkPolicies.
+ - apiGroups: ["networking.k8s.io"]
+ resources:
+ - networkpolicies
+ verbs:
+ - watch
+ - list
+ # Watch for changes to Kubernetes (Baseline)AdminNetworkPolicies.
+ - apiGroups: ["policy.networking.k8s.io"]
+ resources:
+ - adminnetworkpolicies
+ - baselineadminnetworkpolicies
+ verbs:
+ - watch
+ - list
+ # Used by Calico for policy information.
+ - apiGroups: [""]
+ resources:
+ - pods
+ - namespaces
+ - serviceaccounts
+ verbs:
+ - list
+ - watch
+ # The CNI plugin patches pods/status.
+ - apiGroups: [""]
+ resources:
+ - pods/status
+ verbs:
+ - patch
+ # Calico monitors various CRDs for config.
+ - apiGroups: ["crd.projectcalico.org"]
+ resources:
+ - globalfelixconfigs
+ - felixconfigurations
+ - bgppeers
+ - bgpfilters
+ - globalbgpconfigs
+ - bgpconfigurations
+ - ippools
+ - ipreservations
+ - ipamblocks
+ - globalnetworkpolicies
+ - globalnetworksets
+ - networkpolicies
+ - networksets
+ - clusterinformations
+ - hostendpoints
+ - blockaffinities
+ - caliconodestatuses
+ - tiers
+ verbs:
+ - get
+ - list
+ - watch
+ # Calico creates some tiers on startup.
+ - apiGroups: ["crd.projectcalico.org"]
+ resources:
+ - tiers
+ verbs:
+ - create
+ # Calico must create and update some CRDs on startup.
+ - apiGroups: ["crd.projectcalico.org"]
+ resources:
+ - ippools
+ - felixconfigurations
+ - clusterinformations
+ verbs:
+ - create
+ - update
+ # Calico must update some CRDs.
+ - apiGroups: ["crd.projectcalico.org"]
+ resources:
+ - caliconodestatuses
+ verbs:
+ - update
+ # Calico stores some configuration information on the node.
+ - apiGroups: [""]
+ resources:
+ - nodes
+ verbs:
+ - get
+ - list
+ - watch
+ # These permissions are only required for upgrade from v2.6, and can
+ # be removed after upgrade or on fresh installations.
+ - apiGroups: ["crd.projectcalico.org"]
+ resources:
+ - bgpconfigurations
+ - bgppeers
+ verbs:
+ - create
+ - update
+ # These permissions are required for Calico CNI to perform IPAM allocations.
+ - apiGroups: ["crd.projectcalico.org"]
+ resources:
+ - blockaffinities
+ - ipamblocks
+ - ipamhandles
+ verbs:
+ - get
+ - list
+ - create
+ - update
+ - delete
+ # The CNI plugin and calico/node need to be able to create a default
+ # IPAMConfiguration
+ - apiGroups: ["crd.projectcalico.org"]
+ resources:
+ - ipamconfigs
+ verbs:
+ - get
+ - create
+ # Block affinities must also be watchable by confd for route aggregation.
+ - apiGroups: ["crd.projectcalico.org"]
+ resources:
+ - blockaffinities
+ verbs:
+ - watch
+ # The Calico IPAM migration needs to get daemonsets. These permissions can be
+ # removed if not upgrading from an installation using host-local IPAM.
+ - apiGroups: ["apps"]
+ resources:
+ - daemonsets
+ verbs:
+ - get
+---
+# Source: calico/templates/calico-node-rbac.yaml
+# CNI cluster role
+kind: ClusterRole
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+ name: calico-cni-plugin
+rules:
+ - apiGroups: [""]
+ resources:
+ - pods
+ - nodes
+ - namespaces
+ verbs:
+ - get
+ - apiGroups: [""]
+ resources:
+ - pods/status
+ verbs:
+ - patch
+ - apiGroups: ["crd.projectcalico.org"]
+ resources:
+ - blockaffinities
+ - ipamblocks
+ - ipamhandles
+ - clusterinformations
+ - ippools
+ - ipreservations
+ - ipamconfigs
+ verbs:
+ - get
+ - list
+ - create
+ - update
+ - delete
+---
+# Source: calico/templates/calico-kube-controllers-rbac.yaml
+kind: ClusterRoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+ name: calico-kube-controllers
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: calico-kube-controllers
+subjects:
+- kind: ServiceAccount
+ name: calico-kube-controllers
+ namespace: kube-system
+---
+# Source: calico/templates/calico-node-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: calico-node
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: calico-node
+subjects:
+- kind: ServiceAccount
+ name: calico-node
+ namespace: kube-system
+---
+# Source: calico/templates/calico-node-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: calico-cni-plugin
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: calico-cni-plugin
+subjects:
+- kind: ServiceAccount
+ name: calico-cni-plugin
+ namespace: kube-system
+---
+# Source: calico/templates/calico-node.yaml
+# This manifest installs the calico-node container, as well
+# as the CNI plugins and network config on
+# each master and worker node in a Kubernetes cluster.
+kind: DaemonSet
+apiVersion: apps/v1
+metadata:
+ name: calico-node
+ namespace: kube-system
+ labels:
+ k8s-app: calico-node
+spec:
+ selector:
+ matchLabels:
+ k8s-app: calico-node
+ updateStrategy:
+ type: RollingUpdate
+ rollingUpdate:
+ maxUnavailable: 1
+ template:
+ metadata:
+ labels:
+ k8s-app: calico-node
+ spec:
+ nodeSelector:
+ kubernetes.io/os: linux
+ hostNetwork: true
+ tolerations:
+ # Make sure calico-node gets scheduled on all nodes.
+ - effect: NoSchedule
+ operator: Exists
+ # Mark the pod as a critical add-on for rescheduling.
+ - key: CriticalAddonsOnly
+ operator: Exists
+ - effect: NoExecute
+ operator: Exists
+ serviceAccountName: calico-node
+ securityContext:
+ seccompProfile:
+ type: RuntimeDefault
+ # Minimize downtime during a rolling upgrade or deletion; tell Kubernetes to do a "force
+ # deletion": https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods.
+ terminationGracePeriodSeconds: 0
+ priorityClassName: system-node-critical
+ initContainers:
+ # This container performs upgrade from host-local IPAM to calico-ipam.
+ # It can be deleted if this is a fresh installation, or if you have already
+ # upgraded to use calico-ipam.
+ - name: upgrade-ipam
+ image: docker.io/calico/cni:master
+ imagePullPolicy: IfNotPresent
+ command: ["/opt/cni/bin/calico-ipam", "-upgrade"]
+ envFrom:
+ - configMapRef:
+ # Allow KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT to be overridden for eBPF mode.
+ name: kubernetes-services-endpoint
+ optional: true
+ env:
+ - name: KUBERNETES_NODE_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: spec.nodeName
+ - name: CALICO_NETWORKING_BACKEND
+ valueFrom:
+ configMapKeyRef:
+ name: calico-config
+ key: calico_backend
+ volumeMounts:
+ - mountPath: /var/lib/cni/networks
+ name: host-local-net-dir
+ - mountPath: /host/opt/cni/bin
+ name: cni-bin-dir
+ securityContext:
+ privileged: true
+ # This container installs the CNI binaries
+ # and CNI network config file on each node.
+ - name: install-cni
+ image: docker.io/calico/cni:master
+ imagePullPolicy: IfNotPresent
+ command: ["/opt/cni/bin/install"]
+ envFrom:
+ - configMapRef:
+ # Allow KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT to be overridden for eBPF mode.
+ name: kubernetes-services-endpoint
+ optional: true
+ env:
+ # Name of the CNI config file to create.
+ - name: CNI_CONF_NAME
+ value: "10-calico.conflist"
+ # The CNI network config to install on each node.
+ - name: CNI_NETWORK_CONFIG
+ valueFrom:
+ configMapKeyRef:
+ name: calico-config
+ key: cni_network_config
+ # Set the hostname based on the k8s node name.
+ - name: KUBERNETES_NODE_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: spec.nodeName
+ # CNI MTU Config variable
+ - name: CNI_MTU
+ valueFrom:
+ configMapKeyRef:
+ name: calico-config
+ key: veth_mtu
+ # Prevents the container from sleeping forever.
+ - name: SLEEP
+ value: "false"
+ volumeMounts:
+ - mountPath: /host/opt/cni/bin
+ name: cni-bin-dir
+ - mountPath: /host/etc/cni/net.d
+ name: cni-net-dir
+ securityContext:
+ privileged: true
+ # This init container mounts the necessary filesystems needed by the BPF data plane
+ # i.e. bpf at /sys/fs/bpf and cgroup2 at /run/calico/cgroup. Calico-node initialisation is executed
+ # in best effort fashion, i.e. no failure for errors, to not disrupt pod creation in iptable mode.
+ - name: "mount-bpffs"
+ image: docker.io/calico/node:master
+ imagePullPolicy: IfNotPresent
+ command: ["calico-node", "-init", "-best-effort"]
+ volumeMounts:
+ - mountPath: /sys/fs
+ name: sys-fs
+ # Bidirectional is required to ensure that the new mount we make at /sys/fs/bpf propagates to the host
+ # so that it outlives the init container.
+ mountPropagation: Bidirectional
+ - mountPath: /var/run/calico
+ name: var-run-calico
+ # Bidirectional is required to ensure that the new mount we make at /run/calico/cgroup propagates to the host
+ # so that it outlives the init container.
+ mountPropagation: Bidirectional
+ # Mount /proc/ from host which usually is an init program at /nodeproc. It's needed by mountns binary,
+ # executed by calico-node, to mount root cgroup2 fs at /run/calico/cgroup to attach CTLB programs correctly.
+ - mountPath: /nodeproc
+ name: nodeproc
+ readOnly: true
+ securityContext:
+ privileged: true
+ containers:
+ # Runs calico-node container on each Kubernetes node. This
+ # container programs network policy and routes on each
+ # host.
+ - name: calico-node
+ image: docker.io/calico/node:master
+ imagePullPolicy: IfNotPresent
+ envFrom:
+ - configMapRef:
+ # Allow KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT to be overridden for eBPF mode.
+ name: kubernetes-services-endpoint
+ optional: true
+ env:
+ # Use Kubernetes API as the backing datastore.
+ - name: DATASTORE_TYPE
+ value: "kubernetes"
+ # Wait for the datastore.
+ - name: WAIT_FOR_DATASTORE
+ value: "true"
+ # Set based on the k8s node name.
+ - name: NODENAME
+ valueFrom:
+ fieldRef:
+ fieldPath: spec.nodeName
+ # Choose the backend to use.
+ - name: CALICO_NETWORKING_BACKEND
+ valueFrom:
+ configMapKeyRef:
+ name: calico-config
+ key: calico_backend
+ # Cluster type to identify the deployment type
+ - name: CLUSTER_TYPE
+ value: "k8s,bgp"
+ # Auto-detect the BGP IP address.
+ - name: IP
+ value: "autodetect"
+ # Enable IPIP
+ - name: CALICO_IPV4POOL_IPIP
+ value: "Always"
+ # Enable or Disable VXLAN on the default IP pool.
+ - name: CALICO_IPV4POOL_VXLAN
+ value: "Never"
+ # Enable or Disable VXLAN on the default IPv6 IP pool.
+ - name: CALICO_IPV6POOL_VXLAN
+ value: "Never"
+ # Set if Felix should program IPIP routes or not.
+ - name: FELIX_PROGRAMROUTES
+ value: "IPIP"
+ # Set MTU for tunnel device used if ipip is enabled
+ - name: FELIX_IPINIPMTU
+ valueFrom:
+ configMapKeyRef:
+ name: calico-config
+ key: veth_mtu
+ # Set MTU for the VXLAN tunnel device.
+ - name: FELIX_VXLANMTU
+ valueFrom:
+ configMapKeyRef:
+ name: calico-config
+ key: veth_mtu
+ # Set MTU for the Wireguard tunnel device.
+ - name: FELIX_WIREGUARDMTU
+ valueFrom:
+ configMapKeyRef:
+ name: calico-config
+ key: veth_mtu
+ # The default IPv4 pool to create on startup if none exists. Pod IPs will be
+ # chosen from this range. Changing this value after installation will have
+ # no effect. This should fall within `--cluster-cidr`.
+ # - name: CALICO_IPV4POOL_CIDR
+ # value: "192.168.0.0/16"
+ # Disable file logging so `kubectl logs` works.
+ - name: CALICO_DISABLE_FILE_LOGGING
+ value: "true"
+ # Set Felix endpoint to host default action to ACCEPT.
+ - name: FELIX_DEFAULTENDPOINTTOHOSTACTION
+ value: "ACCEPT"
+ # Disable IPv6 on Kubernetes.
+ - name: FELIX_IPV6SUPPORT
+ value: "false"
+ - name: FELIX_HEALTHENABLED
+ value: "true"
+ securityContext:
+ privileged: true
+ resources:
+ requests:
+ cpu: 250m
+ lifecycle:
+ preStop:
+ exec:
+ command:
+ - /bin/calico-node
+ - -shutdown
+ livenessProbe:
+ exec:
+ command:
+ - /bin/calico-node
+ - -felix-live
+ periodSeconds: 10
+ initialDelaySeconds: 10
+ failureThreshold: 6
+ timeoutSeconds: 10
+ readinessProbe:
+ exec:
+ command:
+ - /bin/calico-node
+ - -felix-ready
+ periodSeconds: 10
+ timeoutSeconds: 10
+ volumeMounts:
+ # For maintaining CNI plugin API credentials.
+ - mountPath: /host/etc/cni/net.d
+ name: cni-net-dir
+ readOnly: false
+ - mountPath: /lib/modules
+ name: lib-modules
+ readOnly: true
+ - mountPath: /run/xtables.lock
+ name: xtables-lock
+ readOnly: false
+ - mountPath: /var/run/calico
+ name: var-run-calico
+ readOnly: false
+ - mountPath: /var/lib/calico
+ name: var-lib-calico
+ readOnly: false
+ - name: policysync
+ mountPath: /var/run/nodeagent
+ # For eBPF mode, we need to be able to mount the BPF filesystem at /sys/fs/bpf so we mount in the
+ # parent directory.
+ - name: bpffs
+ mountPath: /sys/fs/bpf
+ - name: cni-log-dir
+ mountPath: /var/log/calico/cni
+ readOnly: true
+ volumes:
+ # Used by calico-node.
+ - name: lib-modules
+ hostPath:
+ path: /lib/modules
+ - name: var-run-calico
+ hostPath:
+ path: /var/run/calico
+ type: DirectoryOrCreate
+ - name: var-lib-calico
+ hostPath:
+ path: /var/lib/calico
+ type: DirectoryOrCreate
+ - name: xtables-lock
+ hostPath:
+ path: /run/xtables.lock
+ type: FileOrCreate
+ - name: sys-fs
+ hostPath:
+ path: /sys/fs/
+ type: DirectoryOrCreate
+ - name: bpffs
+ hostPath:
+ path: /sys/fs/bpf
+ type: Directory
+ # mount /proc at /nodeproc to be used by mount-bpffs initContainer to mount root cgroup2 fs.
+ - name: nodeproc
+ hostPath:
+ path: /proc
+ # Used to install CNI.
+ - name: cni-bin-dir
+ hostPath:
+ path: /opt/cni/bin
+ type: DirectoryOrCreate
+ - name: cni-net-dir
+ hostPath:
+ path: /etc/cni/net.d
+ # Used to access CNI logs.
+ - name: cni-log-dir
+ hostPath:
+ path: /var/log/calico/cni
+ # Mount in the directory for host-local IPAM allocations. This is
+ # used when upgrading from host-local to calico-ipam, and can be removed
+ # if not using the upgrade-ipam init container.
+ - name: host-local-net-dir
+ hostPath:
+ path: /var/lib/cni/networks
+ # Used to create per-pod Unix Domain Sockets
+ - name: policysync
+ hostPath:
+ type: DirectoryOrCreate
+ path: /var/run/nodeagent
+---
+# Source: calico/templates/calico-kube-controllers.yaml
+# See https://github.com/projectcalico/kube-controllers
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: calico-kube-controllers
+ namespace: kube-system
+ labels:
+ k8s-app: calico-kube-controllers
+spec:
+ # The controllers can only have a single active instance.
+ replicas: 1
+ selector:
+ matchLabels:
+ k8s-app: calico-kube-controllers
+ strategy:
+ type: Recreate
+ template:
+ metadata:
+ name: calico-kube-controllers
+ namespace: kube-system
+ labels:
+ k8s-app: calico-kube-controllers
+ spec:
+ nodeSelector:
+ kubernetes.io/os: linux
+ tolerations:
+ # Mark the pod as a critical add-on for rescheduling.
+ - key: CriticalAddonsOnly
+ operator: Exists
+ - key: node-role.kubernetes.io/master
+ effect: NoSchedule
+ - key: node-role.kubernetes.io/control-plane
+ effect: NoSchedule
+ serviceAccountName: calico-kube-controllers
+ securityContext:
+ seccompProfile:
+ type: RuntimeDefault
+ priorityClassName: system-cluster-critical
+ containers:
+ - name: calico-kube-controllers
+ image: docker.io/calico/kube-controllers:master
+ imagePullPolicy: IfNotPresent
+ env:
+ # Choose which controllers to run.
+ - name: ENABLED_CONTROLLERS
+ value: node,loadbalancer
+ - name: DATASTORE_TYPE
+ value: kubernetes
+ livenessProbe:
+ exec:
+ command:
+ - /usr/bin/check-status
+ - -l
+ periodSeconds: 10
+ initialDelaySeconds: 10
+ failureThreshold: 6
+ timeoutSeconds: 10
+ readinessProbe:
+ exec:
+ command:
+ - /usr/bin/check-status
+ - -r
+ periodSeconds: 10
+ securityContext:
+ runAsNonRoot: true
diff --git a/manifests/calico-policy-only.yaml b/manifests/calico-policy-only.yaml
index 654778662d4..fefee89f3c7 100644
--- a/manifests/calico-policy-only.yaml
+++ b/manifests/calico-policy-only.yaml
@@ -1984,6 +1984,10 @@ spec:
PolicySyncPathPrefix is used to by Felix to communicate policy changes to external services,
like Application layer policy. [Default: Empty]
type: string
+ programRoutes:
+ description: 'ProgramRoutes specifies what type of routes Felix should
+ program. [Default: None]. [Default: None]'
+ type: string
prometheusGoMetricsEnabled:
description: |-
PrometheusGoMetricsEnabled disables Go runtime metrics collection, which the Prometheus client does by default, when
diff --git a/manifests/calico-typha.yaml b/manifests/calico-typha.yaml
index d19bbd9e040..0a4d94e404d 100644
--- a/manifests/calico-typha.yaml
+++ b/manifests/calico-typha.yaml
@@ -1985,6 +1985,10 @@ spec:
PolicySyncPathPrefix is used to by Felix to communicate policy changes to external services,
like Application layer policy. [Default: Empty]
type: string
+ programRoutes:
+ description: 'ProgramRoutes specifies what type of routes Felix should
+ program. [Default: None]. [Default: None]'
+ type: string
prometheusGoMetricsEnabled:
description: |-
PrometheusGoMetricsEnabled disables Go runtime metrics collection, which the Prometheus client does by default, when
@@ -7639,6 +7643,9 @@ spec:
# Enable or Disable VXLAN on the default IPv6 IP pool.
- name: CALICO_IPV6POOL_VXLAN
value: "Never"
+ # Set if Felix should program IPIP routes or not.
+ - name: FELIX_PROGRAMROUTES
+ value: "None"
# Set MTU for tunnel device used if ipip is enabled
- name: FELIX_IPINIPMTU
valueFrom:
diff --git a/manifests/calico-vxlan.yaml b/manifests/calico-vxlan.yaml
index 0073b053b1b..98b8652e836 100644
--- a/manifests/calico-vxlan.yaml
+++ b/manifests/calico-vxlan.yaml
@@ -1969,6 +1969,10 @@ spec:
PolicySyncPathPrefix is used to by Felix to communicate policy changes to external services,
like Application layer policy. [Default: Empty]
type: string
+ programRoutes:
+ description: 'ProgramRoutes specifies what type of routes Felix should
+ program. [Default: None]. [Default: None]'
+ type: string
prometheusGoMetricsEnabled:
description: |-
PrometheusGoMetricsEnabled disables Go runtime metrics collection, which the Prometheus client does by default, when
@@ -7597,6 +7601,9 @@ spec:
# Enable or Disable VXLAN on the default IPv6 IP pool.
- name: CALICO_IPV6POOL_VXLAN
value: "CrossSubnet"
+ # Set if Felix should program IPIP routes or not.
+ - name: FELIX_PROGRAMROUTES
+ value: "None"
# Set MTU for tunnel device used if ipip is enabled
- name: FELIX_IPINIPMTU
valueFrom:
diff --git a/manifests/calico.yaml b/manifests/calico.yaml
index 37c321c8cf2..522fb3dbf63 100644
--- a/manifests/calico.yaml
+++ b/manifests/calico.yaml
@@ -1969,6 +1969,10 @@ spec:
PolicySyncPathPrefix is used to by Felix to communicate policy changes to external services,
like Application layer policy. [Default: Empty]
type: string
+ programRoutes:
+ description: 'ProgramRoutes specifies what type of routes Felix should
+ program. [Default: None]. [Default: None]'
+ type: string
prometheusGoMetricsEnabled:
description: |-
PrometheusGoMetricsEnabled disables Go runtime metrics collection, which the Prometheus client does by default, when
@@ -7597,6 +7601,9 @@ spec:
# Enable or Disable VXLAN on the default IPv6 IP pool.
- name: CALICO_IPV6POOL_VXLAN
value: "Never"
+ # Set if Felix should program IPIP routes or not.
+ - name: FELIX_PROGRAMROUTES
+ value: "None"
# Set MTU for tunnel device used if ipip is enabled
- name: FELIX_IPINIPMTU
valueFrom:
diff --git a/manifests/canal.yaml b/manifests/canal.yaml
index a82b28883fc..e12c1c7da7e 100644
--- a/manifests/canal.yaml
+++ b/manifests/canal.yaml
@@ -1986,6 +1986,10 @@ spec:
PolicySyncPathPrefix is used to by Felix to communicate policy changes to external services,
like Application layer policy. [Default: Empty]
type: string
+ programRoutes:
+ description: 'ProgramRoutes specifies what type of routes Felix should
+ program. [Default: None]. [Default: None]'
+ type: string
prometheusGoMetricsEnabled:
description: |-
PrometheusGoMetricsEnabled disables Go runtime metrics collection, which the Prometheus client does by default, when
diff --git a/manifests/crds.yaml b/manifests/crds.yaml
index 17b408e1bc7..d844d6089ef 100644
--- a/manifests/crds.yaml
+++ b/manifests/crds.yaml
@@ -1879,6 +1879,10 @@ spec:
PolicySyncPathPrefix is used to by Felix to communicate policy changes to external services,
like Application layer policy. [Default: Empty]
type: string
+ programRoutes:
+ description: 'ProgramRoutes specifies what type of routes Felix should
+ program. [Default: None]. [Default: None]'
+ type: string
prometheusGoMetricsEnabled:
description: |-
PrometheusGoMetricsEnabled disables Go runtime metrics collection, which the Prometheus client does by default, when
diff --git a/manifests/flannel-migration/calico.yaml b/manifests/flannel-migration/calico.yaml
index e39c4e6066e..384d6a5da56 100644
--- a/manifests/flannel-migration/calico.yaml
+++ b/manifests/flannel-migration/calico.yaml
@@ -1969,6 +1969,10 @@ spec:
PolicySyncPathPrefix is used to by Felix to communicate policy changes to external services,
like Application layer policy. [Default: Empty]
type: string
+ programRoutes:
+ description: 'ProgramRoutes specifies what type of routes Felix should
+ program. [Default: None]. [Default: None]'
+ type: string
prometheusGoMetricsEnabled:
description: |-
PrometheusGoMetricsEnabled disables Go runtime metrics collection, which the Prometheus client does by default, when
@@ -7599,6 +7603,9 @@ spec:
# Enable or Disable VXLAN on the default IPv6 IP pool.
- name: CALICO_IPV6POOL_VXLAN
value: "Never"
+ # Set if Felix should program IPIP routes or not.
+ - name: FELIX_PROGRAMROUTES
+ value: "None"
# Set MTU for tunnel device used if ipip is enabled
- name: FELIX_IPINIPMTU
valueFrom:
diff --git a/manifests/ocp/crd.projectcalico.org_felixconfigurations.yaml b/manifests/ocp/crd.projectcalico.org_felixconfigurations.yaml
index f74fdc717b8..008c761bc5a 100644
--- a/manifests/ocp/crd.projectcalico.org_felixconfigurations.yaml
+++ b/manifests/ocp/crd.projectcalico.org_felixconfigurations.yaml
@@ -865,6 +865,10 @@ spec:
policy changes to external services, like Application layer policy.
[Default: Empty]'
type: string
+ programRoutes:
+ description: 'ProgramRoutes specifies what type of routes Felix should
+ program. [Default: None]. [Default: None]'
+ type: string
prometheusGoMetricsEnabled:
description: 'PrometheusGoMetricsEnabled disables Go runtime metrics
collection, which the Prometheus client does by default, when set
diff --git a/manifests/operator-crds.yaml b/manifests/operator-crds.yaml
index 684a1fac7a7..7c63ae4f150 100644
--- a/manifests/operator-crds.yaml
+++ b/manifests/operator-crds.yaml
@@ -20505,6 +20505,10 @@ spec:
PolicySyncPathPrefix is used to by Felix to communicate policy changes to external services,
like Application layer policy. [Default: Empty]
type: string
+ programRoutes:
+ description: 'ProgramRoutes specifies what type of routes Felix should
+ program. [Default: None]. [Default: None]'
+ type: string
prometheusGoMetricsEnabled:
description: |-
PrometheusGoMetricsEnabled disables Go runtime metrics collection, which the Prometheus client does by default, when
diff --git a/node/filesystem/etc/rc.local b/node/filesystem/etc/rc.local
index 24768f9dff2..8efbdf9f46a 100755
--- a/node/filesystem/etc/rc.local
+++ b/node/filesystem/etc/rc.local
@@ -52,6 +52,10 @@ case "$CALICO_NETWORKING_BACKEND" in
# If running in policy only mode, we don't need to run BIRD / Confd.
echo "CALICO_NETWORKING_BACKEND is none - no BGP daemon running"
;;
+ "ipip" )
+ # If running in IPIP-only mode, we don't need to run BIRD / Confd.
+ echo "CALICO_NETWORKING_BACKEND is ipip - no need to run a BGP daemon"
+ ;;
"vxlan" )
# If running in VXLAN-only mode, we don't need to run BIRD / Confd.
echo "CALICO_NETWORKING_BACKEND is vxlan - no need to run a BGP daemon"
diff --git a/node/tests/k8st/infra/calico-kdd.yaml b/node/tests/k8st/infra/calico-kdd.yaml
index ad1f5883dce..80afc69ede3 100644
--- a/node/tests/k8st/infra/calico-kdd.yaml
+++ b/node/tests/k8st/infra/calico-kdd.yaml
@@ -673,6 +673,9 @@ spec:
# Enable or Disable VXLAN on the default IPv6 IP pool.
- name: CALICO_IPV6POOL_VXLAN
value: "Never"
+ # Set if Felix should program IPIP routes or not.
+ - name: FELIX_PROGRAMROUTES
+ value: "None"
# Set MTU for tunnel device used if ipip is enabled
- name: FELIX_IPINIPMTU
valueFrom: