Merge "Implement Mellanox ML2 MechanismDriver"
This commit is contained in:
commit
283dafc824
@ -15,6 +15,7 @@
|
|||||||
# (ListOpt) Ordered list of networking mechanism driver entrypoints
|
# (ListOpt) Ordered list of networking mechanism driver entrypoints
|
||||||
# to be loaded from the neutron.ml2.mechanism_drivers namespace.
|
# to be loaded from the neutron.ml2.mechanism_drivers namespace.
|
||||||
# mechanism_drivers =
|
# mechanism_drivers =
|
||||||
|
# Example: mechanism drivers = openvswitch,mlnx
|
||||||
# Example: mechanism_drivers = arista
|
# Example: mechanism_drivers = arista
|
||||||
# Example: mechanism_drivers = cisco,logger
|
# Example: mechanism_drivers = cisco,logger
|
||||||
|
|
||||||
|
4
etc/neutron/plugins/ml2/ml2_conf_mlnx.ini
Normal file
4
etc/neutron/plugins/ml2/ml2_conf_mlnx.ini
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
[eswitch]
|
||||||
|
# (StrOpt) Type of Network Interface to allocate for VM:
|
||||||
|
# mlnx_direct or hostdev according to libvirt terminology
|
||||||
|
# vnic_type = mlnx_direct
|
@ -55,11 +55,13 @@ VIF_TYPE_802_QBG = '802.1qbg'
|
|||||||
VIF_TYPE_802_QBH = '802.1qbh'
|
VIF_TYPE_802_QBH = '802.1qbh'
|
||||||
VIF_TYPE_HYPERV = 'hyperv'
|
VIF_TYPE_HYPERV = 'hyperv'
|
||||||
VIF_TYPE_MIDONET = 'midonet'
|
VIF_TYPE_MIDONET = 'midonet'
|
||||||
|
VIF_TYPE_MLNX_DIRECT = 'mlnx_direct'
|
||||||
|
VIF_TYPE_MLNX_HOSTDEV = 'hostdev'
|
||||||
VIF_TYPE_OTHER = 'other'
|
VIF_TYPE_OTHER = 'other'
|
||||||
VIF_TYPES = [VIF_TYPE_UNBOUND, VIF_TYPE_BINDING_FAILED, VIF_TYPE_OVS,
|
VIF_TYPES = [VIF_TYPE_UNBOUND, VIF_TYPE_BINDING_FAILED, VIF_TYPE_OVS,
|
||||||
VIF_TYPE_IVS, VIF_TYPE_BRIDGE, VIF_TYPE_802_QBG,
|
VIF_TYPE_IVS, VIF_TYPE_BRIDGE, VIF_TYPE_802_QBG,
|
||||||
VIF_TYPE_802_QBH, VIF_TYPE_HYPERV, VIF_TYPE_MIDONET,
|
VIF_TYPE_802_QBH, VIF_TYPE_HYPERV, VIF_TYPE_MIDONET,
|
||||||
VIF_TYPE_OTHER]
|
VIF_TYPE_MLNX_DIRECT, VIF_TYPE_MLNX_HOSTDEV, VIF_TYPE_OTHER]
|
||||||
|
|
||||||
VNIC_NORMAL = 'normal'
|
VNIC_NORMAL = 'normal'
|
||||||
VNIC_DIRECT = 'direct'
|
VNIC_DIRECT = 'direct'
|
||||||
|
@ -87,6 +87,13 @@ def get_port(session, port_id):
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def get_port_from_device_mac(device_mac):
|
||||||
|
LOG.debug(_("get_port_from_device_mac() called for mac %s"), device_mac)
|
||||||
|
session = db_api.get_session()
|
||||||
|
qry = session.query(models_v2.Port).filter_by(mac_address=device_mac)
|
||||||
|
return qry.first()
|
||||||
|
|
||||||
|
|
||||||
def get_port_and_sgs(port_id):
|
def get_port_and_sgs(port_id):
|
||||||
"""Get port from database with security group info."""
|
"""Get port from database with security group info."""
|
||||||
|
|
||||||
|
0
neutron/plugins/ml2/drivers/mlnx/__init__.py
Normal file
0
neutron/plugins/ml2/drivers/mlnx/__init__.py
Normal file
29
neutron/plugins/ml2/drivers/mlnx/config.py
Normal file
29
neutron/plugins/ml2/drivers/mlnx/config.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Copyright (c) 2014 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 neutron.extensions import portbindings
|
||||||
|
|
||||||
|
eswitch_opts = [
|
||||||
|
cfg.StrOpt('vnic_type',
|
||||||
|
default=portbindings.VIF_TYPE_MLNX_DIRECT,
|
||||||
|
help=_("Type of VM network interface: mlnx_direct or "
|
||||||
|
"hostdev")),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
cfg.CONF.register_opts(eswitch_opts, "ESWITCH")
|
79
neutron/plugins/ml2/drivers/mlnx/mech_mlnx.py
Normal file
79
neutron/plugins/ml2/drivers/mlnx/mech_mlnx.py
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
# Copyright (c) 2014 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 neutron.common import constants
|
||||||
|
from neutron.extensions import portbindings
|
||||||
|
from neutron.openstack.common import log
|
||||||
|
from neutron.plugins.ml2 import driver_api as api
|
||||||
|
from neutron.plugins.ml2.drivers import mech_agent
|
||||||
|
from neutron.plugins.ml2.drivers.mlnx import config # noqa
|
||||||
|
|
||||||
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class MlnxMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase):
|
||||||
|
"""Attach to networks using Mellanox eSwitch L2 agent.
|
||||||
|
|
||||||
|
The MellanoxMechanismDriver integrates the ml2 plugin with the
|
||||||
|
Mellanox eswitch L2 agent. Port binding with this driver requires the
|
||||||
|
Mellanox eswitch agent to be running on the port's host, and that agent
|
||||||
|
to have connectivity to at least one segment of the port's
|
||||||
|
network.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
# REVISIT(irenab): update supported_vnic_types to contain
|
||||||
|
# only VNIC_DIRECT and VNIC_MACVTAP once its possible to specify
|
||||||
|
# vnic_type via nova API/GUI. Currently VNIC_NORMAL is included
|
||||||
|
# to enable VM creation via GUI. It should be noted, that if
|
||||||
|
# several MDs are capable to bing bind port on chosen host, the
|
||||||
|
# first listed MD will bind the port for VNIC_NORMAL.
|
||||||
|
super(MlnxMechanismDriver, self).__init__(
|
||||||
|
constants.AGENT_TYPE_MLNX,
|
||||||
|
cfg.CONF.ESWITCH.vnic_type,
|
||||||
|
{portbindings.CAP_PORT_FILTER: False},
|
||||||
|
portbindings.VNIC_TYPES)
|
||||||
|
|
||||||
|
def check_segment_for_agent(self, segment, agent):
|
||||||
|
mappings = agent['configurations'].get('interface_mappings', {})
|
||||||
|
LOG.debug(_("Checking segment: %(segment)s "
|
||||||
|
"for mappings: %(mappings)s "),
|
||||||
|
{'segment': segment, 'mappings': mappings})
|
||||||
|
|
||||||
|
network_type = segment[api.NETWORK_TYPE]
|
||||||
|
if network_type == 'local':
|
||||||
|
return True
|
||||||
|
elif network_type in ['flat', 'vlan']:
|
||||||
|
return segment[api.PHYSICAL_NETWORK] in mappings
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def try_to_bind_segment_for_agent(self, context, segment, agent):
|
||||||
|
if self.check_segment_for_agent(segment, agent):
|
||||||
|
vif_type = self._get_vif_type(
|
||||||
|
context.current[portbindings.VNIC_TYPE])
|
||||||
|
context.set_binding(segment[api.ID],
|
||||||
|
vif_type,
|
||||||
|
self.vif_details)
|
||||||
|
|
||||||
|
def _get_vif_type(self, requested_vnic_type):
|
||||||
|
if requested_vnic_type == portbindings.VNIC_MACVTAP:
|
||||||
|
return portbindings.VIF_TYPE_MLNX_DIRECT
|
||||||
|
elif requested_vnic_type == portbindings.VNIC_DIRECT:
|
||||||
|
return portbindings.VIF_TYPE_MLNX_HOSTDEV
|
||||||
|
return self.vif_type
|
@ -24,6 +24,7 @@ from neutron.db import securitygroups_rpc_base as sg_db_rpc
|
|||||||
from neutron import manager
|
from neutron import manager
|
||||||
from neutron.openstack.common import log
|
from neutron.openstack.common import log
|
||||||
from neutron.openstack.common.rpc import proxy
|
from neutron.openstack.common.rpc import proxy
|
||||||
|
from neutron.openstack.common import uuidutils
|
||||||
from neutron.plugins.ml2 import db
|
from neutron.plugins.ml2 import db
|
||||||
from neutron.plugins.ml2 import driver_api as api
|
from neutron.plugins.ml2 import driver_api as api
|
||||||
from neutron.plugins.ml2.drivers import type_tunnel
|
from neutron.plugins.ml2.drivers import type_tunnel
|
||||||
@ -69,7 +70,13 @@ class RpcCallbacks(dhcp_rpc_base.DhcpRpcCallbackMixin,
|
|||||||
if device.startswith(TAP_DEVICE_PREFIX):
|
if device.startswith(TAP_DEVICE_PREFIX):
|
||||||
return device[TAP_DEVICE_PREFIX_LENGTH:]
|
return device[TAP_DEVICE_PREFIX_LENGTH:]
|
||||||
else:
|
else:
|
||||||
return device
|
# REVISIT(irenab): Consider calling into bound MD to
|
||||||
|
# handle the get_device_details RPC, then remove the 'else' clause
|
||||||
|
if not uuidutils.is_uuid_like(device):
|
||||||
|
port = db.get_port_from_device_mac(device)
|
||||||
|
if port:
|
||||||
|
return port.id
|
||||||
|
return device
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_port_from_device(cls, device):
|
def get_port_from_device(cls, device):
|
||||||
|
@ -190,7 +190,8 @@ class MlnxEswitchRpcCallbacks(sg_rpc.SecurityGroupAgentRpcCallbackMixin):
|
|||||||
# update plugin about port status
|
# update plugin about port status
|
||||||
self.agent.plugin_rpc.update_device_up(self.context,
|
self.agent.plugin_rpc.update_device_up(self.context,
|
||||||
port['mac_address'],
|
port['mac_address'],
|
||||||
self.agent.agent_id)
|
self.agent.agent_id,
|
||||||
|
cfg.CONF.host)
|
||||||
else:
|
else:
|
||||||
self.eswitch.port_down(net_id,
|
self.eswitch.port_down(net_id,
|
||||||
physical_network,
|
physical_network,
|
||||||
@ -199,7 +200,8 @@ class MlnxEswitchRpcCallbacks(sg_rpc.SecurityGroupAgentRpcCallbackMixin):
|
|||||||
self.agent.plugin_rpc.update_device_down(
|
self.agent.plugin_rpc.update_device_down(
|
||||||
self.context,
|
self.context,
|
||||||
port['mac_address'],
|
port['mac_address'],
|
||||||
self.agent.agent_id)
|
self.agent.agent_id,
|
||||||
|
cfg.CONF.host)
|
||||||
except rpc_common.Timeout:
|
except rpc_common.Timeout:
|
||||||
LOG.error(_("RPC timeout while updating port %s"), port['id'])
|
LOG.error(_("RPC timeout while updating port %s"), port['id'])
|
||||||
else:
|
else:
|
||||||
@ -227,11 +229,12 @@ class MlnxEswitchNeutronAgent(sg_rpc.SecurityGroupAgentRpcMixin):
|
|||||||
def __init__(self, interface_mapping):
|
def __init__(self, interface_mapping):
|
||||||
self._polling_interval = cfg.CONF.AGENT.polling_interval
|
self._polling_interval = cfg.CONF.AGENT.polling_interval
|
||||||
self._setup_eswitches(interface_mapping)
|
self._setup_eswitches(interface_mapping)
|
||||||
|
configurations = {'interface_mappings': interface_mapping}
|
||||||
self.agent_state = {
|
self.agent_state = {
|
||||||
'binary': 'neutron-mlnx-agent',
|
'binary': 'neutron-mlnx-agent',
|
||||||
'host': cfg.CONF.host,
|
'host': cfg.CONF.host,
|
||||||
'topic': q_constants.L2_AGENT_TOPIC,
|
'topic': q_constants.L2_AGENT_TOPIC,
|
||||||
'configurations': interface_mapping,
|
'configurations': configurations,
|
||||||
'agent_type': q_constants.AGENT_TYPE_MLNX,
|
'agent_type': q_constants.AGENT_TYPE_MLNX,
|
||||||
'start_flag': True}
|
'start_flag': True}
|
||||||
self._setup_rpc()
|
self._setup_rpc()
|
||||||
@ -245,7 +248,7 @@ class MlnxEswitchNeutronAgent(sg_rpc.SecurityGroupAgentRpcMixin):
|
|||||||
def _report_state(self):
|
def _report_state(self):
|
||||||
try:
|
try:
|
||||||
devices = len(self.eswitch.get_vnics_mac())
|
devices = len(self.eswitch.get_vnics_mac())
|
||||||
self.agent_state['configurations']['devices'] = devices
|
self.agent_state.get('configurations')['devices'] = devices
|
||||||
self.state_rpc.report_state(self.context,
|
self.state_rpc.report_state(self.context,
|
||||||
self.agent_state)
|
self.agent_state)
|
||||||
self.agent_state.pop('start_flag', None)
|
self.agent_state.pop('start_flag', None)
|
||||||
@ -336,7 +339,7 @@ class MlnxEswitchNeutronAgent(sg_rpc.SecurityGroupAgentRpcMixin):
|
|||||||
LOG.info(_("Port %s updated"), device)
|
LOG.info(_("Port %s updated"), device)
|
||||||
LOG.debug(_("Device details %s"), str(dev_details))
|
LOG.debug(_("Device details %s"), str(dev_details))
|
||||||
self.treat_vif_port(dev_details['port_id'],
|
self.treat_vif_port(dev_details['port_id'],
|
||||||
dev_details['port_mac'],
|
dev_details['device'],
|
||||||
dev_details['network_id'],
|
dev_details['network_id'],
|
||||||
dev_details['network_type'],
|
dev_details['network_type'],
|
||||||
dev_details['physical_network'],
|
dev_details['physical_network'],
|
||||||
@ -359,7 +362,8 @@ class MlnxEswitchNeutronAgent(sg_rpc.SecurityGroupAgentRpcMixin):
|
|||||||
port_id = self.eswitch.get_port_id_by_mac(device)
|
port_id = self.eswitch.get_port_id_by_mac(device)
|
||||||
dev_details = self.plugin_rpc.update_device_down(self.context,
|
dev_details = self.plugin_rpc.update_device_down(self.context,
|
||||||
port_id,
|
port_id,
|
||||||
self.agent_id)
|
self.agent_id,
|
||||||
|
cfg.CONF.host)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.debug(_("Removing port failed for device %(device)s "
|
LOG.debug(_("Removing port failed for device %(device)s "
|
||||||
"due to %(exc)s"), {'device': device, 'exc': e})
|
"due to %(exc)s"), {'device': device, 'exc': e})
|
||||||
|
@ -40,17 +40,20 @@ class FakeNetworkContext(api.NetworkContext):
|
|||||||
|
|
||||||
|
|
||||||
class FakePortContext(api.PortContext):
|
class FakePortContext(api.PortContext):
|
||||||
def __init__(self, agent_type, agents, segments):
|
def __init__(self, agent_type, agents, segments,
|
||||||
|
vnic_type=portbindings.VNIC_NORMAL):
|
||||||
self._agent_type = agent_type
|
self._agent_type = agent_type
|
||||||
self._agents = agents
|
self._agents = agents
|
||||||
self._network_context = FakeNetworkContext(segments)
|
self._network_context = FakeNetworkContext(segments)
|
||||||
|
self._bound_vnic_type = vnic_type
|
||||||
self._bound_segment_id = None
|
self._bound_segment_id = None
|
||||||
self._bound_vif_type = None
|
self._bound_vif_type = None
|
||||||
self._bound_vif_details = None
|
self._bound_vif_details = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current(self):
|
def current(self):
|
||||||
return {'id': PORT_ID}
|
return {'id': PORT_ID,
|
||||||
|
'binding:vnic_type': self._bound_vnic_type}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def original(self):
|
def original(self):
|
||||||
|
89
neutron/tests/unit/ml2/drivers/test_mech_mlnx.py
Normal file
89
neutron/tests/unit/ml2/drivers/test_mech_mlnx.py
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
# Copyright (c) 2014 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.common import constants
|
||||||
|
from neutron.extensions import portbindings
|
||||||
|
from neutron.plugins.ml2.drivers.mlnx import mech_mlnx
|
||||||
|
from neutron.tests.unit.ml2 import _test_mech_agent as base
|
||||||
|
|
||||||
|
|
||||||
|
class MlnxMechanismBaseTestCase(base.AgentMechanismBaseTestCase):
|
||||||
|
VIF_TYPE = portbindings.VIF_TYPE_MLNX_DIRECT
|
||||||
|
CAP_PORT_FILTER = False
|
||||||
|
AGENT_TYPE = constants.AGENT_TYPE_MLNX
|
||||||
|
|
||||||
|
GOOD_MAPPINGS = {'fake_physical_network': 'fake_bridge'}
|
||||||
|
GOOD_CONFIGS = {'interface_mappings': GOOD_MAPPINGS}
|
||||||
|
|
||||||
|
BAD_MAPPINGS = {'wrong_physical_network': 'wrong_bridge'}
|
||||||
|
BAD_CONFIGS = {'interface_mappings': BAD_MAPPINGS}
|
||||||
|
|
||||||
|
AGENTS = [{'alive': True,
|
||||||
|
'configurations': GOOD_CONFIGS}]
|
||||||
|
AGENTS_DEAD = [{'alive': False,
|
||||||
|
'configurations': GOOD_CONFIGS}]
|
||||||
|
AGENTS_BAD = [{'alive': False,
|
||||||
|
'configurations': GOOD_CONFIGS},
|
||||||
|
{'alive': True,
|
||||||
|
'configurations': BAD_CONFIGS}]
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(MlnxMechanismBaseTestCase, self).setUp()
|
||||||
|
self.driver = mech_mlnx.MlnxMechanismDriver()
|
||||||
|
self.driver.initialize()
|
||||||
|
|
||||||
|
|
||||||
|
class MlnxMechanismGenericTestCase(MlnxMechanismBaseTestCase,
|
||||||
|
base.AgentMechanismGenericTestCase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MlnxMechanismLocalTestCase(MlnxMechanismBaseTestCase,
|
||||||
|
base.AgentMechanismLocalTestCase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MlnxMechanismFlatTestCase(MlnxMechanismBaseTestCase,
|
||||||
|
base.AgentMechanismFlatTestCase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MlnxMechanismVlanTestCase(MlnxMechanismBaseTestCase,
|
||||||
|
base.AgentMechanismVlanTestCase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MlnxMechanismVnicTypeTestCase(MlnxMechanismBaseTestCase,
|
||||||
|
base.AgentMechanismVlanTestCase):
|
||||||
|
def _check_vif_type_for_vnic_type(self, vnic_type,
|
||||||
|
expected_vif_type):
|
||||||
|
context = base.FakePortContext(self.AGENT_TYPE,
|
||||||
|
self.AGENTS,
|
||||||
|
self.VLAN_SEGMENTS,
|
||||||
|
vnic_type)
|
||||||
|
self.driver.bind_port(context)
|
||||||
|
self.assertEqual(expected_vif_type, context._bound_vif_type)
|
||||||
|
|
||||||
|
def test_vnic_type_direct(self):
|
||||||
|
self._check_vif_type_for_vnic_type(portbindings.VNIC_DIRECT,
|
||||||
|
portbindings.VIF_TYPE_MLNX_HOSTDEV)
|
||||||
|
|
||||||
|
def test_vnic_type_macvtap(self):
|
||||||
|
self._check_vif_type_for_vnic_type(portbindings.VNIC_MACVTAP,
|
||||||
|
portbindings.VIF_TYPE_MLNX_DIRECT)
|
||||||
|
|
||||||
|
def test_vnic_type_normal(self):
|
||||||
|
self._check_vif_type_for_vnic_type(portbindings.VNIC_NORMAL,
|
||||||
|
self.VIF_TYPE)
|
@ -91,7 +91,7 @@ class TestEswitchAgent(base.BaseTestCase):
|
|||||||
|
|
||||||
def test_treat_devices_added_updates_known_port_admin_down(self):
|
def test_treat_devices_added_updates_known_port_admin_down(self):
|
||||||
details = {'port_id': '1234567890',
|
details = {'port_id': '1234567890',
|
||||||
'port_mac': '01:02:03:04:05:06',
|
'device': '01:02:03:04:05:06',
|
||||||
'network_id': '123456789',
|
'network_id': '123456789',
|
||||||
'network_type': 'vlan',
|
'network_type': 'vlan',
|
||||||
'physical_network': 'default',
|
'physical_network': 'default',
|
||||||
|
@ -170,6 +170,7 @@ neutron.ml2.mechanism_drivers =
|
|||||||
l2population = neutron.plugins.ml2.drivers.l2pop.mech_driver:L2populationMechanismDriver
|
l2population = neutron.plugins.ml2.drivers.l2pop.mech_driver:L2populationMechanismDriver
|
||||||
bigswitch = neutron.plugins.ml2.drivers.mech_bigswitch.driver:BigSwitchMechanismDriver
|
bigswitch = neutron.plugins.ml2.drivers.mech_bigswitch.driver:BigSwitchMechanismDriver
|
||||||
ofagent = neutron.plugins.ml2.drivers.mech_ofagent:OfagentMechanismDriver
|
ofagent = neutron.plugins.ml2.drivers.mech_ofagent:OfagentMechanismDriver
|
||||||
|
mlnx = neutron.plugins.ml2.drivers.mlnx.mech_mlnx:MlnxMechanismDriver
|
||||||
neutron.openstack.common.cache.backends =
|
neutron.openstack.common.cache.backends =
|
||||||
memory = neutron.openstack.common.cache._backends.memory:MemoryBackend
|
memory = neutron.openstack.common.cache._backends.memory:MemoryBackend
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user