def _update_ips_for_pd_subnet(self,
                               context,
                               subnets,
                               fixed_ips,
                               mac_address=None):
     fixed_ip_list = []
     subnet_set = {
         fixed['subnet_id']
         for fixed in fixed_ips if 'subnet_id' in fixed
     }
     pd_subnets = [
         s for s in subnets
         if (s['id'] in subnet_set and ipv6_utils.is_ipv6_pd_enabled(s))
     ]
     for subnet in pd_subnets:
         # Already checked subnet validity in _get_subnet_for_fixed_ip
         if mac_address:
             fixed_ip_list.append({
                 'subnet_id': subnet['id'],
                 'subnet_cidr': subnet['cidr'],
                 'eui64_address': True,
                 'mac': mac_address
             })
         else:
             fixed_ip_list.append({'subnet_id': subnet['id']})
     return fixed_ip_list
예제 #2
0
def get_assigned_pd_interfaces(router):
    pd_intfs = []
    for intf in router[lib_constants.INTERFACE_KEY]:
        for subnet in intf['subnets']:
            if (ipv6_utils.is_ipv6_pd_enabled(subnet) and subnet['cidr'] !=
                    lib_constants.PROVISIONAL_IPV6_PD_PREFIX):
                pd_intfs.append(intf)
    return pd_intfs
예제 #3
0
def get_unassigned_pd_interfaces(router):
    pd_intfs = []
    for intf in router[lib_constants.INTERFACE_KEY]:
        for subnet in intf['subnets']:
            if (ipv6_utils.is_ipv6_pd_enabled(subnet) and
                subnet['cidr'] == n_const.PROVISIONAL_IPV6_PD_PREFIX):
                pd_intfs.append(intf)
    return pd_intfs
예제 #4
0
def assign_prefix_for_pd_interfaces(router):
    pd_intfs = []
    for ifno, intf in enumerate(router[lib_constants.INTERFACE_KEY]):
        for subnet in intf['subnets']:
            if (ipv6_utils.is_ipv6_pd_enabled(subnet) and subnet['cidr']
                    == lib_constants.PROVISIONAL_IPV6_PD_PREFIX):
                subnet['cidr'] = "2001:db8:%d::/64" % ifno
                pd_intfs.append(intf)
    return pd_intfs
예제 #5
0
    def _is_ip_required_by_subnet(self, context, subnet_id, device_owner):
        # For ports that are not router ports, retain any automatic
        # (non-optional, e.g. IPv6 SLAAC) addresses.
        if device_owner in constants.ROUTER_INTERFACE_OWNERS:
            return True

        subnet = self._get_subnet(context, subnet_id)
        return not (ipv6_utils.is_auto_address_subnet(subnet) and
                    not ipv6_utils.is_ipv6_pd_enabled(subnet))
예제 #6
0
    def _is_ip_required_by_subnet(self, context, subnet_id, device_owner):
        # For ports that are not router ports, retain any automatic
        # (non-optional, e.g. IPv6 SLAAC) addresses.
        if device_owner in constants.ROUTER_INTERFACE_OWNERS:
            return True

        subnet = self._get_subnet(context, subnet_id)
        return not (ipv6_utils.is_auto_address_subnet(subnet)
                    and not ipv6_utils.is_ipv6_pd_enabled(subnet))
예제 #7
0
def assign_prefix_for_pd_interfaces(router):
    pd_intfs = []
    for ifno, intf in enumerate(router[lib_constants.INTERFACE_KEY]):
        for subnet in intf['subnets']:
            if (ipv6_utils.is_ipv6_pd_enabled(subnet) and
                subnet['cidr'] == n_const.PROVISIONAL_IPV6_PD_PREFIX):
                subnet['cidr'] = "2001:db8:%d::/64" % ifno
                pd_intfs.append(intf)
    return pd_intfs
예제 #8
0
    def _is_ip_required_by_subnet(self, context, subnet_id, device_owner):
        # For ports that are not router ports, retain any automatic
        # (non-optional, e.g. IPv6 SLAAC) addresses.
        # NOTE: Need to check the SNAT ports for DVR routers here since
        # they consume an IP.
        if device_owner in const.ROUTER_INTERFACE_OWNERS_SNAT:
            return True

        subnet = self._get_subnet(context, subnet_id)
        return not (ipv6_utils.is_auto_address_subnet(subnet) and
                    not ipv6_utils.is_ipv6_pd_enabled(subnet))
    def _is_ip_required_by_subnet(self, context, subnet_id, device_owner):
        # For ports that are not router ports, retain any automatic
        # (non-optional, e.g. IPv6 SLAAC) addresses.
        # NOTE: Need to check the SNAT ports for DVR routers here since
        # they consume an IP.
        if device_owner in const.ROUTER_INTERFACE_OWNERS_SNAT:
            return True

        subnet_obj = self._get_subnet_object(context, subnet_id)
        return not (ipv6_utils.is_auto_address_subnet(subnet_obj)
                    and not ipv6_utils.is_ipv6_pd_enabled(subnet_obj))
