From 27c58c6cf0e02916c862c25a9c0317306001d1e4 Mon Sep 17 00:00:00 2001 From: zhsun Date: Mon, 11 Dec 2017 14:17:33 +0800 Subject: [PATCH] Add missing iptable rule in snat ns for centralized fips. The following iptable rule should be added to snat ns: "-A neutron-l3-agent-snat -j neutron-l3-agent-float-snat", or the snat rule will take effect instead of centralized fips when accessing to the outside for vms. Closes-Bug: #1735866 Change-Id: I286283bfb4dbf935a34c5919ee0af5225e75fac9 (cherry picked from commit 0f08b2c625d9158e7dce80ff2d01ffd273e0d9c3) --- neutron/agent/l3/dvr_edge_router.py | 7 +++++-- .../unit/agent/l3/test_dvr_local_router.py | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/neutron/agent/l3/dvr_edge_router.py b/neutron/agent/l3/dvr_edge_router.py index c5d958f14a0..e2e68c8ce56 100644 --- a/neutron/agent/l3/dvr_edge_router.py +++ b/neutron/agent/l3/dvr_edge_router.py @@ -195,8 +195,11 @@ class DvrEdgeRouter(dvr_local_router.DvrLocalRouter): with self.snat_iptables_manager.defer_apply(): self._empty_snat_chains(self.snat_iptables_manager) - # NOTE: DVR adds the jump to float snat via super class, - # but that is in the router namespace and not snat. + # NOTE: float-snat should be added for the + # centralized floating-ips supported by the + # snat namespace. + self.snat_iptables_manager.ipv4['nat'].add_rule( + 'snat', '-j $float-snat') self._add_snat_rules(ex_gw_port, self.snat_iptables_manager, interface_name) diff --git a/neutron/tests/unit/agent/l3/test_dvr_local_router.py b/neutron/tests/unit/agent/l3/test_dvr_local_router.py index 1e148a5e620..25fba7f2f54 100644 --- a/neutron/tests/unit/agent/l3/test_dvr_local_router.py +++ b/neutron/tests/unit/agent/l3/test_dvr_local_router.py @@ -778,3 +778,22 @@ class TestDvrRouterOperations(base.BaseTestCase): device.exists = mock.Mock(return_value=False) with mock.patch.object(ip_lib, 'IPDevice', return_value=device): self.assertFalse(ri.get_router_cidrs(device)) + + @mock.patch.object(router_info.RouterInfo, '_add_snat_rules') + @mock.patch.object(dvr_router.DvrLocalRouter, '_handle_router_snat_rules') + def test_handle_snat_rule_for_centralized_fip( + self, _add_snat_rules, _handle_router_snat_rules): + agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) + agent.conf.agent_mode = lib_constants.L3_AGENT_MODE_DVR_SNAT + self.mock_driver.unplug.reset_mock() + + router = l3_test_common.prepare_router_data(enable_floating_ip=True) + router['gw_port_host'] = HOSTNAME + self._set_ri_kwargs(agent, router['id'], router) + ri = dvr_edge_rtr.DvrEdgeRouter(HOSTNAME, **self.ri_kwargs) + ri.snat_iptables_manager = mock.MagicMock() + ipv4_nat = ri.snat_iptables_manager.ipv4['nat'] + interface_name, ex_gw_port = l3_test_common.prepare_ext_gw_test(self, + ri) + ri._handle_router_snat_rules(ex_gw_port, interface_name) + ipv4_nat.add_rule.assert_called_once_with('snat', '-j $float-snat')