Allow IptablesManager to manage mangle table

This change enables the IptablesManager to manage mangle table (used
by daughter change).

Partial-Bug: #1187102
Change-Id: Ic2d681f1515aaa541c6d137ce981622f2fff90e5
This commit is contained in:
Cedric Brandily 2014-11-18 10:34:30 +01:00
parent f83b08abf5
commit c7e533c367
5 changed files with 179 additions and 19 deletions

View File

@ -316,6 +316,11 @@ class IptablesManager(object):
6: {'filter': ['INPUT', 'OUTPUT', 'FORWARD']}}
if not state_less:
self.ipv4.update(
{'mangle': IptablesTable(binary_name=self.wrap_name)})
builtin_chains[4].update(
{'mangle': ['PREROUTING', 'INPUT', 'FORWARD', 'OUTPUT',
'POSTROUTING']})
self.ipv4.update(
{'nat': IptablesTable(binary_name=self.wrap_name)})
builtin_chains[4].update({'nat': ['PREROUTING',

View File

@ -28,6 +28,11 @@ from neutron.tests import sub_base
BR_PREFIX = 'test-br'
PORT_PREFIX = 'test-port'
MARK_VALUE = '0x1'
MARK_MASK = '0xffffffff'
ICMP_MARK_RULE = ('-j MARK --set-xmark %(value)s/%(mask)s'
% {'value': MARK_VALUE, 'mask': MARK_MASK})
MARKED_BLOCK_RULE = '-m mark --mark %s -j DROP' % MARK_VALUE
ICMP_BLOCK_RULE = '-p icmp -j DROP'
VETH_PREFIX = 'tst-vth'

View File

@ -35,3 +35,16 @@ class IptablesManagerTestCase(base.BaseIPVethTestCase):
base.ICMP_BLOCK_RULE)
self.iptables.apply()
self.pinger.assert_ping_from_ns(self.src_ns, self.DST_ADDRESS)
def test_mangle_icmp(self):
self.pinger.assert_ping_from_ns(self.src_ns, self.DST_ADDRESS)
self.iptables.ipv4['mangle'].add_rule('INPUT', base.ICMP_MARK_RULE)
self.iptables.ipv4['filter'].add_rule('INPUT', base.MARKED_BLOCK_RULE)
self.iptables.apply()
self.pinger.assert_no_ping_from_ns(self.src_ns, self.DST_ADDRESS)
self.iptables.ipv4['mangle'].remove_rule('INPUT',
base.ICMP_MARK_RULE)
self.iptables.ipv4['filter'].remove_rule('INPUT',
base.MARKED_BLOCK_RULE)
self.iptables.apply()
self.pinger.assert_ping_from_ns(self.src_ns, self.DST_ADDRESS)

View File

@ -153,22 +153,23 @@ class IptablesCommentsTestCase(base.BaseTestCase):
filter_dump_mod = FILTER_WITH_RULES_TEMPLATE % iptables_args
raw_dump = _generate_raw_dump(IPTABLES_ARG)
mangle_dump = _generate_mangle_dump(IPTABLES_ARG)
expected_calls_and_values = [
(mock.call(['iptables-save', '-c'],
root_helper=self.root_helper),
''),
(mock.call(['iptables-restore', '-c'],
process_input=(
raw_dump + COMMENTED_NAT_DUMP + filter_dump_mod),
process_input=(raw_dump + COMMENTED_NAT_DUMP +
mangle_dump + filter_dump_mod),
root_helper=self.root_helper),
None),
(mock.call(['iptables-save', '-c'],
root_helper=self.root_helper),
''),
(mock.call(['iptables-restore', '-c'],
process_input=(
raw_dump + COMMENTED_NAT_DUMP + FILTER_DUMP),
process_input=(raw_dump + COMMENTED_NAT_DUMP +
mangle_dump + FILTER_DUMP),
root_helper=self.root_helper
),
None),
@ -194,6 +195,23 @@ class IptablesCommentsTestCase(base.BaseTestCase):
tools.verify_mock_calls(self.execute, expected_calls_and_values)
def _generate_mangle_dump(iptables_args):
return ('# Generated by iptables_manager\n'
'*mangle\n'
':%(bn)s-FORWARD - [0:0]\n'
':%(bn)s-INPUT - [0:0]\n'
':%(bn)s-OUTPUT - [0:0]\n'
':%(bn)s-POSTROUTING - [0:0]\n'
':%(bn)s-PREROUTING - [0:0]\n'
'[0:0] -A PREROUTING -j %(bn)s-PREROUTING\n'
'[0:0] -A INPUT -j %(bn)s-INPUT\n'
'[0:0] -A FORWARD -j %(bn)s-FORWARD\n'
'[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
'[0:0] -A POSTROUTING -j %(bn)s-POSTROUTING\n'
'COMMIT\n'
'# Completed by iptables_manager\n' % iptables_args)
def _generate_raw_dump(iptables_args):
return ('# Generated by iptables_manager\n'
'*raw\n'
@ -204,6 +222,7 @@ def _generate_raw_dump(iptables_args):
'COMMIT\n'
'# Completed by iptables_manager\n' % iptables_args)
MANGLE_DUMP = _generate_mangle_dump(IPTABLES_ARG)
RAW_DUMP = _generate_raw_dump(IPTABLES_ARG)
@ -271,20 +290,23 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
nat_dump = NAT_TEMPLATE % iptables_args
raw_dump = _generate_raw_dump(iptables_args)
mangle_dump = _generate_mangle_dump(iptables_args)
expected_calls_and_values = [
(mock.call(['iptables-save', '-c'],
root_helper=self.root_helper),
''),
(mock.call(['iptables-restore', '-c'],
process_input=raw_dump + nat_dump + filter_dump_mod,
process_input=(raw_dump + nat_dump + mangle_dump +
filter_dump_mod),
root_helper=self.root_helper),
None),
(mock.call(['iptables-save', '-c'],
root_helper=self.root_helper),
''),
(mock.call(['iptables-restore', '-c'],
process_input=raw_dump + nat_dump + filter_dump,
process_input=(raw_dump + nat_dump + mangle_dump +
filter_dump),
root_helper=self.root_helper),
None),
]
@ -329,20 +351,23 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
nat_dump = NAT_TEMPLATE % iptables_args
raw_dump = _generate_raw_dump(iptables_args)
mangle_dump = _generate_mangle_dump(iptables_args)
expected_calls_and_values = [
(mock.call(['iptables-save', '-c'],
root_helper=self.root_helper),
''),
(mock.call(['iptables-restore', '-c'],
process_input=raw_dump + nat_dump + filter_dump_mod,
process_input=(raw_dump + nat_dump + mangle_dump +
filter_dump_mod),
root_helper=self.root_helper),
None),
(mock.call(['iptables-save', '-c'],
root_helper=self.root_helper),
''),
(mock.call(['iptables-restore', '-c'],
process_input=raw_dump + nat_dump + filter_dump,
process_input=(raw_dump + nat_dump + mangle_dump +
filter_dump),
root_helper=self.root_helper),
None),
]
@ -381,14 +406,16 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
root_helper=self.root_helper),
''),
(mock.call(['iptables-restore', '-c'],
process_input=RAW_DUMP + NAT_DUMP + filter_dump_mod,
process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
filter_dump_mod),
root_helper=self.root_helper),
None),
(mock.call(['iptables-save', '-c'],
root_helper=self.root_helper),
''),
(mock.call(['iptables-restore', '-c'],
process_input=RAW_DUMP + NAT_DUMP + FILTER_DUMP,
process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
FILTER_DUMP),
root_helper=self.root_helper),
None),
]
@ -431,14 +458,16 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
root_helper=self.root_helper),
''),
(mock.call(['iptables-restore', '-c'],
process_input=RAW_DUMP + NAT_DUMP + filter_dump_mod,
process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
filter_dump_mod),
root_helper=self.root_helper),
None),
(mock.call(['iptables-save', '-c'],
root_helper=self.root_helper),
''),
(mock.call(['iptables-restore', '-c'],
process_input=RAW_DUMP + NAT_DUMP + FILTER_DUMP,
process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
FILTER_DUMP),
root_helper=self.root_helper
),
None),
@ -511,14 +540,16 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
root_helper=self.root_helper),
''),
(mock.call(['iptables-restore', '-c'],
process_input=RAW_DUMP + NAT_DUMP + filter_dump_mod,
process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
filter_dump_mod),
root_helper=self.root_helper),
None),
(mock.call(['iptables-save', '-c'],
root_helper=self.root_helper),
''),
(mock.call(['iptables-restore', '-c'],
process_input=RAW_DUMP + NAT_DUMP + FILTER_DUMP,
process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
FILTER_DUMP),
root_helper=self.root_helper),
None),
]
@ -549,6 +580,77 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
def test_rule_with_wrap_target_with_ipv6(self):
self._test_rule_with_wrap_target_helper(True)
def _test_add_mangle_rule_helper(self, use_ipv6):
self.iptables = iptables_manager.IptablesManager(
root_helper=self.root_helper,
use_ipv6=use_ipv6)
self.execute = mock.patch.object(self.iptables, "execute").start()
mangle_dump_mod = (
'# Generated by iptables_manager\n'
'*mangle\n'
':%(bn)s-FORWARD - [0:0]\n'
':%(bn)s-INPUT - [0:0]\n'
':%(bn)s-OUTPUT - [0:0]\n'
':%(bn)s-POSTROUTING - [0:0]\n'
':%(bn)s-PREROUTING - [0:0]\n'
':%(bn)s-mangle - [0:0]\n'
'[0:0] -A PREROUTING -j %(bn)s-PREROUTING\n'
'[0:0] -A INPUT -j %(bn)s-INPUT\n'
'[0:0] -A FORWARD -j %(bn)s-FORWARD\n'
'[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
'[0:0] -A POSTROUTING -j %(bn)s-POSTROUTING\n'
'[0:0] -A %(bn)s-PREROUTING -j MARK --set-xmark 0x1/0xffffffff\n'
'COMMIT\n'
'# Completed by iptables_manager\n'
% IPTABLES_ARG)
expected_calls_and_values = [
(mock.call(['iptables-save', '-c'],
root_helper=self.root_helper),
''),
(mock.call(['iptables-restore', '-c'],
process_input=(RAW_DUMP + NAT_DUMP + mangle_dump_mod +
FILTER_DUMP),
root_helper=self.root_helper),
None),
(mock.call(['iptables-save', '-c'],
root_helper=self.root_helper),
''),
(mock.call(['iptables-restore', '-c'],
process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
FILTER_DUMP),
root_helper=self.root_helper),
None),
]
if use_ipv6:
self._extend_with_ip6tables_filter(expected_calls_and_values,
FILTER_DUMP)
tools.setup_mock_calls(self.execute, expected_calls_and_values)
self.iptables.ipv4['mangle'].add_chain('mangle')
self.iptables.ipv4['mangle'].add_rule(
'PREROUTING',
'-j MARK --set-xmark 0x1/0xffffffff')
self.iptables.apply()
self.iptables.ipv4['mangle'].remove_rule(
'PREROUTING',
'-j MARK --set-xmark 0x1/0xffffffff')
self.iptables.ipv4['mangle'].remove_chain('mangle')
self.iptables.apply()
tools.verify_mock_calls(self.execute, expected_calls_and_values)
def test_add_mangle_rule(self):
self._test_add_mangle_rule_helper(False)
def test_add_mangle_rule_with_ipv6(self):
self._test_add_mangle_rule_helper(True)
def _test_add_nat_rule_helper(self, use_ipv6):
self.iptables = iptables_manager.IptablesManager(
root_helper=self.root_helper,
@ -585,14 +687,16 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
root_helper=self.root_helper),
''),
(mock.call(['iptables-restore', '-c'],
process_input=RAW_DUMP + nat_dump_mod + FILTER_DUMP,
process_input=(RAW_DUMP + nat_dump_mod + MANGLE_DUMP +
FILTER_DUMP),
root_helper=self.root_helper),
None),
(mock.call(['iptables-save', '-c'],
root_helper=self.root_helper),
''),
(mock.call(['iptables-restore', '-c'],
process_input=RAW_DUMP + nat_dump + FILTER_DUMP,
process_input=(RAW_DUMP + nat_dump + MANGLE_DUMP +
FILTER_DUMP),
root_helper=self.root_helper),
None),
]
@ -653,14 +757,16 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
root_helper=self.root_helper),
''),
(mock.call(['iptables-restore', '-c'],
process_input=raw_dump_mod + NAT_DUMP + FILTER_DUMP,
process_input=(raw_dump_mod + NAT_DUMP + MANGLE_DUMP +
FILTER_DUMP),
root_helper=self.root_helper),
None),
(mock.call(['iptables-save', '-c'],
root_helper=self.root_helper),
''),
(mock.call(['iptables-restore', '-c'],
process_input=RAW_DUMP + NAT_DUMP + FILTER_DUMP,
process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
FILTER_DUMP),
root_helper=self.root_helper),
None),
]
@ -799,6 +905,10 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
'-v', '-x'],
root_helper=self.root_helper),
''),
(mock.call(['iptables', '-t', 'mangle', '-L', 'OUTPUT', '-n',
'-v', '-x'],
root_helper=self.root_helper),
''),
(mock.call(['iptables', '-t', 'nat', '-L', 'OUTPUT', '-n',
'-v', '-x'],
root_helper=self.root_helper),
@ -845,6 +955,10 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
'-v', '-x', '-Z'],
root_helper=self.root_helper),
''),
(mock.call(['iptables', '-t', 'mangle', '-L', 'OUTPUT', '-n',
'-v', '-x', '-Z'],
root_helper=self.root_helper),
''),
(mock.call(['iptables', '-t', 'nat', '-L', 'OUTPUT', '-n',
'-v', '-x', '-Z'],
root_helper=self.root_helper),
@ -909,3 +1023,6 @@ class IptablesManagerStateLessTestCase(base.BaseTestCase):
def test_nat_not_found(self):
self.assertNotIn('nat', self.iptables.ipv4)
def test_mangle_not_found(self):
self.assertNotIn('mangle', self.iptables.ipv4)

View File

@ -1678,6 +1678,25 @@ IPTABLES_ARG = {'bn': iptables_manager.binary_name,
'physdev_mod': PHYSDEV_MOD,
'physdev_is_bridged': PHYSDEV_IS_BRIDGED}
CHAINS_MANGLE = 'FORWARD|INPUT|OUTPUT|POSTROUTING|PREROUTING'
IPTABLES_ARG['chains'] = CHAINS_MANGLE
IPTABLES_MANGLE = """# Generated by iptables_manager
*mangle
:%(bn)s-(%(chains)s) - [0:0]
:%(bn)s-(%(chains)s) - [0:0]
:%(bn)s-(%(chains)s) - [0:0]
:%(bn)s-(%(chains)s) - [0:0]
:%(bn)s-(%(chains)s) - [0:0]
[0:0] -A PREROUTING -j %(bn)s-PREROUTING
[0:0] -A INPUT -j %(bn)s-INPUT
[0:0] -A FORWARD -j %(bn)s-FORWARD
[0:0] -A OUTPUT -j %(bn)s-OUTPUT
[0:0] -A POSTROUTING -j %(bn)s-POSTROUTING
COMMIT
# Completed by iptables_manager
""" % IPTABLES_ARG
CHAINS_NAT = 'OUTPUT|POSTROUTING|PREROUTING|float-snat|snat'
# These Dicts use the same keys as devices2 and devices3 in
@ -2630,7 +2649,8 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
return_value='')
self._register_mock_call(
['iptables-restore', '-c'],
process_input=self._regex(IPTABLES_RAW + IPTABLES_NAT + v4_filter),
process_input=self._regex(IPTABLES_RAW + IPTABLES_NAT +
IPTABLES_MANGLE + v4_filter),
root_helper=self.root_helper,
return_value='')
self._register_mock_call(