Esempio n. 1
0
    def validate_allocation_pools(self, ip_pools, subnet_cidr):
        """Validate IP allocation pools.

        Verify start and end address for each allocation pool are valid,
        ie: constituted by valid and appropriately ordered IP addresses.
        Also, verify pools do not overlap among themselves.
        Finally, verify that each range fall within the subnet's CIDR.
        """
        subnet = netaddr.IPNetwork(subnet_cidr)
        if subnet.version == const.IP_VERSION_4:
            if subnet.prefixlen <= 30:
                subnet_first_ip = netaddr.IPAddress(subnet.first + 1)
                # last address is broadcast in v4
                subnet_last_ip = netaddr.IPAddress(subnet.last - 1)
            else:
                subnet_first_ip = netaddr.IPAddress(subnet.first)
                subnet_last_ip = netaddr.IPAddress(subnet.last)
        else:  # IPv6 case
            subnet_first_ip = netaddr.IPAddress(subnet.first + 1)
            subnet_last_ip = netaddr.IPAddress(subnet.last)

        LOG.debug("Performing IP validity checks on allocation pools")
        ip_sets = []
        for ip_pool in ip_pools:
            start_ip = netaddr.IPAddress(ip_pool.first, ip_pool.version)
            end_ip = netaddr.IPAddress(ip_pool.last, ip_pool.version)
            if (start_ip.version != subnet.version or
                    end_ip.version != subnet.version):
                LOG.info("Specified IP addresses do not match "
                         "the subnet IP version")
                raise exc.InvalidAllocationPool(pool=ip_pool)
            if start_ip < subnet_first_ip or end_ip > subnet_last_ip:
                LOG.info("Found pool larger than subnet "
                         "CIDR:%(start)s - %(end)s",
                         {'start': start_ip, 'end': end_ip})
                raise exc.OutOfBoundsAllocationPool(
                    pool=ip_pool,
                    subnet_cidr=subnet_cidr)
            # Valid allocation pool
            # Create an IPSet for it for easily verifying overlaps
            ip_sets.append(netaddr.IPSet(ip_pool.cidrs()))

        LOG.debug("Checking for overlaps among allocation pools "
                  "and gateway ip")
        ip_ranges = ip_pools[:]

        # Use integer cursors as an efficient way for implementing
        # comparison and avoiding comparing the same pair twice
        for l_cursor in range(len(ip_sets)):
            for r_cursor in range(l_cursor + 1, len(ip_sets)):
                if ip_sets[l_cursor] & ip_sets[r_cursor]:
                    l_range = ip_ranges[l_cursor]
                    r_range = ip_ranges[r_cursor]
                    LOG.info("Found overlapping ranges: %(l_range)s and "
                             "%(r_range)s",
                             {'l_range': l_range, 'r_range': r_range})
                    raise exc.OverlappingAllocationPools(
                        pool_1=l_range,
                        pool_2=r_range,
                        subnet_cidr=subnet_cidr)
Esempio n. 2
0
 def pools_to_ip_range(ip_pools):
     ip_range_pools = []
     for ip_pool in ip_pools:
         try:
             ip_range_pools.append(netaddr.IPRange(ip_pool['start'],
                                                   ip_pool['end']))
         except netaddr.AddrFormatError:
             LOG.info("Found invalid IP address in pool: "
                      "%(start)s - %(end)s:",
                      {'start': ip_pool['start'],
                       'end': ip_pool['end']})
             raise exc.InvalidAllocationPool(pool=ip_pool)
     return ip_range_pools