Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions features.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
| NewOLMCatalogdAPIV1Metas| | | | <span style="background-color: #519450">Enabled</span> | | | | <span style="background-color: #519450">Enabled</span> |
| NewOLMConfigAPI| | | | <span style="background-color: #519450">Enabled</span> | | | | <span style="background-color: #519450">Enabled</span> |
| NewOLMOwnSingleNamespace| | | | <span style="background-color: #519450">Enabled</span> | | | | <span style="background-color: #519450">Enabled</span> |
| OVNKubernetesUplinkMode| | | <span style="background-color: #519450">Enabled</span> | <span style="background-color: #519450">Enabled</span> | | | | |
| ProvisioningRequestAvailable| | | <span style="background-color: #519450">Enabled</span> | <span style="background-color: #519450">Enabled</span> | | | | |
| AWSClusterHostedDNS| | | <span style="background-color: #519450">Enabled</span> | <span style="background-color: #519450">Enabled</span> | | | <span style="background-color: #519450">Enabled</span> | <span style="background-color: #519450">Enabled</span> |
| AWSDedicatedHosts| | | <span style="background-color: #519450">Enabled</span> | <span style="background-color: #519450">Enabled</span> | | | <span style="background-color: #519450">Enabled</span> | <span style="background-color: #519450">Enabled</span> |
Expand Down
8 changes: 8 additions & 0 deletions features/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,14 @@ var (
enable(inDevPreviewNoUpgrade()).
mustRegister()

FeatureGateOVNKubernetesUplinkMode = newFeatureGate("OVNKubernetesUplinkMode").
reportProblemsToJiraComponent("Networking/ovn-kubernetes").
contactPerson("anbhat").
productScope(ocpSpecific).
enhancementPR("https://github.com/openshift/enhancements/pull/2093").
enable(inDevPreviewNoUpgrade()).
mustRegister()

FeatureGateNoOverlayMode = newFeatureGate("NoOverlayMode").
reportProblemsToJiraComponent("Networking/ovn-kubernetes").
contactPerson("pliurh").
Expand Down
2 changes: 1 addition & 1 deletion hack/verify-payload-crds.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ files=$(echo "${files}" | tr "," "\n")
# by the crd_globs into the payload CRDs folder.
for f in "${SCRIPT_ROOT}/payload-manifests/crds/"*; do
basename=$(basename "${f}")
if ! echo "${files}" | grep -F -q -x "${basename}"; then
if ! grep -F -q -x "${basename}" <<< "${files}"; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did this change need to be made?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so verify-payload-crds.sh was failing the prow verify job.

The script fails with echo receiving SIGPIPE when the ${files} list is large and echo is still piping it to grep, when grep -q finds an early match and exits.

Without the fix, the script would incorrectly report a generated payload crd as untracked, although it did find the file. The change gets rid of the piping business entirely.

echo "Found untracked file ${basename} in payload CRD manifests. Please add the file to crd_globs in hack/update-payload-crds.sh."
exit 1
fi
Expand Down
7 changes: 7 additions & 0 deletions openapi/generated_openapi/zz_generated.openapi.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions openapi/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -33049,6 +33049,10 @@
"routingViaHost": {
"description": "routingViaHost allows pod egress traffic to exit via the ovn-k8s-mp0 management port into the host before sending it out. If this is not set, traffic will always egress directly from OVN to outside without touching the host stack. Setting this to true means hardware offload will not be supported. Default is false if GatewayConfig is specified.",
"type": "boolean"
},
"uplinkMode": {
"description": "uplinkMode controls whether the external gateway bridge (br-ex) requires a physical uplink port. Allowed values are \"Required\" and \"Optional\". When set to \"Required\", ovn-kubernetes requires an uplink on the gateway bridge. When set to \"Optional\", ovn-kubernetes allows the gateway bridge to start without an uplink. When omitted, this means no opinion and the platform is left to choose a reasonable default, which is subject to change over time. The current default is \"Required\". This setting only takes effect when routingViaHost is true (local gateway mode).",
"type": "string"
}
}
},
Expand Down
101 changes: 101 additions & 0 deletions operator/v1/tests/networks.operator.openshift.io/AAA_ungated.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,107 @@ tests:
disableNetworkDiagnostics: false
logLevel: "Normal"
operatorLogLevel: "Normal"
- name: "Should omit uplinkMode when not specified"
initial: |
apiVersion: operator.openshift.io/v1
kind: Network
spec:
defaultNetwork:
ovnKubernetesConfig:
gatewayConfig:
routingViaHost: true
expected: |
apiVersion: operator.openshift.io/v1
kind: Network
spec:
defaultNetwork:
ovnKubernetesConfig:
gatewayConfig:
routingViaHost: true
ipsecConfig:
mode: Disabled
disableNetworkDiagnostics: false
logLevel: "Normal"
operatorLogLevel: "Normal"
- name: "Should be able to set uplinkMode to Optional"
initial: |
apiVersion: operator.openshift.io/v1
kind: Network
spec:
defaultNetwork:
ovnKubernetesConfig:
gatewayConfig:
routingViaHost: true
uplinkMode: Optional
expected: |
apiVersion: operator.openshift.io/v1
kind: Network
spec:
defaultNetwork:
ovnKubernetesConfig:
gatewayConfig:
uplinkMode: Optional
routingViaHost: true
ipsecConfig:
mode: Disabled
disableNetworkDiagnostics: false
logLevel: "Normal"
operatorLogLevel: "Normal"
- name: "Should be able to set uplinkMode to Required"
initial: |
apiVersion: operator.openshift.io/v1
kind: Network
spec:
defaultNetwork:
ovnKubernetesConfig:
gatewayConfig:
routingViaHost: true
uplinkMode: Required
expected: |
apiVersion: operator.openshift.io/v1
kind: Network
spec:
defaultNetwork:
ovnKubernetesConfig:
gatewayConfig:
uplinkMode: Required
routingViaHost: true
ipsecConfig:
mode: Disabled
disableNetworkDiagnostics: false
logLevel: "Normal"
operatorLogLevel: "Normal"
- name: "Should not be able to set uplinkMode to an invalid value"
initial: |
apiVersion: operator.openshift.io/v1
kind: Network
spec:
defaultNetwork:
ovnKubernetesConfig:
gatewayConfig:
uplinkMode: Invalid
expectedError: "spec.defaultNetwork.ovnKubernetesConfig.gatewayConfig.uplinkMode: Unsupported value: \"Invalid\": supported values: \"Required\", \"Optional\""
- name: "Should not be able to set uplinkMode when routingViaHost is omitted"
initial: |
apiVersion: operator.openshift.io/v1
kind: Network
spec:
defaultNetwork:
ovnKubernetesConfig:
gatewayConfig:
uplinkMode: Optional
expectedError: "spec.defaultNetwork.ovnKubernetesConfig.gatewayConfig: Invalid value: \"object\": uplinkMode can only be set when routingViaHost is true"
- name: "Should not be able to set uplinkMode when routingViaHost is false"
initial: |
apiVersion: operator.openshift.io/v1
kind: Network
spec:
defaultNetwork:
ovnKubernetesConfig:
gatewayConfig:
routingViaHost: false
uplinkMode: Optional
expectedError: "spec.defaultNetwork.ovnKubernetesConfig.gatewayConfig: Invalid value: \"object\": uplinkMode can only be set when routingViaHost is true"
onUpdate:
- name: "IPsec - Removing ipsecConfig.mode is not allowed"
initial: |
Expand Down
21 changes: 21 additions & 0 deletions operator/v1/types_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,7 @@ const (
)

