From 37ca2cc802c88f31f41e22a352edc535d040eb6a Mon Sep 17 00:00:00 2001
From: Oren Cohen
Date: Thu, 7 May 2026 14:42:37 +0300
Subject: [PATCH] fix(api): OCPBUGS-84303: add IPv6 OVN join subnet config to
prevent dual-stack routing collision
Cherry-pick of #8421 to release-4.21.
On KubeVirt dual-stack hosted clusters, the guest OVN-Kubernetes cluster
shares the same default IPv6 join subnet (fd98::/64) as the management
cluster. When external IPv6 LoadBalancer traffic is SNAT'd to a join
switch IP, the guest cluster intercepts the response because both
clusters own the same fd98::/64 range, causing a routing black hole.
This fix:
- Defaults the guest cluster's IPv6 OVN join subnet to fd99::/64 for
KubeVirt hosted clusters, avoiding the collision automatically
- Adds OVNIPv6Config API type allowing users to explicitly configure
IPv6 internalJoinSubnet and internalTransitSwitchSubnet
- Extends CIDR overlap validation to cover IPv6 OVN subnets including
the implicit KubeVirt default (fd99::/64)
- Adds unit tests for all new IPv6 validation and reconciliation logic
Signed-off-by: Oren Cohen
Assisted-by: Claude Opus 4 (via Cursor)
Co-authored-by: Cursor
---
api/hypershift/v1beta1/operator.go | 49 +++++++
.../v1beta1/zz_generated.deepcopy.go | 16 +++
.../AAA_ungated.yaml | 64 +++++++++
.../AutoNodeKarpenter.yaml | 64 +++++++++
.../ClusterVersionOperatorConfiguration.yaml | 64 +++++++++
.../ExternalOIDC.yaml | 64 +++++++++
...ernalOIDCWithUIDAndExtraClaimMappings.yaml | 64 +++++++++
.../GCPPlatform.yaml | 64 +++++++++
...perShiftOnlyDynamicResourceAllocation.yaml | 64 +++++++++
.../ImageStreamImportMode.yaml | 64 +++++++++
.../KMSEncryptionProvider.yaml | 64 +++++++++
.../NetworkDiagnosticsConfig.yaml | 64 +++++++++
.../OpenStack.yaml | 64 +++++++++
.../AAA_ungated.yaml | 64 +++++++++
.../AutoNodeKarpenter.yaml | 64 +++++++++
.../ClusterVersionOperatorConfiguration.yaml | 64 +++++++++
.../ExternalOIDC.yaml | 64 +++++++++
...ernalOIDCWithUIDAndExtraClaimMappings.yaml | 64 +++++++++
.../GCPPlatform.yaml | 64 +++++++++
...perShiftOnlyDynamicResourceAllocation.yaml | 64 +++++++++
.../ImageStreamImportMode.yaml | 64 +++++++++
.../KMSEncryptionProvider.yaml | 64 +++++++++
.../NetworkDiagnosticsConfig.yaml | 64 +++++++++
.../OpenStack.yaml | 64 +++++++++
.../hypershift/v1beta1/ovnipv6config.go | 47 +++++++
.../hypershift/v1beta1/ovnkubernetesconfig.go | 9 ++
client/applyconfiguration/utils.go | 2 +
...usters-Hypershift-CustomNoUpgrade.crd.yaml | 64 +++++++++
...hostedclusters-Hypershift-Default.crd.yaml | 64 +++++++++
...s-Hypershift-TechPreviewNoUpgrade.crd.yaml | 64 +++++++++
...planes-Hypershift-CustomNoUpgrade.crd.yaml | 64 +++++++++
...dcontrolplanes-Hypershift-Default.crd.yaml | 64 +++++++++
...s-Hypershift-TechPreviewNoUpgrade.crd.yaml | 64 +++++++++
.../resources/network/reconcile.go | 25 ++++
.../resources/network/reconcile_test.go | 98 ++++++++++++++
docs/content/reference/api.md | 81 ++++++++++++
.../hostedcluster/hostedcluster_controller.go | 28 ++++
.../hostedcluster_controller_test.go | 125 ++++++++++++++++--
.../api/hypershift/v1beta1/operator.go | 49 +++++++
.../v1beta1/zz_generated.deepcopy.go | 16 +++
40 files changed, 2328 insertions(+), 9 deletions(-)
create mode 100644 client/applyconfiguration/hypershift/v1beta1/ovnipv6config.go
diff --git a/api/hypershift/v1beta1/operator.go b/api/hypershift/v1beta1/operator.go
index c1e455682903..6e902f9c3e29 100644
--- a/api/hypershift/v1beta1/operator.go
+++ b/api/hypershift/v1beta1/operator.go
@@ -62,6 +62,7 @@ type ClusterNetworkOperatorSpec struct {
// OVNKubernetesConfig contains OVN-Kubernetes specific configuration options.
// https://github.com/openshift/api/blob/6d3c4e25a8d3aeb57ad61649d80c38cbd27d1cc8/operator/v1/types_network.go#L400-L471
// +kubebuilder:validation:XValidation:rule="!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet) || !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet != self.ipv4.internalTransitSwitchSubnet", message="internalJoinSubnet and internalTransitSwitchSubnet must not be the same"
+// +kubebuilder:validation:XValidation:rule="!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet) || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet != self.ipv6.internalTransitSwitchSubnet", message="IPv6 internalJoinSubnet and internalTransitSwitchSubnet must not be the same"
// +kubebuilder:validation:MinProperties=1
type OVNKubernetesConfig struct {
// ipv4 allows users to configure IP settings for IPv4 connections. When omitted,
@@ -69,6 +70,15 @@ type OVNKubernetesConfig struct {
// fields within ipv4 for details of default values.
// +optional
IPv4 *OVNIPv4Config `json:"ipv4,omitempty"`
+
+ // ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ // this means no opinions and the default configuration is used. Check individual
+ // fields within ipv6 for details of default values.
+ // For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ // set ipv6.internalJoinSubnet to a value different from the management cluster's
+ // join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ // +optional
+ IPv6 OVNIPv6Config `json:"ipv6,omitzero,omitempty"`
}
// OVNIPv4Config contains IPv4-specific configuration options for OVN-Kubernetes.
@@ -108,6 +118,45 @@ type OVNIPv4Config struct {
InternalJoinSubnet string `json:"internalJoinSubnet,omitempty"`
}
+// OVNIPv6Config contains IPv6-specific configuration options for OVN-Kubernetes.
+// +kubebuilder:validation:MinProperties=1
+type OVNIPv6Config struct {
+ // internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ // by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ // architecture that connects the cluster routers on each node together to enable
+ // east west traffic. The subnet chosen should not overlap with other networks
+ // specified for OVN-Kubernetes as well as other networks used on the host.
+ // 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 subnet is fd97::/64.
+ // The subnet must be large enough to accommodate one IP per node in your cluster.
+ // The value must be in proper IPv6 CIDR format.
+ // Note that IPv6 dual addresses are not permitted.
+ // +kubebuilder:validation:MaxLength=48
+ // +kubebuilder:validation:MinLength=3
+ // +kubebuilder:validation:XValidation:rule="self.matches('^\\\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')", message="Subnet must be in valid IPv6 CIDR format (e.g., fd97::/64)"
+ // +kubebuilder:validation:XValidation:rule="self.matches('^.*/[0-9]+$') && int(self.split('/')[1]) <= 125", message="subnet must be in the range /0 to /125 inclusive"
+ // +optional
+ InternalTransitSwitchSubnet string `json:"internalTransitSwitchSubnet,omitempty"`
+ // internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ // default one is being already used by something else. It must not overlap with
+ // any other subnet being used by OpenShift or by the node network. The size of the
+ // subnet must be larger than the number of nodes.
+ // The current default value is fd98::/64.
+ // For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ // automatically use fd99::/64 to avoid collisions with the management cluster's
+ // default join subnet (fd98::/64).
+ // The subnet must be large enough to accommodate one IP per node in your cluster.
+ // The value must be in proper IPv6 CIDR format.
+ // Note that IPv6 dual addresses are not permitted.
+ // +kubebuilder:validation:MaxLength=48
+ // +kubebuilder:validation:MinLength=3
+ // +kubebuilder:validation:XValidation:rule="self.matches('^\\\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')", message="Subnet must be in valid IPv6 CIDR format (e.g., fd98::/64)"
+ // +kubebuilder:validation:XValidation:rule="self.matches('^.*/[0-9]+$') && int(self.split('/')[1]) <= 125", message="subnet must be in the range /0 to /125 inclusive"
+ // +optional
+ InternalJoinSubnet string `json:"internalJoinSubnet,omitempty"`
+}
+
// IngressOperatorSpec is the specification of the desired behavior of the Ingress Operator.
type IngressOperatorSpec struct {
// endpointPublishingStrategy is used to publish the default ingress controller endpoints.
diff --git a/api/hypershift/v1beta1/zz_generated.deepcopy.go b/api/hypershift/v1beta1/zz_generated.deepcopy.go
index 033c005b7996..06e27795385d 100644
--- a/api/hypershift/v1beta1/zz_generated.deepcopy.go
+++ b/api/hypershift/v1beta1/zz_generated.deepcopy.go
@@ -3205,6 +3205,21 @@ func (in *OVNIPv4Config) DeepCopy() *OVNIPv4Config {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *OVNIPv6Config) DeepCopyInto(out *OVNIPv6Config) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVNIPv6Config.
+func (in *OVNIPv6Config) DeepCopy() *OVNIPv6Config {
+ if in == nil {
+ return nil
+ }
+ out := new(OVNIPv6Config)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OVNKubernetesConfig) DeepCopyInto(out *OVNKubernetesConfig) {
*out = *in
@@ -3213,6 +3228,7 @@ func (in *OVNKubernetesConfig) DeepCopyInto(out *OVNKubernetesConfig) {
*out = new(OVNIPv4Config)
**out = **in
}
+ out.IPv6 = in.IPv6
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVNKubernetesConfig.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml
index 67d4c67aa1b8..fa76c5bd88a6 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml
@@ -2908,6 +2908,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -2915,6 +2974,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AutoNodeKarpenter.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AutoNodeKarpenter.yaml
index 6f97b3457f9c..2b6acde6cc57 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AutoNodeKarpenter.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AutoNodeKarpenter.yaml
@@ -2946,6 +2946,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -2953,6 +3012,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
index 0a323bb4efe0..7f68212bb754 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
@@ -2899,6 +2899,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -2906,6 +2965,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
clusterVersionOperator:
description: clusterVersionOperator specifies the configuration
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml
index 6754575c6eb3..1eede2f18bfa 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml
@@ -3256,6 +3256,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -3263,6 +3322,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
index 2d921aefee19..c53ce18fc700 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
@@ -3410,6 +3410,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -3417,6 +3476,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml
index 22364d504b01..b4b900474429 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml
@@ -2899,6 +2899,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -2906,6 +2965,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
index a289044c10fc..7365430d6092 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
@@ -2921,6 +2921,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -2928,6 +2987,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml
index 8367c5054ed6..0f34b3ea661b 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml
@@ -2917,6 +2917,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -2924,6 +2983,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml
index 0dc3539806fc..228b7ef738ba 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml
@@ -2975,6 +2975,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -2982,6 +3041,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/NetworkDiagnosticsConfig.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/NetworkDiagnosticsConfig.yaml
index e4f7780bc9d6..6d628fbc1e31 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/NetworkDiagnosticsConfig.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/NetworkDiagnosticsConfig.yaml
@@ -3051,6 +3051,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -3058,6 +3117,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml
index ca5271513024..7ea39d59e856 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml
@@ -2899,6 +2899,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -2906,6 +2965,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml
index b3f2af593574..36deab38e0e5 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml
@@ -2808,6 +2808,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -2815,6 +2874,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AutoNodeKarpenter.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AutoNodeKarpenter.yaml
index 5f530d52a9d0..23cb4c34122a 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AutoNodeKarpenter.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AutoNodeKarpenter.yaml
@@ -2846,6 +2846,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -2853,6 +2912,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
index 9fe3f7cdda1e..78987c3ceb74 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
@@ -2799,6 +2799,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -2806,6 +2865,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
clusterVersionOperator:
description: clusterVersionOperator specifies the configuration
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml
index bbc0a377f1cf..1989eb0a7d65 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml
@@ -3156,6 +3156,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -3163,6 +3222,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
index 8cd1b1a5fadc..8faee6f2a4b4 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
@@ -3310,6 +3310,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -3317,6 +3376,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
index 8841aba982ec..2b0778a66d25 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
@@ -2799,6 +2799,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -2806,6 +2865,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
index b6fbd0537dfa..9418b0426b55 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
@@ -2821,6 +2821,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -2828,6 +2887,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml
index 1ca8beb484a9..5b16187601c4 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml
@@ -2817,6 +2817,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -2824,6 +2883,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml
index d6aa6a4163cd..49799e6d6c9e 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml
@@ -2875,6 +2875,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -2882,6 +2941,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/NetworkDiagnosticsConfig.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/NetworkDiagnosticsConfig.yaml
index 99810c89aef7..8ca736db2b15 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/NetworkDiagnosticsConfig.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/NetworkDiagnosticsConfig.yaml
@@ -2951,6 +2951,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -2958,6 +3017,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml
index 9e019144a409..a5dda6b1f681 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml
@@ -2799,6 +2799,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -2806,6 +2865,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/client/applyconfiguration/hypershift/v1beta1/ovnipv6config.go b/client/applyconfiguration/hypershift/v1beta1/ovnipv6config.go
new file mode 100644
index 000000000000..2205ac30a97e
--- /dev/null
+++ b/client/applyconfiguration/hypershift/v1beta1/ovnipv6config.go
@@ -0,0 +1,47 @@
+/*
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+// Code generated by applyconfiguration-gen. DO NOT EDIT.
+
+package v1beta1
+
+// OVNIPv6ConfigApplyConfiguration represents a declarative configuration of the OVNIPv6Config type for use
+// with apply.
+type OVNIPv6ConfigApplyConfiguration struct {
+ InternalTransitSwitchSubnet *string `json:"internalTransitSwitchSubnet,omitempty"`
+ InternalJoinSubnet *string `json:"internalJoinSubnet,omitempty"`
+}
+
+// OVNIPv6ConfigApplyConfiguration constructs a declarative configuration of the OVNIPv6Config type for use with
+// apply.
+func OVNIPv6Config() *OVNIPv6ConfigApplyConfiguration {
+ return &OVNIPv6ConfigApplyConfiguration{}
+}
+
+// WithInternalTransitSwitchSubnet sets the InternalTransitSwitchSubnet field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the InternalTransitSwitchSubnet field is set to the value of the last call.
+func (b *OVNIPv6ConfigApplyConfiguration) WithInternalTransitSwitchSubnet(value string) *OVNIPv6ConfigApplyConfiguration {
+ b.InternalTransitSwitchSubnet = &value
+ return b
+}
+
+// WithInternalJoinSubnet sets the InternalJoinSubnet field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the InternalJoinSubnet field is set to the value of the last call.
+func (b *OVNIPv6ConfigApplyConfiguration) WithInternalJoinSubnet(value string) *OVNIPv6ConfigApplyConfiguration {
+ b.InternalJoinSubnet = &value
+ return b
+}
diff --git a/client/applyconfiguration/hypershift/v1beta1/ovnkubernetesconfig.go b/client/applyconfiguration/hypershift/v1beta1/ovnkubernetesconfig.go
index 28220930f5cd..0e2832da983d 100644
--- a/client/applyconfiguration/hypershift/v1beta1/ovnkubernetesconfig.go
+++ b/client/applyconfiguration/hypershift/v1beta1/ovnkubernetesconfig.go
@@ -21,6 +21,7 @@ package v1beta1
// with apply.
type OVNKubernetesConfigApplyConfiguration struct {
IPv4 *OVNIPv4ConfigApplyConfiguration `json:"ipv4,omitempty"`
+ IPv6 *OVNIPv6ConfigApplyConfiguration `json:"ipv6,omitempty"`
}
// OVNKubernetesConfigApplyConfiguration constructs a declarative configuration of the OVNKubernetesConfig type for use with
@@ -36,3 +37,11 @@ func (b *OVNKubernetesConfigApplyConfiguration) WithIPv4(value *OVNIPv4ConfigApp
b.IPv4 = value
return b
}
+
+// WithIPv6 sets the IPv6 field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the IPv6 field is set to the value of the last call.
+func (b *OVNKubernetesConfigApplyConfiguration) WithIPv6(value *OVNIPv6ConfigApplyConfiguration) *OVNKubernetesConfigApplyConfiguration {
+ b.IPv6 = value
+ return b
+}
diff --git a/client/applyconfiguration/utils.go b/client/applyconfiguration/utils.go
index 00fde501d38c..d1dafc8ed848 100644
--- a/client/applyconfiguration/utils.go
+++ b/client/applyconfiguration/utils.go
@@ -293,6 +293,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &hypershiftv1beta1.OperatorConfigurationApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("OVNIPv4Config"):
return &hypershiftv1beta1.OVNIPv4ConfigApplyConfiguration{}
+ case v1beta1.SchemeGroupVersion.WithKind("OVNIPv6Config"):
+ return &hypershiftv1beta1.OVNIPv6ConfigApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("OVNKubernetesConfig"):
return &hypershiftv1beta1.OVNKubernetesConfigApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("PersistentVolumeEtcdStorageSpec"):
diff --git a/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml b/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml
index 9fdbd7f66d07..b7dc8ef45557 100644
--- a/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml
+++ b/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml
@@ -3727,6 +3727,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -3734,6 +3793,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
clusterVersionOperator:
description: clusterVersionOperator specifies the configuration
diff --git a/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml b/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml
index a38ac68dfd6d..71c2a8626206 100644
--- a/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml
+++ b/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml
@@ -3591,6 +3591,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -3598,6 +3657,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml b/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml
index 6e1abf441e60..27bdfb998229 100644
--- a/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml
+++ b/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml
@@ -3638,6 +3638,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -3645,6 +3704,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
clusterVersionOperator:
description: clusterVersionOperator specifies the configuration
diff --git a/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml b/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
index 79c28ac986aa..401ff1ec16b9 100644
--- a/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
+++ b/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
@@ -3627,6 +3627,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -3634,6 +3693,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
clusterVersionOperator:
description: clusterVersionOperator specifies the configuration
diff --git a/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml b/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml
index c2d3f779771d..7fc7b4cc4a5f 100644
--- a/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml
+++ b/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml
@@ -3491,6 +3491,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -3498,6 +3557,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
ingressOperator:
description: |-
diff --git a/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml b/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml
index 5062a7530618..532ec687a0ca 100644
--- a/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml
+++ b/cmd/install/assets/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml
@@ -3538,6 +3538,65 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ 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 subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be in proper IPv6 CIDR format.
+ Note that IPv6 dual addresses are not permitted.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: self.matches('^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: self.matches('^.*/[0-9]+$') && int(self.split('/')[1])
+ <= 125
+ type: object
type: object
x-kubernetes-validations:
- message: internalJoinSubnet and internalTransitSwitchSubnet
@@ -3545,6 +3604,11 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: IPv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
type: object
clusterVersionOperator:
description: clusterVersionOperator specifies the configuration
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/network/reconcile.go b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/network/reconcile.go
index b37768bc8563..5bd16b71f1b1 100644
--- a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/network/reconcile.go
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/network/reconcile.go
@@ -36,6 +36,12 @@ const kubevirtDefaultGenevePort = uint32(9880)
// is 100.65.0.0/16. We need to avoid that for kubernetes which runs nested.
const kubevirtDefaultV4InternalSubnet = "100.66.0.0/16"
+// The default OVN IPv6 join subnet is fd98::/64. We need to avoid that for
+// KubeVirt hosted clusters which run nested, because both the management and
+// guest clusters would use the same join subnet, causing IPv6 routing conflicts
+// when external traffic is SNAT'd to a join switch IP.
+const kubevirtDefaultV6InternalJoinSubnet = "fd99::/64"
+
func ReconcileNetworkOperator(network *operatorv1.Network, networkType hyperv1.NetworkType, platformType hyperv1.PlatformType, disableMultiNetwork bool, ovnConfig *hyperv1.OVNKubernetesConfig) {
switch platformType {
case hyperv1.KubevirtPlatform:
@@ -60,6 +66,12 @@ func ReconcileNetworkOperator(network *operatorv1.Network, networkType hyperv1.N
if network.Spec.DefaultNetwork.OVNKubernetesConfig.GenevePort == nil {
network.Spec.DefaultNetwork.OVNKubernetesConfig.GenevePort = &port
}
+ if network.Spec.DefaultNetwork.OVNKubernetesConfig.IPv6 == nil {
+ network.Spec.DefaultNetwork.OVNKubernetesConfig.IPv6 = &operatorv1.IPv6OVNKubernetesConfig{}
+ }
+ if network.Spec.DefaultNetwork.OVNKubernetesConfig.IPv6.InternalJoinSubnet == "" {
+ network.Spec.DefaultNetwork.OVNKubernetesConfig.IPv6.InternalJoinSubnet = kubevirtDefaultV6InternalJoinSubnet
+ }
}
case hyperv1.PowerVSPlatform:
if networkType == hyperv1.OVNKubernetes {
@@ -94,6 +106,19 @@ func ReconcileNetworkOperator(network *operatorv1.Network, networkType hyperv1.N
ovnCfg.IPv4.InternalTransitSwitchSubnet = ovnConfig.IPv4.InternalTransitSwitchSubnet
}
}
+ // Apply IPv6 configuration
+ if ovnConfig.IPv6.InternalJoinSubnet != "" {
+ if ovnCfg.IPv6 == nil {
+ ovnCfg.IPv6 = &operatorv1.IPv6OVNKubernetesConfig{}
+ }
+ ovnCfg.IPv6.InternalJoinSubnet = ovnConfig.IPv6.InternalJoinSubnet
+ }
+ if ovnConfig.IPv6.InternalTransitSwitchSubnet != "" {
+ if ovnCfg.IPv6 == nil {
+ ovnCfg.IPv6 = &operatorv1.IPv6OVNKubernetesConfig{}
+ }
+ ovnCfg.IPv6.InternalTransitSwitchSubnet = ovnConfig.IPv6.InternalTransitSwitchSubnet
+ }
}
// Setting the management state is required in order to create
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/network/reconcile_test.go b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/network/reconcile_test.go
index 19160194dbc9..734246d77c71 100644
--- a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/network/reconcile_test.go
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/network/reconcile_test.go
@@ -16,6 +16,7 @@ func TestReconcileDefaultIngressController(t *testing.T) {
vxlanPort := kubevirtDefaultVXLANPort
genevePort := kubevirtDefaultGenevePort
v4InternalSubnet := kubevirtDefaultV4InternalSubnet
+ v6InternalJoinSubnet := kubevirtDefaultV6InternalJoinSubnet
fakePort := uint32(11111)
testsCases := []struct {
@@ -43,6 +44,9 @@ func TestReconcileDefaultIngressController(t *testing.T) {
OVNKubernetesConfig: &operatorv1.OVNKubernetesConfig{
GenevePort: &genevePort,
V4InternalSubnet: v4InternalSubnet,
+ IPv6: &operatorv1.IPv6OVNKubernetesConfig{
+ InternalJoinSubnet: v6InternalJoinSubnet,
+ },
},
},
},
@@ -129,6 +133,9 @@ func TestReconcileDefaultIngressController(t *testing.T) {
OVNKubernetesConfig: &operatorv1.OVNKubernetesConfig{
GenevePort: &fakePort,
V4InternalSubnet: kubevirtDefaultV4InternalSubnet,
+ IPv6: &operatorv1.IPv6OVNKubernetesConfig{
+ InternalJoinSubnet: v6InternalJoinSubnet,
+ },
},
},
},
@@ -163,6 +170,9 @@ func TestReconcileDefaultIngressController(t *testing.T) {
OVNKubernetesConfig: &operatorv1.OVNKubernetesConfig{
V4InternalSubnet: "100.66.0.0/16",
GenevePort: &genevePort,
+ IPv6: &operatorv1.IPv6OVNKubernetesConfig{
+ InternalJoinSubnet: v6InternalJoinSubnet,
+ },
},
},
},
@@ -356,6 +366,94 @@ func TestReconcileDefaultIngressController(t *testing.T) {
},
},
},
+ {
+ name: "When IPv6 subnets configured for OVN Kubernetes it should propagate to network operator",
+ inputNetwork: NetworkOperator(),
+ inputNetworkType: hyperv1.OVNKubernetes,
+ inputPlatformType: hyperv1.AWSPlatform,
+ ovnConfig: &hyperv1.OVNKubernetesConfig{
+ IPv6: hyperv1.OVNIPv6Config{
+ InternalJoinSubnet: "fd99::/64",
+ InternalTransitSwitchSubnet: "fd97::/64",
+ },
+ },
+ expectedNetwork: &operatorv1.Network{
+ ObjectMeta: NetworkOperator().ObjectMeta,
+ Spec: operatorv1.NetworkSpec{
+ OperatorSpec: operatorv1.OperatorSpec{
+ ManagementState: "Managed",
+ },
+ DefaultNetwork: operatorv1.DefaultNetworkDefinition{
+ OVNKubernetesConfig: &operatorv1.OVNKubernetesConfig{
+ IPv6: &operatorv1.IPv6OVNKubernetesConfig{
+ InternalJoinSubnet: "fd99::/64",
+ InternalTransitSwitchSubnet: "fd97::/64",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ name: "When OVN config has IPv4 and IPv6 subnets it should propagate both",
+ inputNetwork: NetworkOperator(),
+ inputNetworkType: hyperv1.OVNKubernetes,
+ inputPlatformType: hyperv1.AWSPlatform,
+ ovnConfig: &hyperv1.OVNKubernetesConfig{
+ IPv4: &hyperv1.OVNIPv4Config{
+ InternalJoinSubnet: "100.64.0.0/16",
+ },
+ IPv6: hyperv1.OVNIPv6Config{
+ InternalJoinSubnet: "fd99::/64",
+ },
+ },
+ expectedNetwork: &operatorv1.Network{
+ ObjectMeta: NetworkOperator().ObjectMeta,
+ Spec: operatorv1.NetworkSpec{
+ OperatorSpec: operatorv1.OperatorSpec{
+ ManagementState: "Managed",
+ },
+ DefaultNetwork: operatorv1.DefaultNetworkDefinition{
+ OVNKubernetesConfig: &operatorv1.OVNKubernetesConfig{
+ IPv4: &operatorv1.IPv4OVNKubernetesConfig{
+ InternalJoinSubnet: "100.64.0.0/16",
+ },
+ IPv6: &operatorv1.IPv6OVNKubernetesConfig{
+ InternalJoinSubnet: "fd99::/64",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ name: "When KubeVirt with user-specified IPv6 join subnet it should not override",
+ inputNetwork: NetworkOperator(),
+ inputNetworkType: hyperv1.OVNKubernetes,
+ inputPlatformType: hyperv1.KubevirtPlatform,
+ ovnConfig: &hyperv1.OVNKubernetesConfig{
+ IPv6: hyperv1.OVNIPv6Config{
+ InternalJoinSubnet: "fdbb::/64",
+ },
+ },
+ expectedNetwork: &operatorv1.Network{
+ ObjectMeta: NetworkOperator().ObjectMeta,
+ Spec: operatorv1.NetworkSpec{
+ OperatorSpec: operatorv1.OperatorSpec{
+ ManagementState: "Managed",
+ },
+ DefaultNetwork: operatorv1.DefaultNetworkDefinition{
+ OVNKubernetesConfig: &operatorv1.OVNKubernetesConfig{
+ GenevePort: &genevePort,
+ V4InternalSubnet: v4InternalSubnet,
+ IPv6: &operatorv1.IPv6OVNKubernetesConfig{
+ InternalJoinSubnet: "fdbb::/64",
+ },
+ },
+ },
+ },
+ },
+ },
}
for _, tc := range testsCases {
diff --git a/docs/content/reference/api.md b/docs/content/reference/api.md
index ed2fdc2c4da9..fc2dede23c5b 100644
--- a/docs/content/reference/api.md
+++ b/docs/content/reference/api.md
@@ -10911,6 +10911,68 @@ The value must be in proper IPV4 CIDR format
+###OVNIPv6Config { #hypershift.openshift.io/v1beta1.OVNIPv6Config }
+
+(Appears on:
+OVNKubernetesConfig)
+
+
+
OVNIPv6Config contains IPv6-specific configuration options for OVN-Kubernetes.
+
+
+
+
+| Field |
+Description |
+
+
+
+
+
+internalTransitSwitchSubnet
+
+string
+
+ |
+
+(Optional)
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+architecture that connects the cluster routers on each node together to enable
+east west traffic. The subnet chosen should not overlap with other networks
+specified for OVN-Kubernetes as well as other networks used on the host.
+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 subnet is fd97::/64.
+The subnet must be large enough to accommodate one IP per node in your cluster.
+The value must be in proper IPv6 CIDR format.
+Note that IPv6 dual addresses are not permitted.
+ |
+
+
+
+internalJoinSubnet
+
+string
+
+ |
+
+(Optional)
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+default one is being already used by something else. It must not overlap with
+any other subnet being used by OpenShift or by the node network. The size of the
+subnet must be larger than the number of nodes.
+The current default value is fd98::/64.
+For KubeVirt hosted clusters, if this field is not set, HyperShift will
+automatically use fd99::/64 to avoid collisions with the management cluster’s
+default join subnet (fd98::/64).
+The subnet must be large enough to accommodate one IP per node in your cluster.
+The value must be in proper IPv6 CIDR format.
+Note that IPv6 dual addresses are not permitted.
+ |
+
+
+
###OVNKubernetesConfig { #hypershift.openshift.io/v1beta1.OVNKubernetesConfig }
(Appears on:
@@ -10944,6 +11006,25 @@ this means no opinions and the default configuration is used. Check individual
fields within ipv4 for details of default values.
+
+
+ipv6,omitzero
+
+
+OVNIPv6Config
+
+
+ |
+
+(Optional)
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+this means no opinions and the default configuration is used. Check individual
+fields within ipv6 for details of default values.
+For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+set ipv6.internalJoinSubnet to a value different from the management cluster’s
+join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ |
+
###ObjectEncodingFormat { #hypershift.openshift.io/v1beta1.ObjectEncodingFormat }
diff --git a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
index 2c72e5b62554..076a307fb00f 100644
--- a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
+++ b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
@@ -4155,6 +4155,34 @@ func validateSliceNetworkCIDRs(hc *hyperv1.HostedCluster) field.ErrorList {
}
}
}
+
+ if hc.Spec.Networking.NetworkType == hyperv1.OVNKubernetes {
+ var ipv6JoinSubnet, ipv6TransitSubnet string
+ if hc.Spec.OperatorConfiguration != nil && hc.Spec.OperatorConfiguration.ClusterNetworkOperator != nil &&
+ hc.Spec.OperatorConfiguration.ClusterNetworkOperator.OVNKubernetesConfig != nil {
+ ipv6JoinSubnet = hc.Spec.OperatorConfiguration.ClusterNetworkOperator.OVNKubernetesConfig.IPv6.InternalJoinSubnet
+ ipv6TransitSubnet = hc.Spec.OperatorConfiguration.ClusterNetworkOperator.OVNKubernetesConfig.IPv6.InternalTransitSwitchSubnet
+ }
+ // The reconciler defaults KubeVirt IPv6 join subnet to fd99::/64;
+ // include the effective value so overlaps are caught at admission time.
+ if ipv6JoinSubnet == "" && hc.Spec.Platform.Type == hyperv1.KubevirtPlatform {
+ ipv6JoinSubnet = "fd99::/64"
+ }
+ if ipv6JoinSubnet != "" {
+ _, cidr, err := net.ParseCIDR(ipv6JoinSubnet)
+ if err == nil {
+ ce := cidrEntry{*cidr, *field.NewPath("spec", "operatorConfiguration", "clusterNetworkOperator", "ovnKubernetesConfig", "ipv6", "internalJoinSubnet")}
+ cidrEntries = append(cidrEntries, ce)
+ }
+ }
+ if ipv6TransitSubnet != "" {
+ _, cidr, err := net.ParseCIDR(ipv6TransitSubnet)
+ if err == nil {
+ ce := cidrEntry{*cidr, *field.NewPath("spec", "operatorConfiguration", "clusterNetworkOperator", "ovnKubernetesConfig", "ipv6", "internalTransitSwitchSubnet")}
+ cidrEntries = append(cidrEntries, ce)
+ }
+ }
+ }
return compareCIDREntries(cidrEntries)
}
diff --git a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go
index ed2ef823b879..1532253a8931 100644
--- a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go
+++ b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go
@@ -3504,13 +3504,14 @@ func TestComputeAWSEndpointServiceCondition(t *testing.T) {
func TestValidateSliceNetworkCIDRs(t *testing.T) {
tests := []struct {
- name string
- mn []hyperv1.MachineNetworkEntry
- cn []hyperv1.ClusterNetworkEntry
- sn []hyperv1.ServiceNetworkEntry
- networkType hyperv1.NetworkType
- ovnConfig *hyperv1.OVNKubernetesConfig
- wantErr bool
+ name string
+ mn []hyperv1.MachineNetworkEntry
+ cn []hyperv1.ClusterNetworkEntry
+ sn []hyperv1.ServiceNetworkEntry
+ networkType hyperv1.NetworkType
+ platformType hyperv1.PlatformType
+ ovnConfig *hyperv1.OVNKubernetesConfig
+ wantErr bool
}{
{
name: "given a conflicting IPv6 clusterNetwork overlapped with machineNetwork, it should fail",
@@ -3655,6 +3656,111 @@ func TestValidateSliceNetworkCIDRs(t *testing.T) {
},
wantErr: false,
},
+ {
+ name: "When OVN-Kubernetes with valid IPv6 internal join and transit subnets it should succeed",
+ mn: []hyperv1.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd01::/48")}},
+ cn: []hyperv1.ClusterNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd02::/64")}},
+ sn: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd03::/112")}},
+ networkType: hyperv1.OVNKubernetes,
+ ovnConfig: &hyperv1.OVNKubernetesConfig{
+ IPv6: hyperv1.OVNIPv6Config{
+ InternalJoinSubnet: "fd99::/64",
+ InternalTransitSwitchSubnet: "fd97::/64",
+ },
+ },
+ wantErr: false,
+ },
+ {
+ name: "When OVN-Kubernetes IPv6 internal join subnet overlaps with MachineNetwork it should fail",
+ mn: []hyperv1.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd99::/48")}},
+ cn: []hyperv1.ClusterNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd02::/64")}},
+ sn: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd03::/112")}},
+ networkType: hyperv1.OVNKubernetes,
+ ovnConfig: &hyperv1.OVNKubernetesConfig{
+ IPv6: hyperv1.OVNIPv6Config{
+ InternalJoinSubnet: "fd99::/64",
+ },
+ },
+ wantErr: true,
+ },
+ {
+ name: "When OVN-Kubernetes IPv6 OVN subnets overlap with each other it should fail",
+ mn: []hyperv1.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd01::/48")}},
+ cn: []hyperv1.ClusterNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd02::/64")}},
+ sn: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd03::/112")}},
+ networkType: hyperv1.OVNKubernetes,
+ ovnConfig: &hyperv1.OVNKubernetesConfig{
+ IPv6: hyperv1.OVNIPv6Config{
+ InternalJoinSubnet: "fd99::/64",
+ InternalTransitSwitchSubnet: "fd99::/64",
+ },
+ },
+ wantErr: true,
+ },
+ {
+ name: "When OVN-Kubernetes with combined valid IPv4 and IPv6 subnets it should succeed",
+ mn: []hyperv1.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("192.168.1.0/24")}},
+ cn: []hyperv1.ClusterNetworkEntry{{CIDR: *ipnet.MustParseCIDR("10.128.0.0/14")}},
+ sn: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("172.30.0.0/16")}},
+ networkType: hyperv1.OVNKubernetes,
+ ovnConfig: &hyperv1.OVNKubernetesConfig{
+ IPv4: &hyperv1.OVNIPv4Config{
+ InternalJoinSubnet: "100.64.0.0/16",
+ },
+ IPv6: hyperv1.OVNIPv6Config{
+ InternalJoinSubnet: "fd99::/64",
+ },
+ },
+ wantErr: false,
+ },
+ {
+ name: "When OVN-Kubernetes with empty IPv6 subnet strings it should succeed",
+ mn: []hyperv1.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("192.168.1.0/24")}},
+ cn: []hyperv1.ClusterNetworkEntry{{CIDR: *ipnet.MustParseCIDR("10.128.0.0/14")}},
+ sn: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("172.30.0.0/16")}},
+ networkType: hyperv1.OVNKubernetes,
+ ovnConfig: &hyperv1.OVNKubernetesConfig{
+ IPv6: hyperv1.OVNIPv6Config{
+ InternalJoinSubnet: "",
+ InternalTransitSwitchSubnet: "",
+ },
+ },
+ wantErr: false,
+ },
+ {
+ name: "When KubeVirt OVN-Kubernetes with no IPv6 config and MachineNetwork overlaps default fd99::/64 it should fail",
+ mn: []hyperv1.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd99::/48")}},
+ cn: []hyperv1.ClusterNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd01::/64")}},
+ sn: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd02::/112")}},
+ networkType: hyperv1.OVNKubernetes,
+ platformType: hyperv1.KubevirtPlatform,
+ ovnConfig: nil,
+ wantErr: true,
+ },
+ {
+ name: "When KubeVirt OVN-Kubernetes with no IPv6 config and non-overlapping networks it should succeed",
+ mn: []hyperv1.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd01::/48")}},
+ cn: []hyperv1.ClusterNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd02::/64")}},
+ sn: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd03::/112")}},
+ networkType: hyperv1.OVNKubernetes,
+ platformType: hyperv1.KubevirtPlatform,
+ ovnConfig: nil,
+ wantErr: false,
+ },
+ {
+ name: "When KubeVirt OVN-Kubernetes with explicit IPv6 join subnet it should use explicit value not default",
+ mn: []hyperv1.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd99::/48")}},
+ cn: []hyperv1.ClusterNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd01::/64")}},
+ sn: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd02::/112")}},
+ networkType: hyperv1.OVNKubernetes,
+ platformType: hyperv1.KubevirtPlatform,
+ ovnConfig: &hyperv1.OVNKubernetesConfig{
+ IPv6: hyperv1.OVNIPv6Config{
+ InternalJoinSubnet: "fdaa::/64",
+ },
+ },
+ wantErr: false,
+ },
}
for _, tt := range tests {
@@ -3665,6 +3771,9 @@ func TestValidateSliceNetworkCIDRs(t *testing.T) {
Namespace: "any",
},
Spec: hyperv1.HostedClusterSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: tt.platformType,
+ },
Networking: hyperv1.ClusterNetworking{
NetworkType: tt.networkType,
MachineNetwork: tt.mn,
@@ -3674,9 +3783,7 @@ func TestValidateSliceNetworkCIDRs(t *testing.T) {
},
}
- // Set OVN configuration if provided
if tt.ovnConfig != nil {
- //OperatorConfiguration
hc.Spec.OperatorConfiguration = &hyperv1.OperatorConfiguration{
ClusterNetworkOperator: &hyperv1.ClusterNetworkOperatorSpec{
OVNKubernetesConfig: tt.ovnConfig,
diff --git a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/operator.go b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/operator.go
index c1e455682903..6e902f9c3e29 100644
--- a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/operator.go
+++ b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/operator.go
@@ -62,6 +62,7 @@ type ClusterNetworkOperatorSpec struct {
// OVNKubernetesConfig contains OVN-Kubernetes specific configuration options.
// https://github.com/openshift/api/blob/6d3c4e25a8d3aeb57ad61649d80c38cbd27d1cc8/operator/v1/types_network.go#L400-L471
// +kubebuilder:validation:XValidation:rule="!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet) || !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet != self.ipv4.internalTransitSwitchSubnet", message="internalJoinSubnet and internalTransitSwitchSubnet must not be the same"
+// +kubebuilder:validation:XValidation:rule="!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet) || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet != self.ipv6.internalTransitSwitchSubnet", message="IPv6 internalJoinSubnet and internalTransitSwitchSubnet must not be the same"
// +kubebuilder:validation:MinProperties=1
type OVNKubernetesConfig struct {
// ipv4 allows users to configure IP settings for IPv4 connections. When omitted,
@@ -69,6 +70,15 @@ type OVNKubernetesConfig struct {
// fields within ipv4 for details of default values.
// +optional
IPv4 *OVNIPv4Config `json:"ipv4,omitempty"`
+
+ // ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ // this means no opinions and the default configuration is used. Check individual
+ // fields within ipv6 for details of default values.
+ // For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ // set ipv6.internalJoinSubnet to a value different from the management cluster's
+ // join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ // +optional
+ IPv6 OVNIPv6Config `json:"ipv6,omitzero,omitempty"`
}
// OVNIPv4Config contains IPv4-specific configuration options for OVN-Kubernetes.
@@ -108,6 +118,45 @@ type OVNIPv4Config struct {
InternalJoinSubnet string `json:"internalJoinSubnet,omitempty"`
}
+// OVNIPv6Config contains IPv6-specific configuration options for OVN-Kubernetes.
+// +kubebuilder:validation:MinProperties=1
+type OVNIPv6Config struct {
+ // internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ // by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ // architecture that connects the cluster routers on each node together to enable
+ // east west traffic. The subnet chosen should not overlap with other networks
+ // specified for OVN-Kubernetes as well as other networks used on the host.
+ // 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 subnet is fd97::/64.
+ // The subnet must be large enough to accommodate one IP per node in your cluster.
+ // The value must be in proper IPv6 CIDR format.
+ // Note that IPv6 dual addresses are not permitted.
+ // +kubebuilder:validation:MaxLength=48
+ // +kubebuilder:validation:MinLength=3
+ // +kubebuilder:validation:XValidation:rule="self.matches('^\\\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')", message="Subnet must be in valid IPv6 CIDR format (e.g., fd97::/64)"
+ // +kubebuilder:validation:XValidation:rule="self.matches('^.*/[0-9]+$') && int(self.split('/')[1]) <= 125", message="subnet must be in the range /0 to /125 inclusive"
+ // +optional
+ InternalTransitSwitchSubnet string `json:"internalTransitSwitchSubnet,omitempty"`
+ // internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ // default one is being already used by something else. It must not overlap with
+ // any other subnet being used by OpenShift or by the node network. The size of the
+ // subnet must be larger than the number of nodes.
+ // The current default value is fd98::/64.
+ // For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ // automatically use fd99::/64 to avoid collisions with the management cluster's
+ // default join subnet (fd98::/64).
+ // The subnet must be large enough to accommodate one IP per node in your cluster.
+ // The value must be in proper IPv6 CIDR format.
+ // Note that IPv6 dual addresses are not permitted.
+ // +kubebuilder:validation:MaxLength=48
+ // +kubebuilder:validation:MinLength=3
+ // +kubebuilder:validation:XValidation:rule="self.matches('^\\\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){5}((:[0-9A-Fa-f]{1,4}){1,2}|:))|(([0-9A-Fa-f]{1,4}:){4}((:[0-9A-Fa-f]{1,4}){1,3}|:))|(([0-9A-Fa-f]{1,4}:){3}((:[0-9A-Fa-f]{1,4}){1,4}|:))|(([0-9A-Fa-f]{1,4}:){2}((:[0-9A-Fa-f]{1,4}){1,5}|:))|(([0-9A-Fa-f]{1,4}:){1}((:[0-9A-Fa-f]{1,4}){1,6}|:))|(::((:[0-9A-Fa-f]{1,4}){1,7}|:)))\\\\s*/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])$')", message="Subnet must be in valid IPv6 CIDR format (e.g., fd98::/64)"
+ // +kubebuilder:validation:XValidation:rule="self.matches('^.*/[0-9]+$') && int(self.split('/')[1]) <= 125", message="subnet must be in the range /0 to /125 inclusive"
+ // +optional
+ InternalJoinSubnet string `json:"internalJoinSubnet,omitempty"`
+}
+
// IngressOperatorSpec is the specification of the desired behavior of the Ingress Operator.
type IngressOperatorSpec struct {
// endpointPublishingStrategy is used to publish the default ingress controller endpoints.
diff --git a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go
index 033c005b7996..06e27795385d 100644
--- a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go
+++ b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go
@@ -3205,6 +3205,21 @@ func (in *OVNIPv4Config) DeepCopy() *OVNIPv4Config {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *OVNIPv6Config) DeepCopyInto(out *OVNIPv6Config) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVNIPv6Config.
+func (in *OVNIPv6Config) DeepCopy() *OVNIPv6Config {
+ if in == nil {
+ return nil
+ }
+ out := new(OVNIPv6Config)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OVNKubernetesConfig) DeepCopyInto(out *OVNKubernetesConfig) {
*out = *in
@@ -3213,6 +3228,7 @@ func (in *OVNKubernetesConfig) DeepCopyInto(out *OVNKubernetesConfig) {
*out = new(OVNIPv4Config)
**out = **in
}
+ out.IPv6 = in.IPv6
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVNKubernetesConfig.