tunnels on the tunnel bridge.
For each virtual network realized as a VLAN or flat network, a
- veth is used to connect the local VLAN on the integration bridge
- with the physical network bridge, with flow rules adding,
- modifying, or stripping VLAN tags as necessary.
+ veth or a pair of patch ports is used to connect the local VLAN on
+ the integration bridge with the physical network bridge, with flow
+ rules adding, modifying, or stripping VLAN tags as necessary.
'''
# history
minimize_polling=False,
ovsdb_monitor_respawn_interval=(
constants.DEFAULT_OVSDBMON_RESPAWN),
- arp_responder=False):
+ arp_responder=False,
+ use_veth_interconnection=False):
'''Constructor.
:param integ_br: name of the integration bridge.
the ovsdb monitor.
:param arp_responder: Optional, enable local ARP responder if it is
supported.
+ :param use_veth_interconnection: use veths instead of patch ports to
+ interconnect the integration bridge to physical bridges.
'''
super(OVSNeutronAgent, self).__init__()
+ self.use_veth_interconnection = use_veth_interconnection
self.veth_mtu = veth_mtu
self.root_helper = root_helper
self.available_local_vlans = set(moves.xrange(q_const.MIN_VLAN_TAG,
priority=0,
actions="drop")
- def get_veth_name(self, prefix, name):
- """Construct a veth name based on the prefix and name that does not
- exceed the maximum length allowed for a linux device. Longer names
- are hashed to help ensure uniqueness.
+ def get_peer_name(self, prefix, name):
+ """Construct a peer name based on the prefix and name.
+
+ The peer name can not exceed the maximum length allowed for a linux
+ device. Longer names are hashed to help ensure uniqueness.
"""
if len(prefix + name) <= q_const.DEVICE_NAME_MAX_LEN:
return prefix + name
br.add_flow(priority=1, actions="normal")
self.phys_brs[physical_network] = br
- # create veth to patch physical bridge with integration bridge
- int_veth_name = self.get_veth_name(
- constants.VETH_INTEGRATION_PREFIX, bridge)
- self.int_br.delete_port(int_veth_name)
- phys_veth_name = self.get_veth_name(
- constants.VETH_PHYSICAL_PREFIX, bridge)
- br.delete_port(phys_veth_name)
- if ip_lib.device_exists(int_veth_name, self.root_helper):
- ip_lib.IPDevice(int_veth_name, self.root_helper).link.delete()
- # Give udev a chance to process its rules here, to avoid
- # race conditions between commands launched by udev rules
- # and the subsequent call to ip_wrapper.add_veth
- utils.execute(['/sbin/udevadm', 'settle', '--timeout=10'])
- int_veth, phys_veth = ip_wrapper.add_veth(int_veth_name,
- phys_veth_name)
- self.int_ofports[physical_network] = self.int_br.add_port(int_veth)
- self.phys_ofports[physical_network] = br.add_port(phys_veth)
-
- # block all untranslated traffic over veth between bridges
- self.int_br.add_flow(priority=2,
- in_port=self.int_ofports[physical_network],
+ # interconnect physical and integration bridges using veth/patchs
+ int_if_name = self.get_peer_name(constants.PEER_INTEGRATION_PREFIX,
+ bridge)
+ phys_if_name = self.get_peer_name(constants.PEER_PHYSICAL_PREFIX,
+ bridge)
+ self.int_br.delete_port(int_if_name)
+ br.delete_port(phys_if_name)
+ if self.use_veth_interconnection:
+ if ip_lib.device_exists(int_if_name, self.root_helper):
+ ip_lib.IPDevice(int_if_name,
+ self.root_helper).link.delete()
+ # Give udev a chance to process its rules here, to avoid
+ # race conditions between commands launched by udev rules
+ # and the subsequent call to ip_wrapper.add_veth
+ utils.execute(['/sbin/udevadm', 'settle', '--timeout=10'])
+ int_veth, phys_veth = ip_wrapper.add_veth(int_if_name,
+ phys_if_name)
+ int_ofport = self.int_br.add_port(int_veth)
+ phys_ofport = br.add_port(phys_veth)
+ else:
+ # Create patch ports without associating them in order to block
+ # untranslated traffic before association
+ int_ofport = self.int_br.add_patch_port(
+ int_if_name, constants.NONEXISTENT_PEER)
+ phys_ofport = br.add_patch_port(
+ phys_if_name, constants.NONEXISTENT_PEER)
+
+ self.int_ofports[physical_network] = int_ofport
+ self.phys_ofports[physical_network] = phys_ofport
+
+ # block all untranslated traffic between bridges
+ self.int_br.add_flow(priority=2, in_port=int_ofport,
actions="drop")
- br.add_flow(priority=2,
- in_port=self.phys_ofports[physical_network],
- actions="drop")
-
- # enable veth to pass traffic
- int_veth.link.set_up()
- phys_veth.link.set_up()
-
- if self.veth_mtu:
- # set up mtu size for veth interfaces
- int_veth.link.set_mtu(self.veth_mtu)
- phys_veth.link.set_mtu(self.veth_mtu)
+ br.add_flow(priority=2, in_port=phys_ofport, actions="drop")
+
+ if self.use_veth_interconnection:
+ # enable veth to pass traffic
+ int_veth.link.set_up()
+ phys_veth.link.set_up()
+ if self.veth_mtu:
+ # set up mtu size for veth interfaces
+ int_veth.link.set_mtu(self.veth_mtu)
+ phys_veth.link.set_mtu(self.veth_mtu)
+ else:
+ # associate patch ports to pass traffic
+ self.int_br.set_db_attribute('Interface', int_if_name,
+ 'options:peer', phys_if_name)
+ br.set_db_attribute('Interface', phys_if_name,
+ 'options:peer', int_if_name)
def scan_ports(self, registered_ports, updated_ports=None):
cur_ports = self.int_br.get_vif_port_set()
veth_mtu=config.AGENT.veth_mtu,
l2_population=config.AGENT.l2_population,
arp_responder=config.AGENT.arp_responder,
+ use_veth_interconnection=config.OVS.use_veth_interconnection,
)
# If enable_tunneling is TRUE, set tunnel_type to default to GRE
self.assertEqual(set(['123']), self.agent.updated_ports)
def test_setup_physical_bridges(self):
+ with contextlib.nested(
+ mock.patch.object(ip_lib, "device_exists"),
+ mock.patch.object(sys, "exit"),
+ mock.patch.object(utils, "execute"),
+ mock.patch.object(ovs_lib.OVSBridge, "remove_all_flows"),
+ mock.patch.object(ovs_lib.OVSBridge, "add_flow"),
+ mock.patch.object(ovs_lib.OVSBridge, "add_patch_port"),
+ mock.patch.object(ovs_lib.OVSBridge, "delete_port"),
+ mock.patch.object(ovs_lib.OVSBridge, "set_db_attribute"),
+ mock.patch.object(self.agent.int_br, "add_flow"),
+ mock.patch.object(self.agent.int_br, "add_patch_port"),
+ mock.patch.object(self.agent.int_br, "delete_port"),
+ mock.patch.object(self.agent.int_br, "set_db_attribute"),
+ ) as (devex_fn, sysexit_fn, utilsexec_fn, remflows_fn, ovs_add_flow_fn,
+ ovs_addpatch_port_fn, ovs_delport_fn, ovs_set_attr_fn,
+ br_add_flow_fn, br_addpatch_port_fn, br_delport_fn,
+ br_set_attr_fn):
+ devex_fn.return_value = True
+ parent = mock.MagicMock()
+ parent.attach_mock(ovs_addpatch_port_fn, 'phy_add_patch_port')
+ parent.attach_mock(ovs_add_flow_fn, 'phy_add_flow')
+ parent.attach_mock(ovs_set_attr_fn, 'phy_set_attr')
+ parent.attach_mock(br_addpatch_port_fn, 'int_add_patch_port')
+ parent.attach_mock(br_add_flow_fn, 'int_add_flow')
+ parent.attach_mock(br_set_attr_fn, 'int_set_attr')
+
+ ovs_addpatch_port_fn.return_value = "phy_ofport"
+ br_addpatch_port_fn.return_value = "int_ofport"
+ self.agent.setup_physical_bridges({"physnet1": "br-eth"})
+ expected_calls = [
+ mock.call.phy_add_flow(priority=1, actions='normal'),
+ mock.call.int_add_patch_port('int-br-eth',
+ constants.NONEXISTENT_PEER),
+ mock.call.phy_add_patch_port('phy-br-eth',
+ constants.NONEXISTENT_PEER),
+ mock.call.int_add_flow(priority=2, in_port='int_ofport',
+ actions='drop'),
+ mock.call.phy_add_flow(priority=2, in_port='phy_ofport',
+ actions='drop'),
+ mock.call.int_set_attr('Interface', 'int-br-eth',
+ 'options:peer', 'phy-br-eth'),
+ mock.call.phy_set_attr('Interface', 'phy-br-eth',
+ 'options:peer', 'int-br-eth'),
+
+ ]
+ parent.assert_has_calls(expected_calls)
+ self.assertEqual(self.agent.int_ofports["physnet1"],
+ "int_ofport")
+ self.assertEqual(self.agent.phys_ofports["physnet1"],
+ "phy_ofport")
+
+ def test_setup_physical_bridges_using_veth_interconnection(self):
+ self.agent.use_veth_interconnection = True
with contextlib.nested(
mock.patch.object(ip_lib, "device_exists"),
mock.patch.object(sys, "exit"),
self.assertEqual(self.agent.phys_ofports["physnet1"],
"int_ofport")
- def test_get_veth_name(self):
+ def test_get_peer_name(self):
bridge1 = "A_REALLY_LONG_BRIDGE_NAME1"
bridge2 = "A_REALLY_LONG_BRIDGE_NAME2"
- self.assertEqual(len(self.agent.get_veth_name('int-', bridge1)),
+ self.agent.use_veth_interconnection = True
+ self.assertEqual(len(self.agent.get_peer_name('int-', bridge1)),
n_const.DEVICE_NAME_MAX_LEN)
- self.assertEqual(len(self.agent.get_veth_name('int-', bridge2)),
+ self.assertEqual(len(self.agent.get_peer_name('int-', bridge2)),
n_const.DEVICE_NAME_MAX_LEN)
- self.assertNotEqual(self.agent.get_veth_name('int-', bridge1),
- self.agent.get_veth_name('int-', bridge2))
+ self.assertNotEqual(self.agent.get_peer_name('int-', bridge1),
+ self.agent.get_peer_name('int-', bridge2))
def test_port_unbound(self):
with mock.patch.object(self.agent, "reclaim_local_vlan") as reclvl_fn:
class TunnelTest(base.BaseTestCase):
+ USE_VETH_INTERCONNECTION = False
+ VETH_MTU = None
def setUp(self):
super(TunnelTest, self).setUp()
self.NET_MAPPING = {'net1': self.MAP_TUN_BRIDGE}
self.INT_OFPORT = 11111
self.TUN_OFPORT = 22222
- self.MAP_TUN_OFPORT = 33333
- self.VETH_MTU = None
+ self.MAP_TUN_INT_OFPORT = 33333
+ self.MAP_TUN_PHY_OFPORT = 44444
+
self.inta = mock.Mock()
self.intb = mock.Mock()
self.TUN_BRIDGE: mock.Mock(),
self.MAP_TUN_BRIDGE: mock.Mock(),
}
+ self.ovs_int_ofports = {
+ 'patch-tun': self.TUN_OFPORT,
+ 'int-%s' % self.MAP_TUN_BRIDGE: self.MAP_TUN_INT_OFPORT
+ }
self.mock_bridge = mock.patch.object(ovs_lib, 'OVSBridge').start()
self.mock_bridge.side_effect = (lambda br_name, root_helper:
self.ovs_bridges[br_name])
+
+ self.mock_int_bridge = self.ovs_bridges[self.INT_BRIDGE]
+ self.mock_int_bridge.add_port.return_value = self.MAP_TUN_INT_OFPORT
+ self.mock_int_bridge.add_patch_port.side_effect = (
+ lambda tap, peer: self.ovs_int_ofports[tap])
+
+ self.mock_map_tun_bridge = self.ovs_bridges[self.MAP_TUN_BRIDGE]
+ self.mock_map_tun_bridge.br_name = self.MAP_TUN_BRIDGE
+ self.mock_map_tun_bridge.add_port.return_value = (
+ self.MAP_TUN_PHY_OFPORT)
+ self.mock_map_tun_bridge.add_patch_port.return_value = (
+ self.MAP_TUN_PHY_OFPORT)
+
+ self.mock_tun_bridge = self.ovs_bridges[self.TUN_BRIDGE]
+ self.mock_tun_bridge.add_port.return_value = self.INT_OFPORT
+ self.mock_tun_bridge.add_patch_port.return_value = self.INT_OFPORT
+
+ self.device_exists = mock.patch.object(ip_lib, 'device_exists').start()
+ self.device_exists.return_value = True
+
+ self.ipdevice = mock.patch.object(ip_lib, 'IPDevice').start()
+
+ self.ipwrapper = mock.patch.object(ip_lib, 'IPWrapper').start()
+ add_veth = self.ipwrapper.return_value.add_veth
+ add_veth.return_value = [self.inta, self.intb]
+
+ self.get_bridges = mock.patch.object(ovs_lib, 'get_bridges').start()
+ self.get_bridges.return_value = [self.INT_BRIDGE,
+ self.TUN_BRIDGE,
+ self.MAP_TUN_BRIDGE]
+
+ self.execute = mock.patch('neutron.agent.linux.utils.execute').start()
+
+ self._define_expected_calls()
+
+ def _define_expected_calls(self):
self.mock_bridge_expected = [
mock.call(self.INT_BRIDGE, 'sudo'),
mock.call(self.MAP_TUN_BRIDGE, 'sudo'),
actions='drop'),
]
- self.mock_map_tun_bridge = self.ovs_bridges[self.MAP_TUN_BRIDGE]
- self.mock_map_tun_bridge.br_name = self.MAP_TUN_BRIDGE
- self.mock_map_tun_bridge.add_port.return_value = None
self.mock_map_tun_bridge_expected = [
mock.call.remove_all_flows(),
mock.call.add_flow(priority=1, actions='normal'),
mock.call.delete_port('phy-%s' % self.MAP_TUN_BRIDGE),
- mock.call.add_port(self.intb),
+ mock.call.add_patch_port('phy-%s' % self.MAP_TUN_BRIDGE,
+ constants.NONEXISTENT_PEER),
]
- self.mock_int_bridge.add_port.return_value = None
self.mock_int_bridge_expected += [
mock.call.delete_port('int-%s' % self.MAP_TUN_BRIDGE),
- mock.call.add_port(self.inta)
+ mock.call.add_patch_port('int-%s' % self.MAP_TUN_BRIDGE,
+ constants.NONEXISTENT_PEER),
]
- self.inta_expected = [mock.call.link.set_up()]
- self.intb_expected = [mock.call.link.set_up()]
self.mock_int_bridge_expected += [
- mock.call.add_flow(priority=2, in_port=None, actions='drop')
+ mock.call.add_flow(priority=2,
+ in_port=self.MAP_TUN_INT_OFPORT,
+ actions='drop'),
+ mock.call.set_db_attribute(
+ 'Interface', 'int-%s' % self.MAP_TUN_BRIDGE,
+ 'options:peer', 'phy-%s' % self.MAP_TUN_BRIDGE),
]
self.mock_map_tun_bridge_expected += [
- mock.call.add_flow(priority=2, in_port=None, actions='drop')
+ mock.call.add_flow(priority=2,
+ in_port=self.MAP_TUN_PHY_OFPORT,
+ actions='drop'),
+ mock.call.set_db_attribute(
+ 'Interface', 'phy-%s' % self.MAP_TUN_BRIDGE,
+ 'options:peer', 'int-%s' % self.MAP_TUN_BRIDGE),
]
- self.mock_tun_bridge = self.ovs_bridges[self.TUN_BRIDGE]
self.mock_tun_bridge_expected = [
mock.call.reset_bridge(),
mock.call.add_patch_port('patch-int', 'patch-tun'),
self.mock_int_bridge_expected += [
mock.call.add_patch_port('patch-tun', 'patch-int')
]
- self.mock_int_bridge.add_patch_port.return_value = self.TUN_OFPORT
- self.mock_tun_bridge.add_patch_port.return_value = self.INT_OFPORT
self.mock_tun_bridge_expected += [
mock.call.remove_all_flows(),
actions="drop")
]
- self.device_exists = mock.patch.object(ip_lib, 'device_exists').start()
- self.device_exists.return_value = True
self.device_exists_expected = [
mock.call(self.MAP_TUN_BRIDGE, 'sudo'),
- mock.call('int-%s' % self.MAP_TUN_BRIDGE, 'sudo'),
]
- self.ipdevice = mock.patch.object(ip_lib, 'IPDevice').start()
- self.ipdevice_expected = [
- mock.call('int-%s' % self.MAP_TUN_BRIDGE, 'sudo'),
- mock.call().link.delete()
- ]
- self.ipwrapper = mock.patch.object(ip_lib, 'IPWrapper').start()
- add_veth = self.ipwrapper.return_value.add_veth
- add_veth.return_value = [self.inta, self.intb]
- self.ipwrapper_expected = [
- mock.call('sudo'),
- mock.call().add_veth('int-%s' % self.MAP_TUN_BRIDGE,
- 'phy-%s' % self.MAP_TUN_BRIDGE)
- ]
+ self.ipdevice_expected = []
+ self.ipwrapper_expected = [mock.call('sudo')]
- self.get_bridges = mock.patch.object(ovs_lib, 'get_bridges').start()
- self.get_bridges.return_value = [self.INT_BRIDGE,
- self.TUN_BRIDGE,
- self.MAP_TUN_BRIDGE]
- self.get_bridges_expected = [
- mock.call('sudo')
- ]
- self.execute = mock.patch('neutron.agent.linux.utils.execute').start()
- self.execute_expected = [mock.call(['/sbin/udevadm', 'settle',
- '--timeout=10'])]
+ self.get_bridges_expected = [mock.call('sudo')]
+
+ self.inta_expected = []
+ self.intb_expected = []
+ self.execute_expected = []
+
+ def _build_agent(self, **kwargs):
+ kwargs.setdefault('integ_br', self.INT_BRIDGE)
+ kwargs.setdefault('tun_br', self.TUN_BRIDGE)
+ kwargs.setdefault('local_ip', '10.0.0.1')
+ kwargs.setdefault('bridge_mappings', self.NET_MAPPING)
+ kwargs.setdefault('root_helper', 'sudo')
+ kwargs.setdefault('polling_interval', 2)
+ kwargs.setdefault('tunnel_types', ['gre'])
+ kwargs.setdefault('veth_mtu', self.VETH_MTU)
+ kwargs.setdefault('use_veth_interconnection',
+ self.USE_VETH_INTERCONNECTION)
+ return ovs_neutron_agent.OVSNeutronAgent(**kwargs)
def _verify_mock_call(self, mock_obj, expected):
mock_obj.assert_has_calls(expected)
self._verify_mock_call(self.execute, self.execute_expected)
def test_construct(self):
- agent = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
- self.TUN_BRIDGE,
- '10.0.0.1', self.NET_MAPPING,
- 'sudo', 2, ['gre'],
- self.VETH_MTU)
+ agent = self._build_agent()
self.assertEqual(agent.agent_id, 'ovs-agent-%s' % cfg.CONF.host)
self._verify_mock_calls()
# ML2 l2 population mechanism driver.
# The next two tests use l2_pop flag to test ARP responder
def test_construct_with_arp_responder(self):
- ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
- self.TUN_BRIDGE,
- '10.0.0.1', self.NET_MAPPING,
- 'sudo', 2, ['gre'],
- self.VETH_MTU, l2_population=True,
- arp_responder=True)
+ self._build_agent(l2_population=True, arp_responder=True)
self.mock_tun_bridge_expected.insert(
5, mock.call.add_flow(table=constants.PATCH_LV_TO_TUN,
priority=1,
self._verify_mock_calls()
def test_construct_without_arp_responder(self):
- ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
- self.TUN_BRIDGE,
- '10.0.0.1', self.NET_MAPPING,
- 'sudo', 2, ['gre'],
- self.VETH_MTU, l2_population=False,
- arp_responder=True)
+ self._build_agent(l2_population=False, arp_responder=True)
self._verify_mock_calls()
def test_construct_vxlan(self):
- ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
- self.TUN_BRIDGE,
- '10.0.0.1',
- self.NET_MAPPING,
- 'sudo', 2, ['vxlan'],
- self.VETH_MTU)
+ self._build_agent(tunnel_types=['vxlan'])
self._verify_mock_calls()
def test_provision_local_vlan(self):
(LV_ID, constants.LEARN_FROM_TUN)),
]
- a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
- self.TUN_BRIDGE,
- '10.0.0.1', self.NET_MAPPING,
- 'sudo', 2, ['gre'],
- self.VETH_MTU)
+ a = self._build_agent()
a.available_local_vlans = set([LV_ID])
a.tun_br_ofports = TUN_OFPORTS
a.provision_local_vlan(NET_UUID, p_const.TYPE_GRE, None, LS_ID)
def test_provision_local_vlan_flat(self):
action_string = 'strip_vlan,normal'
self.mock_map_tun_bridge_expected.append(
- mock.call.add_flow(priority=4, in_port=self.MAP_TUN_OFPORT,
+ mock.call.add_flow(priority=4, in_port=self.MAP_TUN_PHY_OFPORT,
dl_vlan=LV_ID, actions=action_string))
action_string = 'mod_vlan_vid:%s,normal' % LV_ID
mock.call.add_flow(priority=3, in_port=self.INT_OFPORT,
dl_vlan=65535, actions=action_string))
- a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
- self.TUN_BRIDGE,
- '10.0.0.1', self.NET_MAPPING,
- 'sudo', 2, ['gre'],
- self.VETH_MTU)
+ a = self._build_agent()
a.available_local_vlans = set([LV_ID])
a.phys_brs['net1'] = self.mock_map_tun_bridge
- a.phys_ofports['net1'] = self.MAP_TUN_OFPORT
+ a.phys_ofports['net1'] = self.MAP_TUN_PHY_OFPORT
a.int_ofports['net1'] = self.INT_OFPORT
a.provision_local_vlan(NET_UUID, p_const.TYPE_FLAT, 'net1', LS_ID)
self._verify_mock_calls()
def test_provision_local_vlan_flat_fail(self):
- a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
- self.TUN_BRIDGE,
- '10.0.0.1', self.NET_MAPPING,
- 'sudo', 2, ['gre'],
- self.VETH_MTU)
+ a = self._build_agent()
a.provision_local_vlan(NET_UUID, p_const.TYPE_FLAT, 'net2', LS_ID)
self._verify_mock_calls()
def test_provision_local_vlan_vlan(self):
action_string = 'mod_vlan_vid:%s,normal' % LS_ID
self.mock_map_tun_bridge_expected.append(
- mock.call.add_flow(priority=4, in_port=self.MAP_TUN_OFPORT,
+ mock.call.add_flow(priority=4, in_port=self.MAP_TUN_PHY_OFPORT,
dl_vlan=LV_ID, actions=action_string))
action_string = 'mod_vlan_vid:%s,normal' % LS_ID
mock.call.add_flow(priority=3, in_port=self.INT_OFPORT,
dl_vlan=LV_ID, actions=action_string))
- a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
- self.TUN_BRIDGE,
- '10.0.0.1', self.NET_MAPPING,
- 'sudo', 2, ['gre'],
- self.VETH_MTU)
+ a = self._build_agent()
a.available_local_vlans = set([LV_ID])
a.phys_brs['net1'] = self.mock_map_tun_bridge
- a.phys_ofports['net1'] = self.MAP_TUN_OFPORT
+ a.phys_ofports['net1'] = self.MAP_TUN_PHY_OFPORT
a.int_ofports['net1'] = self.INT_OFPORT
a.provision_local_vlan(NET_UUID, p_const.TYPE_VLAN, 'net1', LS_ID)
self._verify_mock_calls()
def test_provision_local_vlan_vlan_fail(self):
- a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
- self.TUN_BRIDGE,
- '10.0.0.1', self.NET_MAPPING,
- 'sudo', 2, ['gre'],
- self.VETH_MTU)
+ a = self._build_agent()
a.provision_local_vlan(NET_UUID, p_const.TYPE_VLAN, 'net2', LS_ID)
self._verify_mock_calls()
mock.call.delete_flows(dl_vlan=LVM.vlan)
]
- a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
- self.TUN_BRIDGE,
- '10.0.0.1', self.NET_MAPPING,
- 'sudo', 2, ['gre'],
- self.VETH_MTU)
+ a = self._build_agent()
a.available_local_vlans = set()
a.local_vlan_map[NET_UUID] = LVM
a.reclaim_local_vlan(NET_UUID)
def test_reclaim_local_vlan_flat(self):
self.mock_map_tun_bridge_expected.append(
mock.call.delete_flows(
- in_port=self.MAP_TUN_OFPORT, dl_vlan=LVM_FLAT.vlan))
+ in_port=self.MAP_TUN_PHY_OFPORT, dl_vlan=LVM_FLAT.vlan))
self.mock_int_bridge_expected.append(
mock.call.delete_flows(
dl_vlan=65535, in_port=self.INT_OFPORT))
- a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
- self.TUN_BRIDGE,
- '10.0.0.1', self.NET_MAPPING,
- 'sudo', 2, ['gre'],
- self.VETH_MTU)
+ a = self._build_agent()
a.phys_brs['net1'] = self.mock_map_tun_bridge
- a.phys_ofports['net1'] = self.MAP_TUN_OFPORT
+ a.phys_ofports['net1'] = self.MAP_TUN_PHY_OFPORT
a.int_ofports['net1'] = self.INT_OFPORT
a.available_local_vlans = set()
def test_reclaim_local_vlan_vlan(self):
self.mock_map_tun_bridge_expected.append(
mock.call.delete_flows(
- in_port=self.MAP_TUN_OFPORT, dl_vlan=LVM_VLAN.vlan))
+ in_port=self.MAP_TUN_PHY_OFPORT, dl_vlan=LVM_VLAN.vlan))
self.mock_int_bridge_expected.append(
mock.call.delete_flows(
dl_vlan=LV_ID, in_port=self.INT_OFPORT))
- a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
- self.TUN_BRIDGE,
- '10.0.0.1', self.NET_MAPPING,
- 'sudo', 2, ['gre'],
- self.VETH_MTU)
+ a = self._build_agent()
a.phys_brs['net1'] = self.mock_map_tun_bridge
- a.phys_ofports['net1'] = self.MAP_TUN_OFPORT
+ a.phys_ofports['net1'] = self.MAP_TUN_PHY_OFPORT
a.int_ofports['net1'] = self.INT_OFPORT
a.available_local_vlans = set()
mock.call.delete_flows(in_port=VIF_PORT.ofport)
]
- a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
- self.TUN_BRIDGE,
- '10.0.0.1', self.NET_MAPPING,
- 'sudo', 2, ['gre'],
- self.VETH_MTU)
+ a = self._build_agent()
a.local_vlan_map[NET_UUID] = LVM
a.port_bound(VIF_PORT, NET_UUID, 'gre', None, LS_ID, False)
self._verify_mock_calls()
def test_port_unbound(self):
with mock.patch.object(ovs_neutron_agent.OVSNeutronAgent,
'reclaim_local_vlan') as reclaim_local_vlan:
- a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
- self.TUN_BRIDGE,
- '10.0.0.1', self.NET_MAPPING,
- 'sudo', 2, ['gre'],
- self.VETH_MTU)
+ a = self._build_agent()
a.local_vlan_map[NET_UUID] = LVM
a.port_unbound(VIF_ID, NET_UUID)
actions='drop')
]
- a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
- self.TUN_BRIDGE,
- '10.0.0.1', self.NET_MAPPING,
- 'sudo', 2, ['gre'],
- self.VETH_MTU)
+ a = self._build_agent()
a.available_local_vlans = set([LV_ID])
a.local_vlan_map[NET_UUID] = LVM
a.port_dead(VIF_PORT)
actions='resubmit(,2)')
]
- a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
- self.TUN_BRIDGE,
- '10.0.0.1', self.NET_MAPPING,
- 'sudo', 2, ['gre'],
- self.VETH_MTU)
+ a = self._build_agent()
a.tunnel_update(
mock.sentinel.ctx, tunnel_id='1', tunnel_ip='10.0.10.1',
tunnel_type=p_const.TYPE_GRE)
self._verify_mock_calls()
def test_tunnel_update_self(self):
- a = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
- self.TUN_BRIDGE,
- '10.0.0.1', self.NET_MAPPING,
- 'sudo', 2, ['gre'],
- self.VETH_MTU)
+ a = self._build_agent()
a.tunnel_update(
mock.sentinel.ctx, tunnel_id='1', tunnel_ip='10.0.0.1')
self._verify_mock_calls()
process_network_ports.side_effect = [
False, Exception('Fake exception to get out of the loop')]
- q_agent = ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
- self.TUN_BRIDGE,
- '10.0.0.1',
- self.NET_MAPPING,
- 'sudo', 2, ['gre'],
- self.VETH_MTU)
+ q_agent = self._build_agent()
# Hack to test loop
# We start method and expect it will raise after 2nd loop
self._verify_mock_calls()
-class TunnelTestWithMTU(TunnelTest):
+class TunnelTestUseVethInterco(TunnelTest):
+ USE_VETH_INTERCONNECTION = True
- def setUp(self):
- super(TunnelTestWithMTU, self).setUp()
- self.VETH_MTU = 1500
+ def _define_expected_calls(self):
+ self.mock_bridge_expected = [
+ mock.call(self.INT_BRIDGE, 'sudo'),
+ mock.call(self.MAP_TUN_BRIDGE, 'sudo'),
+ mock.call(self.TUN_BRIDGE, 'sudo'),
+ ]
+
+ self.mock_int_bridge_expected = [
+ mock.call.create(),
+ mock.call.set_secure_mode(),
+ mock.call.delete_port('patch-tun'),
+ mock.call.remove_all_flows(),
+ mock.call.add_flow(priority=1, actions='normal'),
+ mock.call.add_flow(table=constants.CANARY_TABLE, priority=0,
+ actions="drop")
+ ]
+
+ self.mock_map_tun_bridge_expected = [
+ mock.call.remove_all_flows(),
+ mock.call.add_flow(priority=1, actions='normal'),
+ mock.call.delete_port('phy-%s' % self.MAP_TUN_BRIDGE),
+ mock.call.add_port(self.intb),
+ ]
+ self.mock_int_bridge_expected += [
+ mock.call.delete_port('int-%s' % self.MAP_TUN_BRIDGE),
+ mock.call.add_port(self.inta)
+ ]
+
+ self.mock_int_bridge_expected += [
+ mock.call.add_flow(priority=2,
+ in_port=self.MAP_TUN_INT_OFPORT,
+ actions='drop')
+ ]
+ self.mock_map_tun_bridge_expected += [
+ mock.call.add_flow(priority=2,
+ in_port=self.MAP_TUN_PHY_OFPORT,
+ actions='drop')
+ ]
+
+ self.mock_tun_bridge_expected = [
+ mock.call.reset_bridge(),
+ mock.call.add_patch_port('patch-int', 'patch-tun'),
+ ]
+ self.mock_int_bridge_expected += [
+ mock.call.add_patch_port('patch-tun', 'patch-int')
+ ]
+
+ self.mock_tun_bridge_expected += [
+ mock.call.remove_all_flows(),
+ mock.call.add_flow(priority=1,
+ in_port=self.INT_OFPORT,
+ actions="resubmit(,%s)" %
+ constants.PATCH_LV_TO_TUN),
+ mock.call.add_flow(priority=0, actions='drop'),
+ mock.call.add_flow(priority=0,
+ table=constants.PATCH_LV_TO_TUN,
+ dl_dst=UCAST_MAC,
+ actions="resubmit(,%s)" %
+ constants.UCAST_TO_TUN),
+ mock.call.add_flow(priority=0,
+ table=constants.PATCH_LV_TO_TUN,
+ dl_dst=BCAST_MAC,
+ actions="resubmit(,%s)" %
+ constants.FLOOD_TO_TUN),
+ ]
+ for tunnel_type in constants.TUNNEL_NETWORK_TYPES:
+ self.mock_tun_bridge_expected.append(
+ mock.call.add_flow(
+ table=constants.TUN_TABLE[tunnel_type],
+ priority=0,
+ actions="drop"))
+ learned_flow = ("table=%s,"
+ "priority=1,"
+ "hard_timeout=300,"
+ "NXM_OF_VLAN_TCI[0..11],"
+ "NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],"
+ "load:0->NXM_OF_VLAN_TCI[],"
+ "load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],"
+ "output:NXM_OF_IN_PORT[]" %
+ constants.UCAST_TO_TUN)
+ self.mock_tun_bridge_expected += [
+ mock.call.add_flow(table=constants.LEARN_FROM_TUN,
+ priority=1,
+ actions="learn(%s),output:%s" %
+ (learned_flow, self.INT_OFPORT)),
+ mock.call.add_flow(table=constants.UCAST_TO_TUN,
+ priority=0,
+ actions="resubmit(,%s)" %
+ constants.FLOOD_TO_TUN),
+ mock.call.add_flow(table=constants.FLOOD_TO_TUN,
+ priority=0,
+ actions="drop")
+ ]
+
+ self.device_exists_expected = [
+ mock.call(self.MAP_TUN_BRIDGE, 'sudo'),
+ mock.call('int-%s' % self.MAP_TUN_BRIDGE, 'sudo'),
+ ]
+
+ self.ipdevice_expected = [
+ mock.call('int-%s' % self.MAP_TUN_BRIDGE, 'sudo'),
+ mock.call().link.delete()
+ ]
+ self.ipwrapper_expected = [
+ mock.call('sudo'),
+ mock.call().add_veth('int-%s' % self.MAP_TUN_BRIDGE,
+ 'phy-%s' % self.MAP_TUN_BRIDGE)
+ ]
+
+ self.get_bridges_expected = [mock.call('sudo')]
+
+ self.inta_expected = [mock.call.link.set_up()]
+ self.intb_expected = [mock.call.link.set_up()]
+ self.execute_expected = [mock.call(['/sbin/udevadm', 'settle',
+ '--timeout=10'])]
+
+
+class TunnelTestWithMTU(TunnelTestUseVethInterco):
+ VETH_MTU = 1500
+
+ def _define_expected_calls(self):
+ super(TunnelTestWithMTU, self)._define_expected_calls()
self.inta_expected.append(mock.call.link.set_mtu(self.VETH_MTU))
self.intb_expected.append(mock.call.link.set_mtu(self.VETH_MTU))