Browse Source

Merge "Enable ipv6_forwarding in HA router's namespace"

tags/14.0.0.0rc1
Zuul 3 months ago
parent
commit
9b897782f8

+ 19
- 13
neutron/agent/l3/ha.py View File

@@ -125,7 +125,7 @@ class AgentMixin(object):
125 125
         # configuration to keepalived-state-change in order to remove the
126 126
         # dependency that currently exists on l3-agent running for the IPv6
127 127
         # failover.
128
-        self._configure_ipv6_params_on_ext_gw_port_if_necessary(ri, state)
128
+        self._configure_ipv6_params(ri, state)
129 129
         if self.conf.enable_metadata_proxy:
130 130
             self._update_metadata_proxy(ri, router_id, state)
131 131
         self._update_radvd_daemon(ri, state)
@@ -133,25 +133,31 @@ class AgentMixin(object):
133 133
         self.state_change_notifier.queue_event((router_id, state))
134 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):
137
-        # If ipv6 is enabled on the platform, ipv6_gateway config flag is
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:
136
+    def _configure_ipv6_params(self, ri, state):
137
+        if not self.use_ipv6:
144 138
             return
145 139
 
146
-        interface_name = ri.get_external_device_name(ex_gw_port_id)
140
+        ipv6_forwarding_enable = state == 'master'
147 141
         if ri.router.get('distributed', False):
148 142
             namespace = ri.ha_namespace
149 143
         else:
150 144
             namespace = ri.ns_name
151 145
 
152
-        enable = state == 'master'
153
-        ri._configure_ipv6_params_on_gw(ri.ex_gw_port, namespace,
154
-                                        interface_name, enable)
146
+        if ipv6_forwarding_enable:
147
+            ri.driver.configure_ipv6_forwarding(
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 162
     def _update_metadata_proxy(self, ri, router_id, state):
157 163
         # NOTE(slaweq): Since the metadata proxy is spawned in the qrouter

+ 3
- 1
neutron/tests/functional/agent/l3/framework.py View File

@@ -112,7 +112,8 @@ class L3AgentTestFramework(base.BaseSudoTestCase):
112 112
                              extra_routes=True,
113 113
                              enable_fip=True, enable_snat=True,
114 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 117
                              enable_pf_floating_ip=False,
117 118
                              qos_policy_id=None):
118 119
         if ip_version == constants.IP_VERSION_6 and not dual_stack:
@@ -129,6 +130,7 @@ class L3AgentTestFramework(base.BaseSudoTestCase):
129 130
                                                   enable_ha=enable_ha,
130 131
                                                   extra_routes=extra_routes,
131 132
                                                   dual_stack=dual_stack,
133
+                                                  enable_gw=enable_gw,
132 134
                                                   v6_ext_gw_with_sub=(
133 135
                                                       v6_ext_gw_with_sub),
134 136
                                                   enable_pf_floating_ip=(

+ 23
- 2
neutron/tests/functional/agent/l3/test_ha_router.py View File

@@ -119,8 +119,11 @@ class L3HATestCase(framework.L3AgentTestFramework):
119 119
         router_info['gw_port'] = ex_port
120 120
         router.process()
121 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 125
         self._assert_ipv6_forwarding(router, expected_forwarding,
123
-                                     expected_forwarding)
126
+                                     True)
124 127
 
125 128
     @testtools.skipUnless(ipv6_utils.is_enabled_and_bind_by_default(),
126 129
                           "IPv6 is not enabled")
@@ -364,6 +367,24 @@ class L3HATestCase(framework.L3AgentTestFramework):
364 367
         self._wait_until_ipv6_forwarding_has_state(
365 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
 
368 389
 class L3HATestFailover(framework.L3AgentTestFramework):
369 390
 
@@ -428,7 +449,7 @@ class L3HATestFailover(framework.L3AgentTestFramework):
428 449
         self._assert_ipv6_forwarding(new_master, True, True)
429 450
         self._assert_ipv6_accept_ra(new_slave, False)
430 451
         # after transition from master -> slave, 'all' IPv6 forwarding should
431
-        # still be enabled
452
+        # be enabled
432 453
         self._assert_ipv6_forwarding(new_slave, False, True)
433 454
 
434 455
     def test_ha_router_lost_gw_connection(self):

+ 37
- 21
neutron/tests/unit/agent/l3/test_agent.py View File

@@ -270,29 +270,45 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
270 270
         spawn_metadata_proxy.assert_called()
271 271
         destroy_metadata_proxy.assert_not_called()
272 272
 
273
-    def _test__configure_ipv6_params_on_ext_gw_port_if_necessary_helper(
274
-            self, state, enable_expected):
273
+    def _test__configure_ipv6_params_helper(self, state, gw_port_id):
275 274
         agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
276 275
         router_info = l3router.RouterInfo(agent, _uuid(), {}, **self.ri_kwargs)
277
-        router_info.ex_gw_port = {'id': _uuid()}
278
-        with mock.patch.object(router_info, '_configure_ipv6_params_on_gw'
279
-                               ) as mock_configure_ipv6:
280
-            agent._configure_ipv6_params_on_ext_gw_port_if_necessary(
281
-                router_info, state)
282
-            interface_name = router_info.get_external_device_name(
283
-                    router_info.ex_gw_port['id'])
284
-
285
-            mock_configure_ipv6.assert_called_once_with(
286
-                router_info.ex_gw_port, router_info.ns_name, interface_name,
287
-                enable_expected)
288
-
289
-    def test__configure_ipv6_params_on_ext_gw_port_if_necessary_master(self):
290
-        self._test__configure_ipv6_params_on_ext_gw_port_if_necessary_helper(
291
-            'master', True)
292
-
293
-    def test__configure_ipv6_params_on_ext_gw_port_if_necessary_backup(self):
294
-        self._test__configure_ipv6_params_on_ext_gw_port_if_necessary_helper(
295
-            'backup', False)
276
+        if gw_port_id:
277
+            router_info.ex_gw_port = {'id': gw_port_id}
278
+        expected_forwarding_state = state == 'master'
279
+        with mock.patch.object(
280
+            router_info.driver, "configure_ipv6_forwarding"
281
+        ) as configure_ipv6_forwarding, mock.patch.object(
282
+            router_info, "_configure_ipv6_params_on_gw"
283
+        ) as configure_ipv6_on_gw:
284
+            agent._configure_ipv6_params(router_info, state)
285
+
286
+            if state == 'master':
287
+                configure_ipv6_forwarding.assert_called_once_with(
288
+                    router_info.ns_name, 'all', expected_forwarding_state)
289
+            else:
290
+                configure_ipv6_forwarding.assert_not_called()
291
+
292
+            if gw_port_id:
293
+                interface_name = router_info.get_external_device_name(
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 313
     def test_check_ha_state_for_router_master_standby(self):
298 314
         agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)

Loading…
Cancel
Save