lb: interface name hashing for too long vlan interface names

The linuxbridge agent creates vlan subinterfaces for each vlan
neutron network. The name for this vlan subinterface is
"<phys-interface>.<vlan-id>". Todays code crashes if the
physical interface name is too long. Therefore this hashing is
being introduced.

Change-Id: Ieb3c0a7282b28eed556236ead4993ab83a29a12f
Closes-Bug: #1495960
This commit is contained in:
Andreas Scheuring 2015-11-18 15:33:03 +01:00
parent 53c03f5ed3
commit 7ececa3a20
2 changed files with 51 additions and 6 deletions

View File

@ -40,6 +40,7 @@ from neutron.common import exceptions
from neutron.common import topics
from neutron.common import utils as n_utils
from neutron.plugins.common import constants as p_const
from neutron.plugins.common import utils as p_utils
from neutron.plugins.ml2.drivers.agent import _agent_manager_base as amb
from neutron.plugins.ml2.drivers.agent import _common_agent as ca
from neutron.plugins.ml2.drivers.agent import config as cagt_config # noqa
@ -55,6 +56,7 @@ LOG = logging.getLogger(__name__)
LB_AGENT_BINARY = 'neutron-linuxbridge-agent'
BRIDGE_NAME_PREFIX = "brq"
MAX_VLAN_POSTFIX_LEN = 5
VXLAN_INTERFACE_PREFIX = "vxlan-"
@ -141,8 +143,32 @@ class LinuxBridgeManager(amb.CommonAgentManagerBase):
if not vlan_id:
LOG.warning(_LW("Invalid VLAN ID, will lead to incorrect "
"subinterface name"))
subinterface_name = '%s.%s' % (physical_interface, vlan_id)
return subinterface_name
vlan_postfix = '.%s' % vlan_id
# For the vlan subinterface name prefix we use:
# * the physical_interface, if len(physical_interface) +
# len(vlan_postifx) <= 15 for backward compatibility reasons
# Example: physical_interface = eth0
# prefix = eth0.1
# prefix = eth0.1111
#
# * otherwise a unique hash per physical_interface to help debugging
# Example: physical_interface = long_interface
# prefix = longHASHED.1
# prefix = longHASHED.1111
#
# Remark: For some physical_interface values, the used prefix can be
# both, the physical_interface itself or a hash, depending
# on the vlan_postfix length.
# Example: physical_interface = mix_interface
# prefix = mix_interface.1 (backward compatible)
# prefix = mix_iHASHED.1111
if (len(physical_interface) + len(vlan_postfix) >
constants.DEVICE_NAME_MAX_LEN):
physical_interface = p_utils.get_interface_name(
physical_interface, max_len=(constants.DEVICE_NAME_MAX_LEN -
MAX_VLAN_POSTFIX_LEN))
return "%s%s" % (physical_interface, vlan_postfix)
@staticmethod
def get_tap_device_name(interface_id):

View File

@ -175,10 +175,29 @@ class TestLinuxBridgeManager(base.BaseTestCase):
nw_id = ""
self.assertEqual("brq", self.lbm.get_bridge_name(nw_id))
def test_get_subinterface_name(self):
self.assertEqual("eth0.0",
self.lbm.get_subinterface_name("eth0", "0"))
self.assertEqual("eth0.", self.lbm.get_subinterface_name("eth0", ""))
def test_get_subinterface_name_backwards_compatibility(self):
self.assertEqual("abcdefghijklm.1",
self.lbm.get_subinterface_name("abcdefghijklm", "1"))
self.assertEqual("abcdefghijkl.11",
self.lbm.get_subinterface_name("abcdefghijkl", "11"))
self.assertEqual("abcdefghij.1111",
self.lbm.get_subinterface_name("abcdefghij",
"1111"))
def test_get_subinterface_name_advanced(self):
"""Ensure the same hash is used for long interface names.
If the generated vlan device name would be too long, make sure that
everything before the '.' is equal. This might be helpful when
debugging problems.
"""
max_device_name = "abcdefghijklmno"
vlan_dev_name1 = self.lbm.get_subinterface_name(max_device_name, "1")
vlan_dev_name2 = self.lbm.get_subinterface_name(max_device_name,
"1111")
self.assertEqual(vlan_dev_name1.partition(".")[0],
vlan_dev_name2.partition(".")[0])
def test_get_tap_device_name(self):
if_id = "123456789101112"