예제 #10
0
    def _test_fixed_ips_for_port(self, context, network_id, fixed_ips,
                                 device_owner):
        """Test fixed IPs for port.

        Check that configured subnets are valid prior to allocating any
        IPs. Include the subnet_id in the result if only an IP address is
        configured.

        :raises: InvalidInput, IpAddressInUse, InvalidIpForNetwork,
                 InvalidIpForSubnet
        """
        fixed_ip_set = []
        for fixed in fixed_ips:
            subnet = self._get_subnet_for_fixed_ip(context, fixed, network_id)

            is_auto_addr_subnet = ipv6_utils.is_auto_address_subnet(subnet)
            if ('ip_address' in fixed and
                    subnet['cidr'] != constants.PROVISIONAL_IPV6_PD_PREFIX):
                # Ensure that the IP's are unique
                if not IpamNonPluggableBackend._check_unique_ip(
                        context, network_id, subnet['id'],
                        fixed['ip_address']):
                    raise n_exc.IpAddressInUse(net_id=network_id,
                                               ip_address=fixed['ip_address'])

                if (is_auto_addr_subnet and device_owner
                        not in constants.ROUTER_INTERFACE_OWNERS):
                    msg = (_("IPv6 address %(address)s can not be directly "
                             "assigned to a port on subnet %(id)s since the "
                             "subnet is configured for automatic addresses") %
                           {
                               'address': fixed['ip_address'],
                               'id': subnet['id']
                           })
                    raise n_exc.InvalidInput(error_message=msg)
                fixed_ip_set.append({
                    'subnet_id': subnet['id'],
                    'ip_address': fixed['ip_address']
                })
            else:
                # A scan for auto-address subnets on the network is done
                # separately so that all such subnets (not just those
                # listed explicitly here by subnet ID) are associated
                # with the port.
                if (device_owner in constants.ROUTER_INTERFACE_OWNERS_SNAT
                        or ipv6_utils.is_ipv6_pd_enabled(subnet)
                        or not is_auto_addr_subnet):
                    fixed_ip_set.append({'subnet_id': subnet['id']})

        self._validate_max_ips_per_port(fixed_ip_set)
        return fixed_ip_set
    def _test_fixed_ips_for_port(self, context, network_id, fixed_ips,
                                 device_owner):
        """Test fixed IPs for port.

        Check that configured subnets are valid prior to allocating any
        IPs. Include the subnet_id in the result if only an IP address is
        configured.

        :raises: InvalidInput, IpAddressInUse, InvalidIpForNetwork,
                 InvalidIpForSubnet
        """
        fixed_ip_set = []
        for fixed in fixed_ips:
            subnet = self._get_subnet_for_fixed_ip(context, fixed, network_id)

            is_auto_addr_subnet = ipv6_utils.is_auto_address_subnet(subnet)
            if ('ip_address' in fixed and
                subnet['cidr'] != constants.PROVISIONAL_IPV6_PD_PREFIX):
                # Ensure that the IP's are unique
                if not IpamNonPluggableBackend._check_unique_ip(
                        context, network_id,
                        subnet['id'], fixed['ip_address']):
                    raise n_exc.IpAddressInUse(net_id=network_id,
                                               ip_address=fixed['ip_address'])

                if (is_auto_addr_subnet and
                    device_owner not in
                        constants.ROUTER_INTERFACE_OWNERS):
                    msg = (_("IPv6 address %(address)s can not be directly "
                            "assigned to a port on subnet %(id)s since the "
                            "subnet is configured for automatic addresses") %
                           {'address': fixed['ip_address'],
                            'id': subnet['id']})
                    raise n_exc.InvalidInput(error_message=msg)
                fixed_ip_set.append({'subnet_id': subnet['id'],
                                     'ip_address': fixed['ip_address']})
            else:
                # A scan for auto-address subnets on the network is done
                # separately so that all such subnets (not just those
                # listed explicitly here by subnet ID) are associated
                # with the port.
                if (device_owner in constants.ROUTER_INTERFACE_OWNERS_SNAT or
                    ipv6_utils.is_ipv6_pd_enabled(subnet) or
                    not is_auto_addr_subnet):
                    fixed_ip_set.append({'subnet_id': subnet['id']})

        self._validate_max_ips_per_port(fixed_ip_set)
        return fixed_ip_set
