From 7b7c15ba4e2f0646000ecca2acecb98081268772 Mon Sep 17 00:00:00 2001 From: Aaron Rosen Date: Tue, 5 May 2015 14:35:08 -0700 Subject: [PATCH] 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 : 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: #1461069 --- doc/source/devref/openvswitch_agent.rst | 12 +- etc/neutron/plugins/ml2/ml2_conf.ini | 23 +++- neutron/cmd/sanity/checks.py | 7 ++ neutron/cmd/sanity_check.py | 13 +++ .../alembic_migrations/versions/HEADS | 2 +- ...11926bcfe72d_add_geneve_ml2_type_driver.py | 49 +++++++++ neutron/db/migration/models/head.py | 1 + neutron/plugins/common/constants.py | 6 + neutron/plugins/common/utils.py | 7 +- neutron/plugins/ml2/config.py | 2 +- .../openvswitch/agent/common/constants.py | 10 +- .../openvswitch/agent/ovs_neutron_agent.py | 13 ++- neutron/plugins/ml2/drivers/type_geneve.py | 103 ++++++++++++++++++ .../tests/functional/sanity/test_sanity.py | 3 + .../agent/openflow/ovs_ofctl/test_br_tun.py | 2 + .../plugins/ml2/drivers/test_type_geneve.py | 55 ++++++++++ setup.cfg | 1 + 17 files changed, 295 insertions(+), 14 deletions(-) create mode 100644 neutron/db/migration/alembic_migrations/versions/liberty/contract/11926bcfe72d_add_geneve_ml2_type_driver.py create mode 100644 neutron/plugins/ml2/drivers/type_geneve.py create mode 100644 neutron/tests/unit/plugins/ml2/drivers/test_type_geneve.py diff --git a/doc/source/devref/openvswitch_agent.rst b/doc/source/devref/openvswitch_agent.rst index a4b268532..177520071 100644 --- a/doc/source/devref/openvswitch_agent.rst +++ b/doc/source/devref/openvswitch_agent.rst @@ -26,7 +26,6 @@ GRE Tunneling is documented in depth in the `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. `_ +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. +`_ + 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 --------------- diff --git a/etc/neutron/plugins/ml2/ml2_conf.ini b/etc/neutron/plugins/ml2/ml2_conf.ini index 9aad25b7b..2cef2c6ff 100644 --- a/etc/neutron/plugins/ml2/ml2_conf.ini +++ b/etc/neutron/plugins/ml2/ml2_conf.ini @@ -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 : 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. diff --git a/neutron/cmd/sanity/checks.py b/neutron/cmd/sanity/checks.py index 484438e05..819d00c23 100644 --- a/neutron/cmd/sanity/checks.py +++ b/neutron/cmd/sanity/checks.py @@ -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) diff --git a/neutron/cmd/sanity_check.py b/neutron/cmd/sanity_check.py index 123db3edb..2188f3771 100644 --- a/neutron/cmd/sanity_check.py +++ b/neutron/cmd/sanity_check.py @@ -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) diff --git a/neutron/db/migration/alembic_migrations/versions/HEADS b/neutron/db/migration/alembic_migrations/versions/HEADS index 5e424af8a..9928899ef 100644 --- a/neutron/db/migration/alembic_migrations/versions/HEADS +++ b/neutron/db/migration/alembic_migrations/versions/HEADS @@ -1,2 +1,2 @@ -2e5352a0ad4d +11926bcfe72d 34af2b5c5a59 diff --git a/neutron/db/migration/alembic_migrations/versions/liberty/contract/11926bcfe72d_add_geneve_ml2_type_driver.py b/neutron/db/migration/alembic_migrations/versions/liberty/contract/11926bcfe72d_add_geneve_ml2_type_driver.py new file mode 100644 index 000000000..9ef55843d --- /dev/null +++ b/neutron/db/migration/alembic_migrations/versions/liberty/contract/11926bcfe72d_add_geneve_ml2_type_driver.py @@ -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'), + ) diff --git a/neutron/db/migration/models/head.py b/neutron/db/migration/models/head.py index 549539818..72e5e660e 100644 --- a/neutron/db/migration/models/head.py +++ b/neutron/db/migration/models/head.py @@ -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 diff --git a/neutron/plugins/common/constants.py b/neutron/plugins/common/constants.py index e5aa166d1..65a0fb3e5 100644 --- a/neutron/plugins/common/constants.py +++ b/neutron/plugins/common/constants.py @@ -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 diff --git a/neutron/plugins/common/utils.py b/neutron/plugins/common/utils.py index 287ea1a30..61e7c164f 100644 --- a/neutron/plugins/common/utils.py +++ b/neutron/plugins/common/utils.py @@ -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): diff --git a/neutron/plugins/ml2/config.py b/neutron/plugins/ml2/config.py index 3eb3b2bd4..a248c1ceb 100644 --- a/neutron/plugins/ml2/config.py +++ b/neutron/plugins/ml2/config.py @@ -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', diff --git a/neutron/plugins/ml2/drivers/openvswitch/agent/common/constants.py b/neutron/plugins/ml2/drivers/openvswitch/agent/common/constants.py index 6dde277a8..4643ffe27 100644 --- a/neutron/plugins/ml2/drivers/openvswitch/agent/common/constants.py +++ b/neutron/plugins/ml2/drivers/openvswitch/agent/common/constants.py @@ -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 diff --git a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py index 0c590e38c..117b18149 100644 --- a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py +++ b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py @@ -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): diff --git a/neutron/plugins/ml2/drivers/type_geneve.py b/neutron/plugins/ml2/drivers/type_geneve.py new file mode 100644 index 000000000..d8f430aaf --- /dev/null +++ b/neutron/plugins/ml2/drivers/type_geneve.py @@ -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 : 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 "" % 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 diff --git a/neutron/tests/functional/sanity/test_sanity.py b/neutron/tests/functional/sanity/test_sanity.py index f6029e8ed..a47bb4e27 100644 --- a/neutron/tests/functional/sanity/test_sanity.py +++ b/neutron/tests/functional/sanity/test_sanity.py @@ -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() diff --git a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/openflow/ovs_ofctl/test_br_tun.py b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/openflow/ovs_ofctl/test_br_tun.py index 6d04f230c..9f730246e 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/openflow/ovs_ofctl/test_br_tun.py +++ b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/openflow/ovs_ofctl/test_br_tun.py @@ -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],' diff --git a/neutron/tests/unit/plugins/ml2/drivers/test_type_geneve.py b/neutron/tests/unit/plugins/ml2/drivers/test_type_geneve.py new file mode 100644 index 000000000..fb0ffdfc4 --- /dev/null +++ b/neutron/tests/unit/plugins/ml2/drivers/test_type_geneve.py @@ -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 diff --git a/setup.cfg b/setup.cfg index c2ac4ac29..27feb9a38 100644 --- a/setup.cfg +++ b/setup.cfg @@ -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 = -- 2.45.2