'Originally, the Neutron pluggable IPAM backend would ask the driver
to try to allocate an IP from each subnet in turn, one by one.  This
implementation preserves that behavior so that existing drivers work
as they did before while giving them the opportunity to optimize it
by overridding the implementation.'

def allocate(self, address_request):

    for subnet_id in self._subnet_ids:
        try:
            ipam_subnet = self._driver.get_subnet(subnet_id)
            return (ipam_subnet.allocate(address_request), subnet_id)
        except ipam_exc.IpAddressGenerationFailure:
            continue
    raise ipam_exc.IpAddressGenerationFailureAllSubnets()
