Merge "Linuxbridge support for L3 agent"

This commit is contained in:
Jenkins 2012-08-22 17:07:01 +00:00 committed by Gerrit Code Review
commit 9c915b0d7f
4 changed files with 32 additions and 17 deletions

View File

@ -291,7 +291,8 @@ class L3NATAgent(object):
self.driver.plug(None, ex_gw_port['id'], interface_name, self.driver.plug(None, ex_gw_port['id'], interface_name,
ex_gw_port['mac_address'], ex_gw_port['mac_address'],
bridge=self.conf.external_network_bridge, bridge=self.conf.external_network_bridge,
namespace=ri.ns_name()) namespace=ri.ns_name(),
prefix=EXTERNAL_DEV_PREFIX)
self.driver.init_l3(interface_name, [ex_gw_port['ip_cidr']], self.driver.init_l3(interface_name, [ex_gw_port['ip_cidr']],
namespace=ri.ns_name()) namespace=ri.ns_name())
@ -346,7 +347,8 @@ class L3NATAgent(object):
root_helper=self.conf.root_helper, root_helper=self.conf.root_helper,
namespace=ri.ns_name()): namespace=ri.ns_name()):
self.driver.plug(None, port_id, interface_name, mac_address, self.driver.plug(None, port_id, interface_name, mac_address,
namespace=ri.ns_name()) namespace=ri.ns_name(),
prefix=INTERNAL_DEV_PREFIX)
self.driver.init_l3(interface_name, [internal_cidr], self.driver.init_l3(interface_name, [internal_cidr],
namespace=ri.ns_name()) namespace=ri.ns_name())

View File

@ -86,7 +86,7 @@ class LinuxInterfaceDriver(object):
@abc.abstractmethod @abc.abstractmethod
def plug(self, network_id, port_id, device_name, mac_address, def plug(self, network_id, port_id, device_name, mac_address,
bridge=None, namespace=None): bridge=None, namespace=None, prefix=None):
"""Plug in the interface.""" """Plug in the interface."""
@abc.abstractmethod @abc.abstractmethod
@ -96,7 +96,7 @@ class LinuxInterfaceDriver(object):
class NullDriver(LinuxInterfaceDriver): class NullDriver(LinuxInterfaceDriver):
def plug(self, network_id, port_id, device_name, mac_address, def plug(self, network_id, port_id, device_name, mac_address,
bridge=None, namespace=None): bridge=None, namespace=None, prefix=None):
pass pass
def unplug(self, device_name, bridge=None, namespace=None): def unplug(self, device_name, bridge=None, namespace=None):
@ -107,7 +107,7 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
"""Driver for creating an internal interface on an OVS bridge.""" """Driver for creating an internal interface on an OVS bridge."""
def plug(self, network_id, port_id, device_name, mac_address, def plug(self, network_id, port_id, device_name, mac_address,
bridge=None, namespace=None): bridge=None, namespace=None, prefix=None):
"""Plug in the interface.""" """Plug in the interface."""
if not bridge: if not bridge:
bridge = self.conf.ovs_integration_bridge bridge = self.conf.ovs_integration_bridge
@ -156,17 +156,21 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
class BridgeInterfaceDriver(LinuxInterfaceDriver): class BridgeInterfaceDriver(LinuxInterfaceDriver):
"""Driver for creating bridge interfaces.""" """Driver for creating bridge interfaces."""
DEV_NAME_PREFIX = 'dhc' DEV_NAME_PREFIX = 'ns-'
def plug(self, network_id, port_id, device_name, mac_address, def plug(self, network_id, port_id, device_name, mac_address,
bridge=None, namespace=None): bridge=None, namespace=None, prefix=None):
"""Plugin the interface.""" """Plugin the interface."""
if not ip_lib.device_exists(device_name, if not ip_lib.device_exists(device_name,
self.conf.root_helper, self.conf.root_helper,
namespace=namespace): namespace=namespace):
ip = ip_lib.IPWrapper(self.conf.root_helper) ip = ip_lib.IPWrapper(self.conf.root_helper)
tap_name = device_name.replace(self.DEV_NAME_PREFIX, 'tap') # Enable agent to define the prefix
if prefix:
tap_name = device_name.replace(prefix, 'tap')
else:
tap_name = device_name.replace(self.DEV_NAME_PREFIX, 'tap')
root_veth, dhcp_veth = ip.add_veth(tap_name, device_name) root_veth, dhcp_veth = ip.add_veth(tap_name, device_name)
root_veth.link.set_address(mac_address) root_veth.link.set_address(mac_address)
@ -202,11 +206,12 @@ class RyuInterfaceDriver(OVSInterfaceDriver):
self.ryu_client = OFPClient(self.conf.ryu_api_host) self.ryu_client = OFPClient(self.conf.ryu_api_host)
def plug(self, network_id, port_id, device_name, mac_address, def plug(self, network_id, port_id, device_name, mac_address,
bridge=None, namespace=None): bridge=None, namespace=None, prefix=None):
"""Plug in the interface.""" """Plug in the interface."""
super(RyuInterfaceDriver, self).plug(network_id, port_id, device_name, super(RyuInterfaceDriver, self).plug(network_id, port_id, device_name,
mac_address, bridge=bridge, mac_address, bridge=bridge,
namespace=namespace) namespace=namespace,
prefix=prefix)
if not bridge: if not bridge:
bridge = self.conf.ovs_integration_bridge bridge = self.conf.ovs_integration_bridge
@ -254,9 +259,11 @@ class MetaInterfaceDriver(LinuxInterfaceDriver):
driver = self._get_driver_by_network_id(port.network_id) driver = self._get_driver_by_network_id(port.network_id)
return driver.get_device_name(port) return driver.get_device_name(port)
def plug(self, network_id, port_id, device_name, mac_address): def plug(self, network_id, port_id, device_name, mac_address,
bridge=None, namespace=None, prefix=None):
driver = self._get_driver_by_network_id(network_id) driver = self._get_driver_by_network_id(network_id)
return driver.plug(network_id, port_id, device_name, mac_address) return driver.plug(network_id, port_id, device_name, mac_address,
bridge=bridge, namespace=namespace, prefix=prefix)
def unplug(self, device_name): def unplug(self, device_name):
driver = self._get_driver_by_device_name(device_name) driver = self._get_driver_by_device_name(device_name)

