When not creating br-tun in secure fail mode, there are chances to
get a broadcast storm from br-tun.
For example, this occurs when at least three nodes have the br-tun
OpenFlow rules reset in and a broadcast/multicast packet enters br-tun.
This can happen if:
* openvswitch is restarted, until the agent reloads the Openflow rules.
* during neutron-openvswitch-agent restart, br-tun is reset, and there
is a few seconds timeframe where tunnel endpoints are plugged and OF
rules are reset.
Secure fail mode doesn't forward traffic by default if no rule is hit.
Change-Id: Iba5ded14179156decb16dcd4b898c026660f9653
Closes-bug: #
1421232
INVALID_OFPORT = -1
UNASSIGNED_OFPORT = []
+# OVS bridge fail modes
+FAILMODE_SECURE = 'secure'
+
OPTS = [
cfg.IntOpt('ovs_vsctl_timeout',
default=DEFAULT_OVS_VSCTL_TIMEOUT,
check_error=True)
def set_secure_mode(self):
- self.ovsdb.set_fail_mode(self.br_name, 'secure').execute(
+ self.ovsdb.set_fail_mode(self.br_name, FAILMODE_SECURE).execute(
check_error=True)
def set_protocols(self, protocols):
def destroy(self):
self.delete_bridge(self.br_name)
- def reset_bridge(self):
+ def reset_bridge(self, secure_mode=False):
with self.ovsdb.transaction() as txn:
txn.add(self.ovsdb.del_br(self.br_name))
txn.add(self.ovsdb.add_br(self.br_name))
+ if secure_mode:
+ txn.add(self.ovsdb.set_fail_mode(self.br_name,
+ FAILMODE_SECURE))
def add_port(self, port_name, *interface_attr_tuples):
with self.ovsdb.transaction() as txn:
if not self.tun_br:
self.tun_br = ovs_lib.OVSBridge(tun_br_name, self.root_helper)
- self.tun_br.reset_bridge()
+ self.tun_br.reset_bridge(secure_mode=True)
self.patch_tun_ofport = self.int_br.add_patch_port(
cfg.CONF.OVS.int_peer_patch_port, cfg.CONF.OVS.tun_peer_patch_port)
self.patch_int_ofport = self.tun_br.add_patch_port(
def test_set_fail_mode(self):
self.br.set_secure_mode()
+ self._assert_br_fail_mode(ovs_lib.FAILMODE_SECURE)
+
+ def _assert_br_fail_mode(self, fail_mode):
self.assertEqual(
self.br.db_get_val('Bridge', self.br.br_name, 'fail_mode'),
- 'secure')
+ fail_mode)
def test_set_protocols(self):
self.br.set_protocols('OpenFlow10')
self.br.delete_ports(all_ports=True)
self.assertEqual(len(self.br.get_port_name_list()), 0)
+ def test_reset_bridge(self):
+ self.create_ovs_port()
+ self.br.reset_bridge()
+ self.assertEqual(len(self.br.get_port_name_list()), 0)
+ self._assert_br_fail_mode([])
+
+ def test_reset_bridge_secure_mode(self):
+ self.br.reset_bridge(secure_mode=True)
+ self._assert_br_fail_mode(ovs_lib.FAILMODE_SECURE)
+
class OVSLibTestCase(base.BaseOVSLinuxTestCase):
def test_bridge_lifecycle_baseovs(self):
]
self.mock_tun_bridge_expected = [
- mock.call.reset_bridge(),
+ mock.call.reset_bridge(secure_mode=True),
mock.call.add_patch_port('patch-int', 'patch-tun'),
]
self.mock_int_bridge_expected += [
]
self.mock_tun_bridge_expected = [
- mock.call.reset_bridge(),
+ mock.call.reset_bridge(secure_mode=True),
mock.call.add_patch_port('patch-int', 'patch-tun'),
]
self.mock_int_bridge_expected += [