Merge "Clear conntrack entries without zones if CT zones are not used"

This commit is contained in:
Jenkins
2017-01-31 21:13:10 +00:00
committed by Gerrit Code Review
3 changed files with 169 additions and 126 deletions

View File

@@ -1092,8 +1092,8 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
self.assertEqual(l, r)
filter_inst.assert_has_calls(calls)
def _test_remove_conntrack_entries(self, ethertype, protocol,
direction):
def _test_remove_conntrack_entries(self, ethertype, protocol, direction,
ct_zone):
port = self._fake_port()
port['security_groups'] = 'fake_sg_id'
self.firewall.filtered_ports[port['device']] = port
@@ -1102,87 +1102,130 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
{'direction': direction, 'ethertype': ethertype,
'protocol': protocol}]
self.firewall.filter_defer_apply_on()
self.firewall.sg_rules['fake_sg_id'] = []
self.firewall.filter_defer_apply_off()
cmd = ['conntrack', '-D']
if protocol:
cmd.extend(['-p', protocol])
if ethertype == 'IPv4':
cmd.extend(['-f', 'ipv4'])
if direction == 'ingress':
cmd.extend(['-d', '10.0.0.1'])
with mock.patch.dict(self.firewall.ipconntrack._device_zone_map,
{port['device']: ct_zone}):
self.firewall.filter_defer_apply_on()
self.firewall.sg_rules['fake_sg_id'] = []
self.firewall.filter_defer_apply_off()
cmd = ['conntrack', '-D']
if protocol:
cmd.extend(['-p', protocol])
if ethertype == 'IPv4':
cmd.extend(['-f', 'ipv4'])
if direction == 'ingress':
cmd.extend(['-d', '10.0.0.1'])
else:
cmd.extend(['-s', '10.0.0.1'])
else:
cmd.extend(['-s', '10.0.0.1'])
else:
cmd.extend(['-f', 'ipv6'])
if direction == 'ingress':
cmd.extend(['-d', 'fe80::1'])
else:
cmd.extend(['-s', 'fe80::1'])
# initial data has 1, 2, and 9 in use, CT zone will start at 10.
cmd.extend(['-w', 10])
calls = [
mock.call(cmd, run_as_root=True, check_exit_code=True,
extra_ok_codes=[1])]
self.utils_exec.assert_has_calls(calls)
cmd.extend(['-f', 'ipv6'])
if direction == 'ingress':
cmd.extend(['-d', 'fe80::1'])
else:
cmd.extend(['-s', 'fe80::1'])
if ct_zone:
cmd.extend(['-w', ct_zone])
calls = [
mock.call(cmd, run_as_root=True, check_exit_code=True,
extra_ok_codes=[1])]
self.utils_exec.assert_has_calls(calls)
def test_remove_conntrack_entries_for_delete_rule_ipv4(self):
for direction in ['ingress', 'egress']:
for pro in [None, 'tcp', 'icmp', 'udp']:
self._test_remove_conntrack_entries(
'IPv4', pro, direction)
'IPv4', pro, direction, ct_zone=10)
def test_remove_conntrack_entries_for_delete_rule_ipv4_no_ct_zone(self):
for direction in ['ingress', 'egress']:
for pro in [None, 'tcp', 'icmp', 'udp']:
self._test_remove_conntrack_entries(
'IPv4', pro, direction, ct_zone=None)
def test_remove_conntrack_entries_for_delete_rule_ipv6(self):
for direction in ['ingress', 'egress']:
for pro in [None, 'tcp', 'icmp', 'udp']:
self._test_remove_conntrack_entries(
'IPv6', pro, direction)
'IPv6', pro, direction, ct_zone=10)
def test_remove_conntrack_entries_for_delete_rule_ipv6_no_ct_zone(self):
for direction in ['ingress', 'egress']:
for pro in [None, 'tcp', 'icmp', 'udp']:
self._test_remove_conntrack_entries(
'IPv6', pro, direction, ct_zone=None)
def test_remove_conntrack_entries_for_port_sec_group_change(self):
self._test_remove_conntrack_entries_for_port_sec_group_change(
ct_zone=10)
def test_remove_conntrack_entries_for_port_sec_group_change_no_ct_zone(
self):
self._test_remove_conntrack_entries_for_port_sec_group_change(
ct_zone=None)
def _get_expected_conntrack_calls(self, ips, ct_zone):
expected_calls = []
for ip_item in ips:
proto = ip_item[0]
ip = ip_item[1]
for direction in ['-d', '-s']:
cmd = ['conntrack', '-D', '-f', proto, direction, ip]
if ct_zone:
cmd.extend(['-w', ct_zone])
expected_calls.append(
mock.call(cmd, run_as_root=True, check_exit_code=True,
extra_ok_codes=[1]))
return expected_calls
def _test_remove_conntrack_entries_for_port_sec_group_change(self,
ct_zone):
port = self._fake_port()
port['security_groups'] = ['fake_sg_id']
self.firewall.filtered_ports[port['device']] = port
self.firewall.updated_sg_members = set(['tapfake_dev'])
self.firewall.filter_defer_apply_on()
new_port = copy.deepcopy(port)
new_port['security_groups'] = ['fake_sg_id2']
self.firewall.filtered_ports[port['device']] = new_port
self.firewall.filter_defer_apply_off()
calls = [
# initial data has 1, 2, and 9 in use, CT zone will start at 10.
mock.call(['conntrack', '-D', '-f', 'ipv4', '-d', '10.0.0.1',
'-w', 10],
run_as_root=True, check_exit_code=True,
extra_ok_codes=[1]),
mock.call(['conntrack', '-D', '-f', 'ipv4', '-s', '10.0.0.1',
'-w', 10],
run_as_root=True, check_exit_code=True,
extra_ok_codes=[1]),
mock.call(['conntrack', '-D', '-f', 'ipv6', '-d', 'fe80::1',
'-w', 10],
run_as_root=True, check_exit_code=True,
extra_ok_codes=[1]),
mock.call(['conntrack', '-D', '-f', 'ipv6', '-s', 'fe80::1',
'-w', 10],
run_as_root=True, check_exit_code=True,
extra_ok_codes=[1])]
self.utils_exec.assert_has_calls(calls)
with mock.patch.dict(self.firewall.ipconntrack._device_zone_map,
{port['device']: ct_zone}):
self.firewall.filter_defer_apply_on()
new_port = copy.deepcopy(port)
new_port['security_groups'] = ['fake_sg_id2']
self.firewall.filtered_ports[port['device']] = new_port
self.firewall.filter_defer_apply_off()
calls = self._get_expected_conntrack_calls(
[('ipv4', '10.0.0.1'), ('ipv6', 'fe80::1')], ct_zone)
self.utils_exec.assert_has_calls(calls)
def test_remove_conntrack_entries_for_sg_member_changed_ipv4(self):
for direction in ['ingress', 'egress']:
for protocol in [None, 'tcp', 'icmp', 'udp']:
self._test_remove_conntrack_entries_sg_member_changed(
'IPv4', protocol, direction)
'IPv4', protocol, direction, ct_zone=10)
def test_remove_conntrack_entries_for_sg_member_changed_ipv4_no_ct_zone(
self):
for direction in ['ingress', 'egress']:
for protocol in [None, 'tcp', 'icmp', 'udp']:
self._test_remove_conntrack_entries_sg_member_changed(
'IPv4', protocol, direction, ct_zone=10)
def test_remove_conntrack_entries_for_sg_member_changed_ipv6(self):
for direction in ['ingress', 'egress']:
for protocol in [None, 'tcp', 'icmp', 'udp']:
self._test_remove_conntrack_entries_sg_member_changed(
'IPv6', protocol, direction)
'IPv6', protocol, direction, ct_zone=10)
def test_remove_conntrack_entries_for_sg_member_changed_ipv6_no_ct_zone(
self):
for direction in ['ingress', 'egress']:
for protocol in [None, 'tcp', 'icmp', 'udp']:
self._test_remove_conntrack_entries_sg_member_changed(
'IPv6', protocol, direction, ct_zone=None)
def _test_remove_conntrack_entries_sg_member_changed(self, ethertype,
protocol, direction):
protocol, direction,
ct_zone):
port = self._fake_port()
port['security_groups'] = ['fake_sg_id']
port['security_group_source_groups'] = ['fake_sg_id2']
@@ -1201,29 +1244,35 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
members_add = {'IPv6': ['fe80::2', 'fe80::3']}
members_after_delete = {'IPv6': ['fe80::3']}
# add ['10.0.0.2', '10.0.0.3'] or ['fe80::2', 'fe80::3']
self.firewall.security_group_updated('sg_member', ['fake_sg_id2'])
self.firewall.update_security_group_members(
'fake_sg_id2', members_add)
with mock.patch.dict(self.firewall.ipconntrack._device_zone_map,
{port['device']: ct_zone}):
# add ['10.0.0.2', '10.0.0.3'] or ['fe80::2', 'fe80::3']
self.firewall.security_group_updated('sg_member', ['fake_sg_id2'])
self.firewall.update_security_group_members(
'fake_sg_id2', members_add)
# delete '10.0.0.2' or 'fe80::2'
self.firewall.security_group_updated('sg_member', ['fake_sg_id2'])
self.firewall.update_security_group_members(
'fake_sg_id2', members_after_delete)
# delete '10.0.0.2' or 'fe80::2'
self.firewall.security_group_updated('sg_member', ['fake_sg_id2'])
self.firewall.update_security_group_members(
'fake_sg_id2', members_after_delete)
# check conntrack deletion from '10.0.0.1' to '10.0.0.2' or
# from 'fe80::1' to 'fe80::2'
ips = {"ipv4": ['10.0.0.1', '10.0.0.2'],
"ipv6": ['fe80::1', 'fe80::2']}
calls = []
for direction in ['ingress', 'egress']:
direction = '-d' if direction == 'ingress' else '-s'
remote_ip_direction = '-s' if direction == '-d' else '-d'
calls.append(mock.call(['conntrack', '-D', '-f', ethertype,
direction, ips[ethertype][0], '-w', 10,
remote_ip_direction, ips[ethertype][1]],
run_as_root=True, check_exit_code=True,
extra_ok_codes=[1]))
# check conntrack deletion from '10.0.0.1' to '10.0.0.2' or
# from 'fe80::1' to 'fe80::2'
ips = {"ipv4": ['10.0.0.1', '10.0.0.2'],
"ipv6": ['fe80::1', 'fe80::2']}
calls = []
for direction in ['ingress', 'egress']:
direction = '-d' if direction == 'ingress' else '-s'
remote_ip_direction = '-s' if direction == '-d' else '-d'
conntrack_cmd = ['conntrack', '-D', '-f', ethertype,
direction, ips[ethertype][0]]
if ct_zone:
conntrack_cmd.extend(['-w', 10])
conntrack_cmd.extend([remote_ip_direction, ips[ethertype][1]])
calls.append(mock.call(conntrack_cmd,
run_as_root=True, check_exit_code=True,
extra_ok_codes=[1]))
self.utils_exec.assert_has_calls(calls)
@@ -1414,6 +1463,12 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
self.v4filter_inst.assert_has_calls(calls)
def test_delete_conntrack_from_delete_port(self):
self._test_delete_conntrack_from_delete_port(ct_zone=10)
def test_delete_conntrack_from_delete_port_no_ct_zone(self):
self._test_delete_conntrack_from_delete_port(ct_zone=None)
def _test_delete_conntrack_from_delete_port(self, ct_zone):
port = self._fake_port()
port['security_groups'] = ['fake_sg_id']
self.firewall.filtered_ports = {'tapfake_dev': port}
@@ -1425,24 +1480,15 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
new_port['fixed_ips'] = ['10.0.0.2', 'fe80::2']
self.firewall.sg_members['fake_sg_id2'] = {'IPv4': ['10.0.0.2'],
'IPv6': ['fe80::2']}
if ct_zone:
self.firewall.ipconntrack._device_zone_map['tapfake_dev'] = ct_zone
else:
self.firewall.ipconntrack._device_zone_map.pop('tapfake_dev', None)
self.firewall.remove_port_filter(port)
calls = [
mock.call(['conntrack', '-D', '-f', 'ipv4', '-d',
'10.0.0.1', '-w', 10],
run_as_root=True, check_exit_code=True,
extra_ok_codes=[1]),
mock.call(['conntrack', '-D', '-f', 'ipv4', '-s',
'10.0.0.1', '-w', 10],
run_as_root=True, check_exit_code=True,
extra_ok_codes=[1]),
mock.call(['conntrack', '-D', '-f', 'ipv6', '-d',
'fe80::1', '-w', 10],
run_as_root=True, check_exit_code=True,
extra_ok_codes=[1]),
mock.call(['conntrack', '-D', '-f', 'ipv6', '-s',
'fe80::1', '-w', 10],
run_as_root=True, check_exit_code=True,
extra_ok_codes=[1])]
calls = self._get_expected_conntrack_calls(
[('ipv4', '10.0.0.1'), ('ipv6', 'fe80::1')], ct_zone)
self.utils_exec.assert_has_calls(calls)
def test_remove_unknown_port(self):