diff --git a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py index a4158ff10a9..8cb65f6527b 100644 --- a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py +++ b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_dvr_neutron_agent.py @@ -377,8 +377,9 @@ class OVSDVRNeutronAgent(object): subnet_info = self.plugin_rpc.get_subnet_for_dvr( self.context, subnet_uuid, fixed_ips=fixed_ips) if not subnet_info: - LOG.error(_LE("DVR: Unable to retrieve subnet information " - "for subnet_id %s"), subnet_uuid) + LOG.warning(_LW("DVR: Unable to retrieve subnet information " + "for subnet_id %s. The subnet or the gateway " + "may have already been deleted"), subnet_uuid) return LOG.debug("get_subnet_for_dvr for subnet %(uuid)s " "returned with %(info)s", @@ -528,6 +529,14 @@ class OVSDVRNeutronAgent(object): # for this subnet subnet_info = self.plugin_rpc.get_subnet_for_dvr( self.context, subnet_uuid, fixed_ips=fixed_ips) + if not subnet_info: + LOG.warning(_LW("DVR: Unable to retrieve subnet information " + "for subnet_id %s. The subnet or the gateway " + "may have already been deleted"), subnet_uuid) + return + LOG.debug("get_subnet_for_dvr for subnet %(uuid)s " + "returned with %(info)s", + {"uuid": subnet_uuid, "info": subnet_info}) ldm = LocalDVRSubnetMapping(subnet_info, port.ofport) self.local_dvr_map[subnet_uuid] = ldm else: diff --git a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py index f9aec4e685d..0869aba36fc 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py +++ b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py @@ -2350,6 +2350,26 @@ class TestOvsDvrNeutronAgent(object): ] self.assertEqual(expected_on_tun_br, tun_br.mock_calls) + def test_port_bound_for_dvr_with_csnat_ports_without_subnet(self): + self._setup_for_dvr_test() + int_br = mock.create_autospec(self.agent.int_br) + tun_br = mock.create_autospec(self.agent.tun_br) + + # get_subnet_for_dvr RPC returns {} on error + with mock.patch.object(self.agent.dvr_agent.plugin_rpc, + 'get_subnet_for_dvr', + return_value={}),\ + mock.patch.object(self.agent, 'int_br', new=int_br),\ + mock.patch.object(self.agent, 'tun_br', new=tun_br),\ + mock.patch.object(self.agent.dvr_agent, 'int_br', new=int_br),\ + mock.patch.object(self.agent.dvr_agent, 'tun_br', new=tun_br): + self.agent.port_bound( + self._port, self._net_uuid, 'vxlan', + None, None, self._fixed_ips, + n_const.DEVICE_OWNER_ROUTER_SNAT, + False) + self.assertFalse(int_br.install_dvr_to_src_mac.called) + def test_treat_devices_removed_for_dvr_interface(self): self._test_treat_devices_removed_for_dvr_interface() self._test_treat_devices_removed_for_dvr_interface(ip_version=6)