diff --git a/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py b/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py index 76e4f1a721b..b2b67285f06 100644 --- a/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py +++ b/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py @@ -65,6 +65,7 @@ BRIDGE_FS = "/sys/class/net/" BRIDGE_INTERFACE_FS = BRIDGE_FS + "%(bridge)s/brif/%(interface)s" BRIDGE_INTERFACES_FS = BRIDGE_FS + "%s/brif/" BRIDGE_PORT_FS_FOR_DEVICE = BRIDGE_FS + "%s/brport" +BRIDGE_PATH_FOR_DEVICE = BRIDGE_PORT_FS_FOR_DEVICE + '/bridge' VXLAN_INTERFACE_PREFIX = "vxlan-" @@ -201,12 +202,15 @@ class LinuxBridgeManager(object): return 0 def get_bridge_for_tap_device(self, tap_device_name): - bridges = self.get_all_neutron_bridges() - for bridge in bridges: - interfaces = self.get_interfaces_on_bridge(bridge) - if tap_device_name in interfaces: + try: + path = os.readlink(BRIDGE_PATH_FOR_DEVICE % tap_device_name) + except OSError: + pass + else: + bridge = path.rpartition('/')[-1] + if (bridge.startswith(BRIDGE_NAME_PREFIX) + or bridge in self.bridge_mappings.values()): return bridge - return None def is_device_on_bridge(self, device_name): diff --git a/neutron/tests/functional/agent/test_l2_lb_agent.py b/neutron/tests/functional/agent/test_l2_lb_agent.py index ebabc49051e..13939e02277 100644 --- a/neutron/tests/functional/agent/test_l2_lb_agent.py +++ b/neutron/tests/functional/agent/test_l2_lb_agent.py @@ -76,3 +76,15 @@ class LinuxBridgeAgentTests(test_ip_lib.IpLibTestFramework): self.assertFalse( lba.LinuxBridgeManager.interface_exists_on_bridge( port_fixture.bridge.name, port_fixture.port.name)) + + def test_get_bridge_for_tap_device(self): + port_fixture = self.create_bridge_port_fixture() + mappings = {'physnet1': port_fixture.bridge.name} + lbm = lba.LinuxBridgeManager(mappings, {}) + self.assertEqual( + port_fixture.bridge.name, + lbm.get_bridge_for_tap_device(port_fixture.br_port.name)) + + def test_get_no_bridge_for_tap_device(self): + lbm = lba.LinuxBridgeManager({}, {}) + self.assertIsNone(lbm.get_bridge_for_tap_device('fake')) diff --git a/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/agent/test_linuxbridge_neutron_agent.py b/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/agent/test_linuxbridge_neutron_agent.py index 3c5ee4131dc..a789190c108 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/agent/test_linuxbridge_neutron_agent.py +++ b/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/agent/test_linuxbridge_neutron_agent.py @@ -32,7 +32,8 @@ from neutron.tests import base LOCAL_IP = '192.168.0.33' DEVICE_1 = 'tapabcdef01-12' -BRIDGE_MAPPINGS = {'physnet0': 'br-eth2'} +BRIDGE_MAPPING_VALUE = 'br-eth2' +BRIDGE_MAPPINGS = {'physnet0': BRIDGE_MAPPING_VALUE} INTERFACE_MAPPINGS = {'physnet1': 'eth1'} FAKE_DEFAULT_DEV = mock.Mock() FAKE_DEFAULT_DEV.name = 'eth1' @@ -492,14 +493,21 @@ class TestLinuxBridgeManager(base.BaseTestCase): self.assertEqual(self.lbm.get_tap_devices_count('br0'), 0) def test_get_bridge_for_tap_device(self): - with mock.patch.object(self.lbm, - "get_all_neutron_bridges") as get_all_qbr_fn,\ - mock.patch.object(self.lbm, - "get_interfaces_on_bridge") as get_if_fn: - get_all_qbr_fn.return_value = ["br-int", "br-ex"] - get_if_fn.return_value = ["tap1", "tap2", "tap3"] + + with mock.patch.object(os, 'readlink') as readlink: + readlink.return_value = ( + 'blah/%s-fake' % linuxbridge_neutron_agent.BRIDGE_NAME_PREFIX) self.assertEqual(self.lbm.get_bridge_for_tap_device("tap1"), - "br-int") + "brq-fake") + + readlink.return_value = 'blah/%s' % BRIDGE_MAPPING_VALUE + self.assertEqual(self.lbm.get_bridge_for_tap_device("tap2"), + BRIDGE_MAPPING_VALUE) + + readlink.return_value = 'blah/notneutronbridge' + self.assertIsNone(self.lbm.get_bridge_for_tap_device("tap3")) + + readlink.side_effect = OSError() self.assertIsNone(self.lbm.get_bridge_for_tap_device("tap4")) def test_is_device_on_bridge(self):