Add Geneve type driver support to ML2
More information about Geneve protocol can be found here: https://tools.ietf.org/pdf/draft-gross-geneve-02.pdf Following configuration variables were added: [ml2_type_geneve] vni_ranges - Comma-separated list of <vni_min>:<vni_max> tuples enumerating ranges of Geneve VNI IDs that are available for tenant network allocation max_header_size - Geneve encapsulation header size is dynamic, this value is used to calculate the maximum MTU for the driver this is the sum of the sizes of the outer ETH + IP + UDP + GENEVE header sizes DocImpact Change-Id: I8c29a1c1a7c79e02c26ac9e2ad2645d30dfbeefc Closes-Bug: #1461069changes/45/187945/21
parent
9ed4be7559
commit
7b7c15ba4e
|
@ -26,7 +26,6 @@ GRE Tunneling is documented in depth in the `Networking in too much
|
|||
detail <http://openstack.redhat.com/Networking_in_too_much_detail>`_
|
||||
by RedHat.
|
||||
|
||||
|
||||
VXLAN Tunnels
|
||||
-------------
|
||||
|
||||
|
@ -35,6 +34,16 @@ at layer 2 into a UDP header.
|
|||
More information can be found in `The VXLAN wiki page.
|
||||
<http://en.wikipedia.org/wiki/Virtual_Extensible_LAN>`_
|
||||
|
||||
Geneve Tunnels
|
||||
--------------
|
||||
|
||||
Geneve uses UDP as its transport protocol and is dynamic
|
||||
in size using extensible option headers.
|
||||
It is important to note that currently it is only supported in
|
||||
newer kernels. (kernel >= 3.18, OVS version >=2.4)
|
||||
More information can be found in the `Geneve RFC document.
|
||||
<https://tools.ietf.org/html/draft-ietf-nvo3-geneve-00>`_
|
||||
|
||||
|
||||
Bridge Management
|
||||
-----------------
|
||||
|
@ -71,6 +80,7 @@ future to support existing VLAN-tagged traffic (coming from NFV VMs
|
|||
for instance) and/or to deal with potential QinQ support natively
|
||||
available in the Open vSwitch.
|
||||
|
||||
|
||||
Further Reading
|
||||
---------------
|
||||
|
||||
|
|
|
@ -2,15 +2,16 @@
|
|||
# (ListOpt) List of network type driver entrypoints to be loaded from
|
||||
# the neutron.ml2.type_drivers namespace.
|
||||
#
|
||||
# type_drivers = local,flat,vlan,gre,vxlan
|
||||
# Example: type_drivers = flat,vlan,gre,vxlan
|
||||
# type_drivers = local,flat,vlan,gre,vxlan,geneve
|
||||
# Example: type_drivers = flat,vlan,gre,vxlan,geneve
|
||||
|
||||
# (ListOpt) Ordered list of network_types to allocate as tenant
|
||||
# networks. The default value 'local' is useful for single-box testing
|
||||
# but provides no connectivity between hosts.
|
||||
#
|
||||
# tenant_network_types = local
|
||||
# Example: tenant_network_types = vlan,gre,vxlan
|
||||
# Example: tenant_network_types = vlan,gre,vxlan,geneve
|
||||
|
||||
|
||||
# (ListOpt) Ordered list of networking mechanism driver entrypoints
|
||||
# to be loaded from the neutron.ml2.mechanism_drivers namespace.
|
||||
|
@ -93,6 +94,22 @@
|
|||
# vxlan_group =
|
||||
# Example: vxlan_group = 239.1.1.1
|
||||
|
||||
[ml2_type_geneve]
|
||||
# (ListOpt) Comma-separated list of <vni_min>:<vni_max> tuples enumerating
|
||||
# ranges of Geneve VNI IDs that are available for tenant network allocation.
|
||||
#
|
||||
# vni_ranges =
|
||||
|
||||
# (IntOpt) Geneve encapsulation header size is dynamic, this
|
||||
# value is used to calculate the maximum MTU for the driver.
|
||||
# this is the sum of the sizes of the outer ETH+IP+UDP+GENEVE
|
||||
# header sizes.
|
||||
# The default size for this field is 50, which is the size of the
|
||||
# Geneve header without any additional option headers
|
||||
#
|
||||
# max_header_size =
|
||||
# Example: max_header_size = 50 (Geneve headers with no additional options)
|
||||
|
||||
[securitygroup]
|
||||
# Controls if neutron security group is enabled or not.
|
||||
# It should be false when you use nova security group.
|
||||
|
|
|
@ -52,6 +52,13 @@ def ovs_vxlan_supported(from_ip='192.0.2.1', to_ip='192.0.2.2'):
|
|||
return port != ovs_lib.INVALID_OFPORT
|
||||
|
||||
|
||||
def ovs_geneve_supported(from_ip='192.0.2.3', to_ip='192.0.2.4'):
|
||||
name = "genevetest-" + utils.get_random_string(6)
|
||||
with ovs_lib.OVSBridge(name) as br:
|
||||
port = br.add_tunnel_port(from_ip, to_ip, const.TYPE_GENEVE)
|
||||
return port != ovs_lib.INVALID_OFPORT
|
||||
|
||||
|
||||
def iproute2_vxlan_supported():
|
||||
ip = ip_lib.IPWrapper()
|
||||
name = "vxlantest-" + utils.get_random_string(4)
|
||||
|
|
|
@ -56,6 +56,15 @@ def check_ovs_vxlan():
|
|||
return result
|
||||
|
||||
|
||||
def check_ovs_geneve():
|
||||
result = checks.ovs_geneve_supported()
|
||||
if not result:
|
||||
LOG.error(_LE('Check for Open vSwitch Geneve support failed. '
|
||||
'Please ensure that the version of openvswitch '
|
||||
'and kernel being used has Geneve support.'))
|
||||
return result
|
||||
|
||||
|
||||
def check_iproute2_vxlan():
|
||||
result = checks.iproute2_vxlan_supported()
|
||||
if not result:
|
||||
|
@ -181,6 +190,8 @@ def check_ebtables():
|
|||
OPTS = [
|
||||
BoolOptCallback('ovs_vxlan', check_ovs_vxlan, default=False,
|
||||
help=_('Check for OVS vxlan support')),
|
||||
BoolOptCallback('ovs_geneve', check_ovs_geneve, default=False,
|
||||
help=_('Check for OVS Geneve support')),
|
||||
BoolOptCallback('iproute2_vxlan', check_iproute2_vxlan, default=False,
|
||||
help=_('Check for iproute2 vxlan support')),
|
||||
BoolOptCallback('ovs_patch', check_ovs_patch, default=False,
|
||||
|
@ -216,6 +227,8 @@ def enable_tests_from_config():
|
|||
|
||||
if 'vxlan' in cfg.CONF.AGENT.tunnel_types:
|
||||
cfg.CONF.set_override('ovs_vxlan', True)
|
||||
if 'geneve' in cfg.CONF.AGENT.tunnel_types:
|
||||
cfg.CONF.set_override('ovs_geneve', True)
|
||||
if ('vxlan' in cfg.CONF.ml2.type_drivers or
|
||||
cfg.CONF.VXLAN.enable_vxlan):
|
||||
cfg.CONF.set_override('iproute2_vxlan', True)
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
2e5352a0ad4d
|
||||
11926bcfe72d
|
||||
34af2b5c5a59
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
# Copyright 2015 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
"""add geneve ml2 type driver
|
||||
|
||||
Revision ID: 11926bcfe72d
|
||||
Revises: 2e5352a0ad4d
|
||||
Create Date: 2015-08-27 19:56:16.356522
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '11926bcfe72d'
|
||||
down_revision = '2e5352a0ad4d'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.create_table(
|
||||
'ml2_geneve_allocations',
|
||||
sa.Column('geneve_vni', sa.Integer(),
|
||||
autoincrement=False, nullable=False),
|
||||
sa.Column('allocated', sa.Boolean(),
|
||||
server_default=sa.sql.false(), nullable=False),
|
||||
sa.PrimaryKeyConstraint('geneve_vni'),
|
||||
)
|
||||
op.create_index(op.f('ix_ml2_geneve_allocations_allocated'),
|
||||
'ml2_geneve_allocations', ['allocated'], unique=False)
|
||||
op.create_table(
|
||||
'ml2_geneve_endpoints',
|
||||
sa.Column('ip_address', sa.String(length=64), nullable=False),
|
||||
sa.Column('host', sa.String(length=255), nullable=True),
|
||||
sa.PrimaryKeyConstraint('ip_address'),
|
||||
sa.UniqueConstraint('host', name='unique_ml2_geneve_endpoints0host'),
|
||||
)
|
|
@ -56,6 +56,7 @@ from neutron.plugins.cisco.db import network_models_v2 # noqa
|
|||
from neutron.plugins.ml2.drivers.brocade.db import ( # noqa
|
||||
models as ml2_brocade_models)
|
||||
from neutron.plugins.ml2.drivers import type_flat # noqa
|
||||
from neutron.plugins.ml2.drivers import type_geneve # noqa
|
||||
from neutron.plugins.ml2.drivers import type_gre # noqa
|
||||
from neutron.plugins.ml2.drivers import type_vlan # noqa
|
||||
from neutron.plugins.ml2.drivers import type_vxlan # noqa
|
||||
|
|
|
@ -56,6 +56,7 @@ ACTIVE_PENDING_STATUSES = (
|
|||
|
||||
# Network Type constants
|
||||
TYPE_FLAT = 'flat'
|
||||
TYPE_GENEVE = 'geneve'
|
||||
TYPE_GRE = 'gre'
|
||||
TYPE_LOCAL = 'local'
|
||||
TYPE_VXLAN = 'vxlan'
|
||||
|
@ -68,6 +69,10 @@ TYPE_NONE = 'none'
|
|||
MIN_VLAN_TAG = 1
|
||||
MAX_VLAN_TAG = 4094
|
||||
|
||||
# For Geneve Tunnel
|
||||
MIN_GENEVE_VNI = 1
|
||||
MAX_GENEVE_VNI = 2 ** 24 - 1
|
||||
|
||||
# For GRE Tunnel
|
||||
MIN_GRE_ID = 1
|
||||
MAX_GRE_ID = 2 ** 32 - 1
|
||||
|
@ -78,5 +83,6 @@ MAX_VXLAN_VNI = 2 ** 24 - 1
|
|||
VXLAN_UDP_PORT = 4789
|
||||
|
||||
# Network Type MTU overhead
|
||||
GENEVE_ENCAP_MIN_OVERHEAD = 50
|
||||
GRE_ENCAP_OVERHEAD = 42
|
||||
VXLAN_ENCAP_OVERHEAD = 50
|
||||
|
|
|
@ -35,10 +35,15 @@ def is_valid_vxlan_vni(vni):
|
|||
return p_const.MIN_VXLAN_VNI <= vni <= p_const.MAX_VXLAN_VNI
|
||||
|
||||
|
||||
def is_valid_geneve_vni(vni):
|
||||
return p_const.MIN_GENEVE_VNI <= vni <= p_const.MAX_GENEVE_VNI
|
||||
|
||||
|
||||
def verify_tunnel_range(tunnel_range, tunnel_type):
|
||||
"""Raise an exception for invalid tunnel range or malformed range."""
|
||||
mappings = {p_const.TYPE_GRE: is_valid_gre_id,
|
||||
p_const.TYPE_VXLAN: is_valid_vxlan_vni}
|
||||
p_const.TYPE_VXLAN: is_valid_vxlan_vni,
|
||||
p_const.TYPE_GENEVE: is_valid_geneve_vni}
|
||||
if tunnel_type in mappings:
|
||||
for ident in tunnel_range:
|
||||
if not mappings[tunnel_type](ident):
|
||||
|
|
|
@ -18,7 +18,7 @@ from oslo_config import cfg
|
|||
|
||||
ml2_opts = [
|
||||
cfg.ListOpt('type_drivers',
|
||||
default=['local', 'flat', 'vlan', 'gre', 'vxlan'],
|
||||
default=['local', 'flat', 'vlan', 'gre', 'vxlan', 'geneve'],
|
||||
help=_("List of network type driver entrypoints to be loaded "
|
||||
"from the neutron.ml2.type_drivers namespace.")),
|
||||
cfg.ListOpt('tenant_network_types',
|
||||
|
|
|
@ -32,7 +32,9 @@ PEER_PHYSICAL_PREFIX = 'phy-'
|
|||
NONEXISTENT_PEER = 'nonexistent-peer'
|
||||
|
||||
# The different types of tunnels
|
||||
TUNNEL_NETWORK_TYPES = [p_const.TYPE_GRE, p_const.TYPE_VXLAN]
|
||||
TUNNEL_NETWORK_TYPES = [p_const.TYPE_GRE, p_const.TYPE_VXLAN,
|
||||
p_const.TYPE_GENEVE]
|
||||
|
||||
|
||||
# Various tables for DVR use of integration bridge flows
|
||||
LOCAL_SWITCHING = 0
|
||||
|
@ -44,6 +46,8 @@ DVR_PROCESS = 1
|
|||
PATCH_LV_TO_TUN = 2
|
||||
GRE_TUN_TO_LV = 3
|
||||
VXLAN_TUN_TO_LV = 4
|
||||
GENEVE_TUN_TO_LV = 6
|
||||
|
||||
DVR_NOT_LEARN = 9
|
||||
LEARN_FROM_TUN = 10
|
||||
UCAST_TO_TUN = 20
|
||||
|
@ -67,7 +71,9 @@ ARP_REPLY = '0x2'
|
|||
|
||||
# Map tunnel types to tables number
|
||||
TUN_TABLE = {p_const.TYPE_GRE: GRE_TUN_TO_LV,
|
||||
p_const.TYPE_VXLAN: VXLAN_TUN_TO_LV}
|
||||
p_const.TYPE_VXLAN: VXLAN_TUN_TO_LV,
|
||||
p_const.TYPE_GENEVE: GENEVE_TUN_TO_LV}
|
||||
|
||||
|
||||
# The default respawn interval for the ovsdb monitor
|
||||
DEFAULT_OVSDBMON_RESPAWN = 30
|
||||
|
|
|
@ -239,7 +239,9 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
|
|||
self.bridge_mappings = bridge_mappings
|
||||
self.setup_physical_bridges(self.bridge_mappings)
|
||||
self.local_vlan_map = {}
|
||||
self.tun_br_ofports = {p_const.TYPE_GRE: {},
|
||||
|
||||
self.tun_br_ofports = {p_const.TYPE_GENEVE: {},
|
||||
p_const.TYPE_GRE: {},
|
||||
p_const.TYPE_VXLAN: {}}
|
||||
|
||||
self.polling_interval = polling_interval
|
||||
|
@ -584,7 +586,7 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
|
|||
|
||||
:param net_uuid: the uuid of the network associated with this vlan.
|
||||
:param network_type: the network type ('gre', 'vxlan', 'vlan', 'flat',
|
||||
'local')
|
||||
'local', 'geneve')
|
||||
:param physical_network: the physical network for 'vlan' or 'flat'
|
||||
:param segmentation_id: the VID for 'vlan' or tunnel ID for 'tunnel'
|
||||
'''
|
||||
|
@ -1738,9 +1740,10 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
|
|||
def _check_agent_configurations(self):
|
||||
if (self.enable_distributed_routing and self.enable_tunneling
|
||||
and not self.l2_pop):
|
||||
raise ValueError(_("DVR deployments for VXLAN/GRE underlays "
|
||||
"require L2-pop to be enabled, in both the "
|
||||
"Agent and Server side."))
|
||||
|
||||
raise ValueError(_("DVR deployments for VXLAN/GRE/Geneve "
|
||||
"underlays require L2-pop to be enabled, "
|
||||
"in both the Agent and Server side."))
|
||||
|
||||
|
||||
def create_agent_config_map(config):
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
# Copyright (c) 2015 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import sql
|
||||
|
||||
from neutron.common import exceptions as n_exc
|
||||
from neutron.db import model_base
|
||||
from neutron.i18n import _LE
|
||||
from neutron.plugins.common import constants as p_const
|
||||
from neutron.plugins.ml2.drivers import type_tunnel
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
geneve_opts = [
|
||||
cfg.ListOpt('vni_ranges',
|
||||
default=[],
|
||||
help=_("Comma-separated list of <vni_min>:<vni_max> tuples "
|
||||
"enumerating ranges of Geneve VNI IDs that are "
|
||||
"available for tenant network allocation")),
|
||||
cfg.IntOpt('max_header_size',
|
||||
default=p_const.GENEVE_ENCAP_MIN_OVERHEAD,
|
||||
help=_("Geneve encapsulation header size is dynamic, this "
|
||||
"value is used to calculate the maximum MTU "
|
||||
"for the driver."
|
||||
"this is the sum of the sizes of the outer "
|
||||
"ETH + IP + UDP + GENEVE header sizes")),
|
||||
]
|
||||
|
||||
cfg.CONF.register_opts(geneve_opts, "ml2_type_geneve")
|
||||
|
||||
|
||||
class GeneveAllocation(model_base.BASEV2):
|
||||
|
||||
__tablename__ = 'ml2_geneve_allocations'
|
||||
|
||||
geneve_vni = sa.Column(sa.Integer, nullable=False, primary_key=True,
|
||||
autoincrement=False)
|
||||
allocated = sa.Column(sa.Boolean, nullable=False, default=False,
|
||||
server_default=sql.false(), index=True)
|
||||
|
||||
|
||||
class GeneveEndpoints(model_base.BASEV2):
|
||||
"""Represents tunnel endpoint in RPC mode."""
|
||||
|
||||
__tablename__ = 'ml2_geneve_endpoints'
|
||||
__table_args__ = (
|
||||
sa.UniqueConstraint('host',
|
||||
name='unique_ml2_geneve_endpoints0host'),
|
||||
model_base.BASEV2.__table_args__
|
||||
)
|
||||
ip_address = sa.Column(sa.String(64), primary_key=True)
|
||||
host = sa.Column(sa.String(255), nullable=True)
|
||||
|
||||
def __repr__(self):
|
||||
return "<GeneveTunnelEndpoint(%s)>" % self.ip_address
|
||||
|
||||
|
||||
class GeneveTypeDriver(type_tunnel.EndpointTunnelTypeDriver):
|
||||
|
||||
def __init__(self):
|
||||
super(GeneveTypeDriver, self).__init__(GeneveAllocation,
|
||||
GeneveEndpoints)
|
||||
self.max_encap_size = cfg.CONF.ml2_type_geneve.max_header_size
|
||||
|
||||
def get_type(self):
|
||||
return p_const.TYPE_GENEVE
|
||||
|
||||
def initialize(self):
|
||||
try:
|
||||
self._initialize(cfg.CONF.ml2_type_geneve.vni_ranges)
|
||||
except n_exc.NetworkTunnelRangeError:
|
||||
LOG.error(_LE("Failed to parse vni_ranges. "
|
||||
"Service terminated!"))
|
||||
raise SystemExit()
|
||||
|
||||
def get_endpoints(self):
|
||||
"""Get every geneve endpoints from database."""
|
||||
geneve_endpoints = self._get_endpoints()
|
||||
return [{'ip_address': geneve_endpoint.ip_address,
|
||||
'host': geneve_endpoint.host}
|
||||
for geneve_endpoint in geneve_endpoints]
|
||||
|
||||
def add_endpoint(self, ip, host):
|
||||
return self._add_endpoint(ip, host)
|
||||
|
||||
def get_mtu(self, physical_network=None):
|
||||
mtu = super(GeneveTypeDriver, self).get_mtu()
|
||||
return mtu - self.max_encap_size if mtu else 0
|
|
@ -50,6 +50,9 @@ class SanityTestCaseRoot(functional_base.BaseSudoTestCase):
|
|||
def test_ovs_vxlan_support_runs(self):
|
||||
checks.ovs_vxlan_supported()
|
||||
|
||||
def test_ovs_geneve_support_runs(self):
|
||||
checks.ovs_geneve_supported()
|
||||
|
||||
def test_iproute2_vxlan_support_runs(self):
|
||||
checks.iproute2_vxlan_supported()
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ class OVSTunnelBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase,
|
|||
'actions': 'resubmit(,22)'},
|
||||
{'priority': 0, 'table': 3, 'actions': 'drop'},
|
||||
{'priority': 0, 'table': 4, 'actions': 'drop'},
|
||||
{'priority': 0, 'table': 6, 'actions': 'drop'},
|
||||
{'priority': 1, 'table': 10,
|
||||
'actions': 'learn(cookie=0x0,table=20,priority=1,'
|
||||
'hard_timeout=300,NXM_OF_VLAN_TCI[0..11],'
|
||||
|
@ -87,6 +88,7 @@ class OVSTunnelBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase,
|
|||
'actions': 'resubmit(,22)'},
|
||||
{'priority': 0, 'table': 3, 'actions': 'drop'},
|
||||
{'priority': 0, 'table': 4, 'actions': 'drop'},
|
||||
{'priority': 0, 'table': 6, 'actions': 'drop'},
|
||||
{'priority': 1, 'table': 10,
|
||||
'actions': 'learn(cookie=0x0,table=20,priority=1,'
|
||||
'hard_timeout=300,NXM_OF_VLAN_TCI[0..11],'
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
# Copyright (c) 2015 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
from neutron.plugins.common import constants as p_const
|
||||
from neutron.plugins.ml2.drivers import type_geneve
|
||||
from neutron.tests.unit.plugins.ml2.drivers import base_type_tunnel
|
||||
from neutron.tests.unit.plugins.ml2 import test_rpc
|
||||
from neutron.tests.unit import testlib_api
|
||||
|
||||
|
||||
TUNNEL_IP_ONE = "10.10.10.77"
|
||||
TUNNEL_IP_TWO = "10.10.10.78"
|
||||
HOST_ONE = 'fake_host_one1'
|
||||
HOST_TWO = 'fake_host_two2'
|
||||
|
||||
|
||||
class GeneveTypeTest(base_type_tunnel.TunnelTypeTestMixin,
|
||||
testlib_api.SqlTestCase):
|
||||
DRIVER_CLASS = type_geneve.GeneveTypeDriver
|
||||
TYPE = p_const.TYPE_GENEVE
|
||||
|
||||
def test_get_endpoints(self):
|
||||
self.driver.add_endpoint(TUNNEL_IP_ONE, HOST_ONE)
|
||||
self.driver.add_endpoint(TUNNEL_IP_TWO, HOST_TWO)
|
||||
|
||||
endpoints = self.driver.get_endpoints()
|
||||
for endpoint in endpoints:
|
||||
if endpoint['ip_address'] == TUNNEL_IP_ONE:
|
||||
self.assertEqual(HOST_ONE, endpoint['host'])
|
||||
elif endpoint['ip_address'] == TUNNEL_IP_TWO:
|
||||
self.assertEqual(HOST_TWO, endpoint['host'])
|
||||
|
||||
|
||||
class GeneveTypeMultiRangeTest(base_type_tunnel.TunnelTypeMultiRangeTestMixin,
|
||||
testlib_api.SqlTestCase):
|
||||
DRIVER_CLASS = type_geneve.GeneveTypeDriver
|
||||
|
||||
|
||||
class GeneveTypeRpcCallbackTest(base_type_tunnel.TunnelRpcCallbackTestMixin,
|
||||
test_rpc.RpcCallbacksTestCase,
|
||||
testlib_api.SqlTestCase):
|
||||
DRIVER_CLASS = type_geneve.GeneveTypeDriver
|
||||
TYPE = p_const.TYPE_GENEVE
|
|
@ -151,6 +151,7 @@ neutron.ml2.type_drivers =
|
|||
flat = neutron.plugins.ml2.drivers.type_flat:FlatTypeDriver
|
||||
local = neutron.plugins.ml2.drivers.type_local:LocalTypeDriver
|
||||
vlan = neutron.plugins.ml2.drivers.type_vlan:VlanTypeDriver
|
||||
geneve = neutron.plugins.ml2.drivers.type_geneve:GeneveTypeDriver
|
||||
gre = neutron.plugins.ml2.drivers.type_gre:GreTypeDriver
|
||||
vxlan = neutron.plugins.ml2.drivers.type_vxlan:VxlanTypeDriver
|
||||
neutron.ml2.mechanism_drivers =
|
||||
|
|
Loading…
Reference in New Issue