
Current packet processing in br-tun is based on tun-id, as a consequence, two networks using different tunnel types but sharing the same tun-id would not be properly isolated. To ensure proper isolation within a single bridge, NORMAL action can't be used any more as it floods unknown unicasts on all bridges ports. It is replaced by a learn action that dynamically sets-up flows when packets are recieved from tunnel ports. As mac address are learnt in explicit flows (in table 20), we can use a default action in that table to flood unknown unicasts to the right set of ports, like broadcasts and multicasts packets. See https://wiki.openstack.org/wiki/Ovs-flow-logic for a more detailled explanation of the flow logic Another alternative could have been to use distinct bridges for each tunnel type (whithout modifying the current flow logic), but previous alternative may be preferable as it paves the way for new tunneling optimisations (like RPC based mac learning and partial-mesh flooding proposed in bp/l2-population) Change-Id: I1dfe74f96680c2c6fe4d8d4aac4821c6b020c005 Closes-Bug: #1196963
484 lines
21 KiB
Python
484 lines
21 KiB
Python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
# Copyright 2012 Nicira Networks, Inc.
|
|
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
#
|
|
# @author: Dave Lapsley, Nicira Networks, Inc.
|
|
|
|
import mox
|
|
from oslo.config import cfg
|
|
|
|
from neutron.agent.linux import ip_lib
|
|
from neutron.agent.linux import ovs_lib
|
|
from neutron.openstack.common import log
|
|
from neutron.plugins.openvswitch.agent import ovs_neutron_agent
|
|
from neutron.plugins.openvswitch.common import constants
|
|
from neutron.tests import base
|
|
|
|
|
|
# Useful global dummy variables.
|
|
NET_UUID = '3faeebfe-5d37-11e1-a64b-000c29d5f0a7'
|
|
LS_ID = 42
|
|
LV_ID = 42
|
|
LV_IDS = [42, 43]
|
|
VIF_ID = '404deaec-5d37-11e1-a64b-000c29d5f0a8'
|
|
VIF_MAC = '3c:09:24:1e:78:23'
|
|
OFPORT_NUM = 1
|
|
VIF_PORT = ovs_lib.VifPort('port', OFPORT_NUM,
|
|
VIF_ID, VIF_MAC, 'switch')
|
|
VIF_PORTS = {VIF_ID: VIF_PORT}
|
|
LVM = ovs_neutron_agent.LocalVLANMapping(LV_ID, 'gre', None, LS_ID, VIF_PORTS)
|
|
LVM_FLAT = ovs_neutron_agent.LocalVLANMapping(
|
|
LV_ID, 'flat', 'net1', LS_ID, VIF_PORTS)
|
|
LVM_VLAN = ovs_neutron_agent.LocalVLANMapping(
|
|
LV_ID, 'vlan', 'net1', LS_ID, VIF_PORTS)
|
|
|
|
GRE_OFPORTS = set(['11', '12'])
|
|
VXLAN_OFPORTS = set(['13', '14'])
|
|
TUN_OFPORTS = {constants.TYPE_GRE: GRE_OFPORTS,
|
|
constants.TYPE_VXLAN: VXLAN_OFPORTS}
|
|
|
|
BCAST_MAC = "01:00:00:00:00:00/01:00:00:00:00:00"
|
|
UCAST_MAC = "00:00:00:00:00:00/01:00:00:00:00:00"
|
|
|
|
|
|
class DummyPort:
|
|
def __init__(self, interface_id):
|
|
self.interface_id = interface_id
|
|
|
|
|
|
class DummyVlanBinding:
|
|
def __init__(self, network_id, vlan_id):
|
|
self.network_id = network_id
|
|
self.vlan_id = vlan_id
|
|
|
|
|
|
class TunnelTest(base.BaseTestCase):
|
|
|
|
def setUp(self):
|
|
super(TunnelTest, self).setUp()
|
|
cfg.CONF.set_override('rpc_backend',
|
|
'neutron.openstack.common.rpc.impl_fake')
|
|
cfg.CONF.set_override('report_interval', 0, 'AGENT')
|
|
self.mox = mox.Mox()
|
|
self.addCleanup(self.mox.UnsetStubs)
|
|
|
|
self.INT_BRIDGE = 'integration_bridge'
|
|
self.TUN_BRIDGE = 'tunnel_bridge'
|
|
self.MAP_TUN_BRIDGE = 'tunnel_bridge_mapping'
|
|
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.inta = self.mox.CreateMock(ip_lib.IPDevice)
|
|
self.intb = self.mox.CreateMock(ip_lib.IPDevice)
|
|
self.inta.link = self.mox.CreateMock(ip_lib.IpLinkCommand)
|
|
self.intb.link = self.mox.CreateMock(ip_lib.IpLinkCommand)
|
|
|
|
self.mox.StubOutClassWithMocks(ovs_lib, 'OVSBridge')
|
|
self.mock_int_bridge = ovs_lib.OVSBridge(self.INT_BRIDGE, 'sudo')
|
|
self.mock_int_bridge.delete_port('patch-tun')
|
|
self.mock_int_bridge.remove_all_flows()
|
|
self.mock_int_bridge.add_flow(priority=1, actions='normal')
|
|
|
|
self.mock_map_tun_bridge = ovs_lib.OVSBridge(
|
|
self.MAP_TUN_BRIDGE, 'sudo')
|
|
self.mock_map_tun_bridge.br_name = self.MAP_TUN_BRIDGE
|
|
self.mock_map_tun_bridge.remove_all_flows()
|
|
self.mock_map_tun_bridge.add_flow(priority=1, actions='normal')
|
|
self.mock_int_bridge.delete_port('int-tunnel_bridge_mapping')
|
|
self.mock_map_tun_bridge.delete_port('phy-tunnel_bridge_mapping')
|
|
self.mock_int_bridge.add_port(self.inta)
|
|
self.mock_map_tun_bridge.add_port(self.intb)
|
|
self.inta.link.set_up()
|
|
self.intb.link.set_up()
|
|
|
|
self.mock_int_bridge.add_flow(priority=2, in_port=None, actions='drop')
|
|
self.mock_map_tun_bridge.add_flow(
|
|
priority=2, in_port=None, actions='drop')
|
|
|
|
self.mock_tun_bridge = ovs_lib.OVSBridge(self.TUN_BRIDGE, 'sudo')
|
|
self.mock_tun_bridge.reset_bridge()
|
|
self.mock_int_bridge.add_patch_port(
|
|
'patch-tun', 'patch-int').AndReturn(self.TUN_OFPORT)
|
|
self.mock_tun_bridge.add_patch_port(
|
|
'patch-int', 'patch-tun').AndReturn(self.INT_OFPORT)
|
|
|
|
self.mock_tun_bridge.remove_all_flows()
|
|
self.mock_tun_bridge.add_flow(priority=1,
|
|
in_port=self.INT_OFPORT,
|
|
actions="resubmit(,%s)" %
|
|
constants.PATCH_LV_TO_TUN)
|
|
self.mock_tun_bridge.add_flow(priority=0, actions='drop')
|
|
self.mock_tun_bridge.add_flow(table=constants.PATCH_LV_TO_TUN,
|
|
dl_dst=UCAST_MAC,
|
|
actions="resubmit(,%s)" %
|
|
constants.UCAST_TO_TUN)
|
|
self.mock_tun_bridge.add_flow(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.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],"
|
|
"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.add_flow(table=constants.LEARN_FROM_TUN,
|
|
priority=1,
|
|
actions="learn(%s),output:%s" %
|
|
(learned_flow, self.INT_OFPORT))
|
|
self.mock_tun_bridge.add_flow(table=constants.UCAST_TO_TUN,
|
|
priority=0,
|
|
actions="resubmit(,%s)" %
|
|
constants.FLOOD_TO_TUN)
|
|
self.mock_tun_bridge.add_flow(table=constants.FLOOD_TO_TUN,
|
|
priority=0,
|
|
actions="drop")
|
|
|
|
self.mox.StubOutWithMock(ip_lib, 'device_exists')
|
|
ip_lib.device_exists('tunnel_bridge_mapping', 'sudo').AndReturn(True)
|
|
ip_lib.device_exists(
|
|
'int-tunnel_bridge_mapping', 'sudo').AndReturn(True)
|
|
|
|
self.mox.StubOutWithMock(ip_lib.IpLinkCommand, 'delete')
|
|
ip_lib.IPDevice('int-tunnel_bridge_mapping').link.delete()
|
|
|
|
self.mox.StubOutClassWithMocks(ip_lib, 'IPWrapper')
|
|
ip_lib.IPWrapper('sudo').add_veth(
|
|
'int-tunnel_bridge_mapping',
|
|
'phy-tunnel_bridge_mapping').AndReturn([self.inta, self.intb])
|
|
|
|
self.mock_int_bridge.get_local_port_mac().AndReturn('000000000001')
|
|
self.mox.StubOutWithMock(ovs_lib, 'get_bridges')
|
|
ovs_lib.get_bridges('sudo').AndReturn([self.INT_BRIDGE,
|
|
self.TUN_BRIDGE,
|
|
self.MAP_TUN_BRIDGE])
|
|
|
|
def testConstruct(self):
|
|
self.mox.ReplayAll()
|
|
ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
|
|
self.TUN_BRIDGE,
|
|
'10.0.0.1', self.NET_MAPPING,
|
|
'sudo', 2, ['gre'],
|
|
self.VETH_MTU)
|
|
self.mox.VerifyAll()
|
|
|
|
def testConstructVXLAN(self):
|
|
self.mox.StubOutWithMock(ovs_lib, 'get_installed_ovs_klm_version')
|
|
ovs_lib.get_installed_ovs_klm_version().AndReturn("1.10")
|
|
self.mox.StubOutWithMock(ovs_lib, 'get_installed_ovs_usr_version')
|
|
ovs_lib.get_installed_ovs_usr_version('sudo').AndReturn("1.10")
|
|
self.mox.ReplayAll()
|
|
ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
|
|
self.TUN_BRIDGE,
|
|
'10.0.0.1', self.NET_MAPPING,
|
|
'sudo', 2, ['vxlan'],
|
|
self.VETH_MTU)
|
|
self.mox.VerifyAll()
|
|
|
|
def testProvisionLocalVlan(self):
|
|
self.mock_tun_bridge.mod_flow(table=constants.FLOOD_TO_TUN,
|
|
priority=1,
|
|
dl_vlan=LV_ID,
|
|
actions="strip_vlan,"
|
|
"set_tunnel:%s,output:%s" %
|
|
(LS_ID, ','.join(GRE_OFPORTS)))
|
|
|
|
self.mock_tun_bridge.add_flow(table=constants.TUN_TABLE['gre'],
|
|
priority=1,
|
|
tun_id=LS_ID,
|
|
actions="mod_vlan_vid:%s,resubmit(,%s)" %
|
|
(LV_ID, constants.LEARN_FROM_TUN))
|
|
self.mox.ReplayAll()
|
|
|
|
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.available_local_vlans = set([LV_ID])
|
|
a.tun_br_ofports = TUN_OFPORTS
|
|
a.provision_local_vlan(NET_UUID, constants.TYPE_GRE, None, LS_ID)
|
|
self.mox.VerifyAll()
|
|
|
|
def testProvisionLocalVlanFlat(self):
|
|
action_string = 'strip_vlan,normal'
|
|
self.mock_map_tun_bridge.add_flow(
|
|
priority=4, in_port=self.MAP_TUN_OFPORT,
|
|
dl_vlan=LV_ID, actions=action_string)
|
|
|
|
action_string = 'mod_vlan_vid:%s,normal' % LV_ID
|
|
self.mock_int_bridge.add_flow(priority=3, in_port=self.INT_OFPORT,
|
|
dl_vlan=65535, actions=action_string)
|
|
|
|
self.mox.ReplayAll()
|
|
|
|
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.available_local_vlans = set([LV_ID])
|
|
a.phys_brs['net1'] = self.mock_map_tun_bridge
|
|
a.phys_ofports['net1'] = self.MAP_TUN_OFPORT
|
|
a.int_ofports['net1'] = self.INT_OFPORT
|
|
a.provision_local_vlan(NET_UUID, constants.TYPE_FLAT, 'net1', LS_ID)
|
|
self.mox.VerifyAll()
|
|
|
|
def testProvisionLocalVlanFlatFail(self):
|
|
self.mox.ReplayAll()
|
|
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.provision_local_vlan(NET_UUID, constants.TYPE_FLAT, 'net2', LS_ID)
|
|
self.mox.VerifyAll()
|
|
|
|
def testProvisionLocalVlanVlan(self):
|
|
action_string = 'mod_vlan_vid:%s,normal' % LS_ID
|
|
self.mock_map_tun_bridge.add_flow(
|
|
priority=4, in_port=self.MAP_TUN_OFPORT,
|
|
dl_vlan=LV_ID, actions=action_string)
|
|
|
|
action_string = 'mod_vlan_vid:%s,normal' % LS_ID
|
|
self.mock_int_bridge.add_flow(priority=3, in_port=self.INT_OFPORT,
|
|
dl_vlan=LV_ID, actions=action_string)
|
|
|
|
self.mox.ReplayAll()
|
|
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.available_local_vlans = set([LV_ID])
|
|
a.phys_brs['net1'] = self.mock_map_tun_bridge
|
|
a.phys_ofports['net1'] = self.MAP_TUN_OFPORT
|
|
a.int_ofports['net1'] = self.INT_OFPORT
|
|
a.provision_local_vlan(NET_UUID, constants.TYPE_VLAN, 'net1', LS_ID)
|
|
self.mox.VerifyAll()
|
|
|
|
def testProvisionLocalVlanVlanFail(self):
|
|
self.mox.ReplayAll()
|
|
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.provision_local_vlan(NET_UUID, constants.TYPE_VLAN, 'net2', LS_ID)
|
|
self.mox.VerifyAll()
|
|
|
|
def testReclaimLocalVlan(self):
|
|
self.mock_tun_bridge.delete_flows(
|
|
table=constants.TUN_TABLE['gre'], tun_id=LS_ID)
|
|
self.mock_tun_bridge.delete_flows(dl_vlan=LVM.vlan)
|
|
|
|
self.mox.ReplayAll()
|
|
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.available_local_vlans = set()
|
|
a.local_vlan_map[NET_UUID] = LVM
|
|
a.reclaim_local_vlan(NET_UUID, LVM)
|
|
self.assertTrue(LVM.vlan in a.available_local_vlans)
|
|
self.mox.VerifyAll()
|
|
|
|
def testReclaimLocalVlanFlat(self):
|
|
self.mock_map_tun_bridge.delete_flows(
|
|
in_port=self.MAP_TUN_OFPORT, dl_vlan=LVM_FLAT.vlan)
|
|
|
|
self.mock_int_bridge.delete_flows(
|
|
dl_vlan=65535, in_port=self.INT_OFPORT)
|
|
|
|
self.mox.ReplayAll()
|
|
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.phys_brs['net1'] = self.mock_map_tun_bridge
|
|
a.phys_ofports['net1'] = self.MAP_TUN_OFPORT
|
|
a.int_ofports['net1'] = self.INT_OFPORT
|
|
|
|
a.available_local_vlans = set()
|
|
a.local_vlan_map[NET_UUID] = LVM_FLAT
|
|
a.reclaim_local_vlan(NET_UUID, LVM_FLAT)
|
|
self.assertTrue(LVM_FLAT.vlan in a.available_local_vlans)
|
|
self.mox.VerifyAll()
|
|
|
|
def testReclaimLocalVlanVLAN(self):
|
|
self.mock_map_tun_bridge.delete_flows(
|
|
in_port=self.MAP_TUN_OFPORT, dl_vlan=LVM_VLAN.vlan)
|
|
|
|
self.mock_int_bridge.delete_flows(
|
|
dl_vlan=LV_ID, in_port=self.INT_OFPORT)
|
|
|
|
self.mox.ReplayAll()
|
|
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.phys_brs['net1'] = self.mock_map_tun_bridge
|
|
a.phys_ofports['net1'] = self.MAP_TUN_OFPORT
|
|
a.int_ofports['net1'] = self.INT_OFPORT
|
|
|
|
a.available_local_vlans = set()
|
|
a.local_vlan_map[NET_UUID] = LVM_VLAN
|
|
a.reclaim_local_vlan(NET_UUID, LVM_VLAN)
|
|
self.assertTrue(LVM_VLAN.vlan in a.available_local_vlans)
|
|
self.mox.VerifyAll()
|
|
|
|
def testPortBound(self):
|
|
self.mock_int_bridge.set_db_attribute('Port', VIF_PORT.port_name,
|
|
'tag', str(LVM.vlan))
|
|
self.mock_int_bridge.delete_flows(in_port=VIF_PORT.ofport)
|
|
|
|
self.mox.ReplayAll()
|
|
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.local_vlan_map[NET_UUID] = LVM
|
|
a.port_bound(VIF_PORT, NET_UUID, 'gre', None, LS_ID)
|
|
self.mox.VerifyAll()
|
|
|
|
def testPortUnbound(self):
|
|
self.mox.StubOutWithMock(
|
|
ovs_neutron_agent.OVSNeutronAgent, 'reclaim_local_vlan')
|
|
ovs_neutron_agent.OVSNeutronAgent.reclaim_local_vlan(NET_UUID, LVM)
|
|
|
|
self.mox.ReplayAll()
|
|
|
|
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.local_vlan_map[NET_UUID] = LVM
|
|
a.port_unbound(VIF_ID, NET_UUID)
|
|
self.mox.VerifyAll()
|
|
|
|
def testPortDead(self):
|
|
self.mock_int_bridge.set_db_attribute(
|
|
'Port', VIF_PORT.port_name, 'tag', ovs_neutron_agent.DEAD_VLAN_TAG)
|
|
|
|
self.mock_int_bridge.add_flow(priority=2, in_port=VIF_PORT.ofport,
|
|
actions='drop')
|
|
|
|
self.mox.ReplayAll()
|
|
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.available_local_vlans = set([LV_ID])
|
|
a.local_vlan_map[NET_UUID] = LVM
|
|
a.port_dead(VIF_PORT)
|
|
self.mox.VerifyAll()
|
|
|
|
def testTunnelUpdate(self):
|
|
self.mock_tun_bridge.add_tunnel_port('gre-1', '10.0.10.1', '10.0.0.1',
|
|
'gre', 4789)
|
|
self.mox.ReplayAll()
|
|
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.tunnel_update(
|
|
mox.MockAnything, tunnel_id='1', tunnel_ip='10.0.10.1',
|
|
tunnel_type=constants.TYPE_GRE)
|
|
self.mox.VerifyAll()
|
|
|
|
def testTunnelUpdateSelf(self):
|
|
self.mox.ReplayAll()
|
|
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.tunnel_update(
|
|
mox.MockAnything, tunnel_id='1', tunnel_ip='10.0.0.1')
|
|
self.mox.VerifyAll()
|
|
|
|
def testDaemonLoop(self):
|
|
reply2 = {'current': set(['tap0']),
|
|
'added': set([]),
|
|
'removed': set([])}
|
|
|
|
reply3 = {'current': set(['tap2']),
|
|
'added': set([]),
|
|
'removed': set([])}
|
|
|
|
self.mox.StubOutWithMock(log.ContextAdapter, 'exception')
|
|
log.ContextAdapter.exception(
|
|
_("Error in agent event loop")).AndRaise(
|
|
Exception('Fake exception to get out of the loop'))
|
|
|
|
self.mox.StubOutWithMock(
|
|
ovs_neutron_agent.OVSNeutronAgent, 'update_ports')
|
|
ovs_neutron_agent.OVSNeutronAgent.update_ports(set()).AndReturn(reply2)
|
|
ovs_neutron_agent.OVSNeutronAgent.update_ports(
|
|
set(['tap0'])).AndReturn(reply3)
|
|
self.mox.StubOutWithMock(
|
|
ovs_neutron_agent.OVSNeutronAgent, 'process_network_ports')
|
|
ovs_neutron_agent.OVSNeutronAgent.process_network_ports(
|
|
{'current': set(['tap0']),
|
|
'removed': set([]),
|
|
'added': set([])}).AndReturn(False)
|
|
ovs_neutron_agent.OVSNeutronAgent.process_network_ports(
|
|
{'current': set(['tap0']),
|
|
'removed': set([]),
|
|
'added': set([])}).AndRaise(
|
|
Exception('Fake exception to get out of the loop'))
|
|
self.mox.ReplayAll()
|
|
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)
|
|
|
|
# Hack to test loop
|
|
# We start method and expect it will raise after 2nd loop
|
|
# If something goes wrong, mox.VerifyAll() will catch it
|
|
try:
|
|
q_agent.daemon_loop()
|
|
except Exception:
|
|
pass
|
|
|
|
self.mox.VerifyAll()
|
|
|
|
|
|
class TunnelTestWithMTU(TunnelTest):
|
|
|
|
def setUp(self):
|
|
super(TunnelTestWithMTU, self).setUp()
|
|
self.VETH_MTU = 1500
|
|
self.inta.link.set_mtu(self.VETH_MTU)
|
|
self.intb.link.set_mtu(self.VETH_MTU)
|