From 7d7fcf1d126d764a273b96d8ba1c940327470841 Mon Sep 17 00:00:00 2001 From: Ghe Rivero Date: Wed, 23 Jan 2013 12:53:43 +0100 Subject: [PATCH] iptables-restore error when table not loaded. When adding openstack rules, if a table module is not loaded, the resulted file doesn't include the section for the missing table, making new rules added to it, out of place and a no valid file for iptables-restore Fixes bug #1103436 Change-Id: I34ae51a23efec57bfec37b8fa378d043fcf62d70 --- nova/network/linux_net.py | 14 ++++++++++++-- nova/tests/test_iptables_network.py | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index a9b44e94a116..f090064a3529 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -378,7 +378,7 @@ class IptablesManager(object): for table in tables: start, end = self._find_table(all_lines, table) all_lines[start:end] = self._modify_rules( - all_lines[start:end], tables[table]) + all_lines[start:end], tables[table], table_name=table) self.execute('%s-restore' % (cmd,), '-c', run_as_root=True, process_input='\n'.join(all_lines), attempts=5) @@ -397,13 +397,20 @@ class IptablesManager(object): end = lines[start:].index('COMMIT') + start + 2 return (start, end) - def _modify_rules(self, current_lines, table, binary=None): + def _modify_rules(self, current_lines, table, binary=None, + table_name=None): unwrapped_chains = table.unwrapped_chains chains = table.chains remove_chains = table.remove_chains rules = table.rules remove_rules = table.remove_rules + if not current_lines: + fake_table = ['#Generated by nova', + '*' + table_name, 'COMMIT', + '#Completed by nova'] + current_lines = fake_table + # Remove any trace of our rules new_filter = filter(lambda line: binary_name not in line, current_lines) @@ -418,6 +425,9 @@ class IptablesManager(object): if not rule.startswith(':'): break + if not seen_chains: + rules_index = 2 + our_rules = [] bot_rules = [] for rule in rules: diff --git a/nova/tests/test_iptables_network.py b/nova/tests/test_iptables_network.py index c8f310303ea7..95af25ebda8d 100644 --- a/nova/tests/test_iptables_network.py +++ b/nova/tests/test_iptables_network.py @@ -170,3 +170,22 @@ class IptablesManagerTestCase(test.TestCase): self.assertTrue('[0:0] -A %s -j %s-%s' % (chain, self.binary_name, chain) in new_lines, "Built-in chain %s not wrapped" % (chain,)) + + def test_missing_table(self): + current_lines = [] + new_lines = self.manager._modify_rules(current_lines, + self.manager.ipv4['filter'], + table_name='filter') + + for line in ['*filter', + 'COMMIT']: + self.assertTrue(line in new_lines, "One of iptables key lines" + "went missing.") + + self.assertTrue(len(new_lines) > 4, "No iptables rules added") + + self.assertTrue("#Generated by nova" == new_lines[0] and + "*filter" == new_lines[1] and + "COMMIT" == new_lines[-2] and + "#Completed by nova" == new_lines[-1], + "iptables rules not generated in the correct order")