From 74a3e4a0f9726a4864ad53f3349213800321d1c2 Mon Sep 17 00:00:00 2001 From: Slawek Kaplonski Date: Wed, 18 Nov 2020 16:30:33 +0100 Subject: [PATCH] [GRE] Add possibility to create GRE tunnels over IPv6 In case when IPv6 addresses are used for GRE tunnels, tunnel type set for the openvswitch interface should be "ip6gre" instead of "gre" which was set so far. This patch changes that so now Neutron configures correct GRE tunnel types. Conflicts: neutron/tests/functional/agent/common/test_ovs_lib.py Change-Id: I557af0bcafac4583ad9726c9bf707cf1fb92ffc5 Closes-Bug: #1904564 (cherry picked from commit 80e6781bc2d2b39e547e80996743d29ec090c816) --- neutron/agent/common/ovs_lib.py | 16 ++++++++++++++++ neutron/tests/functional/agent/test_ovs_lib.py | 8 +++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/neutron/agent/common/ovs_lib.py b/neutron/agent/common/ovs_lib.py index 70f41a92fa7..b24d1612dde 100644 --- a/neutron/agent/common/ovs_lib.py +++ b/neutron/agent/common/ovs_lib.py @@ -68,6 +68,9 @@ _SENTINEL = object() CTRL_RATE_LIMIT_MIN = 100 CTRL_BURST_LIMIT_MIN = 25 +# TODO(slaweq): move this to neutron_lib.constants +TYPE_GRE_IP6 = 'ip6gre' + def _ovsdb_result_pending(result): """Return True if ovs-vsctl indicates the result is still pending.""" @@ -94,6 +97,13 @@ def _ovsdb_retry(fn): return wrapped +def get_gre_tunnel_port_type(remote_ip, local_ip): + if (common_utils.get_ip_version(remote_ip) == p_const.IP_VERSION_6 or + common_utils.get_ip_version(local_ip) == p_const.IP_VERSION_6): + return TYPE_GRE_IP6 + return p_const.TYPE_GRE + + class VifPort(object): def __init__(self, port_name, ofport, vif_id, vif_mac, switch): self.port_name = port_name @@ -509,6 +519,8 @@ class OVSBridge(BaseOVS): dont_fragment=True, tunnel_csum=False, tos=None): + if tunnel_type == p_const.TYPE_GRE: + tunnel_type = get_gre_tunnel_port_type(remote_ip, local_ip) attrs = [('type', tunnel_type)] # TODO(twilson) This is an OrderedDict solely to make a test happy options = collections.OrderedDict() @@ -532,6 +544,10 @@ class OVSBridge(BaseOVS): options['csum'] = str(tunnel_csum).lower() if tos: options['tos'] = str(tos) + if tunnel_type == TYPE_GRE_IP6: + # NOTE(slaweq) According to the OVS documentation L3 GRE tunnels + # over IPv6 are not supported. + options['packet_type'] = 'legacy' attrs.append(('options', options)) return self.add_port(port_name, *attrs) diff --git a/neutron/tests/functional/agent/test_ovs_lib.py b/neutron/tests/functional/agent/test_ovs_lib.py index 45aa364cb0b..b6e7c8a3caf 100644 --- a/neutron/tests/functional/agent/test_ovs_lib.py +++ b/neutron/tests/functional/agent/test_ovs_lib.py @@ -212,11 +212,12 @@ class OVSBridgeTestCase(OVSBridgeTestBase): self.br.br_name, 'datapath_id', dpid) self.assertIn(dpid, self.br.get_datapath_id()) - def _test_add_tunnel_port(self, attrs): + def _test_add_tunnel_port(self, attrs, + expected_tunnel_type=const.TYPE_GRE): port_name = utils.get_rand_device_name(net_helpers.PORT_PREFIX) self.br.add_tunnel_port(port_name, attrs['remote_ip'], attrs['local_ip']) - self.assertEqual('gre', + self.assertEqual(expected_tunnel_type, self.ovs.db_get_val('Interface', port_name, 'type')) options = self.ovs.db_get_val('Interface', port_name, 'options') for attr, val in attrs.items(): @@ -234,7 +235,8 @@ class OVSBridgeTestCase(OVSBridgeTestBase): 'remote_ip': '2001:db8:200::1', 'local_ip': '2001:db8:100::1', } - self._test_add_tunnel_port(attrs) + self._test_add_tunnel_port( + attrs, expected_tunnel_type=ovs_lib.TYPE_GRE_IP6) def test_add_tunnel_port_custom_port(self): port_name = utils.get_rand_device_name(net_helpers.PORT_PREFIX)