Preventing iptables rule to be thrashed
When update meter label or rule, iptables_manager will update iptables rule in router's namespace. In order to, it will clean traffic counter number collected in interval time, the other iptables always trashing that will clean old iptalbes rule and generate new same significance iptables rule. Change-Id: Ide2b26c98587258175234acded38ce481b7e7f76 Closes-Bug: #1618879
This commit is contained in:
parent
1a4cce9f34
commit
5b7c71a327
|
@ -118,7 +118,10 @@ class IptablesRule(object):
|
|||
chain = '%s-%s' % (self.wrap_name, self.chain)
|
||||
else:
|
||||
chain = self.chain
|
||||
return comment_rule('-A %s %s' % (chain, self.rule), self.comment)
|
||||
rule = '-A %s %s' % (chain, self.rule)
|
||||
# If self.rule is '' the above will cause a trailing space, which
|
||||
# could cause us to not match on save/restore, so strip it now.
|
||||
return comment_rule(rule.strip(), self.comment)
|
||||
|
||||
|
||||
class IptablesTable(object):
|
||||
|
|
|
@ -181,9 +181,9 @@ class IptablesMeteringDriver(abstract_driver.MeteringAbstractDriver):
|
|||
def _prepare_rule(self, ext_dev, rule, label_chain):
|
||||
remote_ip = rule['remote_ip_prefix']
|
||||
if rule['direction'] == 'egress':
|
||||
dir_opt = '-o %s -d %s' % (ext_dev, remote_ip)
|
||||
dir_opt = '-d %s -o %s' % (remote_ip, ext_dev)
|
||||
else:
|
||||
dir_opt = '-i %s -s %s' % (ext_dev, remote_ip)
|
||||
dir_opt = '-s %s -i %s' % (remote_ip, ext_dev)
|
||||
|
||||
if rule['excluded']:
|
||||
ipt_rule = '%s -j RETURN' % dir_opt
|
||||
|
|
|
@ -132,6 +132,50 @@ TRAFFIC_COUNTERS_DUMP = (
|
|||
' 400 65901 chain2 all -- * * 0.0.0.0/0'
|
||||
' 0.0.0.0/0 \n')
|
||||
|
||||
FILTER_RESTORE_DUMP = ('# Generated by iptables_manager\n'
|
||||
'*filter\n'
|
||||
':FORWARD - [0:0]\n'
|
||||
':INPUT - [0:0]\n'
|
||||
':OUTPUT - [0:0]\n'
|
||||
':neutron-filter-top - [0:0]\n'
|
||||
':%(bn)s-FORWARD - [0:0]\n'
|
||||
':%(bn)s-INPUT - [0:0]\n'
|
||||
':%(bn)s-OUTPUT - [0:0]\n'
|
||||
':%(bn)s-test-filter - [0:0]\n'
|
||||
':%(bn)s-local - [0:0]\n'
|
||||
'-A FORWARD -j neutron-filter-top\n'
|
||||
'-A FORWARD -j %(bn)s-FORWARD\n'
|
||||
'-A INPUT -j %(bn)s-INPUT\n'
|
||||
'-A OUTPUT -j neutron-filter-top\n'
|
||||
'-A OUTPUT -j %(bn)s-OUTPUT\n'
|
||||
'-A neutron-filter-top -j %(bn)s-local\n'
|
||||
'%(filter_rules)s'
|
||||
'COMMIT\n'
|
||||
'# Completed by iptables_manager\n')
|
||||
|
||||
NAT_RESTORE_TEMPLATE = ('# Generated by iptables_manager\n'
|
||||
'*nat\n'
|
||||
':OUTPUT - [0:0]\n'
|
||||
':POSTROUTING - [0:0]\n'
|
||||
':PREROUTING - [0:0]\n'
|
||||
':neutron-postrouting-bottom - [0:0]\n'
|
||||
':%(bn)s-OUTPUT - [0:0]\n'
|
||||
':%(bn)s-POSTROUTING - [0:0]\n'
|
||||
':%(bn)s-PREROUTING - [0:0]\n'
|
||||
':%(bn)s-float-snat - [0:0]\n'
|
||||
':%(bn)s-snat - [0:0]\n'
|
||||
'-A OUTPUT -j %(bn)s-OUTPUT\n'
|
||||
'-A POSTROUTING -j %(bn)s-POSTROUTING\n'
|
||||
'-A POSTROUTING -j neutron-postrouting-bottom\n'
|
||||
'-A PREROUTING -j %(bn)s-PREROUTING\n'
|
||||
'-A neutron-postrouting-bottom -j %(bn)s-snat\n'
|
||||
'-A %(bn)s-snat -j '
|
||||
'%(bn)s-float-snat\n'
|
||||
'COMMIT\n'
|
||||
'# Completed by iptables_manager\n')
|
||||
|
||||
NAT_RESTORE_DUMP = NAT_RESTORE_TEMPLATE % IPTABLES_ARG
|
||||
|
||||
|
||||
class IptablesTestCase(base.BaseTestCase):
|
||||
|
||||
|
@ -281,9 +325,47 @@ def _generate_raw_dump(iptables_args):
|
|||
'# Completed by iptables_manager\n' % iptables_args)
|
||||
|
||||
|
||||
def _generate_mangle_restore_dump(iptables_args):
|
||||
return ('# Generated by iptables_manager\n'
|
||||
'*mangle\n'
|
||||
':FORWARD - [0:0]\n'
|
||||
':INPUT - [0:0]\n'
|
||||
':OUTPUT - [0:0]\n'
|
||||
':POSTROUTING - [0:0]\n'
|
||||
':PREROUTING - [0:0]\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-mark - [0:0]\n'
|
||||
'-A FORWARD -j %(bn)s-FORWARD\n'
|
||||
'-A INPUT -j %(bn)s-INPUT\n'
|
||||
'-A OUTPUT -j %(bn)s-OUTPUT\n'
|
||||
'-A POSTROUTING -j %(bn)s-POSTROUTING\n'
|
||||
'-A PREROUTING -j %(bn)s-PREROUTING\n'
|
||||
'-A %(bn)s-PREROUTING -j %(bn)s-mark\n'
|
||||
'COMMIT\n'
|
||||
'# Completed by iptables_manager\n' % iptables_args)
|
||||
|
||||
|
||||
def _generate_raw_restore_dump(iptables_args):
|
||||
return ('# Generated by iptables_manager\n'
|
||||
'*raw\n'
|
||||
':OUTPUT - [0:0]\n'
|
||||
':PREROUTING - [0:0]\n'
|
||||
':%(bn)s-OUTPUT - [0:0]\n'
|
||||
':%(bn)s-PREROUTING - [0:0]\n'
|
||||
'-A OUTPUT -j %(bn)s-OUTPUT\n'
|
||||
'-A PREROUTING -j %(bn)s-PREROUTING\n'
|
||||
'COMMIT\n'
|
||||
'# Completed by iptables_manager\n' % iptables_args)
|
||||
|
||||
MANGLE_DUMP = _generate_mangle_dump(IPTABLES_ARG)
|
||||
MANGLE_DUMP_V6 = _generate_mangle_dump_v6(IPTABLES_ARG)
|
||||
RAW_DUMP = _generate_raw_dump(IPTABLES_ARG)
|
||||
MANGLE_RESTORE_DUMP = _generate_mangle_restore_dump(IPTABLES_ARG)
|
||||
RAW_RESTORE_DUMP = _generate_raw_restore_dump(IPTABLES_ARG)
|
||||
|
||||
|
||||
class IptablesManagerStateFulTestCase(base.BaseTestCase):
|
||||
|
@ -1086,6 +1168,77 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
|
|||
def test_get_traffic_counters_with_zero_with_ipv6(self):
|
||||
self._test_get_traffic_counters_with_zero_helper(True)
|
||||
|
||||
def test_add_blank_rule(self):
|
||||
self.iptables = iptables_manager.IptablesManager(
|
||||
use_ipv6=False)
|
||||
self.execute = mock.patch.object(self.iptables, "execute").start()
|
||||
|
||||
iptables_args = {}
|
||||
iptables_args.update(IPTABLES_ARG)
|
||||
filter_rules = ('-A %(bn)s-test-filter\n' % iptables_args)
|
||||
iptables_args['filter_rules'] = filter_rules
|
||||
filter_dump_mod = FILTER_RESTORE_DUMP % iptables_args
|
||||
|
||||
expected_calls_and_values = [
|
||||
(mock.call(['iptables-save'],
|
||||
run_as_root=True),
|
||||
(filter_dump_mod + MANGLE_RESTORE_DUMP +
|
||||
NAT_RESTORE_DUMP + RAW_RESTORE_DUMP)),
|
||||
]
|
||||
|
||||
tools.setup_mock_calls(self.execute, expected_calls_and_values)
|
||||
|
||||
self.iptables.ipv4['filter'].add_chain('test-filter')
|
||||
self.iptables.ipv4['filter'].add_rule('test-filter', '')
|
||||
|
||||
self.iptables.apply()
|
||||
|
||||
tools.verify_mock_calls(self.execute, expected_calls_and_values)
|
||||
|
||||
def test_add_rule_exchanged_interface_and_ip(self):
|
||||
self.iptables = iptables_manager.IptablesManager(
|
||||
use_ipv6=False)
|
||||
self.execute = mock.patch.object(self.iptables, "execute").start()
|
||||
|
||||
iptables_args = {}
|
||||
iptables_args.update(IPTABLES_ARG)
|
||||
filter_rules = ('-A %(bn)s-test-filter -d 192.168.0.2 -i tap-xxx '
|
||||
'-j ACCEPT\n'
|
||||
% iptables_args)
|
||||
iptables_args['filter_rules'] = filter_rules
|
||||
filter_dump_mod = FILTER_RESTORE_DUMP % iptables_args
|
||||
|
||||
RESTORE_INPUT = ('# Generated by iptables_manager\n'
|
||||
'*filter\n'
|
||||
'-D run.py-test-filter 1\n'
|
||||
'-I run.py-test-filter 1 '
|
||||
'-i tap-xxx -d 192.168.0.2 -j ACCEPT\n'
|
||||
'COMMIT\n'
|
||||
'# Completed by iptables_manager\n'
|
||||
% IPTABLES_ARG)
|
||||
|
||||
expected_calls_and_values = [
|
||||
(mock.call(['iptables-save'],
|
||||
run_as_root=True),
|
||||
(filter_dump_mod + MANGLE_RESTORE_DUMP +
|
||||
NAT_RESTORE_DUMP + RAW_RESTORE_DUMP)),
|
||||
(mock.call(['iptables-restore', '-n'],
|
||||
process_input=RESTORE_INPUT,
|
||||
run_as_root=True),
|
||||
None),
|
||||
]
|
||||
|
||||
tools.setup_mock_calls(self.execute, expected_calls_and_values)
|
||||
|
||||
self.iptables.ipv4['filter'].add_chain('test-filter')
|
||||
self.iptables.ipv4['filter'].add_rule('test-filter',
|
||||
'-i tap-xxx -d 192.168.0.2 '
|
||||
'-j ACCEPT')
|
||||
|
||||
self.iptables.apply()
|
||||
|
||||
tools.verify_mock_calls(self.execute, expected_calls_and_values)
|
||||
|
||||
|
||||
class IptablesManagerStateLessTestCase(base.BaseTestCase):
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ class IptablesDriverTestCase(base.BaseTestCase):
|
|||
'',
|
||||
wrap=False),
|
||||
mock.call.add_rule('neutron-meter-r-c5df2fe5-c60',
|
||||
'-i qg-6d411f48-ec -s 10.0.0.0/24'
|
||||
'-s 10.0.0.0/24 -i qg-6d411f48-ec'
|
||||
' -j neutron-meter-l-c5df2fe5-c60',
|
||||
wrap=False, top=False),
|
||||
mock.call.add_chain('neutron-meter-l-eeef45da-c60',
|
||||
|
@ -160,7 +160,7 @@ class IptablesDriverTestCase(base.BaseTestCase):
|
|||
'',
|
||||
wrap=False),
|
||||
mock.call.add_rule('neutron-meter-r-eeef45da-c60',
|
||||
'-o qg-7d411f48-ec -d 20.0.0.0/24'
|
||||
'-d 20.0.0.0/24 -o qg-7d411f48-ec'
|
||||
' -j neutron-meter-l-eeef45da-c60',
|
||||
wrap=False, top=False)]
|
||||
|
||||
|
@ -215,7 +215,7 @@ class IptablesDriverTestCase(base.BaseTestCase):
|
|||
'',
|
||||
wrap=False),
|
||||
mock.call.add_rule('neutron-meter-r-c5df2fe5-c60',
|
||||
'-i qg-6d411f48-ec -s 10.0.0.0/24'
|
||||
'-s 10.0.0.0/24 -i qg-6d411f48-ec'
|
||||
' -j neutron-meter-l-c5df2fe5-c60',
|
||||
wrap=False, top=False),
|
||||
mock.call.add_chain('neutron-meter-l-eeef45da-c60',
|
||||
|
@ -229,7 +229,7 @@ class IptablesDriverTestCase(base.BaseTestCase):
|
|||
'',
|
||||
wrap=False),
|
||||
mock.call.add_rule('neutron-meter-r-eeef45da-c60',
|
||||
'-i qg-7d411f48-ec -s 20.0.0.0/24'
|
||||
'-s 20.0.0.0/24 -i qg-7d411f48-ec'
|
||||
' -j RETURN',
|
||||
wrap=False, top=True)]
|
||||
|
||||
|
@ -266,17 +266,17 @@ class IptablesDriverTestCase(base.BaseTestCase):
|
|||
'',
|
||||
wrap=False),
|
||||
mock.call.add_rule('neutron-meter-r-c5df2fe5-c60',
|
||||
'-i qg-6d411f48-ec -s 10.0.0.0/24'
|
||||
'-s 10.0.0.0/24 -i qg-6d411f48-ec'
|
||||
' -j neutron-meter-l-c5df2fe5-c60',
|
||||
wrap=False, top=False),
|
||||
mock.call.empty_chain('neutron-meter-r-c5df2fe5-c60',
|
||||
wrap=False),
|
||||
mock.call.add_rule('neutron-meter-r-c5df2fe5-c60',
|
||||
'-o qg-6d411f48-ec -d 10.0.0.0/24'
|
||||
'-d 10.0.0.0/24 -o qg-6d411f48-ec'
|
||||
' -j RETURN',
|
||||
wrap=False, top=True),
|
||||
mock.call.add_rule('neutron-meter-r-c5df2fe5-c60',
|
||||
'-i qg-6d411f48-ec -s 20.0.0.0/24 -j '
|
||||
'-s 20.0.0.0/24 -i qg-6d411f48-ec -j '
|
||||
'neutron-meter-l-c5df2fe5-c60',
|
||||
wrap=False, top=False)]
|
||||
|
||||
|
@ -308,17 +308,17 @@ class IptablesDriverTestCase(base.BaseTestCase):
|
|||
'',
|
||||
wrap=False),
|
||||
mock.call.add_rule('neutron-meter-r-c5df2fe5-c60',
|
||||
'-i qg-6d411f48-ec -s 10.0.0.0/24'
|
||||
'-s 10.0.0.0/24 -i qg-6d411f48-ec'
|
||||
' -j neutron-meter-l-c5df2fe5-c60',
|
||||
wrap=False, top=False),
|
||||
mock.call.add_rule('neutron-meter-r-c5df2fe5-c60',
|
||||
'-i qg-6d411f48-ec -s 20.0.0.0/24'
|
||||
'-s 20.0.0.0/24 -i qg-6d411f48-ec'
|
||||
' -j neutron-meter-l-c5df2fe5-c60',
|
||||
wrap=False, top=False),
|
||||
mock.call.empty_chain('neutron-meter-r-c5df2fe5-c60',
|
||||
wrap=False),
|
||||
mock.call.add_rule('neutron-meter-r-c5df2fe5-c60',
|
||||
'-i qg-6d411f48-ec -s 10.0.0.0/24'
|
||||
'-s 10.0.0.0/24 -i qg-6d411f48-ec'
|
||||
' -j neutron-meter-l-c5df2fe5-c60',
|
||||
wrap=False, top=False)]
|
||||
|
||||
|
@ -330,11 +330,11 @@ class IptablesDriverTestCase(base.BaseTestCase):
|
|||
self.metering.add_metering_label_rule(None, new_routers_rules)
|
||||
calls = [
|
||||
mock.call.add_rule('neutron-meter-r-c5df2fe5-c60',
|
||||
'-i qg-6d411f48-ec -s 30.0.0.0/24'
|
||||
'-s 30.0.0.0/24 -i qg-6d411f48-ec'
|
||||
' -j neutron-meter-l-c5df2fe5-c60',
|
||||
wrap=False, top=False),
|
||||
mock.call.add_rule('neutron-meter-r-eeef45da-c60',
|
||||
'-o qg-7d411f48-ec -d 40.0.0.0/24'
|
||||
'-d 40.0.0.0/24 -o qg-7d411f48-ec'
|
||||
' -j neutron-meter-l-eeef45da-c60',
|
||||
wrap=False, top=False),
|
||||
|
||||
|
@ -348,11 +348,11 @@ class IptablesDriverTestCase(base.BaseTestCase):
|
|||
self.metering.remove_metering_label_rule(None, new_routers_rules)
|
||||
calls = [
|
||||
mock.call.remove_rule('neutron-meter-r-c5df2fe5-c60',
|
||||
'-i qg-6d411f48-ec -s 30.0.0.0/24'
|
||||
'-s 30.0.0.0/24 -i qg-6d411f48-ec'
|
||||
' -j neutron-meter-l-c5df2fe5-c60',
|
||||
wrap=False, top=False),
|
||||
mock.call.remove_rule('neutron-meter-r-eeef45da-c60',
|
||||
'-o qg-7d411f48-ec -d 40.0.0.0/24'
|
||||
'-d 40.0.0.0/24 -o qg-7d411f48-ec'
|
||||
' -j neutron-meter-l-eeef45da-c60',
|
||||
wrap=False, top=False)
|
||||
]
|
||||
|
@ -374,7 +374,7 @@ class IptablesDriverTestCase(base.BaseTestCase):
|
|||
'',
|
||||
wrap=False),
|
||||
mock.call.add_rule('neutron-meter-r-c5df2fe5-c60',
|
||||
'-i qg-6d411f48-ec -s 10.0.0.0/24'
|
||||
'-s 10.0.0.0/24 -i qg-6d411f48-ec'
|
||||
' -j neutron-meter-l-c5df2fe5-c60',
|
||||
wrap=False, top=False),
|
||||
mock.call.remove_chain('neutron-meter-l-c5df2fe5-c60',
|
||||
|
@ -408,7 +408,7 @@ class IptablesDriverTestCase(base.BaseTestCase):
|
|||
'',
|
||||
wrap=False),
|
||||
mock.call.add_rule('neutron-meter-r-c5df2fe5-c60',
|
||||
'-i qg-6d411f48-ec -s 10.0.0.0/24'
|
||||
'-s 10.0.0.0/24 -i qg-6d411f48-ec'
|
||||
' -j neutron-meter-l-c5df2fe5-c60',
|
||||
wrap=False, top=False),
|
||||
mock.call.add_chain('neutron-meter-l-eeef45da-c60',
|
||||
|
@ -422,7 +422,7 @@ class IptablesDriverTestCase(base.BaseTestCase):
|
|||
'',
|
||||
wrap=False),
|
||||
mock.call.add_rule('neutron-meter-r-eeef45da-c60',
|
||||
'-i qg-7d411f48-ec -s 20.0.0.0/24'
|
||||
'-s 20.0.0.0/24 -i qg-7d411f48-ec'
|
||||
' -j RETURN',
|
||||
wrap=False, top=True),
|
||||
mock.call.remove_chain('neutron-meter-l-c5df2fe5-c60',
|
||||
|
@ -440,7 +440,7 @@ class IptablesDriverTestCase(base.BaseTestCase):
|
|||
'',
|
||||
wrap=False),
|
||||
mock.call.add_rule('neutron-meter-r-c5df2fe5-c60',
|
||||
'-i qg-587b63c1-22 -s 10.0.0.0/24'
|
||||
'-s 10.0.0.0/24 -i qg-587b63c1-22'
|
||||
' -j neutron-meter-l-c5df2fe5-c60',
|
||||
wrap=False, top=False)]
|
||||
|
||||
|
|
Loading…
Reference in New Issue