summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2019-03-17 18:45:31 +0000
committerGerrit Code Review <review@openstack.org>2019-03-17 18:45:32 +0000
commit9b897782f82b9852dee15916bcf68651167df1c2 (patch)
treecd5bea51e684e4b299fc98e98a18cbc9fefca933
parent15748a0cd36ded533c3b8dd519f24ec51db3d6be (diff)
parent66eb1e29f31a07573be2a5a7789fb7bfce598827 (diff)
Merge "Enable ipv6_forwarding in HA router's namespace"
-rw-r--r--neutron/agent/l3/ha.py32
-rw-r--r--neutron/tests/functional/agent/l3/framework.py4
-rw-r--r--neutron/tests/functional/agent/l3/test_ha_router.py25
-rw-r--r--neutron/tests/unit/agent/l3/test_agent.py58
4 files changed, 82 insertions, 37 deletions
diff --git a/neutron/agent/l3/ha.py b/neutron/agent/l3/ha.py
index 9ef3bd8..899be9b 100644
--- a/neutron/agent/l3/ha.py
+++ b/neutron/agent/l3/ha.py
@@ -125,7 +125,7 @@ class AgentMixin(object):
125 # configuration to keepalived-state-change in order to remove the 125 # configuration to keepalived-state-change in order to remove the
126 # dependency that currently exists on l3-agent running for the IPv6 126 # dependency that currently exists on l3-agent running for the IPv6
127 # failover. 127 # failover.
128 self._configure_ipv6_params_on_ext_gw_port_if_necessary(ri, state) 128 self._configure_ipv6_params(ri, state)
129 if self.conf.enable_metadata_proxy: 129 if self.conf.enable_metadata_proxy:
130 self._update_metadata_proxy(ri, router_id, state) 130 self._update_metadata_proxy(ri, router_id, state)
131 self._update_radvd_daemon(ri, state) 131 self._update_radvd_daemon(ri, state)
@@ -133,25 +133,31 @@ class AgentMixin(object):
133 self.state_change_notifier.queue_event((router_id, state)) 133 self.state_change_notifier.queue_event((router_id, state))
134 self.l3_ext_manager.ha_state_change(self.context, state_change_data) 134 self.l3_ext_manager.ha_state_change(self.context, state_change_data)
135 135
136 def _configure_ipv6_params_on_ext_gw_port_if_necessary(self, ri, state): 136 def _configure_ipv6_params(self, ri, state):
137 # If ipv6 is enabled on the platform, ipv6_gateway config flag is 137 if not self.use_ipv6:
138 # not set and external_network associated to the router does not
139 # include any IPv6 subnet, enable the gateway interface to accept
140 # Router Advts from upstream router for default route on master
141 # instances as well as ipv6 forwarding. Otherwise, disable them.
142 ex_gw_port_id = ri.ex_gw_port and ri.ex_gw_port['id']
143 if not ex_gw_port_id:
144 return 138 return
145 139
146 interface_name = ri.get_external_device_name(ex_gw_port_id) 140 ipv6_forwarding_enable = state == 'master'
147 if ri.router.get('distributed', False): 141 if ri.router.get('distributed', False):
148 namespace = ri.ha_namespace 142 namespace = ri.ha_namespace
149 else: 143 else:
150 namespace = ri.ns_name 144 namespace = ri.ns_name
151 145
152 enable = state == 'master' 146 if ipv6_forwarding_enable:
153 ri._configure_ipv6_params_on_gw(ri.ex_gw_port, namespace, 147 ri.driver.configure_ipv6_forwarding(
154 interface_name, enable) 148 namespace, 'all', ipv6_forwarding_enable)
149
150 # If ipv6 is enabled on the platform, ipv6_gateway config flag is
151 # not set and external_network associated to the router does not
152 # include any IPv6 subnet, enable the gateway interface to accept
153 # Router Advts from upstream router for default route on master
154 # instances as well as ipv6 forwarding. Otherwise, disable them.
155 ex_gw_port_id = ri.ex_gw_port and ri.ex_gw_port['id']
156 if ex_gw_port_id:
157 interface_name = ri.get_external_device_name(ex_gw_port_id)
158 ri._configure_ipv6_params_on_gw(
159 ri.ex_gw_port, namespace, interface_name,
160 ipv6_forwarding_enable)
155 161
156 def _update_metadata_proxy(self, ri, router_id, state): 162 def _update_metadata_proxy(self, ri, router_id, state):
157 # NOTE(slaweq): Since the metadata proxy is spawned in the qrouter 163 # NOTE(slaweq): Since the metadata proxy is spawned in the qrouter
diff --git a/neutron/tests/functional/agent/l3/framework.py b/neutron/tests/functional/agent/l3/framework.py
index 62187fc..a86c8c3 100644
--- a/neutron/tests/functional/agent/l3/framework.py
+++ b/neutron/tests/functional/agent/l3/framework.py
@@ -112,7 +112,8 @@ class L3AgentTestFramework(base.BaseSudoTestCase):
112 extra_routes=True, 112 extra_routes=True,
113 enable_fip=True, enable_snat=True, 113 enable_fip=True, enable_snat=True,
114 num_internal_ports=1, 114 num_internal_ports=1,
115 dual_stack=False, v6_ext_gw_with_sub=True, 115 dual_stack=False, enable_gw=True,
116 v6_ext_gw_with_sub=True,
116 enable_pf_floating_ip=False, 117 enable_pf_floating_ip=False,
117 qos_policy_id=None): 118 qos_policy_id=None):
118 if ip_version == constants.IP_VERSION_6 and not dual_stack: 119 if ip_version == constants.IP_VERSION_6 and not dual_stack:
@@ -129,6 +130,7 @@ class L3AgentTestFramework(base.BaseSudoTestCase):
129 enable_ha=enable_ha, 130 enable_ha=enable_ha,
130 extra_routes=extra_routes, 131 extra_routes=extra_routes,
131 dual_stack=dual_stack, 132 dual_stack=dual_stack,
133 enable_gw=enable_gw,
132 v6_ext_gw_with_sub=( 134 v6_ext_gw_with_sub=(
133 v6_ext_gw_with_sub), 135 v6_ext_gw_with_sub),
134 enable_pf_floating_ip=( 136 enable_pf_floating_ip=(
diff --git a/neutron/tests/functional/agent/l3/test_ha_router.py b/neutron/tests/functional/agent/l3/test_ha_router.py
index ba24abd..22d8713 100644
--- a/neutron/tests/functional/agent/l3/test_ha_router.py
+++ b/neutron/tests/functional/agent/l3/test_ha_router.py
@@ -119,8 +119,11 @@ class L3HATestCase(framework.L3AgentTestFramework):
119 router_info['gw_port'] = ex_port 119 router_info['gw_port'] = ex_port
120 router.process() 120 router.process()
121 self._assert_ipv6_accept_ra(router, expected_ra) 121 self._assert_ipv6_accept_ra(router, expected_ra)
122 # As router is going first to master and than to backup mode,
123 # ipv6_forwarding should be enabled on "all" interface always after
124 # that transition
122 self._assert_ipv6_forwarding(router, expected_forwarding, 125 self._assert_ipv6_forwarding(router, expected_forwarding,
123 expected_forwarding) 126 True)
124 127
125 @testtools.skipUnless(ipv6_utils.is_enabled_and_bind_by_default(), 128 @testtools.skipUnless(ipv6_utils.is_enabled_and_bind_by_default(),
126 "IPv6 is not enabled") 129 "IPv6 is not enabled")
@@ -364,6 +367,24 @@ class L3HATestCase(framework.L3AgentTestFramework):
364 self._wait_until_ipv6_forwarding_has_state( 367 self._wait_until_ipv6_forwarding_has_state(
365 router.ns_name, external_device_name, 1) 368 router.ns_name, external_device_name, 1)
366 369
370 @testtools.skipUnless(ipv6_utils.is_enabled_and_bind_by_default(),
371 "IPv6 is not enabled")
372 def test_ha_router_without_gw_ipv6_forwarding_state(self):
373 router_info = self.generate_router_info(
374 enable_ha=True, enable_gw=False)
375 router_info[constants.HA_INTERFACE_KEY]['status'] = (
376 constants.PORT_STATUS_DOWN)
377 router = self.manage_router(self.agent, router_info)
378
379 common_utils.wait_until_true(lambda: router.ha_state == 'backup')
380 self._wait_until_ipv6_forwarding_has_state(router.ns_name, 'all', 0)
381
382 router.router[constants.HA_INTERFACE_KEY]['status'] = (
383 constants.PORT_STATUS_ACTIVE)
384 self.agent._process_updated_router(router.router)
385 common_utils.wait_until_true(lambda: router.ha_state == 'master')
386 self._wait_until_ipv6_forwarding_has_state(router.ns_name, 'all', 1)
387
367 388
368class L3HATestFailover(framework.L3AgentTestFramework): 389class L3HATestFailover(framework.L3AgentTestFramework):
369 390
@@ -428,7 +449,7 @@ class L3HATestFailover(framework.L3AgentTestFramework):
428 self._assert_ipv6_forwarding(new_master, True, True) 449 self._assert_ipv6_forwarding(new_master, True, True)
429 self._assert_ipv6_accept_ra(new_slave, False) 450 self._assert_ipv6_accept_ra(new_slave, False)
430 # after transition from master -> slave, 'all' IPv6 forwarding should 451 # after transition from master -> slave, 'all' IPv6 forwarding should
431 # still be enabled 452 # be enabled
432 self._assert_ipv6_forwarding(new_slave, False, True) 453 self._assert_ipv6_forwarding(new_slave, False, True)
433 454
434 def test_ha_router_lost_gw_connection(self): 455 def test_ha_router_lost_gw_connection(self):
diff --git a/neutron/tests/unit/agent/l3/test_agent.py b/neutron/tests/unit/agent/l3/test_agent.py
index 3cf151a..4e23845 100644
--- a/neutron/tests/unit/agent/l3/test_agent.py
+++ b/neutron/tests/unit/agent/l3/test_agent.py
@@ -270,29 +270,45 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
270 spawn_metadata_proxy.assert_called() 270 spawn_metadata_proxy.assert_called()
271 destroy_metadata_proxy.assert_not_called() 271 destroy_metadata_proxy.assert_not_called()
272 272
273 def _test__configure_ipv6_params_on_ext_gw_port_if_necessary_helper( 273 def _test__configure_ipv6_params_helper(self, state, gw_port_id):
274 self, state, enable_expected):
275 agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) 274 agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
276 router_info = l3router.RouterInfo(agent, _uuid(), {}, **self.ri_kwargs) 275 router_info = l3router.RouterInfo(agent, _uuid(), {}, **self.ri_kwargs)
277 router_info.ex_gw_port = {'id': _uuid()} 276 if gw_port_id:
278 with mock.patch.object(router_info, '_configure_ipv6_params_on_gw' 277 router_info.ex_gw_port = {'id': gw_port_id}
279 ) as mock_configure_ipv6: 278 expected_forwarding_state = state == 'master'
280 agent._configure_ipv6_params_on_ext_gw_port_if_necessary( 279 with mock.patch.object(
281 router_info, state) 280 router_info.driver, "configure_ipv6_forwarding"
282 interface_name = router_info.get_external_device_name( 281 ) as configure_ipv6_forwarding, mock.patch.object(
283 router_info.ex_gw_port['id']) 282 router_info, "_configure_ipv6_params_on_gw"
284 283 ) as configure_ipv6_on_gw:
285 mock_configure_ipv6.assert_called_once_with( 284 agent._configure_ipv6_params(router_info, state)
286 router_info.ex_gw_port, router_info.ns_name, interface_name, 285
287 enable_expected) 286 if state == 'master':
288 287 configure_ipv6_forwarding.assert_called_once_with(
289 def test__configure_ipv6_params_on_ext_gw_port_if_necessary_master(self): 288 router_info.ns_name, 'all', expected_forwarding_state)
290 self._test__configure_ipv6_params_on_ext_gw_port_if_necessary_helper( 289 else:
291 'master', True) 290 configure_ipv6_forwarding.assert_not_called()
292 291
293 def test__configure_ipv6_params_on_ext_gw_port_if_necessary_backup(self): 292 if gw_port_id:
294 self._test__configure_ipv6_params_on_ext_gw_port_if_necessary_helper( 293 interface_name = router_info.get_external_device_name(
295 'backup', False) 294 router_info.ex_gw_port['id'])
295 configure_ipv6_on_gw.assert_called_once_with(
296 router_info.ex_gw_port, router_info.ns_name,
297 interface_name, expected_forwarding_state)
298 else:
299 configure_ipv6_on_gw.assert_not_called()
300
301 def test__configure_ipv6_params_master(self):
302 self._test__configure_ipv6_params_helper('master', gw_port_id=_uuid())
303
304 def test__configure_ipv6_params_backup(self):
305 self._test__configure_ipv6_params_helper('backup', gw_port_id=_uuid())
306
307 def test__configure_ipv6_params_master_no_gw_port(self):
308 self._test__configure_ipv6_params_helper('master', gw_port_id=None)
309
310 def test__configure_ipv6_params_backup_no_gw_port(self):
311 self._test__configure_ipv6_params_helper('backup', gw_port_id=None)
296 312
297 def test_check_ha_state_for_router_master_standby(self): 313 def test_check_ha_state_for_router_master_standby(self):
298 agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) 314 agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)