diff --git a/neutron/common/ovn/utils.py b/neutron/common/ovn/utils.py index c878b5f53bb..621927dd568 100644 --- a/neutron/common/ovn/utils.py +++ b/neutron/common/ovn/utils.py @@ -469,7 +469,7 @@ def is_gateway_chassis_invalid(chassis_name, gw_chassis, def is_provider_network(network): - return external_net.EXTERNAL in network + return network.get(external_net.EXTERNAL, False) def is_neutron_dhcp_agent_port(port): diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py index de5e9236c3a..e47e28c693a 100644 --- a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py +++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py @@ -999,12 +999,14 @@ class OVNClient(object): utils.ovn_lrouter_port_name(gw_port_id), gw_lrouter_name)) - def _get_nets_and_ipv6_ra_confs_for_router_port( - self, context, port_fixed_ips): + def _get_nets_and_ipv6_ra_confs_for_router_port(self, context, port): + port_fixed_ips = port['fixed_ips'] networks = set() ipv6_ra_configs = {} ipv6_ra_configs_supported = self._nb_idl.is_col_present( 'Logical_Router_Port', 'ipv6_ra_configs') + is_gw_port = const.DEVICE_OWNER_ROUTER_GW == port.get( + 'device_owner') for fixed_ip in port_fixed_ips: subnet_id = fixed_ip['subnet_id'] @@ -1018,8 +1020,14 @@ class OVNClient(object): ipv6_ra_configs['address_mode'] = ( utils.get_ovn_ipv6_address_mode( subnet['ipv6_address_mode'])) - ipv6_ra_configs['send_periodic'] = 'true' net = self._plugin.get_network(context, subnet['network_id']) + # If it's a gateway port and connected to a provider + # network set send_periodic to False, that way we do not + # leak the RAs generated for the tenant networks via the + # provider network + ipv6_ra_configs['send_periodic'] = 'true' + if is_gw_port and utils.is_provider_network(net): + ipv6_ra_configs['send_periodic'] = 'false' ipv6_ra_configs['mtu'] = str(net['mtu']) return list(networks), ipv6_ra_configs @@ -1341,8 +1349,7 @@ class OVNClient(object): """Create a logical router port.""" lrouter = utils.ovn_name(router['id']) networks, ipv6_ra_configs = ( - self._get_nets_and_ipv6_ra_confs_for_router_port( - context, port['fixed_ips'])) + self._get_nets_and_ipv6_ra_confs_for_router_port(context, port)) lrouter_port_name = utils.ovn_lrouter_port_name(port['id']) is_gw_port = const.DEVICE_OWNER_ROUTER_GW == port.get( 'device_owner') @@ -1416,8 +1423,7 @@ class OVNClient(object): def _update_lrouter_port(self, context, port, if_exists=False, txn=None): """Update a logical router port.""" networks, ipv6_ra_configs = ( - self._get_nets_and_ipv6_ra_confs_for_router_port( - context, port['fixed_ips'])) + self._get_nets_and_ipv6_ra_confs_for_router_port(context, port)) lsp_address = ovn_const.DEFAULT_ADDR_FOR_LSP_WITH_PEER lrp_name = utils.ovn_lrouter_port_name(port['id']) diff --git a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py index 2003ceec412..9a1c6badaa5 100644 --- a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py +++ b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py @@ -1240,18 +1240,18 @@ class TestOvnNbSync(base.TestOVNFunctionalBase): AssertionError, self.assertItemsEqual, db_router_ids, monitor_lrouter_ids) - def _get_networks_for_router_port(port_fixed_ips): + def _get_networks_for_router_port(port): _ovn_client = self.l3_plugin._ovn_client networks, _ = ( _ovn_client._get_nets_and_ipv6_ra_confs_for_router_port( - self.ctx, port_fixed_ips)) + self.ctx, port)) return networks - def _get_ipv6_ra_configs_for_router_port(port_fixed_ips): + def _get_ipv6_ra_configs_for_router_port(port): _ovn_client = self.l3_plugin._ovn_client networks, ipv6_ra_configs = ( _ovn_client._get_nets_and_ipv6_ra_confs_for_router_port( - self.ctx, port_fixed_ips)) + self.ctx, port)) return ipv6_ra_configs for router_id in db_router_ids: @@ -1260,10 +1260,10 @@ class TestOvnNbSync(base.TestOVNFunctionalBase): r_port_ids = [p['id'] for p in r_ports['ports']] r_port_networks = { p['id']: - _get_networks_for_router_port(p['fixed_ips']) + _get_networks_for_router_port(p) for p in r_ports['ports']} r_port_ipv6_ra_configs = { - p['id']: _get_ipv6_ra_configs_for_router_port(p['fixed_ips']) + p['id']: _get_ipv6_ra_configs_for_router_port(p) for p in r_ports['ports']} r_routes = db_routes[router_id] r_nats = db_nats[router_id] diff --git a/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py b/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py index 622b7625027..e8d42b3af6f 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py +++ b/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_db_sync.py @@ -437,7 +437,7 @@ class TestOvnNbSyncML2(test_mech_driver.OVNMechanismDriverTestCase): ovn_nb_synchronizer._ovn_client = mock.Mock() ovn_nb_synchronizer._ovn_client.\ _get_nets_and_ipv6_ra_confs_for_router_port.return_value = ( - self.lrport_networks, {}) + self.lrport_networks, {'fixed_ips': {}}) ovn_nb_synchronizer._ovn_client._get_v4_network_of_all_router_ports. \ side_effect = self._fake_get_v4_network_of_all_router_ports ovn_nb_synchronizer._ovn_client._get_gw_info = mock.Mock()