View File

@ -23,6 +23,7 @@ from quantum.common import topics
from quantum.db import api as db_api from quantum.db import api as db_api
from quantum.db import db_base_plugin_v2 from quantum.db import db_base_plugin_v2
from quantum.db import dhcp_rpc_base from quantum.db import dhcp_rpc_base
from quantum.db import l3_db
from quantum.db import models_v2 from quantum.db import models_v2
from quantum.openstack.common import context from quantum.openstack.common import context
from quantum.openstack.common import cfg from quantum.openstack.common import cfg
@ -131,7 +132,8 @@ class AgentNotifierApi(proxy.RpcProxy):
topic=self.topic_port_update) topic=self.topic_port_update)
class LinuxBridgePluginV2(db_base_plugin_v2.QuantumDbPluginV2): class LinuxBridgePluginV2(db_base_plugin_v2.QuantumDbPluginV2,
l3_db.L3_NAT_db_mixin):
"""Implement the Quantum abstractions using Linux bridging. """Implement the Quantum abstractions using Linux bridging.
A new VLAN is created for each network. An agent is relied upon A new VLAN is created for each network. An agent is relied upon
@ -150,7 +152,7 @@ class LinuxBridgePluginV2(db_base_plugin_v2.QuantumDbPluginV2):
# is qualified by class # is qualified by class
__native_bulk_support = True __native_bulk_support = True
supported_extension_aliases = ["provider"] supported_extension_aliases = ["provider", "os-quantum-router"]
def __init__(self): def __init__(self):
db.initialize() db.initialize()
@ -355,3 +357,7 @@ class LinuxBridgePluginV2(db_base_plugin_v2.QuantumDbPluginV2):
binding.physical_network, binding.physical_network,
binding.vlan_id) binding.vlan_id)
return port return port
def delete_port(self, context, id):
self.disassociate_floatingips(context, id)
return super(LinuxBridgePluginV2, self).delete_port(context, id)

View File

@ -174,7 +174,7 @@ class TestBridgeInterfaceDriver(TestBase):
def test_get_device_name(self): def test_get_device_name(self):
br = interface.BridgeInterfaceDriver(self.conf) br = interface.BridgeInterfaceDriver(self.conf)
device_name = br.get_device_name(FakePort()) device_name = br.get_device_name(FakePort())
self.assertEqual('dhcabcdef01-12', device_name) self.assertEqual('ns-abcdef01-12', device_name)
def test_plug_no_ns(self): def test_plug_no_ns(self):
self._test_plug() self._test_plug()
@ -201,11 +201,11 @@ class TestBridgeInterfaceDriver(TestBase):
br = interface.BridgeInterfaceDriver(self.conf) br = interface.BridgeInterfaceDriver(self.conf)
br.plug('01234567-1234-1234-99', br.plug('01234567-1234-1234-99',
'port-1234', 'port-1234',
'dhc0', 'ns-0',
'aa:bb:cc:dd:ee:ff', 'aa:bb:cc:dd:ee:ff',
namespace=namespace) namespace=namespace)
ip_calls = [mock.call('sudo'), mock.call().add_veth('tap0', 'dhc0')] ip_calls = [mock.call('sudo'), mock.call().add_veth('tap0', 'ns-0')]
if namespace: if namespace:
ip_calls.extend([ ip_calls.extend([
mock.call().ensure_namespace('01234567-1234-1234-99'), mock.call().ensure_namespace('01234567-1234-1234-99'),