예제 #12
0
 def _update_ips_for_pd_subnet(self, context, subnets,
                               fixed_ips, mac_address=None):
     fixed_ip_list = []
     subnet_set = {fixed['subnet_id'] for fixed in fixed_ips
                   if 'subnet_id' in fixed}
     pd_subnets = [s for s in subnets
                   if (s['id'] in subnet_set and
                       ipv6_utils.is_ipv6_pd_enabled(s))]
     for subnet in pd_subnets:
         # Already checked subnet validity in _get_subnet_for_fixed_ip
         if mac_address:
             fixed_ip_list.append({'subnet_id': subnet['id'],
                                   'subnet_cidr': subnet['cidr'],
                                   'eui64_address': True,
                                   'mac': mac_address})
         else:
             fixed_ip_list.append({'subnet_id': subnet['id']})
     return fixed_ip_list
예제 #13
0
 def _update_subnet_allocation_pools(self, context, subnet_id, s):
     context.session.query(models_v2.IPAllocationPool).filter_by(
         subnet_id=subnet_id).delete()
     pools = [(netaddr.IPAddress(p.first, p.version).format(),
               netaddr.IPAddress(p.last, p.version).format())
              for p in s['allocation_pools']]
     new_pools = [models_v2.IPAllocationPool(first_ip=p[0],
                                             last_ip=p[1],
                                             subnet_id=subnet_id)
                  for p in pools]
     context.session.add_all(new_pools)
     # Call static method with self to redefine in child
     # (non-pluggable backend)
     if not ipv6_utils.is_ipv6_pd_enabled(s):
         self._rebuild_availability_ranges(context, [s])
     # Gather new pools for result
     result_pools = [{'start': p[0], 'end': p[1]} for p in pools]
     del s['allocation_pools']
     return result_pools
예제 #14
0
 def _update_subnet_allocation_pools(self, context, subnet_id, s):
     context.session.query(models_v2.IPAllocationPool).filter_by(
         subnet_id=subnet_id).delete()
     pools = [(netaddr.IPAddress(p.first, p.version).format(),
               netaddr.IPAddress(p.last, p.version).format())
              for p in s['allocation_pools']]
     new_pools = [models_v2.IPAllocationPool(first_ip=p[0],
                                             last_ip=p[1],
                                             subnet_id=subnet_id)
                  for p in pools]
     context.session.add_all(new_pools)
     # Call static method with self to redefine in child
     # (non-pluggable backend)
     if not ipv6_utils.is_ipv6_pd_enabled(s):
         self._rebuild_availability_ranges(context, [s])
     # Gather new pools for result
     result_pools = [{'start': p[0], 'end': p[1]} for p in pools]
     del s['allocation_pools']
     return result_pools
예제 #15
0
    def _process_internal_ports(self, pd):
        existing_port_ids = set(p['id'] for p in self.internal_ports)

        internal_ports = self.router.get(l3_constants.INTERFACE_KEY, [])
        current_port_ids = set(p['id'] for p in internal_ports
                               if p['admin_state_up'])

        new_port_ids = current_port_ids - existing_port_ids
        new_ports = [p for p in internal_ports if p['id'] in new_port_ids]
        old_ports = [p for p in self.internal_ports
                     if p['id'] not in current_port_ids]
        updated_ports = self._get_updated_ports(self.internal_ports,
                                                internal_ports)

        enable_ra = False
        for p in new_ports:
            self.internal_network_added(p)
            LOG.debug("appending port %s to internal_ports cache", p)
            self.internal_ports.append(p)
            enable_ra = enable_ra or self._port_has_ipv6_subnet(p)
            for subnet in p['subnets']:
                if ipv6_utils.is_ipv6_pd_enabled(subnet):
                    interface_name = self.get_internal_device_name(p['id'])
                    pd.enable_subnet(self.router_id, subnet['id'],
                                     subnet['cidr'],
                                     interface_name, p['mac_address'])

        for p in old_ports:
            self.internal_network_removed(p)
            LOG.debug("removing port %s from internal_ports cache", p)
            self.internal_ports.remove(p)
            enable_ra = enable_ra or self._port_has_ipv6_subnet(p)
            for subnet in p['subnets']:
                if ipv6_utils.is_ipv6_pd_enabled(subnet):
                    pd.disable_subnet(self.router_id, subnet['id'])

        updated_cidrs = []
        if updated_ports:
            for index, p in enumerate(internal_ports):
                if not updated_ports.get(p['id']):
                    continue
                self.internal_ports[index] = updated_ports[p['id']]
                interface_name = self.get_internal_device_name(p['id'])
                ip_cidrs = common_utils.fixed_ip_cidrs(p['fixed_ips'])
                LOG.debug("updating internal network for port %s", p)
                updated_cidrs += ip_cidrs
                self.internal_network_updated(interface_name, ip_cidrs)
                enable_ra = enable_ra or self._port_has_ipv6_subnet(p)

        # Check if there is any pd prefix update
        for p in internal_ports:
            if p['id'] in (set(current_port_ids) & set(existing_port_ids)):
                for subnet in p.get('subnets', []):
                    if ipv6_utils.is_ipv6_pd_enabled(subnet):
                        old_prefix = pd.update_subnet(self.router_id,
                                                      subnet['id'],
                                                      subnet['cidr'])
                        if old_prefix:
                            self._internal_network_updated(p, subnet['id'],
                                                           subnet['cidr'],
                                                           old_prefix,
                                                           updated_cidrs)
                            enable_ra = True

        # Enable RA
        if enable_ra:
            self.enable_radvd(internal_ports)

        existing_devices = self._get_existing_devices()
        current_internal_devs = set(n for n in existing_devices
                                    if n.startswith(INTERNAL_DEV_PREFIX))
        current_port_devs = set(self.get_internal_device_name(port_id)
                                for port_id in current_port_ids)
        stale_devs = current_internal_devs - current_port_devs
        for stale_dev in stale_devs:
            LOG.debug('Deleting stale internal router device: %s',
                      stale_dev)
            pd.remove_stale_ri_ifname(self.router_id, stale_dev)
            self.driver.unplug(stale_dev,
                               namespace=self.ns_name,
                               prefix=INTERNAL_DEV_PREFIX)
