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
This commit is contained in:
parent
196e685278
commit
1b987be2b5
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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.
|
Loading…
Reference in New Issue