'Checks to make sure a port is allowed to be deleted.
Raises an exception if this is not the case.  This should be called by
any plugin when the API requests the deletion of a port, since some
ports for L3 are not intended to be deleted directly via a DELETE
to /ports, but rather via other API calls that perform the proper
deletion checks.'

def prevent_l3_port_deletion(self, context, port_id):

    try:
        port = self._core_plugin.get_port(context, port_id)
    except n_exc.PortNotFound:
        return
    if (port['device_owner'] not in self.router_device_owners):
        return
    fixed_ips = port['fixed_ips']
    if (not fixed_ips):
        LOG.debug('Port    %(port_id)s    has    owner    %(port_owner)s,    but    no    IP    address,    so    it    can    be    deleted', {'port_id': port['id'], 'port_owner': port['device_owner']})
        return
    if (port['device_owner'] == DEVICE_OWNER_FLOATINGIP):
        if (not self._floating_ip_exists(context, port['device_id'])):
            LOG.debug('Floating    IP    %(f_id)s    corresponding    to    port    %(port_id)s    no    longer    exists,    allowing    deletion.', {'f_id': port['device_id'], 'port_id': port['id']})
            return
    elif (not self._router_exists(context, port['device_id'])):
        LOG.debug('Router    %(router_id)s    corresponding    to    port    %(port_id)s        no    longer    exists,    allowing    deletion.', {'router_id': port['device_id'], 'port_id': port['id']})
        return
    reason = (_('has    device    owner    %s') % port['device_owner'])
    raise n_exc.ServicePortInUse(port_id=port['id'], reason=reason)
