diff --git a/neutron/agent/l3_agent.py b/neutron/agent/l3_agent.py index f632996d232..113af79bb0b 100644 --- a/neutron/agent/l3_agent.py +++ b/neutron/agent/l3_agent.py @@ -1482,6 +1482,13 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback, manager.Manager): fip_ns_name = ( self.get_fip_ns_name(str(network_id))) self._create_namespace(fip_ns_name) + ri.fip_iptables_manager = iptables_manager.IptablesManager( + root_helper=self.root_helper, namespace=fip_ns_name, + use_ipv6=self.use_ipv6) + # no connection tracking needed in fip namespace + ri.fip_iptables_manager.ipv4['raw'].add_rule('PREROUTING', + '-j CT --notrack') + ri.fip_iptables_manager.apply() interface_name = ( self.get_fip_ext_device_name(self.agent_gateway_port['id'])) self.agent_gateway_added(fip_ns_name, self.agent_gateway_port, diff --git a/neutron/agent/linux/iptables_manager.py b/neutron/agent/linux/iptables_manager.py index ebb34d091f7..1a858fd5d4f 100644 --- a/neutron/agent/linux/iptables_manager.py +++ b/neutron/agent/linux/iptables_manager.py @@ -321,6 +321,10 @@ class IptablesManager(object): {'nat': IptablesTable(binary_name=self.wrap_name)}) builtin_chains[4].update({'nat': ['PREROUTING', 'OUTPUT', 'POSTROUTING']}) + self.ipv4.update( + {'raw': IptablesTable(binary_name=self.wrap_name)}) + builtin_chains[4].update({'raw': ['PREROUTING', + 'OUTPUT']}) for ip_version in builtin_chains: if ip_version == 4: diff --git a/neutron/tests/unit/test_iptables_manager.py b/neutron/tests/unit/test_iptables_manager.py index 48173262f21..cc3abeaebf8 100644 --- a/neutron/tests/unit/test_iptables_manager.py +++ b/neutron/tests/unit/test_iptables_manager.py @@ -62,6 +62,19 @@ FILTER_DUMP = ('# Generated by iptables_manager\n' '# Completed by iptables_manager\n' % IPTABLES_ARG) +def _generate_raw_dump(iptables_args): + return ('# Generated by iptables_manager\n' + '*raw\n' + ':%(bn)s-OUTPUT - [0:0]\n' + ':%(bn)s-PREROUTING - [0:0]\n' + '[0:0] -A PREROUTING -j %(bn)s-PREROUTING\n' + '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n' + 'COMMIT\n' + '# Completed by iptables_manager\n' % iptables_args) + +RAW_DUMP = _generate_raw_dump(IPTABLES_ARG) + + class IptablesManagerStateFulTestCase(base.BaseTestCase): def setUp(self): @@ -185,19 +198,21 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase): 'COMMIT\n' '# Completed by iptables_manager\n' % iptables_args) + raw_dump = _generate_raw_dump(iptables_args) + expected_calls_and_values = [ (mock.call(['iptables-save', '-c'], root_helper=self.root_helper), ''), (mock.call(['iptables-restore', '-c'], - process_input=nat_dump + filter_dump_mod, + process_input=raw_dump + nat_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=nat_dump + filter_dump, + process_input=raw_dump + nat_dump + filter_dump, root_helper=self.root_helper), None), ] @@ -285,19 +300,21 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase): 'COMMIT\n' '# Completed by iptables_manager\n' % iptables_args) + raw_dump = _generate_raw_dump(iptables_args) + expected_calls_and_values = [ (mock.call(['iptables-save', '-c'], root_helper=self.root_helper), ''), (mock.call(['iptables-restore', '-c'], - process_input=nat_dump + filter_dump_mod, + process_input=raw_dump + nat_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=nat_dump + filter_dump, + process_input=raw_dump + nat_dump + filter_dump, root_helper=self.root_helper), None), ] @@ -352,14 +369,14 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase): root_helper=self.root_helper), ''), (mock.call(['iptables-restore', '-c'], - process_input=NAT_DUMP + filter_dump_mod, + process_input=RAW_DUMP + NAT_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=NAT_DUMP + FILTER_DUMP, + process_input=RAW_DUMP + NAT_DUMP + FILTER_DUMP, root_helper=self.root_helper), None), ] @@ -415,14 +432,14 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase): root_helper=self.root_helper), ''), (mock.call(['iptables-restore', '-c'], - process_input=NAT_DUMP + filter_dump_mod, + process_input=RAW_DUMP + NAT_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=NAT_DUMP + FILTER_DUMP, + process_input=RAW_DUMP + NAT_DUMP + FILTER_DUMP, root_helper=self.root_helper ), None), @@ -495,14 +512,14 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase): root_helper=self.root_helper), ''), (mock.call(['iptables-restore', '-c'], - process_input=NAT_DUMP + filter_dump_mod, + process_input=RAW_DUMP + NAT_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=NAT_DUMP + FILTER_DUMP, + process_input=RAW_DUMP + NAT_DUMP + FILTER_DUMP, root_helper=self.root_helper), None), ] @@ -585,14 +602,14 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase): root_helper=self.root_helper), ''), (mock.call(['iptables-restore', '-c'], - process_input=nat_dump_mod + FILTER_DUMP, + process_input=RAW_DUMP + nat_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=nat_dump + FILTER_DUMP, + process_input=RAW_DUMP + nat_dump + FILTER_DUMP, root_helper=self.root_helper), None), ] @@ -630,6 +647,66 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase): def test_add_nat_rule_with_ipv6(self): self._test_add_nat_rule_helper(True) + def _test_add_raw_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() + + raw_dump_mod = ('# Generated by iptables_manager\n' + '*raw\n' + ':%(bn)s-OUTPUT - [0:0]\n' + ':%(bn)s-PREROUTING - [0:0]\n' + ':%(bn)s-raw - [0:0]\n' + '[0:0] -A PREROUTING -j %(bn)s-PREROUTING\n' + '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n' + '[0:0] -A %(bn)s-PREROUTING -j CT --notrack\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_mod + NAT_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, + 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['raw'].add_chain('raw') + self.iptables.ipv4['raw'].add_rule('PREROUTING', + '-j CT --notrack') + + self.iptables.apply() + + self.iptables.ipv4['raw'].remove_rule('PREROUTING', + '-j CT --notrack') + self.iptables.ipv4['raw'].remove_chain('raw') + + self.iptables.apply() + + tools.verify_mock_calls(self.execute, expected_calls_and_values) + + def test_add_raw_rule(self): + self._test_add_raw_rule_helper(False) + + def test_add_raw_rule_with_ipv6(self): + self._test_add_raw_rule_helper(True) + def test_add_rule_to_a_nonexistent_chain(self): self.assertRaises(LookupError, self.iptables.ipv4['filter'].add_rule, 'nonexistent', '-j DROP') @@ -744,6 +821,10 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase): '-n', '-v', '-x'], root_helper=self.root_helper), iptables_dump), + (mock.call(['iptables', '-t', 'raw', '-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), @@ -795,6 +876,10 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase): '-n', '-v', '-x', '-Z'], root_helper=self.root_helper), iptables_dump), + (mock.call(['iptables', '-t', 'raw', '-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), diff --git a/neutron/tests/unit/test_security_groups_rpc.py b/neutron/tests/unit/test_security_groups_rpc.py index c841bf322e8..cd42bb76e7d 100644 --- a/neutron/tests/unit/test_security_groups_rpc.py +++ b/neutron/tests/unit/test_security_groups_rpc.py @@ -1477,6 +1477,16 @@ COMMIT # Completed by iptables_manager """ % IPTABLES_ARG +IPTABLES_RAW = """# Generated by iptables_manager +*raw +:%(bn)s-(%(chains)s) - [0:0] +:%(bn)s-(%(chains)s) - [0:0] +[0:0] -A PREROUTING -j %(bn)s-PREROUTING +[0:0] -A OUTPUT -j %(bn)s-OUTPUT +COMMIT +# Completed by iptables_manager +""" % IPTABLES_ARG + CHAINS_EMPTY = 'FORWARD|INPUT|OUTPUT|local|sg-chain|sg-fallback' CHAINS_1 = CHAINS_EMPTY + '|i_port1|o_port1|s_port1' CHAINS_2 = CHAINS_1 + '|i_port2|o_port2|s_port2' @@ -2157,7 +2167,7 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase): return_value='') self._register_mock_call( ['iptables-restore', '-c'], - process_input=self._regex(IPTABLES_NAT + v4_filter), + process_input=self._regex(IPTABLES_RAW + IPTABLES_NAT + v4_filter), root_helper=self.root_helper, return_value='') self._register_mock_call(