From 1b987be2b55558dcc276fcfc8af6e39f8b6bac16 Mon Sep 17 00:00:00 2001 From: Kevin Benton Date: Fri, 17 Mar 2017 14:56:36 -0700 Subject: [PATCH] Use vif_type='tap' for LinuxBridge for consistency This adjusts the Linux Bridge mechanism driver to return the 'tap' VIF type to Nova so the Linux Bridge agent is responsible for plugging all ports into bridges. This completely eliminates all of the work Nova was doing with regard to bridges so we now have one consistent path how ports (both compute and dhcp/l3) are connected into Linux Bridge networks. Both Nova and the DHCP/L3 agents will now just create a device and leave wiring to bridges to be completely the responsibility of the L2 agent. In order to preserve backwards compatibiliy with Ocata agents that won't touch compute ports, we only report back vif_type='tap' if the agent has a report_state value showing that it wires compute ports. This will also solve a longstanding bug (bug #1105488) that is preventing Nova instances from using custom bridge mappings since the agent will be guaranteed to be responsible for the connection to the bridge. Depends-On: I075595158d8f3b5a6811c4794aa7b91912940db5 Related-Bug: #1617447 Closes-Bug: #1673910 Closes-Bug: #1105488 Change-Id: I23c5faaeab69aede1fd038a36f4a0b8f928498ce --- .../agent/linuxbridge_neutron_agent.py | 28 ++++++------------- .../mech_driver/mech_linuxbridge.py | 9 +++++- .../agent/test_linuxbridge_neutron_agent.py | 9 ------ .../mech_driver/test_mech_linuxbridge.py | 15 ++++++++-- .../linuxbridge_cgroups-5943d85adace4de0.yaml | 10 +++++++ 5 files changed, 40 insertions(+), 31 deletions(-) create mode 100644 releasenotes/notes/linuxbridge_cgroups-5943d85adace4de0.yaml 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 f4906e2c945..796515029cd 100644 --- a/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py +++ b/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py @@ -489,25 +489,15 @@ class LinuxBridgeManager(amb.CommonAgentManagerBase): # inherit from the bridge its plugged into, which will be 1500 # at the time. See bug/1684326 for details. self._set_tap_mtu(tap_device_name, mtu) - # Avoid messing with plugging devices into a bridge that the agent - # does not own - if not device_owner.startswith(constants.DEVICE_OWNER_COMPUTE_PREFIX): - # Check if device needs to be added to bridge - if not bridge_lib.BridgeDevice.get_interface_bridge( - tap_device_name): - data = {'tap_device_name': tap_device_name, - 'bridge_name': bridge_name} - LOG.debug("Adding device %(tap_device_name)s to bridge " - "%(bridge_name)s", data) - if bridge_lib.BridgeDevice(bridge_name).addif(tap_device_name): - return False - else: + # Check if device needs to be added to bridge + if not bridge_lib.BridgeDevice.get_interface_bridge( + tap_device_name): data = {'tap_device_name': tap_device_name, - 'device_owner': device_owner, 'bridge_name': bridge_name} - LOG.debug("Skip adding device %(tap_device_name)s to " - "%(bridge_name)s. It is owned by %(device_owner)s and " - "thus added elsewhere.", data) + LOG.debug("Adding device %(tap_device_name)s to bridge " + "%(bridge_name)s", data) + if bridge_lib.BridgeDevice(bridge_name).addif(tap_device_name): + return False return True def _set_tap_mtu(self, tap_device_name, mtu): @@ -744,8 +734,8 @@ class LinuxBridgeManager(amb.CommonAgentManagerBase): def get_agent_configurations(self): configurations = {'bridge_mappings': self.bridge_mappings, - 'interface_mappings': self.interface_mappings - } + 'interface_mappings': self.interface_mappings, + 'wires_compute_ports': True} if self.vxlan_mode != lconst.VXLAN_NONE: configurations['tunneling_ip'] = self.local_ip configurations['tunnel_types'] = [p_const.TYPE_VXLAN] diff --git a/neutron/plugins/ml2/drivers/linuxbridge/mech_driver/mech_linuxbridge.py b/neutron/plugins/ml2/drivers/linuxbridge/mech_driver/mech_linuxbridge.py index d22eca5e6fb..ab46565122b 100644 --- a/neutron/plugins/ml2/drivers/linuxbridge/mech_driver/mech_linuxbridge.py +++ b/neutron/plugins/ml2/drivers/linuxbridge/mech_driver/mech_linuxbridge.py @@ -36,7 +36,7 @@ class LinuxbridgeMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase): sg_enabled = securitygroups_rpc.is_firewall_enabled() super(LinuxbridgeMechanismDriver, self).__init__( constants.AGENT_TYPE_LINUXBRIDGE, - portbindings.VIF_TYPE_BRIDGE, + 'tap', # const merge in I718f514e1673544114063af5e1a14ec29bf3274d {portbindings.CAP_PORT_FILTER: sg_enabled}) lb_qos_driver.register() @@ -50,6 +50,13 @@ class LinuxbridgeMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase): **agent['configurations'].get('bridge_mappings', {})) return mappings + def get_vif_type(self, context, agent, segment): + # TODO(kevinbenton): remove this function after we no longer support + # Ocata agents + if not agent['configurations'].get('wires_compute_ports'): + return portbindings.VIF_TYPE_BRIDGE + return self.vif_type + def check_vlan_transparency(self, context): """Linuxbridge driver vlan transparency support.""" return True 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 cfc257ee36b..d29f5fbdc8c 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 @@ -488,15 +488,6 @@ class TestLinuxBridgeManager(base.BaseTestCase): p_const.TYPE_VLAN, "physnet1", None, "tap1", "foo", None) - def test_add_tap_interface_owner_compute(self): - with mock.patch.object(ip_lib, "device_exists"): - with mock.patch.object(self.lbm, "ensure_local_bridge"): - self.assertTrue(self.lbm.add_tap_interface("123", - p_const.TYPE_LOCAL, - "physnet1", None, - "tap1", - "compute:1", None)) - def _test_add_tap_interface(self, dev_owner_prefix): with mock.patch.object(ip_lib, "device_exists") as de_fn: de_fn.return_value = False diff --git a/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/mech_driver/test_mech_linuxbridge.py b/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/mech_driver/test_mech_linuxbridge.py index 27746f65117..99cc401fcd4 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/mech_driver/test_mech_linuxbridge.py +++ b/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/mech_driver/test_mech_linuxbridge.py @@ -13,6 +13,8 @@ # License for the specific language governing permissions and limitations # under the License. +import copy + from neutron_lib.api.definitions import portbindings from neutron_lib import constants @@ -22,13 +24,14 @@ from neutron.tests.unit.plugins.ml2 import _test_mech_agent as base class LinuxbridgeMechanismBaseTestCase(base.AgentMechanismBaseTestCase): - VIF_TYPE = portbindings.VIF_TYPE_BRIDGE + VIF_TYPE = 'tap' CAP_PORT_FILTER = True AGENT_TYPE = constants.AGENT_TYPE_LINUXBRIDGE GOOD_MAPPINGS = {'fake_physical_network': 'fake_interface'} GOOD_TUNNEL_TYPES = ['gre', 'vxlan'] - GOOD_CONFIGS = {'interface_mappings': GOOD_MAPPINGS, + GOOD_CONFIGS = {'wires_compute_ports': True, + 'interface_mappings': GOOD_MAPPINGS, 'tunnel_types': GOOD_TUNNEL_TYPES} BAD_MAPPINGS = {'wrong_physical_network': 'wrong_interface'} @@ -78,3 +81,11 @@ class LinuxbridgeMechanismVlanTestCase(LinuxbridgeMechanismBaseTestCase, class LinuxbridgeMechanismGreTestCase(LinuxbridgeMechanismBaseTestCase, base.AgentMechanismGreTestCase): pass + + +class LegacyLinuxbridgeMechanismTestCase(LinuxbridgeMechanismBaseTestCase, + base.AgentMechanismVlanTestCase): + """An old agent doesn't wire compute ports so it needs VIF_TYPE_BRIDGE.""" + VIF_TYPE = portbindings.VIF_TYPE_BRIDGE + AGENTS = copy.deepcopy(LinuxbridgeMechanismBaseTestCase.AGENTS) + AGENTS[0]['configurations'].pop('wires_compute_ports') diff --git a/releasenotes/notes/linuxbridge_cgroups-5943d85adace4de0.yaml b/releasenotes/notes/linuxbridge_cgroups-5943d85adace4de0.yaml new file mode 100644 index 00000000000..2c27cb8e759 --- /dev/null +++ b/releasenotes/notes/linuxbridge_cgroups-5943d85adace4de0.yaml @@ -0,0 +1,10 @@ +--- +prelude: > + The Linux Bridge driver now informs Nova to use the 'tap' interface type + to wire interfaces. This requires '/dev/net/tun' to be added to the + 'cgroup_device_acl' in 'qemu.conf' before upgrading. +upgrade: + - | + The Linux Bridge driver now informs Nova to use the 'tap' interface type + to wire interfaces. This requires '/dev/net/tun' to be added to the + 'cgroup_device_acl' in 'qemu.conf' before upgrading.