When changing datapath_type in the config, physical and tunnel bridges
do not have their datapath_type updated. Calling create() on already
created bridges should be safe as it passes '--may-exist' when adding
the bridge, which will do nothing if the bridge already exists, but
the second part of the transaction will still update things like
datapath_type.
It should be noted that ancillary bridges (like br-ex) are not
modified by this patch as datapath_type was never applied to them to
begin with.
Incidentally, the native and vsctl versions behaved slightly
differently when handling datapath_type: vsctl builds the multi-cmd
transaction with add-br ... -- set ..., so that the second cmd would
actually complete. The native just bailed if may_exist and the bridge
existed. This is fixed as part of this patch.
Change-Id: Ib8bc817c7bc724d80193d0ca7af480a7ea103f77
Closes-Bug:
1532273
br = idlutils.row_by_value(self.api.idl, 'Bridge', 'name',
self.name, None)
if br:
+ if self.datapath_type:
+ br.datapath_type = self.datapath_type
return
row = txn.insert(self.api._tables['Bridge'])
row.name = self.name
self.tun_br = self.br_tun_cls(tun_br_name)
self.tun_br.set_agent_uuid_stamp(self.agent_uuid_stamp)
- if not self.tun_br.bridge_exists(self.tun_br.br_name):
- self.tun_br.create(secure_mode=True)
+ # tun_br.create() won't recreate bridge if it exists, but will handle
+ # cases where something like datapath_type has changed
+ self.tun_br.create(secure_mode=True)
self.tun_br.setup_controllers(self.conf)
if (not self.int_br.port_exists(self.conf.OVS.int_peer_patch_port) or
self.patch_tun_ofport == ovs_lib.INVALID_OFPORT):
'bridge': bridge})
sys.exit(1)
br = self.br_phys_cls(bridge)
+ # The bridge already exists, so create won't recreate it, but will
+ # handle things like changing the datapath_type
+ br.create()
br.setup_controllers(self.conf)
br.setup_default_table()
self.phys_brs[physical_network] = br
prefix='br-int')
self.br_tun = base.get_rand_name(n_const.DEVICE_NAME_MAX_LEN,
prefix='br-tun')
+ self.br_phys = base.get_rand_name(n_const.DEVICE_NAME_MAX_LEN,
+ prefix='br-phys')
patch_name_len = n_const.DEVICE_NAME_MAX_LEN - len("-patch-tun")
self.patch_tun = "%s-patch-tun" % self.br_int[patch_name_len:]
self.patch_int = "%s-patch-int" % self.br_tun[patch_name_len:]
tunnel_types = [p_const.TYPE_VXLAN]
else:
tunnel_types = None
- bridge_mappings = ['physnet:%s' % self.br_int]
+ bridge_mappings = ['physnet:%s' % self.br_phys]
self.config.set_override('tunnel_types', tunnel_types, "AGENT")
self.config.set_override('polling_interval', 1, "AGENT")
self.config.set_override('prevent_arp_spoofing', False, "AGENT")
self.config.set_override('local_ip', '192.168.10.1', "OVS")
self.config.set_override('bridge_mappings', bridge_mappings, "OVS")
+ # Physical bridges should be created prior to running
+ self._bridge_classes()['br_phys'](self.br_phys).create()
agent = ovs_agent.OVSNeutronAgent(self._bridge_classes(),
self.config)
self.addCleanup(self.ovs.delete_bridge, self.br_int)
if tunnel_types:
self.addCleanup(self.ovs.delete_bridge, self.br_tun)
+ self.addCleanup(self.ovs.delete_bridge, self.br_phys)
agent.sg_agent = mock.Mock()
agent.ancillary_brs = []
return agent
"OVS")
agent = self.create_agent()
self.start_agent(agent)
- actual = self.ovs.db_get_val('Bridge',
- agent.int_br.br_name,
- 'datapath_type')
- self.assertEqual(expected, actual)
- actual = self.ovs.db_get_val('Bridge',
- agent.tun_br.br_name,
- 'datapath_type')
- self.assertEqual(expected, actual)
+ for br_name in (getattr(self, br) for br in
+ ('br_int', 'br_tun', 'br_phys')):
+ actual = self.ovs.db_get_val('Bridge', br_name, 'datapath_type')
+ self.assertEqual(expected, actual)
+
+ def test_datapath_type_change(self):
+ self._check_datapath_type_netdev('system')
+ self._check_datapath_type_netdev('netdev')
def test_datapath_type_netdev(self):
self._check_datapath_type_netdev(
self.agent.setup_physical_bridges({"physnet1": "br-eth"})
expected_calls = [
mock.call.phys_br_cls('br-eth'),
+ mock.call.phys_br.create(),
mock.call.phys_br.setup_controllers(mock.ANY),
mock.call.phys_br.setup_default_table(),
mock.call.int_br.db_get_val('Interface', 'int-br-eth',
self.agent.setup_physical_bridges({"physnet1": "br-eth"})
expected_calls = [
mock.call.phys_br_cls('br-eth'),
+ mock.call.phys_br.create(),
mock.call.phys_br.setup_controllers(mock.ANY),
mock.call.phys_br.setup_default_table(),
mock.call.int_br.delete_port('int-br-eth'),
]
self.mock_map_tun_bridge_expected = [
+ mock.call.create(),
mock.call.setup_controllers(mock.ANY),
mock.call.setup_default_table(),
mock.call.add_patch_port('phy-%s' % self.MAP_TUN_BRIDGE,
self.mock_tun_bridge_expected = [
mock.call.set_agent_uuid_stamp(mock.ANY),
- mock.call.bridge_exists(mock.ANY),
- nonzero(mock.call.bridge_exists()),
+ mock.call.create(secure_mode=True),
mock.call.setup_controllers(mock.ANY),
mock.call.port_exists('patch-int'),
nonzero(mock.call.port_exists()),
]
self.mock_map_tun_bridge_expected = [
+ mock.call.create(),
mock.call.setup_controllers(mock.ANY),
mock.call.setup_default_table(),
mock.call.add_port(self.intb),
self.mock_tun_bridge_expected = [
mock.call.set_agent_uuid_stamp(mock.ANY),
- mock.call.bridge_exists(mock.ANY),
- nonzero(mock.call.bridge_exists()),
+ mock.call.create(secure_mode=True),
mock.call.setup_controllers(mock.ANY),
mock.call.port_exists('patch-int'),
nonzero(mock.call.port_exists()),