diff --git a/build/charts/antrea/README.md b/build/charts/antrea/README.md index 8276efaae47..2743da639ce 100644 --- a/build/charts/antrea/README.md +++ b/build/charts/antrea/README.md @@ -106,6 +106,7 @@ Kubernetes: `>= 1.16.0-0` | trafficEncryptionMode | string | `"none"` | Determines how tunnel traffic is encrypted. Currently encryption only works with encap mode.It must be one of "none", "ipsec", "wireGuard". | | transportInterface | string | `""` | Name of the interface on Node which is used for tunneling or routing the traffic across Nodes. | | transportInterfaceCIDRs | list | `[]` | Network CIDRs of the interface on Node which is used for tunneling or routing the traffic across Nodes. | +| tunnelPort | int | `0` | TunnelPort is the destination port for UDP and TCP based tunnel protocols (Geneve, VXLAN, and STT). If zero, it will use the assigned IANA port for the protocol, i.e. 6081 for Geneve, 4789 for VXLAN, and 7471 for STT. | | tunnelType | string | `"geneve"` | Tunnel protocol used for encapsulating traffic across Nodes. It must be one of "geneve", "vxlan", "gre", "stt". | | webhooks.labelsMutator.enable | bool | `false` | | | whereabouts.enable | bool | `false` | | diff --git a/build/charts/antrea/conf/antrea-agent.conf b/build/charts/antrea/conf/antrea-agent.conf index ed3f4dbd93c..72d03382e14 100644 --- a/build/charts/antrea/conf/antrea-agent.conf +++ b/build/charts/antrea/conf/antrea-agent.conf @@ -110,6 +110,11 @@ noSNAT: {{ .Values.noSNAT }} # Note that "gre" is not supported for IPv6 clusters (IPv6-only or dual-stack clusters). tunnelType: {{ .Values.tunnelType | quote }} +# TunnelPort is the destination port for UDP and TCP based tunnel protocols (Geneve, VXLAN, and STT). +# If zero, it will use the assigned IANA port for the protocol, i.e. 6081 for Geneve, 4789 for VXLAN, +# and 7471 for STT. +tunnelPort: {{ .Values.tunnelPort }} + # Determines how tunnel traffic is encrypted. Currently encryption only works with encap mode. # It has the following options: # - none (default): Inter-node Pod traffic will not be encrypted. diff --git a/build/charts/antrea/values.yaml b/build/charts/antrea/values.yaml index dd9a48087fe..7eaf6510a69 100644 --- a/build/charts/antrea/values.yaml +++ b/build/charts/antrea/values.yaml @@ -10,6 +10,10 @@ trafficEncapMode: "encap" # -- Tunnel protocol used for encapsulating traffic across Nodes. It must be one # of "geneve", "vxlan", "gre", "stt". tunnelType: "geneve" +# -- TunnelPort is the destination port for UDP and TCP based tunnel protocols +# (Geneve, VXLAN, and STT). If zero, it will use the assigned IANA port for the +# protocol, i.e. 6081 for Geneve, 4789 for VXLAN, and 7471 for STT. +tunnelPort: 0 # -- Determines how tunnel traffic is encrypted. Currently encryption only works # with encap mode.It must be one of "none", "ipsec", "wireGuard". trafficEncryptionMode: "none" diff --git a/build/yamls/antrea-aks.yml b/build/yamls/antrea-aks.yml index 03e3874d5a4..314dc6c5d85 100644 --- a/build/yamls/antrea-aks.yml +++ b/build/yamls/antrea-aks.yml @@ -2647,6 +2647,11 @@ data: # Note that "gre" is not supported for IPv6 clusters (IPv6-only or dual-stack clusters). tunnelType: "geneve" + # TunnelPort is the destination port for UDP and TCP based tunnel protocols (Geneve, VXLAN, and STT). + # If zero, it will use the assigned IANA port for the protocol, i.e. 6081 for Geneve, 4789 for VXLAN, + # and 7471 for STT. + tunnelPort: 0 + # Determines how tunnel traffic is encrypted. Currently encryption only works with encap mode. # It has the following options: # - none (default): Inter-node Pod traffic will not be encrypted. @@ -3692,7 +3697,7 @@ spec: kubectl.kubernetes.io/default-container: antrea-agent # Automatically restart Pods with a RollingUpdate if the ConfigMap changes # See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments - checksum/config: beca655f34bfd122082c7efa73505680278a8aa97e74099ca6040bcc4311622f + checksum/config: 814300ca95f9d7451131665ebed709cb7639deec890e2ff5ae4c357ae9b00c41 labels: app: antrea component: antrea-agent @@ -3933,7 +3938,7 @@ spec: annotations: # Automatically restart Pod if the ConfigMap changes # See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments - checksum/config: beca655f34bfd122082c7efa73505680278a8aa97e74099ca6040bcc4311622f + checksum/config: 814300ca95f9d7451131665ebed709cb7639deec890e2ff5ae4c357ae9b00c41 labels: app: antrea component: antrea-controller diff --git a/build/yamls/antrea-eks.yml b/build/yamls/antrea-eks.yml index 5c9fd89a175..e2e28254dbd 100644 --- a/build/yamls/antrea-eks.yml +++ b/build/yamls/antrea-eks.yml @@ -2647,6 +2647,11 @@ data: # Note that "gre" is not supported for IPv6 clusters (IPv6-only or dual-stack clusters). tunnelType: "geneve" + # TunnelPort is the destination port for UDP and TCP based tunnel protocols (Geneve, VXLAN, and STT). + # If zero, it will use the assigned IANA port for the protocol, i.e. 6081 for Geneve, 4789 for VXLAN, + # and 7471 for STT. + tunnelPort: 0 + # Determines how tunnel traffic is encrypted. Currently encryption only works with encap mode. # It has the following options: # - none (default): Inter-node Pod traffic will not be encrypted. @@ -3692,7 +3697,7 @@ spec: kubectl.kubernetes.io/default-container: antrea-agent # Automatically restart Pods with a RollingUpdate if the ConfigMap changes # See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments - checksum/config: beca655f34bfd122082c7efa73505680278a8aa97e74099ca6040bcc4311622f + checksum/config: 814300ca95f9d7451131665ebed709cb7639deec890e2ff5ae4c357ae9b00c41 labels: app: antrea component: antrea-agent @@ -3935,7 +3940,7 @@ spec: annotations: # Automatically restart Pod if the ConfigMap changes # See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments - checksum/config: beca655f34bfd122082c7efa73505680278a8aa97e74099ca6040bcc4311622f + checksum/config: 814300ca95f9d7451131665ebed709cb7639deec890e2ff5ae4c357ae9b00c41 labels: app: antrea component: antrea-controller diff --git a/build/yamls/antrea-gke.yml b/build/yamls/antrea-gke.yml index 7822ecf0c82..26da7664b87 100644 --- a/build/yamls/antrea-gke.yml +++ b/build/yamls/antrea-gke.yml @@ -2647,6 +2647,11 @@ data: # Note that "gre" is not supported for IPv6 clusters (IPv6-only or dual-stack clusters). tunnelType: "geneve" + # TunnelPort is the destination port for UDP and TCP based tunnel protocols (Geneve, VXLAN, and STT). + # If zero, it will use the assigned IANA port for the protocol, i.e. 6081 for Geneve, 4789 for VXLAN, + # and 7471 for STT. + tunnelPort: 0 + # Determines how tunnel traffic is encrypted. Currently encryption only works with encap mode. # It has the following options: # - none (default): Inter-node Pod traffic will not be encrypted. @@ -3692,7 +3697,7 @@ spec: kubectl.kubernetes.io/default-container: antrea-agent # Automatically restart Pods with a RollingUpdate if the ConfigMap changes # See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments - checksum/config: 741b313c6ab0ed98e7d994985861722f503a93529f90a5141b8a6e0c124d8904 + checksum/config: 3f9907e9f0f4db91b926904114567c4e2c496f6fe03abb4ef80df5af937c0f19 labels: app: antrea component: antrea-agent @@ -3932,7 +3937,7 @@ spec: annotations: # Automatically restart Pod if the ConfigMap changes # See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments - checksum/config: 741b313c6ab0ed98e7d994985861722f503a93529f90a5141b8a6e0c124d8904 + checksum/config: 3f9907e9f0f4db91b926904114567c4e2c496f6fe03abb4ef80df5af937c0f19 labels: app: antrea component: antrea-controller diff --git a/build/yamls/antrea-ipsec.yml b/build/yamls/antrea-ipsec.yml index 04fd7cbf74a..09a4e4c8ab6 100644 --- a/build/yamls/antrea-ipsec.yml +++ b/build/yamls/antrea-ipsec.yml @@ -2660,6 +2660,11 @@ data: # Note that "gre" is not supported for IPv6 clusters (IPv6-only or dual-stack clusters). tunnelType: "gre" + # TunnelPort is the destination port for UDP and TCP based tunnel protocols (Geneve, VXLAN, and STT). + # If zero, it will use the assigned IANA port for the protocol, i.e. 6081 for Geneve, 4789 for VXLAN, + # and 7471 for STT. + tunnelPort: 0 + # Determines how tunnel traffic is encrypted. Currently encryption only works with encap mode. # It has the following options: # - none (default): Inter-node Pod traffic will not be encrypted. @@ -3705,7 +3710,7 @@ spec: kubectl.kubernetes.io/default-container: antrea-agent # Automatically restart Pods with a RollingUpdate if the ConfigMap changes # See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments - checksum/config: c74f29ceba3905db50cef22ee46f73e1c101c108a70e70918b17413c174081e8 + checksum/config: 7b6ba1830aabcf74b5b0a71c74edf49254c4237d604f9d984428252903901f98 checksum/ipsec-secret: d0eb9c52d0cd4311b6d252a951126bf9bea27ec05590bed8a394f0f792dcb2a4 labels: app: antrea @@ -3991,7 +3996,7 @@ spec: annotations: # Automatically restart Pod if the ConfigMap changes # See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments - checksum/config: c74f29ceba3905db50cef22ee46f73e1c101c108a70e70918b17413c174081e8 + checksum/config: 7b6ba1830aabcf74b5b0a71c74edf49254c4237d604f9d984428252903901f98 labels: app: antrea component: antrea-controller diff --git a/build/yamls/antrea-windows.yml b/build/yamls/antrea-windows.yml index 7af06ec8e24..4462812c374 100644 --- a/build/yamls/antrea-windows.yml +++ b/build/yamls/antrea-windows.yml @@ -48,6 +48,11 @@ data: # - stt #tunnelType: geneve + # TunnelPort is the destination port for UDP and TCP based tunnel protocols + # (Geneve, VXLAN, and STT). If zero, it will use the assigned IANA port for the + # protocol, i.e. 6081 for Geneve, 4789 for VXLAN, and 7471 for STT. + #tunnelPort: + # Default MTU to use for the host gateway interface and the network interface of each Pod. # If omitted, antrea-agent will discover the MTU of the Node's primary interface and # also adjust MTU to accommodate for tunnel encapsulation overhead. @@ -163,7 +168,7 @@ kind: ConfigMap metadata: labels: app: antrea - name: antrea-windows-config-8kfkb8t957 + name: antrea-windows-config-gcg7hthbfb namespace: kube-system --- apiVersion: apps/v1 @@ -251,7 +256,7 @@ spec: operator: Exists volumes: - configMap: - name: antrea-windows-config-8kfkb8t957 + name: antrea-windows-config-gcg7hthbfb name: antrea-windows-config - configMap: defaultMode: 420 diff --git a/build/yamls/antrea.yml b/build/yamls/antrea.yml index ba216d1e056..6c48787200c 100644 --- a/build/yamls/antrea.yml +++ b/build/yamls/antrea.yml @@ -2647,6 +2647,11 @@ data: # Note that "gre" is not supported for IPv6 clusters (IPv6-only or dual-stack clusters). tunnelType: "geneve" + # TunnelPort is the destination port for UDP and TCP based tunnel protocols (Geneve, VXLAN, and STT). + # If zero, it will use the assigned IANA port for the protocol, i.e. 6081 for Geneve, 4789 for VXLAN, + # and 7471 for STT. + tunnelPort: 0 + # Determines how tunnel traffic is encrypted. Currently encryption only works with encap mode. # It has the following options: # - none (default): Inter-node Pod traffic will not be encrypted. @@ -3692,7 +3697,7 @@ spec: kubectl.kubernetes.io/default-container: antrea-agent # Automatically restart Pods with a RollingUpdate if the ConfigMap changes # See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments - checksum/config: 056a828ba2400e94aa9c43e6e74a4b007027bf6b95a68e1e15f34cd6ffeb2baa + checksum/config: 05340bff4942128434fb2b7ab2c0288d9586d3324d58da987c1a58db78aab6d3 labels: app: antrea component: antrea-agent @@ -3932,7 +3937,7 @@ spec: annotations: # Automatically restart Pod if the ConfigMap changes # See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments - checksum/config: 056a828ba2400e94aa9c43e6e74a4b007027bf6b95a68e1e15f34cd6ffeb2baa + checksum/config: 05340bff4942128434fb2b7ab2c0288d9586d3324d58da987c1a58db78aab6d3 labels: app: antrea component: antrea-controller diff --git a/build/yamls/windows/base/conf/antrea-agent.conf b/build/yamls/windows/base/conf/antrea-agent.conf index ab72ae1e4b6..72b235883a5 100644 --- a/build/yamls/windows/base/conf/antrea-agent.conf +++ b/build/yamls/windows/base/conf/antrea-agent.conf @@ -30,6 +30,11 @@ featureGates: # - stt #tunnelType: geneve +# TunnelPort is the destination port for UDP and TCP based tunnel protocols +# (Geneve, VXLAN, and STT). If zero, it will use the assigned IANA port for the +# protocol, i.e. 6081 for Geneve, 4789 for VXLAN, and 7471 for STT. +#tunnelPort: + # Default MTU to use for the host gateway interface and the network interface of each Pod. # If omitted, antrea-agent will discover the MTU of the Node's primary interface and # also adjust MTU to accommodate for tunnel encapsulation overhead. diff --git a/cmd/antrea-agent/agent.go b/cmd/antrea-agent/agent.go index 78e715e6070..2f0ea069575 100644 --- a/cmd/antrea-agent/agent.go +++ b/cmd/antrea-agent/agent.go @@ -162,6 +162,7 @@ func run(o *Options) error { _, ipsecAuthenticationMode := config.GetIPsecAuthenticationModeFromStr(o.config.IPsec.AuthenticationMode) networkConfig := &config.NetworkConfig{ TunnelType: ovsconfig.TunnelType(o.config.TunnelType), + TunnelPort: o.config.TunnelPort, TrafficEncapMode: encapMode, TrafficEncryptionMode: encryptionMode, TransportIface: o.config.TransportInterface, diff --git a/pkg/agent/agent.go b/pkg/agent/agent.go index 67a54f21f78..9b1f51f957f 100644 --- a/pkg/agent/agent.go +++ b/pkg/agent/agent.go @@ -726,6 +726,7 @@ func (i *Initializer) setupDefaultTunnelInterface() error { if portExists { if i.networkConfig.TrafficEncapMode.SupportsEncap() && tunnelIface.TunnelInterfaceConfig.Type == i.networkConfig.TunnelType && + tunnelIface.TunnelInterfaceConfig.DestinationPort == i.networkConfig.TunnelPort && tunnelIface.TunnelInterfaceConfig.LocalIP.Equal(localIP) { klog.V(2).Infof("Tunnel port %s already exists on OVS bridge", tunnelPortName) // This could happen when upgrading from previous versions that didn't set it. @@ -761,7 +762,12 @@ func (i *Initializer) setupDefaultTunnelInterface() error { externalIDs := map[string]interface{}{ interfacestore.AntreaInterfaceTypeKey: interfacestore.AntreaTunnel, } - tunnelPortUUID, err := i.ovsBridgeClient.CreateTunnelPortExt(tunnelPortName, i.networkConfig.TunnelType, config.DefaultTunOFPort, shouldEnableCsum, localIPStr, "", "", "", nil, externalIDs) + extraOptions := map[string]interface{}{} + if i.networkConfig.TunnelPort != 0 { + extraOptions["dst_port"] = strconv.Itoa(int(i.networkConfig.TunnelPort)) + } + tunnelPortUUID, err := i.ovsBridgeClient.CreateTunnelPortExt(tunnelPortName, + i.networkConfig.TunnelType, config.DefaultTunOFPort, shouldEnableCsum, localIPStr, "", "", "", extraOptions, externalIDs) if err != nil { klog.ErrorS(err, "Failed to create tunnel port on OVS bridge", "port", tunnelPortName, "type", i.networkConfig.TunnelType) return err @@ -772,7 +778,7 @@ func (i *Initializer) setupDefaultTunnelInterface() error { return err } klog.InfoS("Allocated OpenFlow port for tunnel interface", "port", tunnelPortName, "ofPort", tunPort) - tunnelIface = interfacestore.NewTunnelInterface(tunnelPortName, i.networkConfig.TunnelType, localIP, shouldEnableCsum) + tunnelIface = interfacestore.NewTunnelInterface(tunnelPortName, i.networkConfig.TunnelType, i.networkConfig.TunnelPort, localIP, shouldEnableCsum) tunnelIface.OVSPortConfig = &interfacestore.OVSPortConfig{PortUUID: tunnelPortUUID, OFPort: tunPort} i.ifaceStore.AddInterface(tunnelIface) i.nodeConfig.TunnelOFPort = uint32(tunPort) diff --git a/pkg/agent/config/node_config.go b/pkg/agent/config/node_config.go index 650c25fc409..b230fb578fe 100644 --- a/pkg/agent/config/node_config.go +++ b/pkg/agent/config/node_config.go @@ -172,6 +172,7 @@ type IPsecConfig struct { type NetworkConfig struct { TrafficEncapMode TrafficEncapModeType TunnelType ovsconfig.TunnelType + TunnelPort int32 TrafficEncryptionMode TrafficEncryptionModeType IPsecConfig IPsecConfig TransportIface string diff --git a/pkg/agent/controller/noderoute/node_route_controller.go b/pkg/agent/controller/noderoute/node_route_controller.go index 03f98df73e4..bcfae3ce5b4 100644 --- a/pkg/agent/controller/noderoute/node_route_controller.go +++ b/pkg/agent/controller/noderoute/node_route_controller.go @@ -729,7 +729,7 @@ func ParseTunnelInterfaceConfig( klog.V(2).Infof("OVS port %s has no options", portData.Name) return nil } - remoteIP, localIP, psk, remoteName, csum := ovsconfig.ParseTunnelInterfaceOptions(portData) + remoteIP, localIP, tunnelPort, psk, remoteName, csum := ovsconfig.ParseTunnelInterfaceOptions(portData) var interfaceConfig *interfacestore.InterfaceConfig var nodeName string @@ -746,7 +746,12 @@ func ParseTunnelInterfaceConfig( remoteName, ) } else { - interfaceConfig = interfacestore.NewTunnelInterface(portData.Name, ovsconfig.TunnelType(portData.IFType), localIP, csum) + interfaceConfig = interfacestore.NewTunnelInterface( + portData.Name, + ovsconfig.TunnelType(portData.IFType), + tunnelPort, + localIP, + csum) } interfaceConfig.OVSPortConfig = portConfig return interfaceConfig diff --git a/pkg/agent/interfacestore/types.go b/pkg/agent/interfacestore/types.go index fa838a1167a..c5ea76029be 100644 --- a/pkg/agent/interfacestore/types.go +++ b/pkg/agent/interfacestore/types.go @@ -145,8 +145,8 @@ func NewGatewayInterface(gatewayName string) *InterfaceConfig { // NewTunnelInterface creates InterfaceConfig for the default tunnel port // interface. -func NewTunnelInterface(tunnelName string, tunnelType ovsconfig.TunnelType, localIP net.IP, csum bool) *InterfaceConfig { - tunnelConfig := &TunnelInterfaceConfig{Type: tunnelType, LocalIP: localIP, Csum: csum} +func NewTunnelInterface(tunnelName string, tunnelType ovsconfig.TunnelType, destinationPort int32, localIP net.IP, csum bool) *InterfaceConfig { + tunnelConfig := &TunnelInterfaceConfig{Type: tunnelType, DestinationPort: destinationPort, LocalIP: localIP, Csum: csum} return &InterfaceConfig{InterfaceName: tunnelName, Type: TunnelInterface, TunnelInterfaceConfig: tunnelConfig} } diff --git a/pkg/agent/multicast/mcast_discovery_test.go b/pkg/agent/multicast/mcast_discovery_test.go index 3af352277f3..43466f2df4c 100644 --- a/pkg/agent/multicast/mcast_discovery_test.go +++ b/pkg/agent/multicast/mcast_discovery_test.go @@ -179,7 +179,7 @@ func generatePacketInForRemoteReport(t *testing.T, snooper *IGMPSnooper, groups } func createTunnelInterface(tunnelPort uint32, localNodeIP net.IP) *interfacestore.InterfaceConfig { - tunnelInterface := interfacestore.NewTunnelInterface("antrea-tun0", ovsconfig.GeneveTunnel, localNodeIP, false) + tunnelInterface := interfacestore.NewTunnelInterface("antrea-tun0", ovsconfig.GeneveTunnel, 6081, localNodeIP, false) tunnelInterface.OVSPortConfig = &interfacestore.OVSPortConfig{OFPort: int32(tunnelPort)} return tunnelInterface } diff --git a/pkg/config/agent/config.go b/pkg/config/agent/config.go index 2d0d9d43a2d..caf4bbe867b 100644 --- a/pkg/config/agent/config.go +++ b/pkg/config/agent/config.go @@ -71,6 +71,10 @@ type AgentConfig struct { // - gre // - stt TunnelType string `yaml:"tunnelType,omitempty"` + // TunnelPort is the destination port for UDP and TCP based tunnel protocols (Geneve, VXLAN, and STT). + // If zero, it will use the assigned IANA port for the protocol, i.e. 6081 for Geneve, 4789 for VXLAN, + // and 7471 for STT. + TunnelPort int32 `yaml:"tunnelPort,omitempty"` // Default MTU to use for the host gateway interface and the network interface of each Pod. // If omitted, antrea-agent will discover the MTU of the Node's primary interface and // also adjust MTU to accommodate for tunnel encapsulation overhead (if applicable). diff --git a/pkg/ovs/ovsconfig/ovs_client.go b/pkg/ovs/ovsconfig/ovs_client.go index 67f784f3d2c..db321a90bdb 100644 --- a/pkg/ovs/ovsconfig/ovs_client.go +++ b/pkg/ovs/ovsconfig/ovs_client.go @@ -500,15 +500,16 @@ func (br *OVSBridge) SetInterfaceOptions(name string, options map[string]interfa // ParseTunnelInterfaceOptions reads remote IP, local IP, IPsec PSK, and csum // from the tunnel interface options and returns them. -func ParseTunnelInterfaceOptions(portData *OVSPortData) (net.IP, net.IP, string, string, bool) { +func ParseTunnelInterfaceOptions(portData *OVSPortData) (net.IP, net.IP, int32, string, string, bool) { if portData.Options == nil { - return nil, nil, "", "", false + return nil, nil, 0, "", "", false } var ok bool var remoteIPStr, localIPStr, psk, remoteName string var remoteIP, localIP net.IP var csum bool + var destinationPort int64 if remoteIPStr, ok = portData.Options["remote_ip"]; ok { if remoteIPStr != "flow" { @@ -523,7 +524,10 @@ func ParseTunnelInterfaceOptions(portData *OVSPortData) (net.IP, net.IP, string, csum, _ = strconv.ParseBool(csumStr) } remoteName = portData.Options["remote_name"] - return remoteIP, localIP, psk, remoteName, csum + if destinationPortStr, ok := portData.Options["dst_port"]; ok { + destinationPort, _ = strconv.ParseInt(destinationPortStr, 10, 32) + } + return remoteIP, localIP, int32(destinationPort), psk, remoteName, csum } // CreateUplinkPort creates uplink port. diff --git a/test/integration/ovs/ovs_client_test.go b/test/integration/ovs/ovs_client_test.go index 74a4162ff14..0201949de9e 100644 --- a/test/integration/ovs/ovs_client_test.go +++ b/test/integration/ovs/ovs_client_test.go @@ -287,6 +287,69 @@ func TestTunnelOptionCsum(t *testing.T) { } } +func TestTunnelOptionTunnelPort(t *testing.T) { + testCases := map[string]struct { + initialTunnelPort int32 + updatedTunnelPort int32 + }{ + "initial zero, kept zero": { + initialTunnelPort: 0, + updatedTunnelPort: 0, + }, + "initial zero, updated to 8472": { + initialTunnelPort: 0, + updatedTunnelPort: 8472, + }, + "initial 8472, kept 8473": { + initialTunnelPort: 8472, + updatedTunnelPort: 8473, + }, + "initial 8472, updated to zero": { + initialTunnelPort: 8472, + updatedTunnelPort: 0, + }, + } + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + data := &testData{} + data.setup(t) + defer data.teardown(t) + + name := "vxlan0" + extraOptions := map[string]interface{}{} + if testCase.initialTunnelPort != 0 { + extraOptions["dst_port"] = strconv.Itoa(int(testCase.initialTunnelPort)) + } + _, err := data.br.CreateTunnelPortExt(name, ovsconfig.VXLANTunnel, ofPortRequest, true, "", "", "", "", extraOptions, nil) + require.Nil(t, err, "Error when creating tunnel port") + options, err := data.br.GetInterfaceOptions(name) + require.Nil(t, err, "Error when getting interface options") + if testCase.initialTunnelPort != 0 { + actualInitialTunnelPort, _ := strconv.ParseInt(options["dst_port"], 10, 32) + require.Equal(t, testCase.initialTunnelPort, int32(actualInitialTunnelPort)) + } + + updatedOptions := map[string]interface{}{} + for k, v := range options { + updatedOptions[k] = v + } + if testCase.updatedTunnelPort != 0 { + updatedOptions["dst_port"] = strconv.Itoa(int(testCase.updatedTunnelPort)) + } else if _, ok := updatedOptions["dst_port"]; ok { + delete(updatedOptions, "dst_port") + } + err = data.br.SetInterfaceOptions(name, updatedOptions) + require.Nil(t, err, "Error when setting interface options") + options, err = data.br.GetInterfaceOptions(name) + require.Nil(t, err, "Error when getting interface options") + if testCase.updatedTunnelPort != 0 { + actualTunnelPort, _ := strconv.ParseInt(options["dst_port"], 10, 32) + require.Equal(t, testCase.updatedTunnelPort, int32(actualTunnelPort)) + } + }) + } +} + func deleteAllPorts(t *testing.T, br *ovsconfig.OVSBridge) { portList, err := br.GetPortUUIDList() require.Nil(t, err, "Error when retrieving port list")