예제 #16
0
    def _process_internal_ports(self, pd):
        existing_port_ids = set(p['id'] for p in self.internal_ports)

        internal_ports = self.router.get(lib_constants.INTERFACE_KEY, [])
        current_port_ids = set(p['id'] for p in internal_ports
                               if p['admin_state_up'])

        new_port_ids = current_port_ids - existing_port_ids
        new_ports = [p for p in internal_ports if p['id'] in new_port_ids]
        old_ports = [
            p for p in self.internal_ports if p['id'] not in current_port_ids
        ]
        updated_ports = self._get_updated_ports(self.internal_ports,
                                                internal_ports)

        enable_ra = False
        for p in new_ports:
            self.internal_network_added(p)
            LOG.debug("appending port %s to internal_ports cache", p)
            self.internal_ports.append(p)
            enable_ra = enable_ra or self._port_has_ipv6_subnet(p)
            for subnet in p['subnets']:
                if ipv6_utils.is_ipv6_pd_enabled(subnet):
                    interface_name = self.get_internal_device_name(p['id'])
                    pd.enable_subnet(self.router_id, subnet['id'],
                                     subnet['cidr'], interface_name,
                                     p['mac_address'])

        for p in old_ports:
            self.internal_network_removed(p)
            LOG.debug("removing port %s from internal_ports cache", p)
            self.internal_ports.remove(p)
            enable_ra = enable_ra or self._port_has_ipv6_subnet(p)
            for subnet in p['subnets']:
                if ipv6_utils.is_ipv6_pd_enabled(subnet):
                    pd.disable_subnet(self.router_id, subnet['id'])

        updated_cidrs = []
        if updated_ports:
            for index, p in enumerate(internal_ports):
                if not updated_ports.get(p['id']):
                    continue
                self.internal_ports[index] = updated_ports[p['id']]
                interface_name = self.get_internal_device_name(p['id'])
                ip_cidrs = common_utils.fixed_ip_cidrs(p['fixed_ips'])
                LOG.debug("updating internal network for port %s", p)
                updated_cidrs += ip_cidrs
                self.internal_network_updated(interface_name, ip_cidrs)
                enable_ra = enable_ra or self._port_has_ipv6_subnet(p)

        # Check if there is any pd prefix update
        for p in internal_ports:
            if p['id'] in (set(current_port_ids) & set(existing_port_ids)):
                for subnet in p.get('subnets', []):
                    if ipv6_utils.is_ipv6_pd_enabled(subnet):
                        old_prefix = pd.update_subnet(self.router_id,
                                                      subnet['id'],
                                                      subnet['cidr'])
                        if old_prefix:
                            self._internal_network_updated(
                                p, subnet['id'], subnet['cidr'], old_prefix,
                                updated_cidrs)
                            enable_ra = True

        # Enable RA
        if enable_ra:
            self.enable_radvd(internal_ports)

        existing_devices = self._get_existing_devices()
        current_internal_devs = set(n for n in existing_devices
                                    if n.startswith(INTERNAL_DEV_PREFIX))
        current_port_devs = set(
            self.get_internal_device_name(port_id)
            for port_id in current_port_ids)
        stale_devs = current_internal_devs - current_port_devs
        for stale_dev in stale_devs:
            LOG.debug('Deleting stale internal router device: %s', stale_dev)
            pd.remove_stale_ri_ifname(self.router_id, stale_dev)
            self.driver.unplug(stale_dev,
                               namespace=self.ns_name,
                               prefix=INTERNAL_DEV_PREFIX)