diff --git a/go.mod b/go.mod index 2e07413a68..80a72f7644 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ replace ( sigs.k8s.io/controller-tools => github.com/cilium/controller-tools v0.8.0-2 ) -require github.com/cilium/cilium v1.17.0-pre.3.0.20241206091809-befdbb49a88b +require github.com/cilium/cilium v1.17.0-pre.3.0.20241206234938-95ee091cd967 require ( cel.dev/expr v0.18.0 // indirect @@ -35,7 +35,7 @@ require ( github.com/cilium/ebpf v0.16.1-0.20241119131019-e2607b570f29 // indirect github.com/cilium/hive v0.0.0-20241129122706-af5052cfd6d4 // indirect github.com/cilium/proxy v0.0.0-20241115112946-fb67566cbd95 // indirect - github.com/cilium/statedb v0.3.3 // indirect + github.com/cilium/statedb v0.3.4 // indirect github.com/cilium/stream v0.0.0-20241203114243-53c3e5d79744 // indirect github.com/cilium/workerpool v1.2.0 // indirect github.com/cloudflare/cfssl v1.6.5 // indirect diff --git a/go.sum b/go.sum index 63eaa5efef..3a97ec1a11 100644 --- a/go.sum +++ b/go.sum @@ -56,16 +56,16 @@ github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNS github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= github.com/cilium/charts v0.0.0-20241127112225-7cea2b4f120f h1:SFlZUktu/L/03B3EuLy1uAgjtgfBOy2buQNL+ZMncxc= github.com/cilium/charts v0.0.0-20241127112225-7cea2b4f120f/go.mod h1:M3C9VOlFvRzuV+a01t07Tw4uFLSfkCH3L542IWjf6BU= -github.com/cilium/cilium v1.17.0-pre.3.0.20241206091809-befdbb49a88b h1:qdKxzeIpCgu3p1BU5zAv4AdV2inWN0sapC5BaVci1mI= -github.com/cilium/cilium v1.17.0-pre.3.0.20241206091809-befdbb49a88b/go.mod h1:3atcWZad/w2gPuK+VrdhbV4L6r6HTEghF4WA4WJycN0= +github.com/cilium/cilium v1.17.0-pre.3.0.20241206234938-95ee091cd967 h1:NCPrnnX5HIaB/Kp001CzNLvhg7Ah/wnCVGvp8szw5uY= +github.com/cilium/cilium v1.17.0-pre.3.0.20241206234938-95ee091cd967/go.mod h1:BYWwvslb/PtvuzFMs4I9zLTzDMoq6ichXbcinZjWV+0= github.com/cilium/ebpf v0.16.1-0.20241119131019-e2607b570f29 h1:T7oI6ImaDb8qPVUFTvhQPbp65nIwg9o90tYZKOU+lr0= github.com/cilium/ebpf v0.16.1-0.20241119131019-e2607b570f29/go.mod h1:vay2FaYSmIlv3r8dNACd4mW/OCaZLJKJOo+IHBvCIO8= github.com/cilium/hive v0.0.0-20241129122706-af5052cfd6d4 h1:JcT0Hl5hjbCn2xFPd3yEFDLvvbgUz1DU2IgHHArw7ac= github.com/cilium/hive v0.0.0-20241129122706-af5052cfd6d4/go.mod h1:pI2GJ1n3SLKIQVFrKF7W6A6gb6BQkZ+3Hp4PAEo5SuI= github.com/cilium/proxy v0.0.0-20241115112946-fb67566cbd95 h1:iMn0++U3CDqoDINY5JLOhlPcjj3kW/xCmse+d+EZkOM= github.com/cilium/proxy v0.0.0-20241115112946-fb67566cbd95/go.mod h1:/UoCz3gByKwF5gCHFMUhwmIN5/Pgmb8LTIrfBlmjGCo= -github.com/cilium/statedb v0.3.3 h1:hB1J28yE6KMrwLSxFfus1QjwYK1PEhibKADckxVHNyk= -github.com/cilium/statedb v0.3.3/go.mod h1:hpcYZXvrOhmdBd02/N/WqxSjbeO2HYG8l3Z2fGq6Ioo= +github.com/cilium/statedb v0.3.4 h1:nb5qNntmtaNljJD1r2s5zGOs62LP87AqLhFKIZH2rRE= +github.com/cilium/statedb v0.3.4/go.mod h1:hpcYZXvrOhmdBd02/N/WqxSjbeO2HYG8l3Z2fGq6Ioo= github.com/cilium/stream v0.0.0-20241203114243-53c3e5d79744 h1:f+CgYUy2YyZ2EX31QSqf3vwFiJJQSAMIQLn4d3QQYno= github.com/cilium/stream v0.0.0-20241203114243-53c3e5d79744/go.mod h1:/e83AwqvNKpyg4n3C41qmnmj1x2G9DwzI+jb7GkF4lI= github.com/cilium/workerpool v1.2.0 h1:Wc2iOPTvCgWKQXeq4L5tnx4QFEI+z5q1+bSpSS0cnAY= diff --git a/vendor/github.com/cilium/cilium/cilium-cli/connectivity/builder/client_egress_to_cidrgroup_deny.go b/vendor/github.com/cilium/cilium/cilium-cli/connectivity/builder/client_egress_to_cidrgroup_deny.go index 41b389d89d..1b3cd5a861 100644 --- a/vendor/github.com/cilium/cilium/cilium-cli/connectivity/builder/client_egress_to_cidrgroup_deny.go +++ b/vendor/github.com/cilium/cilium/cilium-cli/connectivity/builder/client_egress_to_cidrgroup_deny.go @@ -15,6 +15,7 @@ func (t clientEgressToCidrgroupDeny) build(ct *check.ConnectivityTest, templates // This policy denies L3 traffic to ExternalCIDR except ExternalIP/32 // It does so using a CiliumCIDRGroup newTest("client-egress-to-cidrgroup-deny", ct). + WithCiliumVersion(">=1.17.0"). WithCiliumPolicy(allowAllEgressPolicyYAML). // Allow all egress traffic WithCiliumPolicy(templates["clientEgressToCIDRGroupExternalDenyPolicyYAML"]). WithScenarios( diff --git a/vendor/github.com/cilium/cilium/pkg/datapath/linux/config/defines/defines.go b/vendor/github.com/cilium/cilium/pkg/datapath/linux/config/defines/defines.go deleted file mode 100644 index ca5d5367e7..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/datapath/linux/config/defines/defines.go +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package defines - -import ( - "fmt" - - "github.com/cilium/hive/cell" -) - -// Map is the type containing the key-value pairs representing extra define -// directives for datapath node configuration. -type Map map[string]string - -func (m Map) Merge(other Map) error { - for key, value := range other { - if _, ok := m[key]; ok { - return fmt.Errorf("extra node define overwrites key %q", key) - } - - m[key] = value - } - return nil -} - -// NodeOut allows injecting configuration into the datapath. -type NodeOut struct { - cell.Out - NodeDefines Map `group:"header-node-defines"` -} - -// Fn is a function returning the key-value pairs representing extra define -// directives for datapath node configuration. -type Fn func() (Map, error) - -// NodeFnOut allows injecting configuration into the datapath -// by invoking a callback. -// -// Prefer using [NodeOut] if possible since it has a valid zero value. -type NodeFnOut struct { - cell.Out - // Fn must not be nil. - Fn `group:"header-node-define-fns"` -} - -// NewNodeFnOut wraps a function returning the key-value pairs representing -// extra define directives for datapath node configuration, so that it can be -// provided through the hive framework. -func NewNodeFnOut(fn Fn) NodeFnOut { - return NodeFnOut{Fn: fn} -} diff --git a/vendor/github.com/cilium/cilium/pkg/datapath/loader/metrics/metrics.go b/vendor/github.com/cilium/cilium/pkg/datapath/loader/metrics/metrics.go deleted file mode 100644 index 5d7f97019b..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/datapath/loader/metrics/metrics.go +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package metrics - -import ( - "github.com/cilium/cilium/pkg/spanstat" -) - -// SpanStat is a statistics structure for storing metrics related to datapath -// load operations. -type SpanStat struct { - BpfCompilation spanstat.SpanStat - BpfWaitForELF spanstat.SpanStat - BpfLoadProg spanstat.SpanStat -} - -// GetMap returns a map of statistic names to stats -func (s *SpanStat) GetMap() map[string]*spanstat.SpanStat { - return map[string]*spanstat.SpanStat{ - "bpfCompilation": &s.BpfCompilation, - "bpfWaitForELF": &s.BpfWaitForELF, - "bpfLoadProg": &s.BpfLoadProg, - } -} diff --git a/vendor/github.com/cilium/cilium/pkg/datapath/tunnel/cell.go b/vendor/github.com/cilium/cilium/pkg/datapath/tunnel/cell.go deleted file mode 100644 index cb0ade967b..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/datapath/tunnel/cell.go +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package tunnel - -import ( - "github.com/cilium/hive/cell" - - "github.com/cilium/cilium/pkg/option" -) - -// Cell is a cell that provides the parameters for the Cilium tunnel, -// based on user configuration and requests from external modules. -var Cell = cell.Module( - "datapath-tunnel-config", - "Tunneling configurations", - - cell.Config(defaultConfig), - - cell.Provide( - newConfig, - - // Provide the datapath options. - Config.datapathConfigProvider, - - // Enable tunnel configuration when it is the primary routing mode. - func(dcfg *option.DaemonConfig) EnablerOut { - return NewEnabler(dcfg.TunnelingEnabled()) - }, - - // Enable tunnel configuration when DSR Geneve is enabled (this is currently - // handled here, as the corresponding logic has not yet been modularized). - func(dcfg *option.DaemonConfig) EnablerOut { - return NewEnabler( - (dcfg.EnableNodePort || - dcfg.KubeProxyReplacement == option.KubeProxyReplacementTrue) && - dcfg.LoadBalancerUsesDSR() && - dcfg.LoadBalancerDSRDispatch == option.DSRDispatchGeneve, - // The datapath logic takes care of the MTU overhead. So no need to - // take it into account here. - // See encap_geneve_dsr_opt[4,6] in nodeport.h - WithoutMTUAdaptation(), - ) - }, - - // Enable tunnel configuration when High Scale IPCache is enabled (this is - // currently handled here, as the corresponding logic has not yet been modularized). - func(dcfg *option.DaemonConfig) EnablerOut { - return NewEnabler(dcfg.EnableHighScaleIPcache) - }, - ), -) diff --git a/vendor/github.com/cilium/cilium/pkg/datapath/tunnel/tunnel.go b/vendor/github.com/cilium/cilium/pkg/datapath/tunnel/tunnel.go deleted file mode 100644 index 54b2f176cd..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/datapath/tunnel/tunnel.go +++ /dev/null @@ -1,238 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package tunnel - -import ( - "fmt" - "strings" - - "github.com/cilium/hive/cell" - "github.com/spf13/pflag" - - dpcfgdef "github.com/cilium/cilium/pkg/datapath/linux/config/defines" - "github.com/cilium/cilium/pkg/datapath/linux/safenetlink" - "github.com/cilium/cilium/pkg/defaults" -) - -// Protocol represents the valid types of encapsulation protocols. -type Protocol string - -const ( - // VXLAN specifies VXLAN encapsulation - VXLAN Protocol = "vxlan" - - // Geneve specifies Geneve encapsulation - Geneve Protocol = "geneve" - - // Disabled specifies to disable encapsulation - Disabled Protocol = "" -) - -func (tp Protocol) String() string { return string(tp) } - -func (tp Protocol) toDpID() string { - switch tp { - case VXLAN: - return "1" - case Geneve: - return "2" - default: - return "" - } -} - -// Config represents the materialized tunneling configuration to be used, -// depending on the user configuration and optional overrides required by -// additional features. -type Config struct { - protocol Protocol - port uint16 - deviceName string - shouldAdaptMTU bool -} - -type newConfigIn struct { - cell.In - - Cfg userCfg - Enablers []enabler `group:"request-enable-tunneling"` -} - -var ( - configDisabled = Config{ - protocol: Disabled, - port: 0, - deviceName: "", - shouldAdaptMTU: false, - } -) - -func newConfig(in newConfigIn) (Config, error) { - switch Protocol(in.Cfg.TunnelProtocol) { - case VXLAN, Geneve: - default: - return Config{}, fmt.Errorf("invalid tunnel protocol %q", in.Cfg.TunnelProtocol) - } - - cfg := Config{ - protocol: Protocol(in.Cfg.TunnelProtocol), - port: in.Cfg.TunnelPort, - deviceName: "", - shouldAdaptMTU: false, - } - - var enabled bool - for _, e := range in.Enablers { - if e.enable { - enabled = true - cfg.shouldAdaptMTU = cfg.shouldAdaptMTU || e.needsMTUAdaptation - - for _, validator := range e.validators { - if err := validator(cfg.protocol); err != nil { - return configDisabled, err - } - } - } - } - - if !enabled { - return configDisabled, nil - } - - switch cfg.protocol { - case VXLAN: - cfg.deviceName = defaults.VxlanDevice - - if cfg.port == 0 { - cfg.port = defaults.TunnelPortVXLAN - } - case Geneve: - cfg.deviceName = defaults.GeneveDevice - - if cfg.port == 0 { - cfg.port = defaults.TunnelPortGeneve - } - } - - return cfg, nil -} - -// NewTestConfig returns a new TunnelConfig for testing purposes. -func NewTestConfig(proto Protocol) Config { - //exhaustruct:ignore // Test code can underspecify the default config - cfg := Config{protocol: proto} - - switch proto { - case VXLAN: - cfg.port = defaults.TunnelPortVXLAN - cfg.deviceName = defaults.VxlanDevice - case Geneve: - cfg.port = defaults.TunnelPortGeneve - cfg.deviceName = defaults.GeneveDevice - } - - return cfg -} - -// Protocol returns the enabled tunnel protocol. The tunnel protocol may be -// set to either VXLAN or Geneve even when the primary mode is native routing, in -// case an additional feature (e.g., egress gateway) may request some traffic to -// be routed through a tunnel. -func (cfg Config) Protocol() Protocol { return cfg.protocol } - -// Port returns the port used by the tunnel (0 if disabled). -func (cfg Config) Port() uint16 { return cfg.port } - -// DeviceName returns the name of the tunnel device (empty if disabled). -func (cfg Config) DeviceName() string { return cfg.deviceName } - -// ShouldAdaptMTU returns whether we should adapt the MTU calculation to -// account for encapsulation. -func (cfg Config) ShouldAdaptMTU() bool { return cfg.shouldAdaptMTU } - -func (cfg Config) datapathConfigProvider() (dpcfgdef.NodeOut, dpcfgdef.NodeFnOut) { - defines := make(dpcfgdef.Map) - definesFn := func() (dpcfgdef.Map, error) { return nil, nil } - - if cfg.Protocol() != Disabled { - defines[fmt.Sprintf("TUNNEL_PROTOCOL_%s", strings.ToUpper(VXLAN.String()))] = VXLAN.toDpID() - defines[fmt.Sprintf("TUNNEL_PROTOCOL_%s", strings.ToUpper(Geneve.String()))] = Geneve.toDpID() - defines["TUNNEL_PROTOCOL"] = cfg.Protocol().toDpID() - defines["TUNNEL_PORT"] = fmt.Sprintf("%d", cfg.Port()) - - definesFn = func() (dpcfgdef.Map, error) { - tunnelDev, err := safenetlink.LinkByName(cfg.DeviceName()) - if err != nil { - return nil, fmt.Errorf("failed to retrieve device info for %q: %w", cfg.DeviceName(), err) - } - - return dpcfgdef.Map{ - "ENCAP_IFINDEX": fmt.Sprintf("%d", tunnelDev.Attrs().Index), - }, nil - } - } - - return dpcfgdef.NodeOut{NodeDefines: defines}, dpcfgdef.NewNodeFnOut(definesFn) -} - -// EnablerOut allows requesting to enable tunneling functionalities. -type EnablerOut struct { - cell.Out - Enabler enabler `group:"request-enable-tunneling"` -} - -// NewEnabler returns an object to be injected through hive to request to -// enable tunneling functionalities. Extra options are meaningful only when -// enable is set to true, and are ignored otherwise. -func NewEnabler(enable bool, opts ...enablerOpt) EnablerOut { - enabler := enabler{enable: enable, needsMTUAdaptation: enable} - - for _, opt := range opts { - opt(&enabler) - } - - return EnablerOut{Enabler: enabler} -} - -// WithValidator allows to register extra validation functions -// to assert that the configured tunnel protocol matches the one expected by -// the given feature. -func WithValidator(validator func(Protocol) error) enablerOpt { - return func(te *enabler) { - te.validators = append(te.validators, validator) - } -} - -// WithoutMTUAdaptation conveys that the given feature request -// to enable tunneling, but the MTU adaptation is already handled externally. -func WithoutMTUAdaptation() enablerOpt { - return func(te *enabler) { - te.needsMTUAdaptation = false - } -} - -type enabler struct { - enable bool - needsMTUAdaptation bool - validators []func(Protocol) error -} - -type enablerOpt func(*enabler) - -// userCfg wraps the tunnel-related user configurations. -type userCfg struct { - TunnelProtocol string - TunnelPort uint16 -} - -// Flags implements the cell.Flagger interface, to register the given flags. -func (def userCfg) Flags(flags *pflag.FlagSet) { - flags.String("tunnel-protocol", def.TunnelProtocol, "Encapsulation protocol to use for the overlay (\"vxlan\" or \"geneve\")") - flags.Uint16("tunnel-port", def.TunnelPort, fmt.Sprintf("Tunnel port (default %d for \"vxlan\" and %d for \"geneve\")", defaults.TunnelPortVXLAN, defaults.TunnelPortGeneve)) -} - -var defaultConfig = userCfg{ - TunnelProtocol: defaults.TunnelProtocol, - TunnelPort: 0, // auto-detect based on the protocol. -} diff --git a/vendor/github.com/cilium/cilium/pkg/datapath/types/bandwidth.go b/vendor/github.com/cilium/cilium/pkg/datapath/types/bandwidth.go deleted file mode 100644 index 38a6963389..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/datapath/types/bandwidth.go +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package types - -import "github.com/spf13/pflag" - -const ( - EnableBandwidthManagerFlag = "enable-bandwidth-manager" - EnableBBRFlag = "enable-bbr" -) - -type BandwidthConfig struct { - // EnableBandwidthManager enables EDT-based pacing - EnableBandwidthManager bool - - // EnableBBR enables BBR TCP congestion control for the node including Pods - EnableBBR bool -} - -func (def BandwidthConfig) Flags(flags *pflag.FlagSet) { - flags.Bool(EnableBandwidthManagerFlag, def.EnableBandwidthManager, "Enable BPF bandwidth manager") - flags.Bool(EnableBBRFlag, def.EnableBBR, "Enable BBR for the bandwidth manager") -} - -var DefaultBandwidthConfig = BandwidthConfig{ - EnableBandwidthManager: false, - EnableBBR: false, -} - -type BandwidthManager interface { - BBREnabled() bool - Enabled() bool - - UpdateBandwidthLimit(endpointID uint16, bytesPerSecond uint64, prio uint32) - DeleteBandwidthLimit(endpointID uint16) -} diff --git a/vendor/github.com/cilium/cilium/pkg/datapath/types/bigtcp.go b/vendor/github.com/cilium/cilium/pkg/datapath/types/bigtcp.go deleted file mode 100644 index e9074fd2da..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/datapath/types/bigtcp.go +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package types - -import ( - "github.com/spf13/pflag" -) - -const ( - EnableIPv4BIGTCPFlag = "enable-ipv4-big-tcp" - EnableIPv6BIGTCPFlag = "enable-ipv6-big-tcp" -) - -// BigTCPUserConfig are the configuration flags that the user can modify. -type BigTCPUserConfig struct { - // EnableIPv6BIGTCP enables IPv6 BIG TCP (larger GSO/GRO limits) for the node including pods. - EnableIPv6BIGTCP bool - - // EnableIPv4BIGTCP enables IPv4 BIG TCP (larger GSO/GRO limits) for the node including pods. - EnableIPv4BIGTCP bool -} - -func (def BigTCPUserConfig) Flags(flags *pflag.FlagSet) { - flags.Bool(EnableIPv4BIGTCPFlag, def.EnableIPv4BIGTCP, "Enable IPv4 BIG TCP option which increases device's maximum GRO/GSO limits for IPv4") - flags.Bool(EnableIPv6BIGTCPFlag, def.EnableIPv6BIGTCP, "Enable IPv6 BIG TCP option which increases device's maximum GRO/GSO limits for IPv6") -} - -func (def BigTCPUserConfig) IsIPv4Enabled() bool { - return def.EnableIPv4BIGTCP -} - -func (def BigTCPUserConfig) IsIPv6Enabled() bool { - return def.EnableIPv6BIGTCP -} - -type BigTCPConfig interface { - IsIPv4Enabled() bool - IsIPv6Enabled() bool -} diff --git a/vendor/github.com/cilium/cilium/pkg/datapath/types/config.go b/vendor/github.com/cilium/cilium/pkg/datapath/types/config.go deleted file mode 100644 index 9177a1be89..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/datapath/types/config.go +++ /dev/null @@ -1,140 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package types - -import ( - "io" - "net/netip" - - "github.com/cilium/cilium/pkg/cidr" - "github.com/cilium/cilium/pkg/identity" - "github.com/cilium/cilium/pkg/mac" - "github.com/cilium/cilium/pkg/node" - nodeTypes "github.com/cilium/cilium/pkg/node/types" - "github.com/cilium/cilium/pkg/option" -) - -// NodeNeighborEnqueuer provides an interface for clients to push node updates -// for further processing. -type NodeNeighborEnqueuer interface { - // Enqueue enqueues a node for processing node neighbors updates. - Enqueue(*nodeTypes.Node, bool) -} - -// DeviceConfiguration is an interface for injecting configuration of datapath -// options that affect lookups and logic applied at a per-device level, whether -// those are devices associated with the endpoint or associated with the host. -type DeviceConfiguration interface { - // GetOptions fetches the configurable datapath options from the owner. - GetOptions() *option.IntOptions -} - -// LoadTimeConfiguration provides datapath implementations a clean interface -// to access endpoint-specific configuration that can be changed at load time. -type LoadTimeConfiguration interface { - // GetID returns a locally-significant endpoint identification number. - GetID() uint64 - // StringID returns the string-formatted version of the ID from GetID(). - StringID() string - // GetIdentity returns a globally-significant numeric security identity. - GetIdentity() identity.NumericIdentity - - // GetIdentityLocked returns a globally-significant numeric security - // identity while assuming that the backing data structure is locked. - // This function should be removed in favour of GetIdentity() - GetIdentityLocked() identity.NumericIdentity - - IPv4Address() netip.Addr - IPv6Address() netip.Addr - GetNodeMAC() mac.MAC - GetIfIndex() int - GetEndpointNetNsCookie() uint64 -} - -// CompileTimeConfiguration provides datapath implementations a clean interface -// to access endpoint-specific configuration that can only be changed at -// compile time. -type CompileTimeConfiguration interface { - DeviceConfiguration - - // TODO: Move this detail into the datapath - ConntrackLocalLocked() bool - - // RequireARPPassthrough returns true if the datapath must implement - // ARP passthrough for this endpoint - RequireARPPassthrough() bool - - // RequireEgressProg returns true if the endpoint requires an egress - // program attached to the InterfaceName() invoking the section - // "to-container" - RequireEgressProg() bool - - // RequireRouting returns true if the endpoint requires BPF routing to - // be enabled, when disabled, routing is delegated to Linux routing - RequireRouting() bool - - // RequireEndpointRoute returns true if the endpoint wishes to have a - // per endpoint route installed in the host's routing table to point to - // the endpoint's interface - RequireEndpointRoute() bool - - // GetPolicyVerdictLogFilter returns the PolicyVerdictLogFilter for the endpoint - GetPolicyVerdictLogFilter() uint32 - - // IsHost returns true if the endpoint is the host endpoint. - IsHost() bool -} - -// EndpointConfiguration provides datapath implementations a clean interface -// to access endpoint-specific configuration when configuring the datapath. -type EndpointConfiguration interface { - CompileTimeConfiguration - LoadTimeConfiguration -} - -// ConfigWriter is anything which writes the configuration for various datapath -// program types. -type ConfigWriter interface { - // WriteNodeConfig writes the implementation-specific configuration of - // node-wide options into the specified writer. - WriteNodeConfig(io.Writer, *LocalNodeConfiguration) error - - // WriteNetdevConfig writes the implementation-specific configuration - // of configurable options to the specified writer. Options specified - // here will apply to base programs and not to endpoints, though - // endpoints may have equivalent configurable options. - WriteNetdevConfig(io.Writer, *option.IntOptions) error - - // WriteTemplateConfig writes the implementation-specific configuration - // of configurable options for BPF templates to the specified writer. - WriteTemplateConfig(w io.Writer, nodeCfg *LocalNodeConfiguration, cfg EndpointConfiguration) error - - // WriteEndpointConfig writes the implementation-specific configuration - // of configurable options for the endpoint to the specified writer. - WriteEndpointConfig(w io.Writer, nodeCfg *LocalNodeConfiguration, cfg EndpointConfiguration) error -} - -// RemoteSNATDstAddrExclusionCIDRv4 returns a CIDR for SNAT exclusion. Any -// packet sent from a local endpoint to an IP address belonging to the CIDR -// should not be SNAT'd. -func RemoteSNATDstAddrExclusionCIDRv4(localNode node.LocalNode) *cidr.CIDR { - if localNode.IPv4NativeRoutingCIDR != nil { - // ipv4-native-routing-cidr is set or has been autodetected, so use it - return localNode.IPv4NativeRoutingCIDR - } - - return localNode.IPv4AllocCIDR -} - -// RemoteSNATDstAddrExclusionCIDRv6 returns a IPv6 CIDR for SNAT exclusion. Any -// packet sent from a local endpoint to an IP address belonging to the CIDR -// should not be SNAT'd. -func RemoteSNATDstAddrExclusionCIDRv6(localNode node.LocalNode) *cidr.CIDR { - if localNode.IPv6NativeRoutingCIDR != nil { - // ipv6-native-routing-cidr is set or has been autodetected, so use it - return localNode.IPv6NativeRoutingCIDR - } - - return localNode.IPv6AllocCIDR -} diff --git a/vendor/github.com/cilium/cilium/pkg/datapath/types/endpoint.go b/vendor/github.com/cilium/cilium/pkg/datapath/types/endpoint.go deleted file mode 100644 index df3bc01aa0..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/datapath/types/endpoint.go +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package types - -import "github.com/sirupsen/logrus" - -// Endpoint provides access endpoint configuration information that is necessary -// to compile and load the datapath. -type Endpoint interface { - EndpointConfiguration - InterfaceName() string - Logger(subsystem string) *logrus.Entry - StateDir() string -} diff --git a/vendor/github.com/cilium/cilium/pkg/datapath/types/ipsec.go b/vendor/github.com/cilium/cilium/pkg/datapath/types/ipsec.go deleted file mode 100644 index a62f7800a6..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/datapath/types/ipsec.go +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package types - -type IPsecKeyCustodian interface { - AuthKeySize() int - SPI() uint8 - StartBackgroundJobs(NodeHandler) error -} diff --git a/vendor/github.com/cilium/cilium/pkg/datapath/types/lbmap.go b/vendor/github.com/cilium/cilium/pkg/datapath/types/lbmap.go deleted file mode 100644 index 742b0d8eb5..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/datapath/types/lbmap.go +++ /dev/null @@ -1,113 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package types - -import ( - "net" - "sort" - - "github.com/cilium/cilium/pkg/cidr" - "github.com/cilium/cilium/pkg/loadbalancer" -) - -// LBMap is the interface describing methods for manipulating service maps. -type LBMap interface { - UpsertService(*UpsertServiceParams) error - UpsertMaglevLookupTable(uint16, map[string]*loadbalancer.Backend, bool) error - IsMaglevLookupTableRecreated(bool) bool - DeleteService(loadbalancer.L3n4AddrID, int, bool, loadbalancer.SVCNatPolicy) error - AddBackend(*loadbalancer.Backend, bool) error - UpdateBackendWithState(*loadbalancer.Backend) error - DeleteBackendByID(loadbalancer.BackendID) error - AddAffinityMatch(uint16, loadbalancer.BackendID) error - DeleteAffinityMatch(uint16, loadbalancer.BackendID) error - UpdateSourceRanges(uint16, []*cidr.CIDR, []*cidr.CIDR, bool) error - DumpServiceMaps() ([]*loadbalancer.SVC, []error) - DumpBackendMaps() ([]*loadbalancer.Backend, error) - DumpAffinityMatches() (BackendIDByServiceIDSet, error) - DumpSourceRanges(bool) (SourceRangeSetByServiceID, error) - ExistsSockRevNat(cookie uint64, addr net.IP, port uint16) bool -} - -type UpsertServiceParams struct { - ID uint16 - IP net.IP - Port uint16 - Protocol uint8 - - // PreferredBackends is a subset of ActiveBackends - // Note: this is only used in clustermesh with service affinity annotation. - PreferredBackends map[string]*loadbalancer.Backend - ActiveBackends map[string]*loadbalancer.Backend - NonActiveBackends []loadbalancer.BackendID - PrevBackendsCount int - IPv6 bool - Type loadbalancer.SVCType - ForwardingMode loadbalancer.SVCForwardingMode - NatPolicy loadbalancer.SVCNatPolicy - SourceRangesPolicy loadbalancer.SVCSourceRangesPolicy - ExtLocal bool - IntLocal bool - Scope uint8 - SessionAffinity bool - SessionAffinityTimeoutSec uint32 - CheckSourceRange bool - UseMaglev bool - L7LBProxyPort uint16 // Non-zero for L7 LB services - Name loadbalancer.ServiceName // Fully qualified name of the service - LoopbackHostport bool - LoadBalancingAlgorithm loadbalancer.SVCLoadBalancingAlgorithm -} - -// GetOrderedBackends returns an ordered list of backends with all the sorted -// preferred backend followed by active and non-active backends. -// Encapsulates logic to be also used in unit tests. -func (p *UpsertServiceParams) GetOrderedBackends() []loadbalancer.BackendID { - backendIDs := make([]loadbalancer.BackendID, 0, len(p.ActiveBackends)+len(p.NonActiveBackends)) - for _, b := range p.ActiveBackends { - backendIDs = append(backendIDs, b.ID) - } - - preferredMap := map[loadbalancer.BackendID]struct{}{} - for _, b := range p.PreferredBackends { - preferredMap[b.ID] = struct{}{} - } - - // Map iterations are non-deterministic so sort the backends by their IDs - // in order to maintain the same order before they are populated in BPF maps. - // This will minimize disruption to existing connections to the backends in the datapath. - sort.Slice(backendIDs, func(i, j int) bool { - // compare preferred flags of two backend IDs - _, firstPreferred := preferredMap[backendIDs[i]] - _, secondPreferred := preferredMap[backendIDs[j]] - - if firstPreferred && secondPreferred { - return backendIDs[i] < backendIDs[j] - } - - if firstPreferred { - return true - } - - if secondPreferred { - return false - } - - return backendIDs[i] < backendIDs[j] - }) - - // Add the non-active backends to the end of preferred/active backends list so that they are - // not considered while selecting backends to load-balance service traffic. - if len(p.NonActiveBackends) > 0 { - backendIDs = append(backendIDs, p.NonActiveBackends...) - } - - return backendIDs -} - -// BackendIDByServiceIDSet is the type of a set for checking whether a backend -// belongs to a given service -type BackendIDByServiceIDSet map[uint16]map[loadbalancer.BackendID]struct{} // svc ID => backend ID - -type SourceRangeSetByServiceID map[uint16][]*cidr.CIDR // svc ID => src range CIDRs diff --git a/vendor/github.com/cilium/cilium/pkg/datapath/types/loader.go b/vendor/github.com/cilium/cilium/pkg/datapath/types/loader.go deleted file mode 100644 index f4fafb5eec..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/datapath/types/loader.go +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package types - -import ( - "context" - "io" - "net" - "net/netip" - - "github.com/cilium/cilium/pkg/datapath/loader/metrics" - "github.com/cilium/cilium/pkg/datapath/tunnel" -) - -// Loader is an interface to abstract out loading of datapath programs. -type Loader interface { - CallsMapPath(id uint16) string - CustomCallsMapPath(id uint16) string - Unload(ep Endpoint) - HostDatapathInitialized() <-chan struct{} - - ReloadDatapath(ctx context.Context, ep Endpoint, cfg *LocalNodeConfiguration, stats *metrics.SpanStat) (string, error) - ReinitializeXDP(ctx context.Context, cfg *LocalNodeConfiguration, extraCArgs []string) error - EndpointHash(cfg EndpointConfiguration, lnCfg *LocalNodeConfiguration) (string, error) - ReinitializeHostDev(ctx context.Context, mtu int) error - Reinitialize(ctx context.Context, cfg *LocalNodeConfiguration, tunnelConfig tunnel.Config, iptMgr IptablesManager, p Proxy) error - WriteEndpointConfig(w io.Writer, cfg EndpointConfiguration, lnCfg *LocalNodeConfiguration) error -} - -// PreFilter an interface for an XDP pre-filter. -type PreFilter interface { - Enabled() bool - WriteConfig(fw io.Writer) - Dump(to []string) ([]string, int64) - Insert(revision int64, cidrs []net.IPNet) error - Delete(revision int64, cidrs []net.IPNet) error -} - -// Proxy is any type which installs rules related to redirecting traffic to -// a proxy. -type Proxy interface { - ReinstallRoutingRules(mtu int) error -} - -// IptablesManager manages iptables rules. -type IptablesManager interface { - // InstallProxyRules creates the necessary datapath config (e.g., iptables - // rules for redirecting host proxy traffic on a specific ProxyPort) - InstallProxyRules(proxyPort uint16, name string) - - // SupportsOriginalSourceAddr tells if the datapath supports - // use of original source addresses in proxy upstream - // connections. - SupportsOriginalSourceAddr() bool - - // GetProxyPorts fetches the existing proxy ports configured in the - // datapath. Used early in bootstrap to reopen proxy ports. - GetProxyPorts() map[string]uint16 - - // InstallNoTrackRules is explicitly called when a pod has valid - // "policy.cilium.io/no-track-port" annotation. When - // InstallNoConntrackIptRules flag is set, a super set of v4 NOTRACK - // rules will be automatically installed upon agent bootstrap (via - // function addNoTrackPodTrafficRules) and this function will be - // skipped. When InstallNoConntrackIptRules is not set, this function - // will be executed to install NOTRACK rules. The rules installed by - // this function is very specific, for now, the only user is - // node-local-dns pods. - InstallNoTrackRules(ip netip.Addr, port uint16) - - // See comments for InstallNoTrackRules. - RemoveNoTrackRules(ip netip.Addr, port uint16) -} - -// CompilationLock is a interface over a mutex, it is used by both the loader, daemon -// and endpoint manager to lock the compilation process. This is a bit of a layer violation -// since certain methods on the loader such as CompileAndLoad and CompileOrLoad expect the -// lock to be taken before being called. -// -// Once we have moved header file generation from the endpoint manager into the loader, we can -// remove this interface and have the loader manage the lock internally. -type CompilationLock interface { - Lock() - Unlock() - RLock() - RUnlock() -} diff --git a/vendor/github.com/cilium/cilium/pkg/datapath/types/node.go b/vendor/github.com/cilium/cilium/pkg/datapath/types/node.go deleted file mode 100644 index d45787f1c9..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/datapath/types/node.go +++ /dev/null @@ -1,272 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package types - -import ( - "context" - "net" - - "github.com/cilium/cilium/api/v1/models" - "github.com/cilium/cilium/pkg/cidr" - "github.com/cilium/cilium/pkg/datapath/tables" - "github.com/cilium/cilium/pkg/datapath/xdp" - nodeTypes "github.com/cilium/cilium/pkg/node/types" -) - -type MTUConfiguration interface { - GetDeviceMTU() int - GetRouteMTU() int - GetRoutePostEncryptMTU() int -} - -// LocalNodeConfiguration represents the configuration of the local node -// -// This configuration struct is immutable even when passed by reference. -// When the configuration is changed at runtime a new instance is allocated -// and passed down. -// -// +deepequal-gen=true -type LocalNodeConfiguration struct { - // NodeIPv4 is the primary IPv4 address of this node. - // Mutable at runtime. - NodeIPv4 net.IP - - // NodeIPv6 is the primary IPv6 address of this node. - // Mutable at runtime. - NodeIPv6 net.IP - - // CiliumInternalIPv4 is the internal IP address assigned to the cilium_host - // interface. - // Immutable at runtime. - CiliumInternalIPv4 net.IP - - // CiliumInternalIPv6 is the internal IP address assigned to the cilium_host - // interface. - // Immutable at runtime. - CiliumInternalIPv6 net.IP - - // AllocCIDRIPv4 is the IPv4 allocation CIDR from which IP addresses for - // endpoints are allocated from. - // Immutable at runtime. - AllocCIDRIPv4 *cidr.CIDR - - // AllocCIDRIPv6 is the IPv6 allocation CIDR from which IP addresses for - // endpoints are allocated from. - // Immutable at runtime. - AllocCIDRIPv6 *cidr.CIDR - - // NativeRoutingCIDRIPv4 is the v4 CIDR in which pod IPs are routable. - NativeRoutingCIDRIPv4 *cidr.CIDR - - // NativeRoutingCIDRIPv6 is the v4 CIDR in which pod IPs are routable. - NativeRoutingCIDRIPv6 *cidr.CIDR - - // LoopbackIPv4 is the IPv4 loopback address. - // Immutable at runtime. - LoopbackIPv4 net.IP - - // Devices is the native network devices selected for datapath use. - // Mutable at runtime. - Devices []*tables.Device - - // DirectRoutingDevice is the device used in direct routing mode. - // Mutable at runtime. - DirectRoutingDevice *tables.Device - - // NodeAddresses are the IP addresses of the local node that are considered - // as this node's addresses. From this set we pick the addresses that are - // used as NodePort frontends and the addresses to use for BPF masquerading. - // Mutable at runtime. - NodeAddresses []tables.NodeAddress - - // DeriveMasqIPAddrFromDevice overrides the interface name to use for deriving - // the masquerading IP address for the node. - DeriveMasqIPAddrFromDevice string - - // HostEndpointID is the endpoint ID assigned to the host endpoint. - // Immutable at runtime. - HostEndpointID uint64 - - // DeviceMTU is the MTU used on workload facing devices. - // This field is immutable at runtime. The value will not change in - // subsequent calls to NodeConfigurationChanged(). - DeviceMTU int - - // RouteMTU is the MTU used on the network. - // This field is immutable at runtime. The value will not change in - // subsequent calls to NodeConfigurationChanged(). - RouteMTU int - - // RoutePostEncryptMTU is the MTU without the encryption overhead - // included. - // This field is immutable at runtime. The value will not change in - // subsequent calls to NodeConfigurationChanged(). - RoutePostEncryptMTU int - - // AuxiliaryPrefixes is the list of auxiliary prefixes that should be - // configured in addition to the node PodCIDR - // - // This field is mutable. The implementation of - // NodeConfigurationChanged() must adjust the routes accordingly. - AuxiliaryPrefixes []*cidr.CIDR - - // EnableIPv4 enables use of IPv4. Routing to the IPv4 allocation CIDR - // of other nodes must be enabled. - // - // This field is immutable at runtime. The value will not change in - // subsequent calls to NodeConfigurationChanged(). - EnableIPv4 bool - - // EnableIPv6 enables use of IPv6. Routing to the IPv6 allocation CIDR - // of other nodes must be enabled. - // - // This field is immutable at runtime. The value will not change in - // subsequent calls to NodeConfigurationChanged(). - EnableIPv6 bool - - // EnableEncapsulation enables use of encapsulation in communication - // between nodes. - // - // This field is immutable at runtime. The value will not change in - // subsequent calls to NodeConfigurationChanged(). - EnableEncapsulation bool - - // EnableAutoDirectRouting enables the use of direct routes for - // communication between nodes if two nodes have direct L2 - // connectivity. - // - // EnableAutoDirectRouting must be compatible with EnableEncapsulation - // and must provide a fallback to use encapsulation if direct routing - // is not feasible and encapsulation is enabled. - // - // This field is immutable at runtime. The value will not change in - // subsequent calls to NodeConfigurationChanged(). - EnableAutoDirectRouting bool - - // DirectRoutingSkipUnreachable will skip any direct routes between - // nodes if they have different L2 connectivity, only adding L2 routes - // if the underlying L2 shares the same gateway. - // - // This field is immutable at runtime. The value will not change in - // subsequent calls to NodeConfigurationChanged(). - DirectRoutingSkipUnreachable bool - - // EnableLocalNodeRoute enables installation of the route which points - // the allocation prefix of the local node. Disabling this option is - // useful when another component is responsible for the routing of the - // allocation CIDR IPs into Cilium endpoints. - EnableLocalNodeRoute bool - - // EnableIPSec enables IPSec routes - EnableIPSec bool - - // EnableIPSecEncryptedOverlay enables IPSec routes for overlay traffic - EnableIPSecEncryptedOverlay bool - - // EncryptNode enables encrypting NodeIP traffic - EncryptNode bool - - // IPv4PodSubnets is a list of IPv4 subnets that pod IPs are assigned from - // these are then used when encryption is enabled to configure the node - // for encryption over these subnets at node initialization. - IPv4PodSubnets []*cidr.CIDR - - // IPv6PodSubnets is a list of IPv6 subnets that pod IPs are assigned from - // these are then used when encryption is enabled to configure the node - // for encryption over these subnets at node initialization. - IPv6PodSubnets []*cidr.CIDR - - // XDPConfig holds configuration options to determine how the node should - // handle XDP programs. - XDPConfig xdp.Config - - // RoutingMode is the current routing mode of the local node. - // Can be 'native' or 'tunnel'. - RoutingMode string -} - -func (cfg *LocalNodeConfiguration) DeviceNames() []string { - return tables.DeviceNames(cfg.Devices) -} - -func (cfg *LocalNodeConfiguration) GetIPv4PodSubnets() []*net.IPNet { - return cidr.CIDRsToIPNets(cfg.IPv4PodSubnets) -} - -func (cfg *LocalNodeConfiguration) GetIPv6PodSubnets() []*net.IPNet { - return cidr.CIDRsToIPNets(cfg.IPv6PodSubnets) -} - -// NodeHandler handles node related events such as addition, update or deletion -// of nodes or changes to the local node configuration. -// -// Node events apply to the local node as well as to remote nodes. The -// implementation can differ between the own local node and remote nodes by -// calling node.IsLocal(). -type NodeHandler interface { - // Name identifies the handler, this is used in logging/reporting handler - // reconciliation errors. - Name() string - - // NodeAdd is called when a node is discovered for the first time. - NodeAdd(newNode nodeTypes.Node) error - - // NodeUpdate is called when a node definition changes. Both the old - // and new node definition is provided. NodeUpdate() is never called - // before NodeAdd() is called for a particular node. - NodeUpdate(oldNode, newNode nodeTypes.Node) error - - // NodeDelete is called after a node has been deleted - NodeDelete(node nodeTypes.Node) error - - // AllNodeValidateImplementation is called to validate the implementation - // of all nodes in the node cache. - AllNodeValidateImplementation() - - // NodeValidateImplementation is called to validate the implementation of - // the node in the datapath. This function is intended to be run on an - // interval to ensure that the datapath is consistently converged. - NodeValidateImplementation(node nodeTypes.Node) error - - // NodeConfigurationChanged is called when the local node configuration - // has changed - NodeConfigurationChanged(config LocalNodeConfiguration) error -} - -type NodeNeighbors interface { - // NodeNeighDiscoveryEnabled returns whether node neighbor discovery is enabled - NodeNeighDiscoveryEnabled() bool - - // NodeNeighborRefresh is called to refresh node neighbor table - NodeNeighborRefresh(ctx context.Context, node nodeTypes.Node, refresh bool) error - - // NodeCleanNeighbors cleans all neighbor entries for the direct routing device - // and the encrypt interface. - NodeCleanNeighbors(migrateOnly bool) - - // InsertMiscNeighbor inserts a neighbor entry for the address passed via newNode. - // This is needed for in-agent users where neighbors outside the cluster need to - // be added, for example, for external service backends. - InsertMiscNeighbor(newNode *nodeTypes.Node) - - // DeleteMiscNeighbor delets a eighbor entry for the address passed via oldNode. - // This is needed to delete the entries which have been inserted at an earlier - // point in time through InsertMiscNeighbor. - DeleteMiscNeighbor(oldNode *nodeTypes.Node) -} - -type NodeIDHandler interface { - // GetNodeIP returns the string node IP that was previously registered as the given node ID. - GetNodeIP(uint16) string - - // GetNodeID gets the node ID for the given node IP. If none is found, exists is false. - GetNodeID(nodeIP net.IP) (nodeID uint16, exists bool) - - // DumpNodeIDs returns all node IDs and their associated IP addresses. - DumpNodeIDs() []*models.NodeID - - // RestoreNodeIDs restores node IDs and their associated IP addresses from the - // BPF map and into the node handler in-memory copy. - RestoreNodeIDs() -} diff --git a/vendor/github.com/cilium/cilium/pkg/datapath/types/node_addressing.go b/vendor/github.com/cilium/cilium/pkg/datapath/types/node_addressing.go deleted file mode 100644 index 5c2fb2be98..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/datapath/types/node_addressing.go +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package types - -import ( - "net" - - "github.com/cilium/cilium/pkg/cidr" -) - -// NodeAddressingFamily is the node addressing information for a particular -// address family -type NodeAddressingFamily interface { - // Router is the address that will act as the router on each node where - // an agent is running on. Endpoints have a default route that points - // to this address. - Router() net.IP - - // PrimaryExternal is the primary external address of the node. Nodes - // must be able to reach each other via this address. - PrimaryExternal() net.IP - - // AllocationCIDR is the CIDR used for IP allocation of all endpoints - // on the node - AllocationCIDR() *cidr.CIDR -} - -// NodeAddressing implements addressing of a node -type NodeAddressing interface { - IPv6() NodeAddressingFamily - IPv4() NodeAddressingFamily -} diff --git a/vendor/github.com/cilium/cilium/pkg/datapath/types/orchestrator.go b/vendor/github.com/cilium/cilium/pkg/datapath/types/orchestrator.go deleted file mode 100644 index 131ae99415..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/datapath/types/orchestrator.go +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package types - -import ( - "context" - "io" - - "github.com/cilium/cilium/pkg/datapath/loader/metrics" -) - -type Orchestrator interface { - Reinitialize(ctx context.Context) error - - ReloadDatapath(ctx context.Context, ep Endpoint, stats *metrics.SpanStat) (string, error) - ReinitializeXDP(ctx context.Context, extraCArgs []string) error - EndpointHash(cfg EndpointConfiguration) (string, error) - WriteEndpointConfig(w io.Writer, cfg EndpointConfiguration) error - Unload(ep Endpoint) -} diff --git a/vendor/github.com/cilium/cilium/pkg/datapath/types/zz_generated.deepequal.go b/vendor/github.com/cilium/cilium/pkg/datapath/types/zz_generated.deepequal.go deleted file mode 100644 index 44edeb933a..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/datapath/types/zz_generated.deepequal.go +++ /dev/null @@ -1,279 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -// Code generated by deepequal-gen. DO NOT EDIT. - -package types - -// DeepEqual is an autogenerated deepequal function, deeply comparing the -// receiver with other. in must be non-nil. -func (in *LocalNodeConfiguration) DeepEqual(other *LocalNodeConfiguration) bool { - if other == nil { - return false - } - - if ((in.NodeIPv4 != nil) && (other.NodeIPv4 != nil)) || ((in.NodeIPv4 == nil) != (other.NodeIPv4 == nil)) { - in, other := &in.NodeIPv4, &other.NodeIPv4 - if other == nil { - return false - } - - if len(*in) != len(*other) { - return false - } else { - for i, inElement := range *in { - if inElement != (*other)[i] { - return false - } - } - } - } - - if ((in.NodeIPv6 != nil) && (other.NodeIPv6 != nil)) || ((in.NodeIPv6 == nil) != (other.NodeIPv6 == nil)) { - in, other := &in.NodeIPv6, &other.NodeIPv6 - if other == nil { - return false - } - - if len(*in) != len(*other) { - return false - } else { - for i, inElement := range *in { - if inElement != (*other)[i] { - return false - } - } - } - } - - if ((in.CiliumInternalIPv4 != nil) && (other.CiliumInternalIPv4 != nil)) || ((in.CiliumInternalIPv4 == nil) != (other.CiliumInternalIPv4 == nil)) { - in, other := &in.CiliumInternalIPv4, &other.CiliumInternalIPv4 - if other == nil { - return false - } - - if len(*in) != len(*other) { - return false - } else { - for i, inElement := range *in { - if inElement != (*other)[i] { - return false - } - } - } - } - - if ((in.CiliumInternalIPv6 != nil) && (other.CiliumInternalIPv6 != nil)) || ((in.CiliumInternalIPv6 == nil) != (other.CiliumInternalIPv6 == nil)) { - in, other := &in.CiliumInternalIPv6, &other.CiliumInternalIPv6 - if other == nil { - return false - } - - if len(*in) != len(*other) { - return false - } else { - for i, inElement := range *in { - if inElement != (*other)[i] { - return false - } - } - } - } - - if (in.AllocCIDRIPv4 == nil) != (other.AllocCIDRIPv4 == nil) { - return false - } else if in.AllocCIDRIPv4 != nil { - if !in.AllocCIDRIPv4.DeepEqual(other.AllocCIDRIPv4) { - return false - } - } - - if (in.AllocCIDRIPv6 == nil) != (other.AllocCIDRIPv6 == nil) { - return false - } else if in.AllocCIDRIPv6 != nil { - if !in.AllocCIDRIPv6.DeepEqual(other.AllocCIDRIPv6) { - return false - } - } - - if (in.NativeRoutingCIDRIPv4 == nil) != (other.NativeRoutingCIDRIPv4 == nil) { - return false - } else if in.NativeRoutingCIDRIPv4 != nil { - if !in.NativeRoutingCIDRIPv4.DeepEqual(other.NativeRoutingCIDRIPv4) { - return false - } - } - - if (in.NativeRoutingCIDRIPv6 == nil) != (other.NativeRoutingCIDRIPv6 == nil) { - return false - } else if in.NativeRoutingCIDRIPv6 != nil { - if !in.NativeRoutingCIDRIPv6.DeepEqual(other.NativeRoutingCIDRIPv6) { - return false - } - } - - if ((in.LoopbackIPv4 != nil) && (other.LoopbackIPv4 != nil)) || ((in.LoopbackIPv4 == nil) != (other.LoopbackIPv4 == nil)) { - in, other := &in.LoopbackIPv4, &other.LoopbackIPv4 - if other == nil { - return false - } - - if len(*in) != len(*other) { - return false - } else { - for i, inElement := range *in { - if inElement != (*other)[i] { - return false - } - } - } - } - - if ((in.Devices != nil) && (other.Devices != nil)) || ((in.Devices == nil) != (other.Devices == nil)) { - in, other := &in.Devices, &other.Devices - if other == nil { - return false - } - - if len(*in) != len(*other) { - return false - } else { - for i, inElement := range *in { - if !inElement.DeepEqual((*other)[i]) { - return false - } - } - } - } - - if (in.DirectRoutingDevice == nil) != (other.DirectRoutingDevice == nil) { - return false - } else if in.DirectRoutingDevice != nil { - if !in.DirectRoutingDevice.DeepEqual(other.DirectRoutingDevice) { - return false - } - } - - if ((in.NodeAddresses != nil) && (other.NodeAddresses != nil)) || ((in.NodeAddresses == nil) != (other.NodeAddresses == nil)) { - in, other := &in.NodeAddresses, &other.NodeAddresses - if other == nil { - return false - } - - if len(*in) != len(*other) { - return false - } else { - for i, inElement := range *in { - if !inElement.DeepEqual(&(*other)[i]) { - return false - } - } - } - } - - if in.DeriveMasqIPAddrFromDevice != other.DeriveMasqIPAddrFromDevice { - return false - } - if in.HostEndpointID != other.HostEndpointID { - return false - } - if in.DeviceMTU != other.DeviceMTU { - return false - } - if in.RouteMTU != other.RouteMTU { - return false - } - if in.RoutePostEncryptMTU != other.RoutePostEncryptMTU { - return false - } - if ((in.AuxiliaryPrefixes != nil) && (other.AuxiliaryPrefixes != nil)) || ((in.AuxiliaryPrefixes == nil) != (other.AuxiliaryPrefixes == nil)) { - in, other := &in.AuxiliaryPrefixes, &other.AuxiliaryPrefixes - if other == nil { - return false - } - - if len(*in) != len(*other) { - return false - } else { - for i, inElement := range *in { - if !inElement.DeepEqual((*other)[i]) { - return false - } - } - } - } - - if in.EnableIPv4 != other.EnableIPv4 { - return false - } - if in.EnableIPv6 != other.EnableIPv6 { - return false - } - if in.EnableEncapsulation != other.EnableEncapsulation { - return false - } - if in.EnableAutoDirectRouting != other.EnableAutoDirectRouting { - return false - } - if in.DirectRoutingSkipUnreachable != other.DirectRoutingSkipUnreachable { - return false - } - if in.EnableLocalNodeRoute != other.EnableLocalNodeRoute { - return false - } - if in.EnableIPSec != other.EnableIPSec { - return false - } - if in.EnableIPSecEncryptedOverlay != other.EnableIPSecEncryptedOverlay { - return false - } - if in.EncryptNode != other.EncryptNode { - return false - } - if ((in.IPv4PodSubnets != nil) && (other.IPv4PodSubnets != nil)) || ((in.IPv4PodSubnets == nil) != (other.IPv4PodSubnets == nil)) { - in, other := &in.IPv4PodSubnets, &other.IPv4PodSubnets - if other == nil { - return false - } - - if len(*in) != len(*other) { - return false - } else { - for i, inElement := range *in { - if !inElement.DeepEqual((*other)[i]) { - return false - } - } - } - } - - if ((in.IPv6PodSubnets != nil) && (other.IPv6PodSubnets != nil)) || ((in.IPv6PodSubnets == nil) != (other.IPv6PodSubnets == nil)) { - in, other := &in.IPv6PodSubnets, &other.IPv6PodSubnets - if other == nil { - return false - } - - if len(*in) != len(*other) { - return false - } else { - for i, inElement := range *in { - if !inElement.DeepEqual((*other)[i]) { - return false - } - } - } - } - - if in.XDPConfig != other.XDPConfig { - return false - } - - if in.RoutingMode != other.RoutingMode { - return false - } - - return true -} diff --git a/vendor/github.com/cilium/cilium/pkg/datapath/xdp/cell.go b/vendor/github.com/cilium/cilium/pkg/datapath/xdp/cell.go deleted file mode 100644 index 02e048ba2f..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/datapath/xdp/cell.go +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package xdp - -import ( - "fmt" - "log/slog" - - "github.com/cilium/hive/cell" - - "github.com/cilium/cilium/pkg/option" -) - -// Cell is a cell that provides the configuration parameters -// for XDP based on requests from external modules. -var Cell = cell.Module( - "datapath-xdp-config", - "XDP configuration", - - cell.Provide( - newConfig, - - // Determine the XDP mode requested by XDP LoadBalancer acceleration - // settings. This is done here since the relevant LoadBalancer configuration - // has not been modularized yet. - // - // Users configure the `loadbalancer.acceleration` helm value, which is - // passed to cilium through --bpf-lb-acceleration. This flag's value is - // stored in `option.LoadBalancerAcceleration`, which is then used during - // DaemonConfig's population to set `DaemonConfig.NodePortAcceleration`. - // - // Eventually, a cell will be created to handle load balancer settings, - // which should import this module's EnablerOut function to request an - // XDP Mode based on the user provided settings. - func(dcfg *option.DaemonConfig) (EnablerOut, error) { - xdpMode, ok := map[string]AccelerationMode{ - "": AccelerationModeDisabled, - option.NodePortAccelerationDisabled: AccelerationModeDisabled, - option.NodePortAccelerationGeneric: AccelerationModeGeneric, - option.NodePortAccelerationBestEffort: AccelerationModeBestEffort, - option.NodePortAccelerationNative: AccelerationModeNative, - }[dcfg.NodePortAcceleration] - - if !ok { - return NewEnabler(AccelerationModeDisabled), fmt.Errorf("Invalid value for --%s: %s", option.NodePortAcceleration, dcfg.NodePortAcceleration) - } - - return NewEnabler(xdpMode), nil - }, - ), - - cell.Invoke(func(c Config, l *slog.Logger) { - l.Info("Determined final XDP mode", "acceleration-mode", c.AccelerationMode(), "mode", c.Mode()) - }), -) diff --git a/vendor/github.com/cilium/cilium/pkg/datapath/xdp/xdp.go b/vendor/github.com/cilium/cilium/pkg/datapath/xdp/xdp.go deleted file mode 100644 index 66a6cc37e8..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/datapath/xdp/xdp.go +++ /dev/null @@ -1,208 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package xdp - -import ( - "fmt" - - "github.com/cilium/ebpf/link" - "github.com/cilium/hive/cell" -) - -// AccelerationMode represents the mode to use when loading XDP programs. -// They are wrappers around the underlying mode names passed to -// the traffic control (tc) system in the kernel. -type AccelerationMode string - -const ( - // AccelerationModeNative for loading progs with TCModeLinkDriver - AccelerationModeNative AccelerationMode = "native" - - // AccelerationModeBestEffort for loading progs with TCModeLinkDriver, - // falling back to TCModeLinkGeneric if unsupported by the - // underlying device. - AccelerationModeBestEffort AccelerationMode = "best-effort" - - // AccelerationModeGeneric for loading progs with TCModeLinkGeneric - AccelerationModeGeneric AccelerationMode = "testing-only" - - // AccelerationModeDisabled for not having XDP enabled - AccelerationModeDisabled AccelerationMode = "disabled" -) - -// Mode represents the name of an XDP mode from the perspective -// of the kernel. -type Mode string - -const ( - - // ModeLinkDriver is the tc selector for native XDP - ModeLinkDriver Mode = "xdpdrv" - - // ModeLinkGeneric is the tc selector for generic XDP - ModeLinkGeneric Mode = "xdpgeneric" - - // XDPModeLinkNone for not having XDP enabled - ModeLinkNone Mode = Mode(AccelerationModeDisabled) -) - -// Config represents the materialized XDP configuration to be used, -// depending on its required use by other features. -type Config struct { - mode AccelerationMode -} - -type newConfigIn struct { - cell.In - - Enablers []enabler `group:"request-xdp-mode"` -} - -func newConfig(in newConfigIn) (Config, error) { - cfg := Config{ - mode: AccelerationModeDisabled, - } - - allValidators := []Validator{} - - for _, e := range in.Enablers { - // Ensure the mode given in the enabler is valid. - switch e.mode { - case AccelerationModeBestEffort, AccelerationModeNative, AccelerationModeGeneric, AccelerationModeDisabled: - break - default: - return cfg, fmt.Errorf("unknown xdp mode: %s", e.mode) - } - - if e.mode != cfg.mode { - allValidators = append(allValidators, e.validators...) - - // If an enabler requests a mode that we've already set, - // then there's nothing to do. - if cfg.mode == e.mode { - continue - } - - // If an enabler passes ModeDisabled, it becomes a no-op since - // that's the default. If an enabler wishes to enforce that - // XDP is disabled, it should use a verifier. - if e.mode == AccelerationModeDisabled { - continue - } - - // Ensure ModeNative takes precedence over ModeBestEffort. - // It doesn't make sense the other way around. - if e.mode == AccelerationModeBestEffort && cfg.mode == AccelerationModeNative { - continue - } else if cfg.mode == AccelerationModeBestEffort && e.mode == AccelerationModeNative { - cfg.mode = e.mode - continue - } - - // If a mode has been set and the enabler requests a conflicting - // mode, then raise an error. - if cfg.mode != AccelerationModeDisabled { - return cfg, fmt.Errorf("XDP mode conflict: trying to set conflicting modes %s and %s", - cfg.mode, e.mode) - } - - cfg.mode = e.mode - } - } - - // Perform validation at the end, when the config is fully determined, - // to ensure that processing order does not play a role in the validation. - for _, v := range allValidators { - if err := v(cfg.AccelerationMode(), cfg.Mode()); err != nil { - return cfg, err - } - } - - return cfg, nil -} - -// AccelerationMode is the high-level XDP operating mode for Cilium. -func (cfg Config) AccelerationMode() AccelerationMode { return cfg.mode } - -// Mode, is the underlying mode name that is used for loading the XDP -// program into the kernel. -func (cfg Config) Mode() Mode { - switch cfg.mode { - case AccelerationModeNative, AccelerationModeBestEffort: - return ModeLinkDriver - case AccelerationModeGeneric: - return ModeLinkGeneric - } - - return ModeLinkNone -} - -// Disabled returns true if XDP is disabled based on the configuration. -func (cfg Config) Disabled() bool { return cfg.mode == AccelerationModeDisabled } - -// GetAttachFlags returns the XDP attach flags for the configured TCMode. -func (cfg Config) GetAttachFlags() link.XDPAttachFlags { - switch cfg.mode { - case AccelerationModeNative, AccelerationModeBestEffort: - return link.XDPDriverMode - case AccelerationModeGeneric: - return link.XDPGenericMode - } - - return 0 -} - -// EnablerOut allows requesting to enable a certain XDP operating mode. -type EnablerOut struct { - cell.Out - Enabler enabler `group:"request-xdp-mode"` -} - -// NewEnabler returns an object to be injected through hive to request to -// enable a specific operating mode for XDP. Extra options are meaningful only -// when enable is set to true, and are ignored otherwise. -func NewEnabler(mode AccelerationMode, opts ...enablerOpt) EnablerOut { - enabler := enabler{mode: mode} - - for _, opt := range opts { - opt(&enabler) - } - - return EnablerOut{Enabler: enabler} -} - -type Validator func(AccelerationMode, Mode) error - -// WithValidator allows to register extra validation functions -// to assert that the configured XDP mode the one expected by -// the given feature. -func WithValidator(validator Validator) enablerOpt { - return func(te *enabler) { - te.validators = append(te.validators, validator) - } -} - -// WithEnforceXDPDisabled registers a validation function that -// returns an error if XDP is enabled. -func WithEnforceXDPDisabled(reason string) enablerOpt { - return func(te *enabler) { - te.validators = append( - te.validators, - func(m AccelerationMode, _ Mode) error { - if m != AccelerationModeDisabled { - return fmt.Errorf("XDP config failed validation: XDP must be disabled because %s", reason) - } - - return nil - }, - ) - } -} - -type enabler struct { - mode AccelerationMode - validators []Validator -} - -type enablerOpt func(*enabler) diff --git a/vendor/github.com/cilium/cilium/pkg/endpoint/regeneration/owner.go b/vendor/github.com/cilium/cilium/pkg/endpoint/regeneration/owner.go deleted file mode 100644 index c86ab7aacf..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/endpoint/regeneration/owner.go +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package regeneration - -import ( - "context" - - datapath "github.com/cilium/cilium/pkg/datapath/types" - "github.com/cilium/cilium/pkg/fqdn/restore" - "github.com/cilium/cilium/pkg/identity" - monitorAPI "github.com/cilium/cilium/pkg/monitor/api" -) - -// Owner is the interface defines the requirements for anybody owning policies. -type Owner interface { - // QueueEndpointBuild puts the given endpoint in the processing queue - QueueEndpointBuild(ctx context.Context, epID uint64) (func(), error) - - // GetCompilationLock returns the mutex responsible for synchronizing compilation - // of BPF programs. - GetCompilationLock() datapath.CompilationLock - - // SendNotification is called to emit an agent notification - SendNotification(msg monitorAPI.AgentNotifyMessage) error - - // Loader returns a reference to the loader implementation. - Loader() datapath.Loader - - Orchestrator() datapath.Orchestrator - - BandwidthManager() datapath.BandwidthManager - - IPTablesManager() datapath.IptablesManager - - // GetDNSRules creates a fresh copy of DNS rules that can be used when - // endpoint is restored on a restart. - // The endpoint lock must not be held while calling this function. - GetDNSRules(epID uint16) restore.DNSRules - - // RemoveRestoredDNSRules removes any restored DNS rules for - // this endpoint from the DNS proxy. - RemoveRestoredDNSRules(epID uint16) - - AddIdentity(*identity.Identity) - RemoveIdentity(*identity.Identity) - RemoveOldAddNewIdentity(*identity.Identity, *identity.Identity) -} diff --git a/vendor/github.com/cilium/cilium/pkg/endpoint/regeneration/regeneration_context.go b/vendor/github.com/cilium/cilium/pkg/endpoint/regeneration/regeneration_context.go deleted file mode 100644 index 0a8395be6c..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/endpoint/regeneration/regeneration_context.go +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package regeneration - -import ( - "context" -) - -// DatapathRegenerationLevel determines what is expected of the datapath when -// a regeneration event is processed. -type DatapathRegenerationLevel int - -const ( - // Invalid is the default level to enforce explicit setting of - // the regeneration level. - Invalid DatapathRegenerationLevel = iota - // RegenerateWithoutDatapath indicates that datapath rebuild or reload - // is not required to implement this regeneration. - RegenerateWithoutDatapath - // RegenerateWithDatapath indicates that the datapath must be - // recompiled and reloaded to implement this regeneration. - RegenerateWithDatapath -) - -// String converts a DatapathRegenerationLevel into a human-readable string. -func (r DatapathRegenerationLevel) String() string { - switch r { - case Invalid: - return "invalid" - case RegenerateWithoutDatapath: - return "no-rebuild" - case RegenerateWithDatapath: - return "rewrite+load" - default: - break - } - return "BUG: Unknown DatapathRegenerationLevel" -} - -// ExternalRegenerationMetadata contains any information about a regeneration that -// the endpoint subsystem should be made aware of for a given endpoint. -type ExternalRegenerationMetadata struct { - // Reason provides context to source for the regeneration, which is - // used to generate useful log messages. - Reason string - - // RegenerationLevel forces datapath regeneration according to the - // levels defined in the DatapathRegenerationLevel description. - RegenerationLevel DatapathRegenerationLevel - - ParentContext context.Context -} diff --git a/vendor/github.com/cilium/cilium/pkg/fqdn/restore/restore.go b/vendor/github.com/cilium/cilium/pkg/fqdn/restore/restore.go deleted file mode 100644 index 7644a48a69..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/fqdn/restore/restore.go +++ /dev/null @@ -1,188 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -// The restore package provides data structures important to restoring -// DNS proxy rules. This package serves as a central source for these -// structures. -// Note that these are marshaled as JSON and any changes need to be compatible -// across an upgrade! -package restore - -import ( - "bytes" - "fmt" - "net/netip" - "sort" - "testing" - - "github.com/cilium/cilium/pkg/u8proto" -) - -// PortProtoV2 is 1 value at bit position 24. -const PortProtoV2 = 1 << 24 - -// PortProto is uint32 that encodes two different -// versions of port protocol keys. Version 1 is protocol -// agnostic and (naturally) encodes no values at bit -// positions 16-31. Version 2 encodes protocol at bit -// positions 16-23, and bit position 24 encodes a 1 -// value to indicate that it is Version 2. Both versions -// encode the port at the -// bit positions 0-15. -// -// This works because Version 1 will naturally encode -// no values at postions 16-31 as the original Version 1 -// was a uint16. Version 2 enforces a 1 value at the 24th -// bit position, so it will always be legible. -type PortProto uint32 - -// MakeV2PortProto returns a Version 2 port protocol. -func MakeV2PortProto(port uint16, proto u8proto.U8proto) PortProto { - return PortProto(PortProtoV2 | (uint32(proto) << 16) | uint32(port)) -} - -// IsPortV2 returns true if the PortProto -// is Version 2. -func (pp PortProto) IsPortV2() bool { - return PortProtoV2&pp == PortProtoV2 -} - -// Port returns the port of the PortProto -func (pp PortProto) Port() uint16 { - return uint16(pp & 0x0000_ffff) -} - -// Protocol returns the protocol of the -// PortProto. It returns "0" for Version 1. -func (pp PortProto) Protocol() uint8 { - return uint8((pp & 0xff_0000) >> 16) -} - -// ToV1 returns the Version 1 (that is, "port") -// version of the PortProto. -func (pp PortProto) ToV1() PortProto { - return pp & 0x0000_ffff -} - -// String returns the decimal representation -// of PortProtocol in string form. -func (pp PortProto) String() string { - return fmt.Sprintf("%d", pp) -} - -// DNSRules contains IP-based DNS rules for a set of port-protocols (e.g., UDP/53) -type DNSRules map[PortProto]IPRules - -// IPRules is an unsorted collection of IPrules -type IPRules []IPRule - -// IPRule stores the allowed destination IPs for a DNS names matching a regex -type IPRule struct { - Re RuleRegex - IPs map[RuleIPOrCIDR]struct{} // IPs, nil set is wildcard and allows all IPs! -} - -// RuleIPOrCIDR is one allowed destination IP or CIDR -// It marshals to/from text in a way that is compatible with net.IP and CIDRs -type RuleIPOrCIDR netip.Prefix - -func ParseRuleIPOrCIDR(s string) (ip RuleIPOrCIDR, err error) { - err = ip.UnmarshalText([]byte(s)) - return -} - -func (ip RuleIPOrCIDR) ContainsAddr(addr RuleIPOrCIDR) bool { - return addr.IsAddr() && netip.Prefix(ip).Contains(netip.Prefix(addr).Addr()) -} - -func (ip RuleIPOrCIDR) IsAddr() bool { - return netip.Prefix(ip).Bits() == -1 -} - -func (ip RuleIPOrCIDR) String() string { - if ip.IsAddr() { - return netip.Prefix(ip).Addr().String() - } else { - return netip.Prefix(ip).String() - } -} - -func (ip RuleIPOrCIDR) ToSingleCIDR() RuleIPOrCIDR { - addr := netip.Prefix(ip).Addr() - return RuleIPOrCIDR(netip.PrefixFrom(addr, addr.BitLen())) -} - -func (ip RuleIPOrCIDR) MarshalText() ([]byte, error) { - if ip.IsAddr() { - return netip.Prefix(ip).Addr().MarshalText() - } else { - return netip.Prefix(ip).MarshalText() - } -} - -func (ip *RuleIPOrCIDR) UnmarshalText(b []byte) (err error) { - if b == nil { - return fmt.Errorf("cannot unmarshal nil into RuleIPOrCIDR") - } - if i := bytes.IndexByte(b, byte('/')); i < 0 { - var addr netip.Addr - if err = addr.UnmarshalText(b); err == nil { - *ip = RuleIPOrCIDR(netip.PrefixFrom(addr, 0xff)) - } - } else { - var prefix netip.Prefix - if err = prefix.UnmarshalText(b); err == nil { - *ip = RuleIPOrCIDR(prefix) - } - } - return -} - -// RuleRegex is a wrapper for a pointer to a string so that we can define marshalers for it. -type RuleRegex struct { - Pattern *string -} - -// Sort is only used for testing -// Sorts in place, but returns IPRules for convenience -func (r IPRules) Sort(_ *testing.T) IPRules { - sort.SliceStable(r, func(i, j int) bool { - if r[i].Re.Pattern != nil && r[j].Re.Pattern != nil { - return *r[i].Re.Pattern < *r[j].Re.Pattern - } - if r[i].Re.Pattern != nil { - return true - } - return false - }) - - return r -} - -// Sort is only used for testing -// Sorts in place, but returns DNSRules for convenience -func (r DNSRules) Sort(_ *testing.T) DNSRules { - for pp, ipRules := range r { - if len(ipRules) > 0 { - ipRules = ipRules.Sort(nil) - r[pp] = ipRules - } - } - return r -} - -// UnmarshalText unmarshals json into a RuleRegex -// This must have a pointer receiver, otherwise the RuleRegex remains empty. -func (r *RuleRegex) UnmarshalText(b []byte) error { - pattern := string(b) - r.Pattern = &pattern - return nil -} - -// MarshalText marshals RuleRegex as string -func (r RuleRegex) MarshalText() ([]byte, error) { - if r.Pattern != nil { - return []byte(*r.Pattern), nil - } - return nil, nil -} diff --git a/vendor/github.com/cilium/cilium/pkg/k8s/statedb.go b/vendor/github.com/cilium/cilium/pkg/k8s/statedb.go index 9e32559935..8c1bef50c3 100644 --- a/vendor/github.com/cilium/cilium/pkg/k8s/statedb.go +++ b/vendor/github.com/cilium/cilium/pkg/k8s/statedb.go @@ -106,7 +106,7 @@ type ReflectorConfig[Obj any] struct { // Optional function to transform the objects given by the ListerWatcher. This can // be used to convert into an internal model on the fly to save space and add additional - // fields or to for example implement TableRow/TableHeader for the "db show" command. + // fields or to for example implement TableRow/TableHeader for the "db/show" command. Transform TransformFunc[Obj] // Optional function to transform the object to a set of objects to insert into the table. diff --git a/vendor/github.com/cilium/cilium/pkg/metrics/metrics.go b/vendor/github.com/cilium/cilium/pkg/metrics/metrics.go index 8b72ee68dc..ac6a77f132 100644 --- a/vendor/github.com/cilium/cilium/pkg/metrics/metrics.go +++ b/vendor/github.com/cilium/cilium/pkg/metrics/metrics.go @@ -543,18 +543,6 @@ var ( // BPFMapCapacity is the max capacity of bpf maps, labelled by map group classification. BPFMapCapacity = NoOpGaugeVec - // TriggerPolicyUpdateTotal is the metric to count total number of - // policy update triggers - TriggerPolicyUpdateTotal = NoOpCounterVec - - // TriggerPolicyUpdateFolds is the current level folding that is - // happening when running policy update triggers - TriggerPolicyUpdateFolds = NoOpGauge - - // TriggerPolicyUpdateCallDuration measures the latency and call - // duration of policy update triggers - TriggerPolicyUpdateCallDuration = NoOpObserverVec - // VersionMetric labelled by Cilium version VersionMetric = NoOpGaugeVec @@ -726,9 +714,6 @@ type LegacyMetrics struct { BPFSyscallDuration metric.Vec[metric.Observer] BPFMapOps metric.Vec[metric.Counter] BPFMapCapacity metric.Vec[metric.Gauge] - TriggerPolicyUpdateTotal metric.Vec[metric.Counter] - TriggerPolicyUpdateFolds metric.Gauge - TriggerPolicyUpdateCallDuration metric.Vec[metric.Observer] VersionMetric metric.Vec[metric.Gauge] APILimiterWaitHistoryDuration metric.Vec[metric.Observer] APILimiterWaitDuration metric.Vec[metric.Gauge] @@ -1226,30 +1211,6 @@ func NewLegacyMetrics() *LegacyMetrics { Help: "Capacity of map, tagged by map group. All maps with a capacity of 65536 are grouped under 'default'", }, []string{LabelMapGroup}), - TriggerPolicyUpdateTotal: metric.NewCounterVec(metric.CounterOpts{ - ConfigName: Namespace + "_" + SubsystemTriggers + "_policy_update_total", - Namespace: Namespace, - Subsystem: SubsystemTriggers, - Name: "policy_update_total", - Help: "Total number of policy update trigger invocations labeled by reason", - }, []string{"reason"}), - - TriggerPolicyUpdateFolds: metric.NewGauge(metric.GaugeOpts{ - ConfigName: Namespace + "_" + SubsystemTriggers + "_policy_update_folds", - Namespace: Namespace, - Subsystem: SubsystemTriggers, - Name: "policy_update_folds", - Help: "Current number of folds", - }), - - TriggerPolicyUpdateCallDuration: metric.NewHistogramVec(metric.HistogramOpts{ - ConfigName: Namespace + "_" + SubsystemTriggers + "_policy_update_call_duration_seconds", - Namespace: Namespace, - Subsystem: SubsystemTriggers, - Name: "policy_update_call_duration_seconds", - Help: "Duration of policy update trigger", - }, []string{LabelType}), - VersionMetric: metric.NewGaugeVec(metric.GaugeOpts{ ConfigName: Namespace + "_version", Namespace: Namespace, @@ -1465,9 +1426,6 @@ func NewLegacyMetrics() *LegacyMetrics { BPFSyscallDuration = lm.BPFSyscallDuration BPFMapOps = lm.BPFMapOps BPFMapCapacity = lm.BPFMapCapacity - TriggerPolicyUpdateTotal = lm.TriggerPolicyUpdateTotal - TriggerPolicyUpdateFolds = lm.TriggerPolicyUpdateFolds - TriggerPolicyUpdateCallDuration = lm.TriggerPolicyUpdateCallDuration VersionMetric = lm.VersionMetric APILimiterWaitHistoryDuration = lm.APILimiterWaitHistoryDuration APILimiterWaitDuration = lm.APILimiterWaitDuration diff --git a/vendor/github.com/cilium/cilium/pkg/option/config.go b/vendor/github.com/cilium/cilium/pkg/option/config.go index 2d905a2bf2..9ef2c30655 100644 --- a/vendor/github.com/cilium/cilium/pkg/option/config.go +++ b/vendor/github.com/cilium/cilium/pkg/option/config.go @@ -287,12 +287,6 @@ const ( // LoadBalancerProtocolDifferentiation enables support for service protocol differentiation (TCP, UDP, SCTP) LoadBalancerProtocolDifferentiation = "bpf-lb-proto-diff" - // MaglevTableSize determines the size of the backend table per service - MaglevTableSize = "bpf-lb-maglev-table-size" - - // MaglevHashSeed contains the cluster-wide seed for the hash - MaglevHashSeed = "bpf-lb-maglev-hash-seed" - // NodePortBindProtection rejects bind requests to NodePort service ports NodePortBindProtection = "node-port-bind-protection" @@ -855,6 +849,9 @@ const ( // endpoints that are no longer alive and healthy. EndpointGCInterval = "endpoint-gc-interval" + // EndpointRegenInterval is the interval of the periodic endpoint regeneration loop. + EndpointRegenInterval = "endpoint-regen-interval" + // LoopbackIPv4 is the address to use for service loopback SNAT LoopbackIPv4 = "ipv4-service-loopback-address" @@ -1141,6 +1138,10 @@ const ( // EnableNonDefaultDenyPolicies allows policies to define whether they are operating in default-deny mode EnableNonDefaultDenyPolicies = "enable-non-default-deny-policies" + + // EnableEndpointLockdownOnPolicyOverflow enables endpoint lockdown when an endpoint's + // policy map overflows. + EnableEndpointLockdownOnPolicyOverflow = "enable-endpoint-lockdown-on-policy-overflow" ) // Default string arguments @@ -1892,12 +1893,6 @@ type DaemonConfig struct { // replies to the client (when needed). EnablePMTUDiscovery bool - // Maglev backend table size (M) per service. Must be prime number. - MaglevTableSize int - - // MaglevHashSeed contains the cluster-wide seed for the hash(es). - MaglevHashSeed string - // NodePortAcceleration indicates whether NodePort should be accelerated // via XDP ("none", "generic", "native", or "best-effort") NodePortAcceleration string @@ -2243,6 +2238,10 @@ type DaemonConfig struct { // EnableSourceIPVerification enables the source ip validation of connection from endpoints to endpoints EnableSourceIPVerification bool + + // EnableEndpointLockdownOnPolicyOverflow enables endpoint lockdown when an endpoint's + // policy map overflows. + EnableEndpointLockdownOnPolicyOverflow bool } var ( @@ -2852,8 +2851,6 @@ func (c *DaemonConfig) Populate(vp *viper.Viper) { c.EnableSVCSourceRangeCheck = vp.GetBool(EnableSVCSourceRangeCheck) c.EnableHostPort = vp.GetBool(EnableHostPort) c.EnableHostLegacyRouting = vp.GetBool(EnableHostLegacyRouting) - c.MaglevTableSize = vp.GetInt(MaglevTableSize) - c.MaglevHashSeed = vp.GetString(MaglevHashSeed) c.NodePortBindProtection = vp.GetBool(NodePortBindProtection) c.EnableAutoProtectNodePortRange = vp.GetBool(EnableAutoProtectNodePortRange) c.KubeProxyReplacement = vp.GetString(KubeProxyReplacement) @@ -3280,6 +3277,9 @@ func (c *DaemonConfig) Populate(vp *viper.Viper) { // Enable BGP control plane status reporting c.EnableBGPControlPlaneStatusReport = vp.GetBool(EnableBGPControlPlaneStatusReport) + // Support failure-mode for policy map overflow + c.EnableEndpointLockdownOnPolicyOverflow = vp.GetBool(EnableEndpointLockdownOnPolicyOverflow) + // Parse node label patterns nodeLabelPatterns := vp.GetStringSlice(ExcludeNodeLabelPatterns) for _, pattern := range nodeLabelPatterns { diff --git a/vendor/github.com/cilium/cilium/pkg/policy/api/l4.go b/vendor/github.com/cilium/cilium/pkg/policy/api/l4.go index 08f38351f3..348fc047a7 100644 --- a/vendor/github.com/cilium/cilium/pkg/policy/api/l4.go +++ b/vendor/github.com/cilium/cilium/pkg/policy/api/l4.go @@ -28,6 +28,12 @@ func (l4 L4Proto) IsAny() bool { return l4 == ProtoAny || string(l4) == "" } +// SupportedProtocols returns the currently supported protocols in the policy +// engine, excluding "ANY". +func SupportedProtocols() []L4Proto { + return []L4Proto{ProtoTCP, ProtoUDP, ProtoSCTP} +} + // PortProtocol specifies an L4 port with an optional transport protocol type PortProtocol struct { // Port can be an L4 port number, or a name in the form of "http" @@ -160,7 +166,7 @@ type Listener struct { // +kubebuilder:validation:Minimum=1 // +kubebuilder:validation:Maximum=100 // +kubebuilder:validation:Optional - Priority uint16 `json:"priority"` + Priority uint8 `json:"priority"` } // PortRule is a list of ports/protocol combinations with optional Layer 7 diff --git a/vendor/github.com/cilium/cilium/pkg/policy/l4.go b/vendor/github.com/cilium/cilium/pkg/policy/l4.go index 0bd37a57bd..5e72934c05 100644 --- a/vendor/github.com/cilium/cilium/pkg/policy/l4.go +++ b/vendor/github.com/cilium/cilium/pkg/policy/l4.go @@ -182,13 +182,10 @@ type PerSelectorPolicy struct { // Priority of the listener used when multiple listeners would apply to the same // MapStateEntry. - // Lower numbers indicate higher priority. If left out, the proxy - // port number (10000-20000) is used as priority, so that traffic will be consistently - // redirected to the same listener. If higher priority desired, a low unique number like 1, - // 2, or 3 should be explicitly specified here. If a lower than default priority is needed, - // then a unique number higher than 20000 should be explicitly specified. Numbers on the - // default range (10000-20000) are not allowed. - Priority uint16 `json:"priority,omitempty"` + // Lower numbers indicate higher priority. Except for the default 0, which indicates the + // lowest priority. If higher priority desired, a low unique number like 1, 2, or 3 should + // be explicitly specified here. + Priority uint8 `json:"priority,omitempty"` // Pre-computed HTTP rules, computed after rule merging is complete EnvoyHTTPRules *cilium.HttpNetworkPolicyRules `json:"-"` @@ -230,7 +227,7 @@ func (a *PerSelectorPolicy) GetListener() string { } // GetPriority returns the pritority of the listener of the PerSelectorPolicy. -func (a *PerSelectorPolicy) GetPriority() uint16 { +func (a *PerSelectorPolicy) GetPriority() uint8 { if a == nil { return 0 } @@ -509,9 +506,9 @@ func (l4 *L4Filter) Equals(bL4 *L4Filter) bool { // ChangeState allows caller to revert changes made by (multiple) toMapState call(s) // All fields are maps so we can pass this by value. type ChangeState struct { - Adds Keys // Added or modified keys, if not nil - Deletes Keys // deleted keys, if not nil - old map[Key]mapStateEntry // Old values of all modified or deleted keys, if not nil + Adds Keys // Added or modified keys, if not nil + Deletes Keys // deleted keys, if not nil + old mapStateMap // Old values of all modified or deleted keys, if not nil } // NewRevertState returns an empty ChangeState suitable for reverting MapState changes. @@ -519,7 +516,7 @@ type ChangeState struct { func NewRevertState() ChangeState { return ChangeState{ Adds: make(Keys), - old: make(map[Key]mapStateEntry), + old: make(mapStateMap), } } @@ -527,11 +524,25 @@ func (c *ChangeState) Empty() bool { return len(c.Adds)+len(c.Deletes)+len(c.old) == 0 } +// Size returns the total number of Adds minus +// the total number of true Deletes (Deletes +// that are not also in Adds). The return value +// can be negative. +func (c *ChangeState) Size() int { + deleteLen := 0 + for k := range c.Deletes { + if _, ok := c.Adds[k]; !ok { + deleteLen++ + } + } + return len(c.Adds) - deleteLen +} + // toMapState converts a single filter into a MapState entries added to 'p.PolicyMapState'. // // Note: It is possible for two selectors to select the same security ID. To give priority to deny, // AuthType, and L7 redirection (e.g., for visibility purposes), the mapstate entries are added to -// 'p.PolicyMapState' using denyPreferredInsertWithChanges(). +// 'p.PolicyMapState' using insertWithChanges(). // Keys and old values of any added or deleted entries are added to 'changes'. // 'redirects' is the map of currently realized redirects, it is used to find the proxy port for any redirects. // p.SelectorCache is used as Identities interface during this call, which only has GetPrefix() that @@ -748,7 +759,7 @@ func (l4 *L4Filter) cacheFQDNSelector(sel api.FQDNSelector, lbls labels.LabelArr } // add L7 rules for all endpoints in the L7DataMap -func (l7 L7DataMap) addPolicyForSelector(rules *api.L7Rules, terminatingTLS, originatingTLS *TLSContext, auth *api.Authentication, deny bool, sni []string, listener string, priority uint16) { +func (l7 L7DataMap) addPolicyForSelector(rules *api.L7Rules, terminatingTLS, originatingTLS *TLSContext, auth *api.Authentication, deny bool, sni []string, listener string, priority uint8) { isRedirect := !deny && (listener != "" || terminatingTLS != nil || originatingTLS != nil || len(sni) > 0 || !rules.IsEmpty()) for epsel := range l7 { l7policy := &PerSelectorPolicy{ @@ -861,7 +872,7 @@ func createL4Filter(policyCtx PolicyContext, peerEndpoints api.EndpointSelectorS var rules *api.L7Rules var sni []string listener := "" - var priority uint16 + var priority uint8 pr := rule.GetPortRule() if pr != nil { @@ -969,6 +980,10 @@ func (l4 *L4Filter) attach(ctx PolicyContext, l4Policy *L4Policy) policyFeatures var features policyFeatures for cs, cp := range l4.PerSelectorPolicies { if cp != nil { + if cp.isRedirect { + features.setFeature(redirectRules) + } + if cp.IsDeny { features.setFeature(denyRules) } @@ -1403,6 +1418,7 @@ type policyFeatures uint8 const ( denyRules policyFeatures = 1 << iota + redirectRules authRules allFeatures policyFeatures = ^policyFeatures(0) diff --git a/vendor/github.com/cilium/cilium/pkg/policy/mapstate.go b/vendor/github.com/cilium/cilium/pkg/policy/mapstate.go index 6a8def338c..a2abbb0630 100644 --- a/vendor/github.com/cilium/cilium/pkg/policy/mapstate.go +++ b/vendor/github.com/cilium/cilium/pkg/policy/mapstate.go @@ -7,7 +7,6 @@ import ( "fmt" "iter" "slices" - "strconv" "github.com/hashicorp/go-hclog" "github.com/sirupsen/logrus" @@ -32,6 +31,7 @@ import ( // lest ye find yourself with hundreds of unnecessary imports. type Key = types.Key type Keys = types.Keys +type MapStateEntry = types.MapStateEntry type MapStateOwner = types.CachedSelector const NoAuthRequirement = types.NoAuthRequirement @@ -40,6 +40,8 @@ const NoAuthRequirement = types.NoAuthRequirement // as well as more extensive indexing via tries. type MapStateMap map[Key]MapStateEntry +type mapStateMap map[Key]mapStateEntry + func EgressKey() types.Key { return types.EgressKey() } @@ -97,7 +99,7 @@ var ( // deletion, and insertion times. type mapState struct { // entries is the map containing the MapStateEntries - entries map[Key]mapStateEntry + entries mapStateMap // trie is a Trie that indexes policy Keys without their identity // and stores the identities in an associated builtin map. trie bitlpm.Trie[bitlpm.Key[types.LPMKey], IDSet] @@ -302,7 +304,7 @@ func (ms *mapState) LPMAncestors(key Key) iter.Seq2[Key, mapStateEntry] { } // Lookup finds the policy verdict applicable to the given 'key' using the same precedence logic -// between L3 and L4-only policies when both match the given 'key'. +// between L3 and L4-only policies as the bpf datapath when both match the given 'key'. // To be used in testing in place of the bpf datapath when full integration testing is not desired. // Returns the closest matching covering policy entry and 'true' if found. // 'key' must not have a wildcard identity or port. @@ -329,6 +331,9 @@ func (ms *mapState) Lookup(key Key) (MapStateEntry, bool) { } authOverride := func(entry, other MapStateEntry) MapStateEntry { + // This logic needs to be the same as in authPreferredInsert() where the newEntry's + // auth type may be overridden by a covering key. + // This also needs to reflect the logic in bpf/lib/policy.h __account_and_check(). if !entry.AuthRequirement.IsExplicit() && other.AuthRequirement.AuthType() > entry.AuthRequirement.AuthType() { entry.AuthRequirement = other.AuthRequirement.AsDerived() @@ -347,69 +352,57 @@ func (ms *mapState) Lookup(key Key) (MapStateEntry, bool) { // both L3 and L4 matches found if haveL3 && haveL4 { // Precedence rules of the bpf datapath between two policy entries: - // 1. deny wins - // 2. if both entries are allows, the one with more specific L4 is selected - // 3. If the two allows have equal port/proto, the policy for a specific L3 is - // selected (rather than the L4-only entry) + // 1. Deny is selected, if any + // 2. Higher proxy port priority wins + // 3. If both entries are allows at the same proxy port priority, the one with more + // specific L4 is selected + // 4. If the two allows on the same proxy port priority have equal port/proto, then + // the policy for a specific L3 is selected (rather than the L4-only entry) // // If the selected entry has non-explicit auth type, it gets the auth type from the // other entry, if the other entry's auth type is numerically higher. - // 1. Deny wins, check for the broader deny first - if l4entry.IsDeny { + // 1. Deny wins + // Check for the L3 deny first to match the datapath behavior + if l3entry.IsDeny() { + return l3entry, true + } + if l4entry.IsDeny() { return l4entry, true } - if l3entry.IsDeny { + + // 2. Entry with higher proxy port priority is selected. + // Auth requirement does not propagate from a lower proxy port priority rule to a + // higher proxy port priority rule! + if l3entry.ProxyPortPriority > l4entry.ProxyPortPriority { return l3entry, true } + if l4entry.ProxyPortPriority > l3entry.ProxyPortPriority { + return l4entry, true + } - // 2. Two allow entries, select the one with more specific L4 + // 3. Two allow entries, select the one with more specific L4 // L3-entry must be selected if prefix lengths are the same! if l4key.PrefixLength() > l3key.PrefixLength() { return authOverride(l4entry, l3entry), true } - - // 3. Two allow entries with equally specific L4 or L3-entry is more specific + // 4. Two allow entries are equally specific port/proto or L3-entry is more specific return authOverride(l3entry, l4entry), true } // Deny by default if no matches are found - return MapStateEntry{IsDeny: true}, false + return types.DenyEntry(), false } func (ms *mapState) Len() int { return len(ms.entries) } -// MapStateEntry is the configuration associated with a Key in a -// MapState. This is a minimized version of policymap.PolicyEntry. -type MapStateEntry struct { - // The proxy port, in host byte order. - // If 0 (default), there is no proxy redirection for the corresponding - // Key. Any other value signifies proxy redirection. - ProxyPort uint16 - - // IsDeny is true when the policy should be denied. - IsDeny bool - - // Invalid is only set to mark the current entry for update when syncing entries to datapath - Invalid bool - - // AuthRequirement is non-zero when authentication is required for the traffic to be - // allowed, except for when it explicitly defines authentication is not required. - AuthRequirement AuthRequirement -} - // mapSteteEntry is the entry type with additional internal bookkeping of the relation between // explicitly and implicitly added entries. type mapStateEntry struct { MapStateEntry - // priority is used to select the proxy port if multiple rules would apply different proxy - // ports to a policy map entry. Lower numbers indicate higher priority. If left out, the - // proxy port number (10000-20000) is used. - priority uint16 - // derivedFromRules tracks the policy rules this entry derives from. // In sorted order. derivedFromRules labels.LabelArrayList @@ -425,41 +418,21 @@ type mapStateEntry struct { // 'cs' is used to keep track of which policy selectors need this entry. If it is 'nil' this entry // will become sticky and cannot be completely removed via incremental updates. Even in this case // the entry may be overridden or removed by a deny entry. -func newMapStateEntry(cs MapStateOwner, derivedFrom labels.LabelArrayList, proxyPort uint16, priority uint16, deny bool, authReq AuthRequirement) mapStateEntry { - if proxyPort == 0 { - priority = 0 - } else if priority == 0 { - priority = proxyPort // default for tie-breaking - } - return mapStateEntry{ - MapStateEntry: MapStateEntry{ - ProxyPort: proxyPort, - IsDeny: deny, - AuthRequirement: authReq, - }, - priority: priority, - derivedFromRules: derivedFrom, - owners: set.NewSet(cs), - } +func newMapStateEntry(cs MapStateOwner, derivedFrom labels.LabelArrayList, proxyPort uint16, priority uint8, deny bool, authReq AuthRequirement) mapStateEntry { + return NewMapStateEntry(types.NewMapStateEntry(deny, proxyPort, priority, authReq), derivedFrom, cs) } // newAllowEntryWithLabels creates an allow entry with the specified labels and a 'nil' owner. -// Used for adding allow-all entries when policy ewnforcement is not wanted. +// Used for adding allow-all entries when policy enforcement is not wanted. func newAllowEntryWithLabels(lbls labels.LabelArray) mapStateEntry { return newMapStateEntry(nil, labels.LabelArrayList{lbls}, 0, 0, false, NoAuthRequirement) } -func (e MapStateEntry) toMapStateEntry(priority uint16, cs MapStateOwner, derivedFrom labels.LabelArrayList) mapStateEntry { - if e.ProxyPort == 0 { - priority = 0 - } else if priority == 0 { - priority = e.ProxyPort // default for tie-breaking - } +func NewMapStateEntry(e MapStateEntry, derivedFrom labels.LabelArrayList, owners ...MapStateOwner) mapStateEntry { return mapStateEntry{ MapStateEntry: e, - priority: priority, derivedFromRules: derivedFrom, - owners: set.NewSet(cs), + owners: set.NewSet(owners...), } } @@ -469,7 +442,7 @@ func (e *mapStateEntry) GetRuleLabels() labels.LabelArrayList { func newMapState() mapState { return mapState{ - entries: make(map[Key]mapStateEntry), + entries: make(mapStateMap), trie: bitlpm.NewTrie[types.LPMKey, IDSet](types.MapStatePrefixLen), } } @@ -608,57 +581,6 @@ func (ms mapState) String() (res string) { return res } -// merge adds owners, and DerivedFromRules from a new 'entry' to an existing -// entry 'e'. 'entry' is not modified. -// Merge is only called if both entries are allow or deny entries, so deny precedence is not -// considered here. -// ProxyPort, and AuthType are merged by giving precedence to proxy redirection over no proxy -// redirection, and explicit auth type over default auth type. -func (e *mapStateEntry) merge(entry *mapStateEntry) { - // Bail out loudly if both entries are not denies or allows - if e.IsDeny != entry.IsDeny { - log.WithField(logfields.Stacktrace, hclog.Stacktrace()). - Errorf("MapStateEntry.merge: both entries must be allows or denies") - return - } - // Only allow entries have proxy redirection or auth requirement - if !e.IsDeny { - // Proxy port takes precedence, but may be updated due to priority - if entry.IsRedirectEntry() { - // Lower number has higher priority, but non-redirects have 0 priority - // value. - // Proxy port value is the tie-breaker when priorities have the same value. - if !e.IsRedirectEntry() || entry.priority < e.priority || entry.priority == e.priority && entry.ProxyPort < e.ProxyPort { - e.ProxyPort = entry.ProxyPort - e.priority = entry.priority - } - } - - // Numerically higher AuthType takes precedence when both are - // either explicitly defined or derived - if entry.AuthRequirement.IsExplicit() == e.AuthRequirement.IsExplicit() { - if entry.AuthRequirement > e.AuthRequirement { - e.AuthRequirement = entry.AuthRequirement - } - } else if entry.AuthRequirement.IsExplicit() { - // Explicit auth takes precedence over defaulted one. - e.AuthRequirement = entry.AuthRequirement - } - } - - e.owners.Merge(entry.owners) - - // merge DerivedFromRules - if len(entry.derivedFromRules) > 0 { - e.derivedFromRules.MergeSorted(entry.derivedFromRules) - } -} - -// IsRedirectEntry returns true if the entry redirects to a proxy port -func (e *MapStateEntry) IsRedirectEntry() bool { - return e.ProxyPort != 0 -} - // DatapathAndDerivedFromEqual returns true of two entries are equal in the datapath's PoV, // i.e., IsDeny, ProxyPort and AuthType are the same for both entries, and the DerivedFromRules // fields are also equal. @@ -679,10 +601,6 @@ func (e *mapStateEntry) deepEqual(o *mapStateEntry) bool { return false } - if e.priority != o.priority { - return false - } - if !e.owners.Equal(o.owners) { return false } @@ -690,27 +608,10 @@ func (e *mapStateEntry) deepEqual(o *mapStateEntry) bool { return true } -// String returns a string representation of the MapStateEntry -func (e MapStateEntry) String() string { - var authText string - if e.AuthRequirement != 0 { - var authNote string - if !e.AuthRequirement.IsExplicit() { - authNote = " (derived)" - } - authText = ",AuthType=" + e.AuthRequirement.AuthType().String() + authNote - } - - return "ProxyPort=" + strconv.FormatUint(uint64(e.ProxyPort), 10) + - ",IsDeny=" + strconv.FormatBool(e.IsDeny) + - authText -} - // String returns a string representation of the MapStateEntry func (e mapStateEntry) String() string { return e.MapStateEntry.String() + ",derivedFromRules=" + fmt.Sprintf("%v", e.derivedFromRules) + - ",priority=" + strconv.FormatUint(uint64(e.priority), 10) + ",owners=" + e.owners.String() } @@ -720,7 +621,7 @@ func (ms *mapState) addKeyWithChanges(key Key, entry mapStateEntry, changes Chan var datapathEqual bool oldEntry, exists := ms.get(key) // Only merge if both old and new are allows or denies - if exists && (oldEntry.IsDeny == entry.IsDeny) { + if exists && oldEntry.IsDeny() == entry.IsDeny() { // Do nothing if entries are equal if entry.deepEqual(&oldEntry) { return false // nothing to do @@ -732,11 +633,17 @@ func (ms *mapState) addKeyWithChanges(key Key, entry mapStateEntry, changes Chan // Compare for datapath equalness before merging, as the old entry is updated in // place! datapathEqual = oldEntry.MapStateEntry == entry.MapStateEntry - oldEntry.merge(&entry) + + oldEntry.MapStateEntry.Merge(entry.MapStateEntry) + oldEntry.owners.Merge(entry.owners) + if len(entry.derivedFromRules) > 0 { + oldEntry.derivedFromRules.MergeSorted(entry.derivedFromRules) + } + ms.updateExisting(key, oldEntry) - } else if !exists || entry.IsDeny { + } else if !exists || entry.IsDeny() { // Insert a new entry if one did not exist or a deny entry is overwriting an allow - // entry. + // entry // Save old value before any changes, if any if exists { @@ -766,7 +673,7 @@ func (ms *mapState) addKeyWithChanges(key Key, entry mapStateEntry, changes Chan // and 'deletes'. // The key is unconditionally deleted if 'owner' is nil, otherwise only the contribution of this // 'owner' is removed. -func (ms *mapState) deleteKeyWithChanges(key Key, owner MapStateOwner, changes ChangeState) { +func (ms *mapState) deleteKeyWithChanges(owner MapStateOwner, key Key, changes ChangeState) { if entry, exists := ms.get(key); exists { // Save old value before any changes, if desired oldAdded := changes.insertOldIfNotExists(key, entry) @@ -803,8 +710,8 @@ func (ms *mapState) deleteKeyWithChanges(key Key, owner MapStateOwner, changes C } } -// RevertChanges undoes changes to 'keys' as indicated by 'changes.adds' and 'changes.old' collected via -// denyPreferredInsertWithChanges(). +// RevertChanges undoes changes to 'keys' as indicated by 'changes.adds' and 'changes.old' collected +// via insertWithChanges(). func (ms *mapState) revertChanges(changes ChangeState) { for k := range changes.Adds { ms.delete(k) @@ -815,37 +722,30 @@ func (ms *mapState) revertChanges(changes ChangeState) { } } -func (ms *mapState) insertWithChanges(key Key, entry mapStateEntry, features policyFeatures, changes ChangeState) { - ms.denyPreferredInsertWithChanges(key, entry, features, changes) -} - -// denyPreferredInsertWithChanges contains the most important business logic for policy -// insertions. It inserts a key and entry into the map by giving preference to deny entries, and -// L3-only deny entries over L3-L4 allows. -// -// Since bpf datapath denies by default, we only need to add deny entries to carve out more specific -// holes to less specific allow rules. But since we don't if allow entries will be added later -// (e.g., incrementally due to FQDN rules), we must generally add deny entries even if there are no -// allow entries yet. +// insertWithChanges contains the most important business logic for policy insertions. It inserts a +// key and entry into the map only if not covered by a deny entry. // // Whenever the bpf datapath finds both L4-only and L3/L4 matching policy entries for a given // packet, it uses the following logic to choose the policy entry: -// - L4-only entry is chosen if it is a deny or has more specific port/proto than the L3/L4 entry -// - otherwise the L3/L4 entry is chosen +// 1. Deny is selected, if any +// 2. Among two allows the one with higher proxy port priority is selected +// 3. Otherwise, the L4-only entry is chosen if it has more specific port/proto than +// the L3/L4 entry +// 4. Otherwise the L3/L4 entry is chosen // -// This gives precedence for deny entry, or if none is present, then the one with the more specific -// L4 is chosen. This means that it suffices to manage deny precedence among the keys with the same -// ID here, the datapath take care of the precedence between different IDs (that is, between a -// specific ID and the wildcard ID (==0) +// This selects the higher precedence rule either by the deny status, or by the more +// specific L4, and for the L3/L4 entry overwise. This means that it suffices to manage +// deny precedence among the keys with the same ID here, the datapath take care of the precedence +// between different IDs (that is, between a specific ID and the wildcard ID (==0) // // Note on bailed or deleted entries: // -// It would seem like that when we bail out due to being covered by an existing -// entry, or delete an entry due to being covered by the new one, we would want this action reversed -// if the existing entry or this new one is incremantally removed, respectively. +// It would seem like that when we bail out due to being covered by an existing entry, or delete an +// entry due to being covered by the new one, we would want this action reversed if the existing +// entry or this new one is incremantally removed, respectively. // // Consider these facts: -// 1. Whenever a deny entry covers an allow entry, the covering key has broader or equal +// 1. Whenever a key covers an another, the covering key has broader or equal // protocol/port, and the keys have the same identity, or the covering key has wildcard identity // (ID == 0). // 2. Only keys with a specific identity (ID != 0) can be incrementally added or deleted. @@ -858,28 +758,43 @@ func (ms *mapState) insertWithChanges(key Key, entry mapStateEntry, features pol // deleted. // // Incremental changes performed are recorded in 'changes'. -func (ms *mapState) denyPreferredInsertWithChanges(newKey Key, newEntry mapStateEntry, features policyFeatures, changes ChangeState) { - // Bail if covered by a deny key - if features.contains(denyRules) { +func (ms *mapState) insertWithChanges(newKey Key, newEntry mapStateEntry, features policyFeatures, changes ChangeState) { + if newEntry.IsDeny() { + // Bail if covered by another (different) deny key for k, v := range ms.BroaderOrEqualKeys(newKey) { - // Identical deny key needs to be added to merge their entries. - if v.IsDeny && !(newEntry.IsDeny && k == newKey) { + if v.IsDeny() && k != newKey { return } } - } - if newEntry.IsDeny { - // Delete covered entries + // Delete covered allows and denies with a different key for k, v := range ms.NarrowerOrEqualKeys(newKey) { - // Except for identical deny keys that need to be merged. - if !(v.IsDeny && k == newKey) { - ms.deleteKeyWithChanges(k, nil, changes) + if !v.IsDeny() || k != newKey { + ms.deleteKeyWithChanges(nil, k, changes) } } } else { - // newEntry is an allow entry. - // NOTE: We do not delete redundant allow entries. + // Bail if covered by a deny key or a key with a higher proxy port priority. + // + // This can be skipped if no rules have denies or proxy redirects + if features.contains(denyRules | redirectRules) { + for _, v := range ms.BroaderOrEqualKeys(newKey) { + if v.IsDeny() || v.ProxyPortPriority > newEntry.ProxyPortPriority { + return + } + } + } + + // Delete covered allow entries with lower proxy port priority. + // + // This can be skipped if no rules have proxy redirects + if features.contains(redirectRules) { + for k, v := range ms.NarrowerOrEqualKeys(newKey) { + if !v.IsDeny() && v.ProxyPortPriority < newEntry.ProxyPortPriority { + ms.deleteKeyWithChanges(nil, k, changes) + } + } + } // Checking for auth feature here is faster than calling 'authPreferredInsert' and // checking for it there. @@ -888,7 +803,6 @@ func (ms *mapState) denyPreferredInsertWithChanges(newKey Key, newEntry mapState return } } - ms.addKeyWithChanges(newKey, newEntry, changes) } @@ -916,12 +830,12 @@ func (ms *mapState) authPreferredInsert(newKey Key, newEntry mapStateEntry, chan if !newEntry.AuthRequirement.IsExplicit() { // New entry has a default auth type. - // Fill in the AuthRequirement from the most specific covering key with the same ID - // and an explicit auth type + // Fill in the AuthType from the most specific covering key with the same ID and an + // explicit auth type for _, v := range ms.CoveringKeysWithSameID(newKey) { if v.AuthRequirement.IsExplicit() { - // AuthRequirement from the most specific covering key is applied to - // 'newEntry' + // AuthType from the most specific covering key is applied + // to 'newEntry' newEntry.AuthRequirement = v.AuthRequirement.AsDerived() break } @@ -931,7 +845,7 @@ func (ms *mapState) authPreferredInsert(newKey Key, newEntry mapStateEntry, chan // with the same ID and default auth type, and propagate the auth type from the new // entry to such entries. for k, v := range ms.SubsetKeysWithSameID(newKey) { - if v.IsDeny || v.AuthRequirement.IsExplicit() { + if v.IsDeny() || v.AuthRequirement.IsExplicit() { // Stop if a subset entry is deny or has an explicit auth type, as // that is the more specific covering key for all remaining subset // keys @@ -1083,7 +997,7 @@ func (mc *MapChanges) consumeMapChanges(p *EndpointPolicy, features policyFeatur changes := ChangeState{ Adds: make(Keys, len(mc.synced)), Deletes: make(Keys, len(mc.synced)), - old: make(map[Key]mapStateEntry, len(mc.synced)), + old: make(mapStateMap, len(mc.synced)), } for i := range mc.synced { @@ -1098,7 +1012,7 @@ func (mc *MapChanges) consumeMapChanges(p *EndpointPolicy, features policyFeatur // Delete the contribution of this cs to the key and collect incremental // changes cs, _ := entry.owners.Get() // get the sole selector - p.policyMapState.deleteKeyWithChanges(key, cs, changes) + p.policyMapState.deleteKeyWithChanges(cs, key, changes) } } diff --git a/vendor/github.com/cilium/cilium/pkg/policy/rule.go b/vendor/github.com/cilium/cilium/pkg/policy/rule.go index 8460c9b61a..29715ea578 100644 --- a/vendor/github.com/cilium/cilium/pkg/policy/rule.go +++ b/vendor/github.com/cilium/cilium/pkg/policy/rule.go @@ -107,7 +107,7 @@ func (epd *PerSelectorPolicy) appendL7WildcardRule(ctx *SearchContext) api.L7Rul // takesListenerPrecedenceOver returns true if the listener reference in 'l7Rules' takes precedence // over the listener reference in 'other'. func (l7Rules *PerSelectorPolicy) takesListenerPrecedenceOver(other *PerSelectorPolicy) bool { - var priority, otherPriority uint16 + var priority, otherPriority uint8 // decrement by one to wrap the undefined value (0) to be the highest numerical // value of the uint16, which is the lowest possible priority diff --git a/vendor/github.com/cilium/cilium/pkg/policy/selectorcache.go b/vendor/github.com/cilium/cilium/pkg/policy/selectorcache.go index 23fe91796d..5e792c2f43 100644 --- a/vendor/github.com/cilium/cilium/pkg/policy/selectorcache.go +++ b/vendor/github.com/cilium/cilium/pkg/policy/selectorcache.go @@ -464,6 +464,32 @@ func (sc *SelectorCache) ChangeUser(selector types.CachedSelector, from, to Cach sc.mutex.Unlock() } +// CanSkipUpdate returns true if a proposed update is already known to the SelectorCache +// and thus a no-op. Is used to de-dup an ID update stream, because identical updates +// may come from multiple sources. +func (sc *SelectorCache) CanSkipUpdate(added, deleted identity.IdentityMap) bool { + sc.mutex.RLock() + defer sc.mutex.RUnlock() + + for nid := range deleted { + if _, exists := sc.idCache[nid]; exists { + return false + } + } + + for nid, lbls := range added { + haslbls, exists := sc.idCache[nid] + if !exists { // id not known to us: cannot skip + return false + } + if !haslbls.lbls.Equals(lbls) { + // labels are not equal: cannot skip + return false + } + } + return true +} + // UpdateIdentities propagates identity updates to selectors // // The caller is responsible for making sure the same identity is not diff --git a/vendor/github.com/cilium/cilium/pkg/policy/trigger.go b/vendor/github.com/cilium/cilium/pkg/policy/trigger.go index 0b84674193..383e8a7cb1 100644 --- a/vendor/github.com/cilium/cilium/pkg/policy/trigger.go +++ b/vendor/github.com/cilium/cilium/pkg/policy/trigger.go @@ -4,87 +4,37 @@ package policy import ( - "strings" - "sync" - - "github.com/cilium/cilium/pkg/endpoint/regeneration" - "github.com/cilium/cilium/pkg/metrics" - "github.com/cilium/cilium/pkg/option" - "github.com/cilium/cilium/pkg/time" - "github.com/cilium/cilium/pkg/trigger" + "github.com/cilium/cilium/pkg/logging/logfields" ) -// TriggerPolicyUpdates triggers the policy update trigger. -// -// To follow what the trigger does, see NewUpdater. -func (u *Updater) TriggerPolicyUpdates(force bool, reason string) { - if force { - log.Debugf("Artificially increasing policy revision to enforce policy recalculation") - u.repo.BumpRevision() - } - - u.TriggerWithReason(reason) +// TriggerPolicyUpdates force full policy recomputation before +// regenerating all endpoints. +// This artificially bumps the policy revision, invalidating +// all cached policies. This is done when an additional resource +// used in policy calculation has changed. +func (u *Updater) TriggerPolicyUpdates(reason string) { + u.repo.BumpRevision() + log.WithField(logfields.Reason, reason).Info("Triggering full policy recalculation and regeneration of all endpoints") + u.regen.TriggerRegenerateAllEndpoints() } // NewUpdater returns a new Updater instance to handle triggering policy // updates ready for use. func NewUpdater(r PolicyRepository, regen regenerator) *Updater { - t, err := trigger.NewTrigger(trigger.Parameters{ - Name: "policy_update", - MetricsObserver: &TriggerMetrics{}, - MinInterval: option.Config.PolicyTriggerInterval, - // Triggers policy updates for every local endpoint. - // This may be called in a variety of situations: after policy changes, - // changes in agent configuration, changes in endpoint labels, and - // change of security identities. - TriggerFunc: func(reasons []string) { - log.Debug("Regenerating all endpoints") - reason := strings.Join(reasons, ", ") - - regenerationMetadata := ®eneration.ExternalRegenerationMetadata{ - Reason: reason, - RegenerationLevel: regeneration.RegenerateWithoutDatapath, - } - regen.RegenerateAllEndpoints(regenerationMetadata) - }, - }) - if err != nil { - panic(err) // unreachable, only occurs if TriggerFunc is nil - } return &Updater{ - Trigger: t, - repo: r, + regen: regen, + repo: r, } } // Updater is responsible for triggering policy updates, in order to perform // policy recalculation. type Updater struct { - *trigger.Trigger - - repo PolicyRepository + repo PolicyRepository + regen regenerator } type regenerator interface { // RegenerateAllEndpoints should trigger a regeneration of all endpoints. - RegenerateAllEndpoints(*regeneration.ExternalRegenerationMetadata) *sync.WaitGroup -} - -// TriggerMetrics handles the metrics for trigger policy recalculations. -type TriggerMetrics struct{} - -func (p *TriggerMetrics) QueueEvent(reason string) { - if metrics.TriggerPolicyUpdateTotal.IsEnabled() { - metrics.TriggerPolicyUpdateTotal.WithLabelValues(reason).Inc() - } -} - -func (p *TriggerMetrics) PostRun(duration, latency time.Duration, folds int) { - if metrics.TriggerPolicyUpdateCallDuration.IsEnabled() { - metrics.TriggerPolicyUpdateCallDuration.WithLabelValues("duration").Observe(duration.Seconds()) - metrics.TriggerPolicyUpdateCallDuration.WithLabelValues("latency").Observe(latency.Seconds()) - } - if metrics.TriggerPolicyUpdateFolds.IsEnabled() { - metrics.TriggerPolicyUpdateFolds.Set(float64(folds)) - } + TriggerRegenerateAllEndpoints() } diff --git a/vendor/github.com/cilium/cilium/pkg/policy/types/entry.go b/vendor/github.com/cilium/cilium/pkg/policy/types/entry.go new file mode 100644 index 0000000000..6881f795a3 --- /dev/null +++ b/vendor/github.com/cilium/cilium/pkg/policy/types/entry.go @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Cilium + +package types + +import "strconv" + +type ProxyPortPriority uint8 + +const ( + MaxProxyPortPriority = 255 + MaxListenerPriority = 100 +) + +// MapStateEntry is the configuration associated with a Key in a +// MapState. This is a minimized version of policymap.PolicyEntry. +type MapStateEntry struct { + // isDeny is true when the policy should be denied. + isDeny bool + + // ProxyPortPriority encodes the listener priority. + ProxyPortPriority ProxyPortPriority + + // The proxy port, in host byte order. + // If 0 (default), there is no proxy redirection for the corresponding + // Key. Any other value signifies proxy redirection. + ProxyPort uint16 + + // Invalid is only set to mark the current entry for update when syncing entries to datapath + Invalid bool + + // AuthRequirement is non-zero when authentication is required for the traffic to be + // allowed, except for when it explicitly defines authentication is not required. + AuthRequirement AuthRequirement +} + +// String returns a string representation of the MapStateEntry +func (e MapStateEntry) String() string { + var authText string + if e.AuthRequirement != 0 { + var authNote string + if !e.AuthRequirement.IsExplicit() { + authNote = " (derived)" + } + authText = ",AuthType=" + e.AuthRequirement.AuthType().String() + authNote + } + + return "IsDeny=" + strconv.FormatBool(e.IsDeny()) + + ",ProxyPort=" + strconv.FormatUint(uint64(e.ProxyPort), 10) + + ",Priority=" + strconv.FormatUint(uint64(e.ProxyPortPriority), 10) + + authText +} + +// NewMapStateEntry creeates a new MapStateEntry +// Listener 'priority' is encoded in ProxyPortPriority, inverted +func NewMapStateEntry(deny bool, proxyPort uint16, priority uint8, authReq AuthRequirement) MapStateEntry { + // Normalize inputs + if deny { + proxyPort = 0 + priority = 0 + authReq = 0 + } + return MapStateEntry{ + isDeny: deny, + ProxyPort: proxyPort, + AuthRequirement: authReq, + }.WithProxyPriority(priority) +} + +func (e MapStateEntry) IsDeny() bool { + return e.isDeny +} + +// IsRedirectEntry returns true if the entry redirects to a proxy port +func (e MapStateEntry) IsRedirectEntry() bool { + return e.ProxyPort != 0 +} + +// AllowEntry returns a MapStateEntry for an allow policy without a proxy redirect +func AllowEntry() MapStateEntry { + return MapStateEntry{} +} + +// DenyEntry returns a MapStateEntry for a deny policy +func DenyEntry() MapStateEntry { + return MapStateEntry{isDeny: true} +} + +// WithDeny returns the entry 'e' with 'isDeny' set as indicated +func (e MapStateEntry) WithDeny(isDeny bool) MapStateEntry { + e.isDeny = isDeny + return e +} + +// WithProxyPriority returns a MapStateEntry with the given listener priority: +// 0 - default (low) priority for all proxy redirects +// 1 - highest listener priority +// .. +// 100 - lowest (non-default) listener priority +func (e MapStateEntry) WithProxyPriority(priority uint8) MapStateEntry { + if e.ProxyPort != 0 { + if priority > 0 { + priority = min(priority, MaxListenerPriority) + + // invert the priority so that higher number has the + // precedence, priority 1 becomes 254, 100 -> 155 + e.ProxyPortPriority = MaxProxyPortPriority - ProxyPortPriority(priority) + } else { + e.ProxyPortPriority = 1 // proxy port without explicit priority + } + } + return e +} + +// WithProxyPort return the MapStateEntry with proxy port set at the default precedence +func (e MapStateEntry) WithProxyPort(proxyPort uint16) MapStateEntry { + e.ProxyPort = proxyPort + e.ProxyPortPriority = 1 // proxy port without explicit priority + return e +} + +// Merge is only called if both entries are denies or allows +func (e *MapStateEntry) Merge(entry MapStateEntry) { + // Only allow entries have proxy redirection or auth requirement + if !e.IsDeny() { + // Proxy port takes precedence, but may be updated due to priority + if entry.IsRedirectEntry() { + // Higher number has higher priority, but non-redirects have 0 priority + // value. + // Proxy port value is the tie-breaker when priorities have the same value. + if entry.ProxyPortPriority > e.ProxyPortPriority || entry.ProxyPortPriority == e.ProxyPortPriority && entry.ProxyPort < e.ProxyPort { + e.ProxyPort = entry.ProxyPort + e.ProxyPortPriority = entry.ProxyPortPriority + } + } + + // Numerically higher AuthType takes precedence when both are + // either explicitly defined or derived + if entry.AuthRequirement.IsExplicit() == e.AuthRequirement.IsExplicit() { + if entry.AuthRequirement > e.AuthRequirement { + e.AuthRequirement = entry.AuthRequirement + } + } else if entry.AuthRequirement.IsExplicit() { + // Explicit auth takes precedence over defaulted one. + e.AuthRequirement = entry.AuthRequirement + } + } +} diff --git a/vendor/github.com/cilium/cilium/pkg/trigger/doc.go b/vendor/github.com/cilium/cilium/pkg/trigger/doc.go deleted file mode 100644 index 7ca449cd3a..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/trigger/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -// Package trigger provides a mechanism to trigger actions that require to be -// serialized while providing a non-blocking notification mechanism -package trigger diff --git a/vendor/github.com/cilium/cilium/pkg/trigger/trigger.go b/vendor/github.com/cilium/cilium/pkg/trigger/trigger.go deleted file mode 100644 index 48c89e9ad0..0000000000 --- a/vendor/github.com/cilium/cilium/pkg/trigger/trigger.go +++ /dev/null @@ -1,220 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package trigger - -import ( - "fmt" - - "github.com/cilium/cilium/pkg/lock" - "github.com/cilium/cilium/pkg/time" -) - -// MetricsObserver is the interface a metrics collector has to implement in -// order to collect trigger metrics -type MetricsObserver interface { - // PostRun is called after a trigger run with the call duration, the - // latency between 1st queue request and the call run and the number of - // queued events folded into the last run - PostRun(callDuration, latency time.Duration, folds int) - - // QueueEvent is called when Trigger() is called to schedule a trigger - // run - QueueEvent(reason string) -} - -// Parameters are the user specified parameters -type Parameters struct { - // MinInterval is the minimum required interval between invocations of - // TriggerFunc - MinInterval time.Duration - - // TriggerFunc is the function to be called when Trigger() is called - // while respecting MinInterval and serialization - TriggerFunc func(reasons []string) - - // ShutdownFunc is called when the trigger is shut down - ShutdownFunc func() - - MetricsObserver MetricsObserver - - // Name is the unique name of the trigger. It must be provided in a - // format compatible to be used as prometheus name string. - Name string - - // sleepInterval controls the waiter sleep duration. This parameter is - // only exposed to tests - sleepInterval time.Duration -} - -type reasonStack map[string]struct{} - -func newReasonStack() reasonStack { - return map[string]struct{}{} -} - -func (r reasonStack) add(reason string) { - r[reason] = struct{}{} -} - -func (r reasonStack) slice() []string { - result := make([]string, len(r)) - i := 0 - for reason := range r { - result[i] = reason - i++ - } - return result -} - -// Trigger represents an active trigger logic. Use NewTrigger() to create a -// trigger -type Trigger struct { - // protect mutual access of 'trigger' between Trigger() and waiter() - mutex lock.Mutex - trigger bool - - // params are the user specified parameters - params Parameters - - // lastTrigger is the timestamp of the last invoked trigger - lastTrigger time.Time - - // wakeupCan is used to wake up the background trigger routine - wakeupChan chan struct{} - - // closeChan is used to stop the background trigger routine - closeChan chan struct{} - - // numFolds is the current count of folds that happened into the - // currently scheduled trigger - numFolds int - - // foldedReasons is the sum of all unique reasons folded together. - foldedReasons reasonStack - - waitStart time.Time -} - -// NewTrigger returns a new trigger based on the provided parameters -func NewTrigger(p Parameters) (*Trigger, error) { - if p.sleepInterval == 0 { - p.sleepInterval = time.Second - } - - if p.TriggerFunc == nil { - return nil, fmt.Errorf("trigger function is nil") - } - - t := &Trigger{ - params: p, - wakeupChan: make(chan struct{}, 1), - closeChan: make(chan struct{}, 1), - foldedReasons: newReasonStack(), - } - - // Guarantee that initial trigger has no delay - if p.MinInterval > time.Duration(0) { - t.lastTrigger = time.Now().Add(-1 * p.MinInterval) - } - - go t.waiter() - - return t, nil -} - -// needsDelay returns whether and how long of a delay is required to fullfil -// MinInterval -func (t *Trigger) needsDelay() (bool, time.Duration) { - if t.params.MinInterval == time.Duration(0) { - return false, 0 - } - - sleepTime := time.Since(t.lastTrigger.Add(t.params.MinInterval)) - return sleepTime < 0, sleepTime * -1 -} - -// Trigger triggers the call to TriggerFunc as specified in the parameters -// provided to NewTrigger(). It respects MinInterval and ensures that calls to -// TriggerFunc are serialized. This function is non-blocking and will return -// immediately before TriggerFunc is potentially triggered and has completed. -func (t *Trigger) TriggerWithReason(reason string) { - t.mutex.Lock() - t.trigger = true - if t.numFolds == 0 { - t.waitStart = time.Now() - } - t.numFolds++ - t.foldedReasons.add(reason) - t.mutex.Unlock() - - if t.params.MetricsObserver != nil { - t.params.MetricsObserver.QueueEvent(reason) - } - - select { - case t.wakeupChan <- struct{}{}: - default: - } -} - -// Trigger triggers the call to TriggerFunc as specified in the parameters -// provided to NewTrigger(). It respects MinInterval and ensures that calls to -// TriggerFunc are serialized. This function is non-blocking and will return -// immediately before TriggerFunc is potentially triggered and has completed. -func (t *Trigger) Trigger() { - t.TriggerWithReason("") -} - -// Shutdown stops the trigger mechanism -func (t *Trigger) Shutdown() { - close(t.closeChan) -} - -func (t *Trigger) waiter() { - tk := time.NewTicker(t.params.sleepInterval) - defer tk.Stop() - - for { - // keep critical section as small as possible - t.mutex.Lock() - triggerEnabled := t.trigger - t.trigger = false - t.mutex.Unlock() - - // run the trigger function - if triggerEnabled { - if delayNeeded, delay := t.needsDelay(); delayNeeded { - time.Sleep(delay) - } - - t.mutex.Lock() - t.lastTrigger = time.Now() - numFolds := t.numFolds - t.numFolds = 0 - reasons := t.foldedReasons.slice() - t.foldedReasons = newReasonStack() - callLatency := time.Since(t.waitStart) - t.mutex.Unlock() - - beforeTrigger := time.Now() - t.params.TriggerFunc(reasons) - - if t.params.MetricsObserver != nil { - callDuration := time.Since(beforeTrigger) - t.params.MetricsObserver.PostRun(callDuration, callLatency, numFolds) - } - } - - select { - case <-t.wakeupChan: - case <-tk.C: - case <-t.closeChan: - shutdownFunc := t.params.ShutdownFunc - if shutdownFunc != nil { - shutdownFunc() - } - return - } - } -} diff --git a/vendor/github.com/cilium/statedb/part/map.go b/vendor/github.com/cilium/statedb/part/map.go index 70d0b070fa..f3d045598b 100644 --- a/vendor/github.com/cilium/statedb/part/map.go +++ b/vendor/github.com/cilium/statedb/part/map.go @@ -243,9 +243,11 @@ func (m *Map[K, V]) UnmarshalJSON(data []byte) error { func (m Map[K, V]) MarshalYAML() (any, error) { kvs := make([]mapKVPair[K, V], 0, m.Len()) - iter := m.tree.Iterator() - for _, kv, ok := iter.Next(); ok; _, kv, ok = iter.Next() { - kvs = append(kvs, kv) + if m.tree != nil { + iter := m.tree.Iterator() + for _, kv, ok := iter.Next(); ok; _, kv, ok = iter.Next() { + kvs = append(kvs, kv) + } } return kvs, nil } diff --git a/vendor/github.com/cilium/statedb/reconciler/incremental.go b/vendor/github.com/cilium/statedb/reconciler/incremental.go index 6bc65141bf..5e45e534be 100644 --- a/vendor/github.com/cilium/statedb/reconciler/incremental.go +++ b/vendor/github.com/cilium/statedb/reconciler/incremental.go @@ -174,7 +174,7 @@ func (round *incrementalRound[Obj]) batch(changes iter.Seq2[statedb.Change[Obj], if entry.Result == nil { round.retries.Clear(entry.Object) } - round.results[entry.Object] = opResult{rev: entry.Revision, id: status.id, err: entry.Result, original: entry.original} + round.results[entry.Object] = opResult{rev: entry.Revision, id: status.ID, err: entry.Result, original: entry.original} } } } @@ -213,7 +213,7 @@ func (round *incrementalRound[Obj]) processSingle(obj Obj, rev statedb.Revision, op = OpUpdate err = round.config.Operations.Update(round.ctx, round.txn, obj) status := round.config.GetObjectStatus(obj) - round.results[obj] = opResult{original: orig, id: status.id, rev: rev, err: err} + round.results[obj] = opResult{original: orig, id: status.ID, rev: rev, err: err} } round.metrics.ReconciliationDuration(round.moduleID, op, time.Since(start)) @@ -256,7 +256,7 @@ func (round *incrementalRound[Obj]) commitStatus() (numErrors int) { // modifying the object during reconciliation as the following will forget // the changes. currentStatus := round.config.GetObjectStatus(current) - if currentStatus.Kind == StatusKindPending && currentStatus.id == result.id { + if currentStatus.Kind == StatusKindPending && currentStatus.ID == result.id { current = round.config.CloneObject(current) current = round.config.SetObjectStatus(current, status) round.table.Insert(wtxn, current) diff --git a/vendor/github.com/cilium/statedb/reconciler/types.go b/vendor/github.com/cilium/statedb/reconciler/types.go index e436fd4c8e..9ae1dca874 100644 --- a/vendor/github.com/cilium/statedb/reconciler/types.go +++ b/vendor/github.com/cilium/statedb/reconciler/types.go @@ -140,7 +140,7 @@ type Status struct { // has really changed when committing the resulting status. // This allows multiple reconcilers to exist for a single // object without repeating work when status is updated. - id uint64 + ID uint64 `json:"id,omitempty" yaml:"id,omitempty"` } func (s Status) IsPendingOrRefreshing() bool { @@ -169,7 +169,7 @@ func StatusPending() Status { Kind: StatusKindPending, UpdatedAt: time.Now(), Error: "", - id: nextID(), + ID: nextID(), } } @@ -186,7 +186,7 @@ func StatusRefreshing() Status { Kind: StatusKindRefreshing, UpdatedAt: time.Now(), Error: "", - id: nextID(), + ID: nextID(), } } @@ -197,7 +197,7 @@ func StatusDone() Status { Kind: StatusKindDone, UpdatedAt: time.Now(), Error: "", - id: nextID(), + ID: nextID(), } } @@ -208,7 +208,7 @@ func StatusError(err error) Status { Kind: StatusKindError, UpdatedAt: time.Now(), Error: err.Error(), - id: nextID(), + ID: nextID(), } } @@ -249,7 +249,7 @@ func (s StatusSet) Pending() StatusSet { s.statuses = slices.Clone(s.statuses) for i := range s.statuses { s.statuses[i].Kind = StatusKindPending - s.statuses[i].id = s.id + s.statuses[i].ID = s.id } return s } @@ -331,7 +331,7 @@ func (s StatusSet) Get(name string) Status { return Status{ Kind: StatusKindPending, UpdatedAt: s.createdAt, - id: s.id, + ID: s.id, } } return s.statuses[idx].Status diff --git a/vendor/github.com/cilium/statedb/script.go b/vendor/github.com/cilium/statedb/script.go index 4db47f87e1..6e94b277bd 100644 --- a/vendor/github.com/cilium/statedb/script.go +++ b/vendor/github.com/cilium/statedb/script.go @@ -6,12 +6,10 @@ package statedb import ( "bytes" "encoding/json" - "errors" "flag" "fmt" "io" "iter" - "maps" "os" "regexp" "slices" @@ -25,62 +23,62 @@ import ( "gopkg.in/yaml.v3" ) -func ScriptCommands(db *DB) hive.ScriptCmdOut { - subCmds := map[string]script.Cmd{ - "tables": TablesCmd(db), - "show": ShowCmd(db), - "cmp": CompareCmd(db), - "insert": InsertCmd(db), - "delete": DeleteCmd(db), - "get": GetCmd(db), - "prefix": PrefixCmd(db), - "list": ListCmd(db), - "lowerbound": LowerBoundCmd(db), - "watch": WatchCmd(db), - "initialized": InitializedCmd(db), - } - subCmdsList := strings.Join(slices.Collect(maps.Keys(subCmds)), ", ") - return hive.NewScriptCmd( - "db", - script.Command( - script.CmdUsage{ - Summary: "Inspect and manipulate StateDB", - Args: "cmd args...", - Detail: []string{ - "Supported commands: " + subCmdsList, - }, - }, - func(s *script.State, args ...string) (script.WaitFunc, error) { - if len(args) < 1 { - return nil, fmt.Errorf("expected command (%s)", subCmdsList) - } - cmd, ok := subCmds[args[0]] - if !ok { - return nil, fmt.Errorf("command not found, expected one of %s", subCmdsList) - } - wf, err := cmd.Run(s, args[1:]...) - if errors.Is(err, errUsage) { - s.Logf("usage: db %s %s\n", args[0], cmd.Usage().Args) - } - return wf, err - }, - ), - ) +func ScriptCommands(db *DB) hive.ScriptCmdsOut { + return hive.NewScriptCmds(map[string]script.Cmd{ + "db": DBCmd(db), + "db/show": ShowCmd(db), + "db/cmp": CompareCmd(db), + "db/insert": InsertCmd(db), + "db/delete": DeleteCmd(db), + "db/get": GetCmd(db), + "db/prefix": PrefixCmd(db), + "db/list": ListCmd(db), + "db/lowerbound": LowerBoundCmd(db), + "db/watch": WatchCmd(db), + "db/initialized": InitializedCmd(db), + }) } -var errUsage = errors.New("bad arguments") - -func TablesCmd(db *DB) script.Cmd { +func DBCmd(db *DB) script.Cmd { return script.Command( script.CmdUsage{ - Summary: "Show StateDB tables", - Args: "table", + Summary: "Describe StateDB configuration", + Detail: []string{ + "The 'db' command describes the StateDB configuration, showing", + "all registered tables and brief summary of their state.", + "", + "The following details are shown:", + "- Name: The name of the table as given to 'NewTable'", + "- Object count: Objects in the table", + "- Zombie objects: Deleted, but not observed objects", + "- Indexes: The indexes specified for the table", + "- Initializers: Pending table initializers", + "- Go type: The Go type, the T in Table[T]", + "- Last WriteTxn: The current/last write against the table", + "", + "The individual tables can be manipulated and inspected with the", + "other commands. See 'help -v db/show' etc. for detailed help.", + "Here is some examples to get you statred:", + "", + "> db/show example", + "Name X", + "one 1", + "two 2", + "", + "> db/prefix -index=id example o", + "Name X", + "one 1", + "", + "> db/insert example three.yaml four.yaml", + "", + "> db/delete example three.yaml", + }, }, func(s *script.State, args ...string) (script.WaitFunc, error) { txn := db.ReadTxn() tbls := db.GetTables(txn) w := newTabWriter(s.LogWriter()) - fmt.Fprintf(w, "Name\tObject count\tDeleted objects\tIndexes\tInitializers\tGo type\tLast WriteTxn\n") + fmt.Fprintf(w, "Name\tObject count\tZombie objects\tIndexes\tInitializers\tGo type\tLast WriteTxn\n") for _, tbl := range tbls { idxs := strings.Join(tbl.Indexes(), ", ") fmt.Fprintf(w, "%s\t%d\t%d\t%s\t%v\t%T\t%s\n", @@ -92,32 +90,39 @@ func TablesCmd(db *DB) script.Cmd { ) } -func newCmdFlagSet() *flag.FlagSet { - return &flag.FlagSet{ - // Disable showing the normal usage. - Usage: func() {}, - } +func newCmdFlagSet(w io.Writer) *flag.FlagSet { + fs := flag.NewFlagSet("", flag.ContinueOnError) + fs.SetOutput(w) + return fs } func InitializedCmd(db *DB) script.Cmd { return script.Command( script.CmdUsage{ Summary: "Wait until all or specific tables have been initialized", - Args: "(-timeout=) table...", + Args: "[-timeout=] table...", + Detail: []string{ + "Waits until all or specific tables have been marked", + "initialized. The default timeout is 5 seconds.", + "", + "This command is useful in tests where you might need to wait", + "for e.g. a background reflector to have started watching before", + "inserting objects.", + }, }, func(s *script.State, args ...string) (script.WaitFunc, error) { - txn := db.ReadTxn() - allTbls := db.GetTables(txn) - tbls := allTbls - - flags := newCmdFlagSet() + flags := newCmdFlagSet(s.LogWriter()) timeout := flags.Duration("timeout", 5*time.Second, "Maximum amount of time to wait for the table contents to match") if err := flags.Parse(args); err != nil { - return nil, fmt.Errorf("%w: %s", errUsage, err) + return nil, fmt.Errorf("%w: %w", script.ErrUsage, err) } - timeoutChan := time.After(*timeout) args = flags.Args() + txn := db.ReadTxn() + timeoutChan := time.After(*timeout) + allTbls := db.GetTables(txn) + tbls := allTbls + if len(args) > 0 { // Specific tables requested, look them up. tbls = make([]TableMeta, 0, len(args)) @@ -160,16 +165,29 @@ func InitializedCmd(db *DB) script.Cmd { func ShowCmd(db *DB) script.Cmd { return script.Command( script.CmdUsage{ - Summary: "Show table", - Args: "(-o=) (-columns=col1,...) (-format={table,yaml,json}) table", + Summary: "Show the contents of a table", + Args: "[-o=] [-columns=col1,...] [-format={table,yaml,json}] table", + Detail: []string{ + "Show the contents of a table.", + "", + "The contents are written to stdout, but can be written to", + "a file instead with the -o flag.", + "", + "By default the table is shown in the table format.", + "For YAML use '-format=yaml' and for JSON use '-format=json'", + "", + "To only show specific columns use the '-columns' flag. The", + "columns are as specified by 'TableHeader()' method.", + "This flag is only supported with 'table' formatting.", + }, }, func(s *script.State, args ...string) (script.WaitFunc, error) { - flags := newCmdFlagSet() + flags := newCmdFlagSet(s.LogWriter()) file := flags.String("o", "", "File to write to instead of stdout") columns := flags.String("columns", "", "Comma-separated list of columns to write") format := flags.String("format", "table", "Format to write in (table, yaml, json)") if err := flags.Parse(args); err != nil { - return nil, fmt.Errorf("%w: %s", errUsage, err) + return nil, fmt.Errorf("%w: %w", script.ErrUsage, err) } var cols []string @@ -179,7 +197,7 @@ func ShowCmd(db *DB) script.Cmd { args = flags.Args() if len(args) < 1 { - return nil, fmt.Errorf("%w: missing table name", errUsage) + return nil, fmt.Errorf("missing table name") } tableName := args[0] return func(*script.State) (stdout, stderr string, err error) { @@ -209,16 +227,32 @@ func CompareCmd(db *DB) script.Cmd { return script.Command( script.CmdUsage{ Summary: "Compare table", - Args: "(-timeout=) (-grep=) table file", + Args: "[-timeout=] [-grep=] table file", + Detail: []string{ + "Compare the contents of a table against a file.", + "The comparison is retried until a timeout (1s default).", + "", + "The file should be formatted in the same style as", + "the output from 'db/show -format=table'. Indentation", + "does not matter as long as header is aligned with the data.", + "", + "Not all columns need to be specified. Remove the columns", + "from the file you do not want compared.", + "", + "The rows can be filtered with the -grep flag.", + }, }, func(s *script.State, args ...string) (script.WaitFunc, error) { - flags := newCmdFlagSet() + flags := newCmdFlagSet(s.LogWriter()) timeout := flags.Duration("timeout", time.Second, "Maximum amount of time to wait for the table contents to match") grep := flags.String("grep", "", "Grep the result rows and only compare matching ones") err := flags.Parse(args) + if err != nil { + return nil, fmt.Errorf("%w: %w", script.ErrUsage, err) + } args = flags.Args() - if err != nil || len(args) != 2 { - return nil, fmt.Errorf("%w: %s", errUsage, err) + if len(args) != 2 { + return nil, fmt.Errorf("expected table and filename") } var grepRe *regexp.Regexp @@ -321,6 +355,10 @@ func InsertCmd(db *DB) script.Cmd { script.CmdUsage{ Summary: "Insert object into a table", Args: "table path...", + Detail: []string{ + "Insert one or more objects into a table. The input files", + "are expected to be YAML.", + }, }, func(s *script.State, args ...string) (script.WaitFunc, error) { return insertOrDelete(true, db, s, args...) @@ -333,6 +371,11 @@ func DeleteCmd(db *DB) script.Cmd { script.CmdUsage{ Summary: "Delete an object from the table", Args: "table path...", + Detail: []string{ + "Delete one or more objects from the table. The input files", + "are expected to be YAML and need to specify enough of the", + "object to construct the primary key", + }, }, func(s *script.State, args ...string) (script.WaitFunc, error) { return insertOrDelete(false, db, s, args...) @@ -351,7 +394,7 @@ func getTable(db *DB, tableName string) (*AnyTable, ReadTxn, error) { func insertOrDelete(insert bool, db *DB, s *script.State, args ...string) (script.WaitFunc, error) { if len(args) < 2 { - return nil, fmt.Errorf("%w: expected table and path(s)", errUsage) + return nil, fmt.Errorf("expected table and path(s)") } tbl, _, err := getTable(db, args[0]) @@ -391,19 +434,44 @@ func insertOrDelete(insert bool, db *DB, s *script.State, args ...string) (scrip } func PrefixCmd(db *DB) script.Cmd { - return queryCmd(db, queryCmdPrefix, "Query table by prefix") + return queryCmd(db, + queryCmdPrefix, + "Query table by prefix", + []string{ + "Show all objects that start with the given " + underline("key") + ".", + }, + ) } func LowerBoundCmd(db *DB) script.Cmd { - return queryCmd(db, queryCmdLowerBound, "Query table by lower bound search") + return queryCmd(db, + queryCmdLowerBound, + "Query table by lower bound search", + []string{ + "Show all objects that have a matching key equal or higher", + "than the query " + underline("key") + ".", + }, + ) } func ListCmd(db *DB) script.Cmd { - return queryCmd(db, queryCmdList, "List objects in the table") + return queryCmd(db, + queryCmdList, + "List objects in the table", + []string{ + "Show all objects matching the query key.", + }, + ) } func GetCmd(db *DB) script.Cmd { - return queryCmd(db, queryCmdGet, "Get the first matching object") + return queryCmd(db, + queryCmdGet, + "Get the first matching object", + []string{ + "Show the first object that matches the query key.", + }, + ) } const ( @@ -413,11 +481,12 @@ const ( queryCmdGet ) -func queryCmd(db *DB, query int, summary string) script.Cmd { +func queryCmd(db *DB, query int, summary string, detail []string) script.Cmd { return script.Command( script.CmdUsage{ Summary: summary, - Args: "(-o=) (-columns=col1,...) (-format={table*,yaml,json}) (-index=) table key", + Args: "[-o=] [-columns=col1,...] [-format={table*,yaml,json}] [-index=] table key", + Detail: detail, }, func(s *script.State, args ...string) (script.WaitFunc, error) { return runQueryCmd(query, db, s, args) @@ -426,14 +495,14 @@ func queryCmd(db *DB, query int, summary string) script.Cmd { } func runQueryCmd(query int, db *DB, s *script.State, args []string) (script.WaitFunc, error) { - flags := newCmdFlagSet() + flags := newCmdFlagSet(s.LogWriter()) file := flags.String("o", "", "File to write results to instead of stdout") index := flags.String("index", "", "Index to query") format := flags.String("format", "table", "Format to write in (table, yaml, json)") columns := flags.String("columns", "", "Comma-separated list of columns to write") delete := flags.Bool("delete", false, "Delete all matching objects") if err := flags.Parse(args); err != nil { - return nil, fmt.Errorf("%w: %s", errUsage, err) + return nil, fmt.Errorf("%w: %w", script.ErrUsage, err) } var cols []string @@ -443,7 +512,7 @@ func runQueryCmd(query int, db *DB, s *script.State, args []string) (script.Wait args = flags.Args() if len(args) < 2 { - return nil, fmt.Errorf("%w: expected table and key", errUsage) + return nil, fmt.Errorf("expected table and key") } return func(*script.State) (stdout, stderr string, err error) { @@ -516,6 +585,10 @@ func WatchCmd(db *DB) script.Cmd { script.CmdUsage{ Summary: "Watch a table for changes", Args: "table", + Detail: []string{ + "Watch a table for changes. Streams each insert or delete", + "that happens to the table.", + }, }, func(s *script.State, args ...string) (script.WaitFunc, error) { if len(args) < 1 { @@ -829,3 +902,28 @@ func newTabWriter(out io.Writer) *tabwriter.Writer { ) return tabwriter.NewWriter(out, minWidth, width, padding, padChar, flags) } + +// sortArgs sorts the arguments to bring '-arg' first. Allows mixing +// the argument order. If e.g. key starts with '-', then it'll just +// need to be quoted: "db/get foo '-mykey'" +func sortedArgs(args []string) []string { + return slices.SortedStableFunc( + slices.Values(args), + func(a, b string) int { + aIsArg := strings.HasPrefix(a, "-") + bIsArg := strings.HasPrefix(b, "-") + switch { + case aIsArg && !bIsArg: + return -1 + case bIsArg && !aIsArg: + return 1 + default: + return 0 + } + }, + ) +} + +func underline(s string) string { + return "\033[4m" + s + "\033[0m" +} diff --git a/vendor/modules.txt b/vendor/modules.txt index c513ca508c..0e2c38a49e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -55,7 +55,7 @@ github.com/chai2010/gettext-go/po # github.com/cilium/charts v0.0.0-20241127112225-7cea2b4f120f ## explicit; go 1.17 github.com/cilium/charts -# github.com/cilium/cilium v1.17.0-pre.3.0.20241206091809-befdbb49a88b +# github.com/cilium/cilium v1.17.0-pre.3.0.20241206234938-95ee091cd967 ## explicit; go 1.23.0 github.com/cilium/cilium/api/v1/client github.com/cilium/cilium/api/v1/client/bgp @@ -136,23 +136,16 @@ github.com/cilium/cilium/pkg/container/set github.com/cilium/cilium/pkg/container/versioned github.com/cilium/cilium/pkg/controller github.com/cilium/cilium/pkg/crypto/certificatemanager -github.com/cilium/cilium/pkg/datapath/linux/config/defines github.com/cilium/cilium/pkg/datapath/linux/probes github.com/cilium/cilium/pkg/datapath/linux/safenetlink -github.com/cilium/cilium/pkg/datapath/loader/metrics github.com/cilium/cilium/pkg/datapath/tables -github.com/cilium/cilium/pkg/datapath/tunnel -github.com/cilium/cilium/pkg/datapath/types -github.com/cilium/cilium/pkg/datapath/xdp github.com/cilium/cilium/pkg/debug github.com/cilium/cilium/pkg/defaults github.com/cilium/cilium/pkg/endpoint/id -github.com/cilium/cilium/pkg/endpoint/regeneration github.com/cilium/cilium/pkg/envoy/resource github.com/cilium/cilium/pkg/fqdn/dns github.com/cilium/cilium/pkg/fqdn/matchpattern github.com/cilium/cilium/pkg/fqdn/re -github.com/cilium/cilium/pkg/fqdn/restore github.com/cilium/cilium/pkg/health/client github.com/cilium/cilium/pkg/health/defaults github.com/cilium/cilium/pkg/hive @@ -251,7 +244,6 @@ github.com/cilium/cilium/pkg/slices github.com/cilium/cilium/pkg/source github.com/cilium/cilium/pkg/spanstat github.com/cilium/cilium/pkg/time -github.com/cilium/cilium/pkg/trigger github.com/cilium/cilium/pkg/u8proto github.com/cilium/cilium/pkg/version github.com/cilium/cilium/pkg/versioncheck @@ -551,7 +543,7 @@ github.com/cilium/proxy/go/envoy/type/tracing/v3 github.com/cilium/proxy/go/envoy/type/v3 github.com/cilium/proxy/go/envoy/watchdog/v3 github.com/cilium/proxy/pkg/policy/api/kafka -# github.com/cilium/statedb v0.3.3 +# github.com/cilium/statedb v0.3.4 ## explicit; go 1.23 github.com/cilium/statedb github.com/cilium/statedb/index