[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.
Change-Id: I557af0bcafac4583ad9726c9bf707cf1fb92ffc5
Closes-Bug: #1904564
(cherry picked from commit 80e6781bc2
)
This commit is contained in:
parent
ab25c89834
commit
c426f7336c
|
@ -74,6 +74,9 @@ _SENTINEL = object()
|
||||||
CTRL_RATE_LIMIT_MIN = 100
|
CTRL_RATE_LIMIT_MIN = 100
|
||||||
CTRL_BURST_LIMIT_MIN = 25
|
CTRL_BURST_LIMIT_MIN = 25
|
||||||
|
|
||||||
|
# TODO(slaweq): move this to neutron_lib.constants
|
||||||
|
TYPE_GRE_IP6 = 'ip6gre'
|
||||||
|
|
||||||
|
|
||||||
def _ovsdb_result_pending(result):
|
def _ovsdb_result_pending(result):
|
||||||
"""Return True if ovsdb indicates the result is still pending."""
|
"""Return True if ovsdb indicates the result is still pending."""
|
||||||
|
@ -100,6 +103,13 @@ def _ovsdb_retry(fn):
|
||||||
return wrapped
|
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):
|
class VifPort(object):
|
||||||
def __init__(self, port_name, ofport, vif_id, vif_mac, switch):
|
def __init__(self, port_name, ofport, vif_id, vif_mac, switch):
|
||||||
self.port_name = port_name
|
self.port_name = port_name
|
||||||
|
@ -490,6 +500,8 @@ class OVSBridge(BaseOVS):
|
||||||
dont_fragment=True,
|
dont_fragment=True,
|
||||||
tunnel_csum=False,
|
tunnel_csum=False,
|
||||||
tos=None):
|
tos=None):
|
||||||
|
if tunnel_type == p_const.TYPE_GRE:
|
||||||
|
tunnel_type = get_gre_tunnel_port_type(remote_ip, local_ip)
|
||||||
attrs = [('type', tunnel_type)]
|
attrs = [('type', tunnel_type)]
|
||||||
# TODO(twilson) This is an OrderedDict solely to make a test happy
|
# TODO(twilson) This is an OrderedDict solely to make a test happy
|
||||||
options = collections.OrderedDict()
|
options = collections.OrderedDict()
|
||||||
|
@ -513,6 +525,10 @@ class OVSBridge(BaseOVS):
|
||||||
options['csum'] = str(tunnel_csum).lower()
|
options['csum'] = str(tunnel_csum).lower()
|
||||||
if tos:
|
if tos:
|
||||||
options['tos'] = str(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))
|
attrs.append(('options', options))
|
||||||
|
|
||||||
return self.add_port(port_name, *attrs)
|
return self.add_port(port_name, *attrs)
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
import functools
|
import functools
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
|
from neutron_lib import constants as p_const
|
||||||
from neutron_lib.services.qos import constants as qos_constants
|
from neutron_lib.services.qos import constants as qos_constants
|
||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
|
|
||||||
|
@ -442,3 +443,30 @@ class BaseOVSTestCase(base.BaseSudoTestCase):
|
||||||
self.assertEqual(8000,
|
self.assertEqual(8000,
|
||||||
self.ovs.db_get_val('Controller', self.br_name,
|
self.ovs.db_get_val('Controller', self.br_name,
|
||||||
'inactivity_probe'))
|
'inactivity_probe'))
|
||||||
|
|
||||||
|
def test_add_gre_tunnel_port(self):
|
||||||
|
ipv4_tunnel_port = "test-ipv4-port"
|
||||||
|
ipv6_tunnel_port = "test-ipv6-port"
|
||||||
|
self._create_bridge()
|
||||||
|
self.ovs.add_tunnel_port(
|
||||||
|
ipv4_tunnel_port, "10.0.0.1", "10.0.0.2",
|
||||||
|
tunnel_type=p_const.TYPE_GRE)
|
||||||
|
self.ovs.add_tunnel_port(
|
||||||
|
ipv6_tunnel_port, "2001:db8::1", "2001:db8:2",
|
||||||
|
tunnel_type=p_const.TYPE_GRE)
|
||||||
|
interfaces = self.ovs.get_ports_attributes(
|
||||||
|
"Interface", columns=["name", "type", "options"],
|
||||||
|
if_exists=True)
|
||||||
|
|
||||||
|
ipv4_port_type = None
|
||||||
|
ipv6_port_type = None
|
||||||
|
ipv6_port_options = {}
|
||||||
|
for interface in interfaces:
|
||||||
|
if interface['name'] == ipv4_tunnel_port:
|
||||||
|
ipv4_port_type = interface['type']
|
||||||
|
elif interface['name'] == ipv6_tunnel_port:
|
||||||
|
ipv6_port_type = interface['type']
|
||||||
|
ipv6_port_options = interface['options']
|
||||||
|
self.assertEqual(p_const.TYPE_GRE, ipv4_port_type)
|
||||||
|
self.assertEqual(ovs_lib.TYPE_GRE_IP6, ipv6_port_type)
|
||||||
|
self.assertEqual('legacy', ipv6_port_options.get('packet_type'))
|
||||||
|
|
|
@ -211,11 +211,12 @@ class OVSBridgeTestCase(OVSBridgeTestBase):
|
||||||
self.br.br_name, 'datapath_id', dpid)
|
self.br.br_name, 'datapath_id', dpid)
|
||||||
self.assertIn(dpid, self.br.get_datapath_id())
|
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)
|
port_name = utils.get_rand_device_name(net_helpers.PORT_PREFIX)
|
||||||
self.br.add_tunnel_port(port_name, attrs['remote_ip'],
|
self.br.add_tunnel_port(port_name, attrs['remote_ip'],
|
||||||
attrs['local_ip'])
|
attrs['local_ip'])
|
||||||
self.assertEqual('gre',
|
self.assertEqual(expected_tunnel_type,
|
||||||
self.ovs.db_get_val('Interface', port_name, 'type'))
|
self.ovs.db_get_val('Interface', port_name, 'type'))
|
||||||
options = self.ovs.db_get_val('Interface', port_name, 'options')
|
options = self.ovs.db_get_val('Interface', port_name, 'options')
|
||||||
for attr, val in attrs.items():
|
for attr, val in attrs.items():
|
||||||
|
@ -233,7 +234,8 @@ class OVSBridgeTestCase(OVSBridgeTestBase):
|
||||||
'remote_ip': '2001:db8:200::1',
|
'remote_ip': '2001:db8:200::1',
|
||||||
'local_ip': '2001:db8:100::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):
|
def test_add_tunnel_port_custom_port(self):
|
||||||
port_name = utils.get_rand_device_name(net_helpers.PORT_PREFIX)
|
port_name = utils.get_rand_device_name(net_helpers.PORT_PREFIX)
|
||||||
|
|
Loading…
Reference in New Issue