ovs-fw: Apply openflow rules immediately during update
Because update operation updates openflow rules three times: 1) New rules with new cookie 2) Delete old rules with old cookie 3) Change new cookie back to old cookie and the step 2) uses --strict parameter, it's needed to apply rules before deleting the old rules because --strict parameter cannot be combined with non-strict. This patch applies openflow rules after step 1), then --strict rules in step 2 are applied right away and then rest of delete part from 2) and all new rules from 3) are applied together. This patch adds optional interval parameter to Pinger class which sends more ICMP packets per second in the firewall blink tests to increase a chance of sending a packet while firewall is in inconsistent state. Change-Id: I25d9c87225feda1b5ddd442dd01529424186e05b Closes-bug: #1708731
This commit is contained in:
parent
0ec54fddc8
commit
f68e7822f4
@ -575,6 +575,13 @@ class OVSFirewallDriver(firewall.FirewallDriver):
|
|||||||
def _update_flows_for_port(self, of_port, old_of_port):
|
def _update_flows_for_port(self, of_port, old_of_port):
|
||||||
with self.update_cookie_context():
|
with self.update_cookie_context():
|
||||||
self._set_port_filters(of_port)
|
self._set_port_filters(of_port)
|
||||||
|
# Flush the flows caused by changes made to deferred bridge. The reason
|
||||||
|
# is that following delete_all_port_flows() call uses --strict
|
||||||
|
# parameter that cannot be combined with other non-strict rules, hence
|
||||||
|
# all parameters with --strict are applied right away. In order to
|
||||||
|
# avoid applying delete rules with --strict *before*
|
||||||
|
# _set_port_filters() we dump currently cached flows here.
|
||||||
|
self.int_br.apply_flows()
|
||||||
self.delete_all_port_flows(old_of_port)
|
self.delete_all_port_flows(old_of_port)
|
||||||
# Rewrite update cookie with default cookie
|
# Rewrite update cookie with default cookie
|
||||||
self._set_port_filters(of_port)
|
self._set_port_filters(of_port)
|
||||||
|
@ -309,7 +309,8 @@ class ConnectionTester(fixtures.Fixture):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
src_namespace, dst_address = self._get_namespace_and_address(
|
src_namespace, dst_address = self._get_namespace_and_address(
|
||||||
direction)
|
direction)
|
||||||
pinger = net_helpers.Pinger(src_namespace, dst_address)
|
pinger = net_helpers.Pinger(
|
||||||
|
src_namespace, dst_address, interval=0.3)
|
||||||
self._pingers[direction] = pinger
|
self._pingers[direction] = pinger
|
||||||
return pinger
|
return pinger
|
||||||
|
|
||||||
|
@ -352,7 +352,8 @@ class Pinger(object):
|
|||||||
r'.* Destination .* Unreachable')
|
r'.* Destination .* Unreachable')
|
||||||
TIMEOUT = 15
|
TIMEOUT = 15
|
||||||
|
|
||||||
def __init__(self, namespace, address, count=None, timeout=1):
|
def __init__(self, namespace, address, count=None, timeout=1,
|
||||||
|
interval=None):
|
||||||
self.proc = None
|
self.proc = None
|
||||||
self.namespace = namespace
|
self.namespace = namespace
|
||||||
self.address = address
|
self.address = address
|
||||||
@ -361,6 +362,7 @@ class Pinger(object):
|
|||||||
self.destination_unreachable = False
|
self.destination_unreachable = False
|
||||||
self.sent = 0
|
self.sent = 0
|
||||||
self.received = 0
|
self.received = 0
|
||||||
|
self.interval = interval
|
||||||
|
|
||||||
def _wait_for_death(self):
|
def _wait_for_death(self):
|
||||||
is_dead = lambda: self.proc.poll() is not None
|
is_dead = lambda: self.proc.poll() is not None
|
||||||
@ -390,6 +392,8 @@ class Pinger(object):
|
|||||||
cmd = [ping_exec, self.address, '-W', str(self.timeout)]
|
cmd = [ping_exec, self.address, '-W', str(self.timeout)]
|
||||||
if self.count:
|
if self.count:
|
||||||
cmd.extend(['-c', str(self.count)])
|
cmd.extend(['-c', str(self.count)])
|
||||||
|
if self.interval:
|
||||||
|
cmd.extend(['-i', str(self.interval)])
|
||||||
self.proc = RootHelperProcess(cmd, namespace=self.namespace)
|
self.proc = RootHelperProcess(cmd, namespace=self.namespace)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
|
@ -610,6 +610,16 @@ class TestOVSFirewallDriver(base.BaseTestCase):
|
|||||||
self.firewall.update_port_filter(port_dict)
|
self.firewall.update_port_filter(port_dict)
|
||||||
self.assertTrue(self.mock_bridge.br.delete_flows.called)
|
self.assertTrue(self.mock_bridge.br.delete_flows.called)
|
||||||
|
|
||||||
|
def test_update_port_filter_applies_added_flows(self):
|
||||||
|
"""Check flows are applied right after _set_flows is called."""
|
||||||
|
port_dict = {'device': 'port-id',
|
||||||
|
'security_groups': [1]}
|
||||||
|
self._prepare_security_group()
|
||||||
|
self.firewall.prepare_port_filter(port_dict)
|
||||||
|
with self.firewall.defer_apply():
|
||||||
|
self.firewall.update_port_filter(port_dict)
|
||||||
|
self.assertEqual(2, self.mock_bridge.apply_flows.call_count)
|
||||||
|
|
||||||
def test_remove_port_filter(self):
|
def test_remove_port_filter(self):
|
||||||
port_dict = {'device': 'port-id',
|
port_dict = {'device': 'port-id',
|
||||||
'security_groups': [1]}
|
'security_groups': [1]}
|
||||||
|
Loading…
Reference in New Issue
Block a user