// GatewayConfig holds node gateway-related parsed config file parameters and command-line overrides
// +openshift:validation:FeatureGateAwareXValidation:featureGate=OVNKubernetesUplinkMode,rule="!has(self.uplinkMode) || (has(self.routingViaHost) && self.routingViaHost == true)",message="uplinkMode can only be set when routingViaHost is true"
type GatewayConfig struct {
// routingViaHost allows pod egress traffic to exit via the ovn-k8s-mp0 management port
// into the host before sending it out. If this is not set, traffic will always egress directly
Expand All @@ -650,6 +651,16 @@ type GatewayConfig struct {
// +kubebuilder:default:=false
// +optional
RoutingViaHost bool `json:"routingViaHost,omitempty"`
// uplinkMode controls whether the external gateway bridge (br-ex) requires a physical uplink port.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forget if the option is only for br-ex or for all Uplinks (example Uplink API+CUDN API https://ovn-kubernetes.io/master/features/user-defined-networks/uplinks/#introduction - there is plans to make the whole CDN bridge an Uplink API defined thing in future and maybe answer is this option would then become a per Uplink thing) In upstream it might not be a well defined thing now and we don't support Uplink API in OCP yet, but its something we need to consider since once we defined the field's purpose as only for br-ex we won't be able to change that scoping, so it would be good for us to think if we only want it for br-ex or keep it vague to accommodate other bridges as well including the APBER Secondary bridge which is also an external gateway bridge today.

// Allowed values are "Required" and "Optional".
// When set to "Required", ovn-kubernetes requires an uplink on the gateway bridge.
// When set to "Optional", ovn-kubernetes allows the gateway bridge to start without an uplink.
// When omitted, this means no opinion and the platform is left to choose a reasonable default,
// which is subject to change over time. The current default is "Required".

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// which is subject to change over time. The current default is "Required".

can defaults really change over time - if its from API standing that's considered breaking change right? if we change from required -> optional later on? maybe we have to reword this - from API standpoint the CRD defaulting is "required" and that is not subject to change, the customer can choose their own value to override that default but when we say "choose a reasonable default" that is confusing with the API default

@tssurya tssurya Sep 3, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also this field is mutable on day2 I suppose? and CNO will roll out the changes? (it comes with conditions apply on if people remove uplinks mid-way on day2 and change this knob that's on them for the downtime)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a disclaimer that we can do without. It's simply saying that if the field is omitted, and tomorrow we move to a different behavior for some reason than requiring uplinks we are covering our bases. If it is adding confusion for a hypothetical future-proofing, I can remove it.

The behavior for Day 2 changes needs to be documented at the very least, if it can't be ensured for correctness functionally by the implementation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For configuration APIs like this, yes we can change default behaviors without warning when we make this explicit statement in the API documentation.

It allows us to change our opinion on what the default value should be for the platform as we see fit.

Customers can always override that by specifying an explicit opinion on the field.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For configuration APIs like this, yes we can change default behaviors without warning when we make this explicit statement in the API documentation.

It allows us to change our opinion on what the default value should be for the platform as we see fit.

oh nice, I learnt something new then!

// This setting only takes effect when routingViaHost is true (local gateway mode).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might want to enforce this using CEL on the parent struct GatewayConfig :

// +kubebuilder:validation:XValidation:rule="!has(self.uplinkMode) || (has(self.routingViaHost) && self.routingViaHost == true)",message="uplinkMode can only be set when routingViaHost is true"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added CEL validation on parent struct GatewayConfig.

// +openshift:enable:FeatureGate=OVNKubernetesUplinkMode
// +optional
UplinkMode UplinkMode `json:"uplinkMode,omitempty"`
// ipForwarding controls IP forwarding for all traffic on OVN-Kubernetes managed interfaces (such as br-ex).
// By default this is set to Restricted, and Kubernetes related traffic is still forwarded appropriately, but other
// IP traffic will not be routed by the OCP node. If there is a desire to allow the host to forward traffic across
Expand Down Expand Up @@ -900,6 +911,16 @@ const (
IPsecModeFull IPsecMode = "Full"
)

// +kubebuilder:validation:Enum:="Required";"Optional"
type UplinkMode string

var (
// UplinkModeRequired requires an uplink on the gateway bridge.
UplinkModeRequired UplinkMode = "Required"
// UplinkModeOptional allows the gateway bridge to start without a physical uplink.
UplinkModeOptional UplinkMode = "Optional"
)

// +kubebuilder:validation:Enum:="";"Enabled";"Disabled"
type RouteAdvertisementsEnablement string

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,25 @@ spec:
from OVN to outside without touching the host stack. Setting this to true means hardware
offload will not be supported. Default is false if GatewayConfig is specified.
type: boolean
uplinkMode:
description: |-
uplinkMode controls whether the external gateway bridge (br-ex) requires a physical uplink port.
Allowed values are "Required" and "Optional".
When set to "Required", ovn-kubernetes requires an uplink on the gateway bridge.
When set to "Optional", ovn-kubernetes allows the gateway bridge to start without an uplink.
When omitted, this means no opinion and the platform is left to choose a reasonable default,
which is subject to change over time. The current default is "Required".
This setting only takes effect when routingViaHost is true (local gateway mode).
enum:
- Required
- Optional
type: string
type: object
x-kubernetes-validations:
- message: uplinkMode can only be set when routingViaHost
is true
rule: '!has(self.uplinkMode) || (has(self.routingViaHost)
&& self.routingViaHost == true)'
genevePort:
description: |-
geneve port is the UDP port to be used by geneve encapulation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,25 @@ spec:
from OVN to outside without touching the host stack. Setting this to true means hardware
offload will not be supported. Default is false if GatewayConfig is specified.
type: boolean
uplinkMode:
description: |-
uplinkMode controls whether the external gateway bridge (br-ex) requires a physical uplink port.
Allowed values are "Required" and "Optional".
When set to "Required", ovn-kubernetes requires an uplink on the gateway bridge.
When set to "Optional", ovn-kubernetes allows the gateway bridge to start without an uplink.
When omitted, this means no opinion and the platform is left to choose a reasonable default,
which is subject to change over time. The current default is "Required".
This setting only takes effect when routingViaHost is true (local gateway mode).
enum:
- Required
- Optional
type: string
type: object
x-kubernetes-validations:
- message: uplinkMode can only be set when routingViaHost
is true
rule: '!has(self.uplinkMode) || (has(self.routingViaHost)
&& self.routingViaHost == true)'
genevePort:
description: |-
geneve port is the UDP port to be used by geneve encapulation.
Expand Down
1 change: 1 addition & 0 deletions operator/v1/zz_generated.featuregated-crd-manifests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ networks.operator.openshift.io:
Category: ""
FeatureGates:
- NoOverlayMode
- OVNKubernetesUplinkMode
FilenameOperatorName: network
FilenameOperatorOrdering: "01"
FilenameRunLevel: "0000_70"
Expand Down
Loading