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)