Optimize get_bridge_for_tap_device
Currently get_bridge_for_tap_device[1] iterates over all neutron bridges and their interfaces. This change proposes to deduce interface bridge from: /sys/class/net/%(interface)s/brif/bridge which is a symlink to bridge interface path to improve performance. [1] neutron.plugins.ml2.drivers.linuxbridge.agent.linuxbridge_neutron_agent Closes-Bug: #1508789 Change-Id: Ia40cd81f47ff082a90d17f58514942ec50553241
This commit is contained in:
parent
0f471be1de
commit
75c881a748
|
@ -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):
|
||||
|
|
|
@ -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'))
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in New Issue