From 84d4fe177b75569628aec96e43b709b8e29b9e05 Mon Sep 17 00:00:00 2001 From: LIU Yulong Date: Tue, 10 Mar 2020 00:49:44 +0800 Subject: [PATCH] [L3] Add missing address scope mark for IPv6 traffic Any IPv6 traffic wants to go in/out directly on the DVR compute node will be dropped by the mis-configured scope mark iptables rule. This patch addresses this issue. Closes-Bug: #1895401 Change-Id: Iee045e963e05f83d497e73bb39bb64c522f19543 --- neutron/agent/l3/dvr_local_router.py | 11 +++++++---- neutron/agent/l3/router_info.py | 8 ++++++-- .../unit/agent/l3/test_dvr_local_router.py | 17 +++++++++++++++++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/neutron/agent/l3/dvr_local_router.py b/neutron/agent/l3/dvr_local_router.py index dbef861f7b7..2666ac76e78 100644 --- a/neutron/agent/l3/dvr_local_router.py +++ b/neutron/agent/l3/dvr_local_router.py @@ -649,10 +649,13 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase): if not ext_device_name: return ports_scopemark - ext_scope = self._get_external_address_scope() - ext_scope_mark = self.get_address_scope_mark_mask(ext_scope) - ports_scopemark[lib_constants.IP_VERSION_4][ext_device_name] = ( - ext_scope_mark) + ext_scope_mark = self._get_port_devicename_scopemark( + [ext_port], self.get_internal_device_name, + interface_name=ext_device_name) + for ip_version in (lib_constants.IP_VERSION_4, + lib_constants.IP_VERSION_6): + ports_scopemark[ip_version].update( + ext_scope_mark[ip_version]) return ports_scopemark def _check_if_floatingip_bound_to_host(self, fip): diff --git a/neutron/agent/l3/router_info.py b/neutron/agent/l3/router_info.py index faaef683072..8103b80dad7 100644 --- a/neutron/agent/l3/router_info.py +++ b/neutron/agent/l3/router_info.py @@ -1103,11 +1103,15 @@ class RouterInfo(BaseRouterInfo): self.iptables_manager.ipv6['mangle'].add_rule( 'PREROUTING', mark_metadata_v6_for_internal_interfaces) - def _get_port_devicename_scopemark(self, ports, name_generator): + def _get_port_devicename_scopemark( + self, ports, name_generator, interface_name=None): devicename_scopemark = {lib_constants.IP_VERSION_4: dict(), lib_constants.IP_VERSION_6: dict()} for p in ports: - device_name = name_generator(p['id']) + if interface_name is None: + device_name = name_generator(p['id']) + else: + device_name = interface_name ip_cidrs = common_utils.fixed_ip_cidrs(p['fixed_ips']) port_as_marks = self.get_port_address_scope_mark(p) for ip_version in {common_utils.get_ip_version(cidr) 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 57e557854fe..349f0e9dd55 100644 --- a/neutron/tests/unit/agent/l3/test_dvr_local_router.py +++ b/neutron/tests/unit/agent/l3/test_dvr_local_router.py @@ -189,6 +189,23 @@ class TestDvrRouterOperations(base.BaseTestCase): def test_create_dvr_fip_interfaces_with_address_scope_mismatch(self): self._setup_create_dvr_fip_interfaces_for_setting_routing_rules() + def test__get_address_scope_mark(self): + ri = self._create_router() + fake_fip_ns = mock.Mock(return_value=True) + fake_fip_ns.get_name = mock.Mock(return_value="fip-fakenamespace") + fake_fip_ns.get_int_device_name = mock.Mock( + return_value="fake-int-device-name") + ri.fip_ns = fake_fip_ns + ri.get_external_device_interface_name = mock.Mock( + return_value="fake-ext-device-name") + ri.get_ex_gw_port = mock.Mock( + return_value={"id": "fake-ext-port-id", + "fixed_ips": [{"ip_address": "1.1.1.1"}, + {"ip_address": "1111::1111"}]}) + + scope_mark = ri._get_address_scope_mark() + self.assertNotEqual({}, scope_mark[6]) + def _setup_create_dvr_fip_interfaces_for_setting_routing_rules( self, address_scopes_match=False): ri = self._create_router()