Make del_fdb_flow() idempotent.

Addresses an issue where del_fdb_flow() gets a duplicate call for
the same port, which results in a KeyError. This change makes the
call more idempotent, so that it doesn't cause other follow-on
errors as a result of the uncaught exception.

Change-Id: I7a3a34dd654e143dee06c3e4642e859211a312ca
Closes-bug: #1421105
This commit is contained in:
Dermot Tynan 2015-02-20 16:57:33 +00:00
parent daf4f1938d
commit 841b2f58f3
3 changed files with 21 additions and 0 deletions

View File

@ -394,6 +394,9 @@ class OFANeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
def del_fdb_flow(self, br, port_info, remote_ip, lvm, ofport):
if port_info == n_const.FLOODING_ENTRY:
if ofport not in lvm.tun_ofports:
LOG.debug("attempt to remove a non-existent port %s", ofport)
return
lvm.tun_ofports.remove(ofport)
if len(lvm.tun_ofports) > 0:
br.install_tunnel_output(

View File

@ -425,6 +425,9 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
def del_fdb_flow(self, br, port_info, remote_ip, lvm, ofport):
if port_info == q_const.FLOODING_ENTRY:
if ofport not in lvm.tun_ofports:
LOG.debug("attempt to remove a non-existent port %s", ofport)
return
lvm.tun_ofports.remove(ofport)
if len(lvm.tun_ofports) > 0:
ofports = _ofport_set_to_str(lvm.tun_ofports)

View File

@ -863,6 +863,21 @@ class TestOvsNeutronAgent(base.BaseTestCase):
self.assertEqual(len(expected_calls),
len(do_action_flows_fn.mock_calls))
def test_del_fdb_flow_idempotency(self):
lvm = mock.Mock()
lvm.network_type = 'gre'
lvm.vlan = 'vlan1'
lvm.segmentation_id = 'seg1'
lvm.tun_ofports = set(['1', '2'])
with contextlib.nested(
mock.patch.object(self.agent.tun_br, 'mod_flow'),
mock.patch.object(self.agent.tun_br, 'delete_flows')
) as (mod_flow_fn, delete_flows_fn):
self.agent.del_fdb_flow(self.agent.tun_br, n_const.FLOODING_ENTRY,
'1.1.1.1', lvm, '3')
self.assertFalse(mod_flow_fn.called)
self.assertFalse(delete_flows_fn.called)
def test_recl_lv_port_to_preserve(self):
self._prepare_l2_pop_ofports()
self.agent.l2_pop = True