def deallocate_fixed_ip(self, context, address, host=None, teardown=True,
            instance=None):
        fixed_ip_ref = objects.FixedIP.get_by_address(
            context, address, expected_attrs=['network'])
        instance_uuid = fixed_ip_ref.instance_uuid
        vif_id = fixed_ip_ref.virtual_interface_id
        LOG.debug('Deallocate fixed IP %s', address,
                  instance_uuid=instance_uuid)

        if not instance:
            # NOTE(vish) This db query could be removed if we pass az and name
            #            (or the whole instance object).
            # NOTE(danms) We can't use fixed_ip_ref.instance because
            #             instance may be deleted and the relationship
            #             doesn't extend to deleted instances
            instance = objects.Instance.get_by_uuid(
                context.elevated(read_deleted='yes'), instance_uuid)

        quotas = self.quotas_cls(context=context)
        quota_project, quota_user = quotas_obj.ids_from_instance(context,
                                                                 instance)
        try:
            quotas.reserve(fixed_ips=-1, project_id=quota_project,
                           user_id=quota_user)
        except Exception:
            LOG.exception(_LE("Failed to update usages deallocating "
                              "fixed IP"))

        try:
            self._do_trigger_security_group_members_refresh_for_instance(
                instance_uuid)

            if self._validate_instance_zone_for_dns_domain(context, instance):
                for n in self.instance_dns_manager.get_entries_by_address(
                    address, self.instance_dns_domain):
                    self.instance_dns_manager.delete_entry(n,
                        self.instance_dns_domain)

            fixed_ip_ref.allocated = False
            fixed_ip_ref.save()

            if teardown:
                network = fixed_ip_ref.network

                if CONF.force_dhcp_release:
                    dev = self.driver.get_dev(network)
                    # NOTE(vish): The below errors should never happen, but
                    #             there may be a race condition that is causing
                    #             them per
                    #             https://code.launchpad.net/bugs/968457,
                    #             so we log a message to help track down
                    #             the possible race.
                    if not vif_id:
                        LOG.info(_LI("Unable to release %s because vif "
                                     "doesn't exist"), address)
                        return

                    vif = objects.VirtualInterface.get_by_id(context, vif_id)

                    if not vif:
                        LOG.info(_LI("Unable to release %s because vif "
                                     "object doesn't exist"), address)
                        return

                    # NOTE(cfb): Call teardown before release_dhcp to ensure
                    #            that the IP can't be re-leased after a release
                    #            packet is sent.
                    self._teardown_network_on_host(context, network)
                    # NOTE(vish): This forces a packet so that the
                    #             release_fixed_ip callback will
                    #             get called by nova-dhcpbridge.
                    try:
                        self.driver.release_dhcp(dev, address, vif.address)
                    except exception.NetworkDhcpReleaseFailed:
                        LOG.error(_LE("Error releasing DHCP for IP %(address)s"
                                      " with MAC %(mac_address)s"),
                                  {'address': address,
                                   'mac_address': vif.address},
                                  instance=instance)

                    # NOTE(yufang521247): This is probably a failed dhcp fixed
                    # ip. DHCPRELEASE packet sent to dnsmasq would not trigger
                    # dhcp-bridge to run. Thus it is better to disassociate
                    # such fixed ip here.
                    fixed_ip_ref = objects.FixedIP.get_by_address(
                        context, address)
                    if (instance_uuid == fixed_ip_ref.instance_uuid and
                            not fixed_ip_ref.leased):
                        LOG.debug('Explicitly disassociating fixed IP %s from '
                                  'instance.', address,
                                  instance_uuid=instance_uuid)
                        fixed_ip_ref.disassociate()
                else:
                    # We can't try to free the IP address so just call teardown
                    self._teardown_network_on_host(context, network)
        except Exception:
            with excutils.save_and_reraise_exception():
                try:
                    quotas.rollback()
                except Exception:
                    LOG.warning(_LW("Failed to rollback quota for "
                                    "deallocate fixed IP: %s"), address,
                                instance=instance)

        # Commit the reservations
        quotas.commit()
Returns a fixed IP to the pool.
dataset/ETHPy150Open BU-NU-CLOUD-SP16/Trusted-Platform-Module-nova/nova/network/manager.py/NetworkManager.deallocate_fixed_ip