def _get_subnet_for_fixed_ip(self, context, fixed, network_id):
        if 'subnet_id' in fixed:
            subnet = self._get_subnet(context, fixed['subnet_id'])
            if subnet['network_id'] != network_id:
                msg = (_("Failed to create port on network %(network_id)s"
                         ", because fixed_ips included invalid subnet "
                         "%(subnet_id)s") %
                       {'network_id': network_id,
                        'subnet_id': fixed['subnet_id']})
                raise n_exc.InvalidInput(error_message=msg)
            # Ensure that the IP is valid on the subnet
            if ('ip_address' in fixed and
                not ipam_utils.check_subnet_ip(subnet['cidr'],
                                               fixed['ip_address'])):
                raise n_exc.InvalidIpForSubnet(ip_address=fixed['ip_address'])
            return subnet

        if 'ip_address' not in fixed:
            msg = _('IP allocation requires subnet_id or ip_address')
            raise n_exc.InvalidInput(error_message=msg)

        filter = {'network_id': [network_id]}
        subnets = self._get_subnets(context, filters=filter)

        for subnet in subnets:
            if ipam_utils.check_subnet_ip(subnet['cidr'],
                                          fixed['ip_address']):
                return subnet
        raise n_exc.InvalidIpForNetwork(ip_address=fixed['ip_address'])
Beispiel #2
0
    def _set_default_route(self, network, device_name):
        """Sets the default gateway for this dhcp namespace.

        This method is idempotent and will only adjust the route if adjusting
        it would change it from what it already is.  This makes it safe to call
        and avoids unnecessary perturbation of the system.
        """
        device = ip_lib.IPDevice(device_name, namespace=network.namespace)
        gateway = device.route.get_gateway()
        if gateway:
            gateway = gateway.get("gateway")

        for subnet in network.subnets:
            skip_subnet = subnet.ip_version != 4 or not subnet.enable_dhcp or subnet.gateway_ip is None

            if skip_subnet:
                continue

            if gateway != subnet.gateway_ip:
                LOG.debug(
                    "Setting gateway for dhcp netns on net %(n)s to " "%(ip)s",
                    {"n": network.id, "ip": subnet.gateway_ip},
                )

                # Check for and remove the on-link route for the old
                # gateway being replaced, if it is outside the subnet
                is_old_gateway_not_in_subnet = gateway and not ipam_utils.check_subnet_ip(subnet.cidr, gateway)
                if is_old_gateway_not_in_subnet:
                    v4_onlink = device.route.list_onlink_routes(constants.IP_VERSION_4)
                    v6_onlink = device.route.list_onlink_routes(constants.IP_VERSION_6)
                    existing_onlink_routes = set(r["cidr"] for r in v4_onlink + v6_onlink)
                    if gateway in existing_onlink_routes:
                        device.route.delete_route(gateway, scope="link")

                is_new_gateway_not_in_subnet = subnet.gateway_ip and not ipam_utils.check_subnet_ip(
                    subnet.cidr, subnet.gateway_ip
                )
                if is_new_gateway_not_in_subnet:
                    device.route.add_route(subnet.gateway_ip, scope="link")
                device.route.add_gateway(subnet.gateway_ip)

            return

        # No subnets on the network have a valid gateway.  Clean it up to avoid
        # confusion from seeing an invalid gateway here.
        if gateway is not None:
            LOG.debug("Removing gateway for dhcp netns on net %s", network.id)

            device.route.delete_gateway(gateway)
Beispiel #3
0
    def _gateway_added(self, ex_gw_port, interface_name):
        """Add Floating IP gateway port."""
        LOG.debug("add gateway interface(%s)", interface_name)
        ns_name = self.get_name()
        self.driver.plug(
            ex_gw_port["network_id"],
            ex_gw_port["id"],
            interface_name,
            ex_gw_port["mac_address"],
            bridge=self.agent_conf.external_network_bridge,
            namespace=ns_name,
            prefix=FIP_EXT_DEV_PREFIX,
        )

        ip_cidrs = common_utils.fixed_ip_cidrs(ex_gw_port["fixed_ips"])
        self.driver.init_l3(interface_name, ip_cidrs, namespace=ns_name, clean_connections=True)

        for fixed_ip in ex_gw_port["fixed_ips"]:
            ip_lib.send_ip_addr_adv_notif(ns_name, interface_name, fixed_ip["ip_address"], self.agent_conf)

        for subnet in ex_gw_port["subnets"]:
            gw_ip = subnet.get("gateway_ip")
            if gw_ip:
                is_gateway_not_in_subnet = not ipam_utils.check_subnet_ip(subnet.get("cidr"), gw_ip)
                ipd = ip_lib.IPDevice(interface_name, namespace=ns_name)
                if is_gateway_not_in_subnet:
                    ipd.route.add_route(gw_ip, scope="link")
                ipd.route.add_gateway(gw_ip)

        cmd = ["sysctl", "-w", "net.ipv4.conf.%s.proxy_arp=1" % interface_name]
        # TODO(Carl) mlavelle's work has self.ip_wrapper
        ip_wrapper = ip_lib.IPWrapper(namespace=ns_name)
        ip_wrapper.netns.execute(cmd, check_exit_code=False)
Beispiel #4
0
    def update_gateway_port(self, agent_gateway_port):
        gateway_ip_not_changed = self.agent_gateway_port and (
            not self._check_for_gateway_ip_change(agent_gateway_port))
        self.agent_gateway_port = agent_gateway_port
        if gateway_ip_not_changed:
            return

        ns_name = self.get_name()
        interface_name = self.get_ext_device_name(agent_gateway_port['id'])
        for fixed_ip in agent_gateway_port['fixed_ips']:
            ip_lib.send_ip_addr_adv_notif(ns_name,
                                          interface_name,
                                          fixed_ip['ip_address'],
                                          self.agent_conf)

        ipd = ip_lib.IPDevice(interface_name, namespace=ns_name)
        for subnet in agent_gateway_port['subnets']:
            gw_ip = subnet.get('gateway_ip')
            if gw_ip:
                is_gateway_not_in_subnet = not ipam_utils.check_subnet_ip(
                                                subnet.get('cidr'), gw_ip)
                if is_gateway_not_in_subnet:
                    ipd.route.add_route(gw_ip, scope='link')
                ipd.route.add_gateway(gw_ip)
            else:
                current_gateway = ipd.route.get_gateway()
                if current_gateway and current_gateway.get('gateway'):
                    ipd.route.delete_gateway(current_gateway.get('gateway'))
Beispiel #5
0
 def _get_subnet_id_for_given_fixed_ip(self, context, fixed_ip, port_dict):
     """Returns the subnet_id that matches the fixedip on a network."""
     filters = {'network_id': [port_dict['network_id']]}
     subnets = self._core_plugin.get_subnets(context, filters)
     for subnet in subnets:
         if ipam_utils.check_subnet_ip(subnet['cidr'], fixed_ip):
             return subnet['id']
Beispiel #6
0
    def _update_gateway_route(self, agent_gateway_port,
                             interface_name, tbl_index):
        ns_name = self.get_name()
        ipd = ip_lib.IPDevice(interface_name, namespace=ns_name)
        # If the 'fg-' device doesn't exist in the namespace then trying
        # to send advertisements or configure the default route will just
        # throw exceptions.  Unsubscribe this external network so that
        # the next call will trigger the interface to be plugged.
        if not ipd.exists():
            LOG.warning(_LW('DVR: FIP gateway port with interface '
                            'name: %(device)s does not exist in the given '
                            'namespace: %(ns)s'), {'device': interface_name,
                                                   'ns': ns_name})
            msg = _('DVR: Gateway update route in FIP namespace failed, retry '
                    'should be attempted on next call')
            raise n_exc.FloatingIpSetupException(msg)

        for fixed_ip in agent_gateway_port['fixed_ips']:
            ip_lib.send_ip_addr_adv_notif(ns_name,
                                          interface_name,
                                          fixed_ip['ip_address'],
                                          self.agent_conf.send_arp_for_ha)

        for subnet in agent_gateway_port['subnets']:
            gw_ip = subnet.get('gateway_ip')
            if gw_ip:
                is_gateway_not_in_subnet = not ipam_utils.check_subnet_ip(
                                                subnet.get('cidr'), gw_ip)
                if is_gateway_not_in_subnet:
                    ipd.route.add_route(gw_ip, scope='link')
                self._add_default_gateway_for_fip(gw_ip, ipd, tbl_index)
            else:
                current_gateway = ipd.route.get_gateway()
                if current_gateway and current_gateway.get('gateway'):
                    ipd.route.delete_gateway(current_gateway.get('gateway'))
Beispiel #7
0
    def update_gateway_port(self, agent_gateway_port):
        gateway_ip_not_changed = self.agent_gateway_port and (
            not self._check_for_gateway_ip_change(agent_gateway_port))
        self.agent_gateway_port = agent_gateway_port
        if gateway_ip_not_changed:
            return

        ns_name = self.get_name()
        interface_name = self.get_ext_device_name(agent_gateway_port['id'])
        for fixed_ip in agent_gateway_port['fixed_ips']:
            ip_lib.send_ip_addr_adv_notif(ns_name, interface_name,
                                          fixed_ip['ip_address'],
                                          self.agent_conf.send_arp_for_ha)

        ipd = ip_lib.IPDevice(interface_name, namespace=ns_name)
        for subnet in agent_gateway_port['subnets']:
            gw_ip = subnet.get('gateway_ip')
            if gw_ip:
                is_gateway_not_in_subnet = not ipam_utils.check_subnet_ip(
                    subnet.get('cidr'), gw_ip)
                if is_gateway_not_in_subnet:
                    ipd.route.add_route(gw_ip, scope='link')
                ipd.route.add_gateway(gw_ip)
            else:
                current_gateway = ipd.route.get_gateway()
                if current_gateway and current_gateway.get('gateway'):
                    ipd.route.delete_gateway(current_gateway.get('gateway'))
Beispiel #8
0
    def _update_gateway_route(self, agent_gateway_port,
                             interface_name, tbl_index):
        ns_name = self.get_name()
        ipd = ip_lib.IPDevice(interface_name, namespace=ns_name)
        # If the 'fg-' device doesn't exist in the namespace then trying
        # to send advertisements or configure the default route will just
        # throw exceptions.  Unsubscribe this external network so that
        # the next call will trigger the interface to be plugged.
        if not ipd.exists():
            LOG.warning('DVR: FIP gateway port with interface '
                        'name: %(device)s does not exist in the given '
                        'namespace: %(ns)s', {'device': interface_name,
                                              'ns': ns_name})
            msg = _('DVR: Gateway update route in FIP namespace failed, retry '
                    'should be attempted on next call')
            raise l3_exc.FloatingIpSetupException(msg)

        for fixed_ip in agent_gateway_port['fixed_ips']:
            ip_lib.send_ip_addr_adv_notif(ns_name,
                                          interface_name,
                                          fixed_ip['ip_address'])

        for subnet in agent_gateway_port['subnets']:
            gw_ip = subnet.get('gateway_ip')
            if gw_ip:
                is_gateway_not_in_subnet = not ipam_utils.check_subnet_ip(
                                                subnet.get('cidr'), gw_ip)
                if is_gateway_not_in_subnet:
                    ipd.route.add_route(gw_ip, scope='link')
                self._add_default_gateway_for_fip(gw_ip, ipd, tbl_index)
            else:
                current_gateway = ipd.route.get_gateway()
                if current_gateway and current_gateway.get('gateway'):
                    ipd.route.delete_gateway(current_gateway.get('gateway'))
Beispiel #9
0
 def _get_subnet_id_for_given_fixed_ip(
     self, context, fixed_ip, port_dict):
     """Returns the subnet_id that matches the fixedip on a network."""
     filters = {'network_id': [port_dict['network_id']]}
     subnets = self._core_plugin.get_subnets(context, filters)
     for subnet in subnets:
         if ipam_utils.check_subnet_ip(subnet['cidr'], fixed_ip):
             return subnet['id']
 def get_matching_subnet(fixed_ip):
     for subnet in subnets:
         if 'subnet_id' in fixed_ip:
             if subnet['id'] == fixed_ip['subnet_id']:
                 return subnet
         elif 'ip_address' in fixed_ip:
             if ipam_utils.check_subnet_ip(subnet['cidr'],
                                           fixed_ip['ip_address']):
                 return subnet
    def _get_subnet_for_fixed_ip(self, context, fixed, subnets, network_id):
        # Subnets are all the subnets belonging to the same network.
        if not subnets:
            msg = _('IP allocation requires subnets for network')
            raise exc.InvalidInput(error_message=msg)

        if 'subnet_id' in fixed:

            def get_matching_subnet():
                for subnet in subnets:
                    if subnet['id'] == fixed['subnet_id']:
                        return subnet

            subnet = get_matching_subnet()
            if not subnet:
                # Call this method to keep original status code
                # in case subnet is not found
                self._get_subnet_object(context, fixed['subnet_id'])
                msg = (_("Failed to create port on network %(network_id)s"
                         ", because fixed_ips included invalid subnet "
                         "%(subnet_id)s") % {
                             'network_id': network_id,
                             'subnet_id': fixed['subnet_id']
                         })
                raise exc.InvalidInput(error_message=msg)
            # Ensure that the IP is valid on the subnet
            if ('ip_address' in fixed and not ipam_utils.check_subnet_ip(
                    subnet['cidr'], fixed['ip_address'],
                    fixed['device_owner'])):
                raise exc.InvalidIpForSubnet(ip_address=fixed['ip_address'])
            return subnet

        if 'ip_address' not in fixed:
            msg = _('IP allocation requires subnet_id or ip_address')
            raise exc.InvalidInput(error_message=msg)

        for subnet in subnets:
            if ipam_utils.check_subnet_ip(subnet['cidr'], fixed['ip_address'],
                                          fixed['device_owner']):
                return subnet
        raise exc.InvalidIpForNetwork(ip_address=fixed['ip_address'])
Beispiel #12
0
 def _add_route_to_gw(self, ex_gw_port, device_name, namespace,
                      preserve_ips):
     # Note: ipv6_gateway is an ipv6 LLA
     # and so doesn't need a special route
     for subnet in ex_gw_port.get('subnets', []):
         is_gateway_not_in_subnet = (
             subnet['gateway_ip'] and not ipam_utils.check_subnet_ip(
                 subnet['cidr'], subnet['gateway_ip']))
         if is_gateway_not_in_subnet:
             preserve_ips.append(subnet['gateway_ip'])
             device = ip_lib.IPDevice(device_name, namespace=namespace)
             device.route.add_route(subnet['gateway_ip'], scope='link')
Beispiel #13
0
 def _add_route_to_gw(self, ex_gw_port, device_name,
                      namespace, preserve_ips):
     # Note: ipv6_gateway is an ipv6 LLA
     # and so doesn't need a special route
     for subnet in ex_gw_port.get('subnets', []):
         is_gateway_not_in_subnet = (subnet['gateway_ip'] and
                                     not ipam_utils.check_subnet_ip(
                                             subnet['cidr'],
                                             subnet['gateway_ip']))
         if is_gateway_not_in_subnet:
             preserve_ips.append(subnet['gateway_ip'])
             device = ip_lib.IPDevice(device_name, namespace=namespace)
             device.route.add_route(subnet['gateway_ip'], scope='link')
Beispiel #14
0
 def test_check_subnet_ip_v6_owner_not_router(self):
     port_owner = 'nova:compute'
     # IP address == network
     self.assertFalse(
         utils.check_subnet_ip('F111::0/64',
                               'F111::0',
                               port_owner=port_owner))
     # IP address == broadcast
     self.assertTrue(
         utils.check_subnet_ip('F111::0/64',
                               'F111::FFFF:FFFF:FFFF:FFFF',
                               port_owner=port_owner))
     # IP address in network
     self.assertTrue(
         utils.check_subnet_ip('F111::0/64',
                               'F111::50',
                               port_owner=port_owner))
     # IP address not in network
     self.assertFalse(
         utils.check_subnet_ip('F111::0/64',
                               'F112::50',
                               port_owner=port_owner))
Beispiel #15
0
 def test_check_subnet_ip_v6_owner_router_or_not_defined(self):
     for port_owner in (constants.ROUTER_PORT_OWNERS + ('', )):
         # IP address == network
         self.assertTrue(
             utils.check_subnet_ip('F111::0/64',
                                   'F111::0',
                                   port_owner=port_owner))
         # IP address == broadcast
         self.assertTrue(
             utils.check_subnet_ip('F111::0/64',
                                   'F111::FFFF:FFFF:FFFF:FFFF',
                                   port_owner=port_owner))
         # IP address in network
         self.assertTrue(
             utils.check_subnet_ip('F111::0/64',
                                   'F111::50',
                                   port_owner=port_owner))
         # IP address not in network
         self.assertFalse(
             utils.check_subnet_ip('F111::0/64',
                                   'F112::50',
                                   port_owner=port_owner))
    def _get_subnet_for_fixed_ip(self, context, fixed, subnets):
        # Subnets are all the subnets belonging to the same network.
        if not subnets:
            msg = _('IP allocation requires subnets for network')
            raise exc.InvalidInput(error_message=msg)

        if 'subnet_id' in fixed:
            def get_matching_subnet():
                for subnet in subnets:
                    if subnet['id'] == fixed['subnet_id']:
                        return subnet
            subnet = get_matching_subnet()
            if not subnet:
                subnet_obj = self._get_subnet_object(context,
                                                     fixed['subnet_id'])
                msg = (_("Failed to create port on network %(network_id)s"
                         ", because fixed_ips included invalid subnet "
                         "%(subnet_id)s") %
                       {'network_id': subnet_obj.network_id,
                        'subnet_id': fixed['subnet_id']})
                raise exc.InvalidInput(error_message=msg)
            # Ensure that the IP is valid on the subnet
            if ('ip_address' in fixed and
                not ipam_utils.check_subnet_ip(subnet['cidr'],
                                               fixed['ip_address'])):
                raise exc.InvalidIpForSubnet(ip_address=fixed['ip_address'])
            return subnet

        if 'ip_address' not in fixed:
            msg = _('IP allocation requires subnet_id or ip_address')
            raise exc.InvalidInput(error_message=msg)

        for subnet in subnets:
            if ipam_utils.check_subnet_ip(subnet['cidr'],
                                          fixed['ip_address']):
                return subnet
        raise exc.InvalidIpForNetwork(ip_address=fixed['ip_address'])
    def _validate_create_redirect_target_vip(self, context, redirect_target,
                                             subnet_mapping, vip):
        # VIP not allowed if redudancyEnabled is False
        if redirect_target.get('redundancy_enabled') == "False":
            if redirect_target.get('virtual_ip_address'):
                msg = (_("VIP can be addded to a redirect target only "
                         "when redundancyEnabled is True"))
                raise nuage_exc.NuageBadRequest(msg=msg)

        # VIP should be in the same subnet as redirect_target['subnet_id']
        if vip:
            subnet = self.core_plugin.get_subnet(context,
                                                 subnet_mapping['subnet_id'])
            if not ipam_utils.check_subnet_ip(subnet['cidr'], vip):
                msg = ("VIP should be in the same subnet as subnet %s " %
                       subnet_mapping['subnet_id'])
                raise nuage_exc.NuageBadRequest(msg=msg)
Beispiel #18
0
    def _verify_ip(self, session, ip_address):
        """Verify whether IP address can be allocated on subnet.

        :param session: database session
        :param ip_address: String representing the IP address to verify
        :raises: InvalidInput, IpAddressAlreadyAllocated
        """
        # Ensure that the IP's are unique
        if not self.subnet_manager.check_unique_allocation(
                session, ip_address):
            raise ipam_exc.IpAddressAlreadyAllocated(
                subnet_id=self.subnet_manager.neutron_id, ip=ip_address)

        # Ensure that the IP is valid on the subnet
        if not ipam_utils.check_subnet_ip(self._cidr, ip_address):
            raise ipam_exc.InvalidIpForSubnet(
                subnet_id=self.subnet_manager.neutron_id, ip=ip_address)
Beispiel #19
0
    def _validate_create_redirect_target_vip(self, context, redirect_target,
                                             subnet_mapping, vip):
        # VIP not allowed if redudancyEnabled is False
        if redirect_target.get('redundancy_enabled') == "False":
            if redirect_target.get('virtual_ip_address'):
                msg = (_("VIP can be addded to a redirect target only "
                         "when redundancyEnabled is True"))
                raise nuage_exc.NuageBadRequest(msg=msg)

        # VIP should be in the same subnet as redirect_target['subnet_id']
        if vip:
            subnet = self.core_plugin.get_subnet(context,
                                                 subnet_mapping['subnet_id'])
            if not ipam_utils.check_subnet_ip(subnet['cidr'], vip):
                msg = ("VIP should be in the same subnet as subnet %s " %
                       subnet_mapping['subnet_id'])
                raise nuage_exc.NuageBadRequest(msg=msg)
Beispiel #20
0
    def _verify_ip(self, context, ip_address):
        """Verify whether IP address can be allocated on subnet.

        :param context: neutron api request context
        :param ip_address: String representing the IP address to verify
        :raises: InvalidInput, IpAddressAlreadyAllocated
        """
        # Ensure that the IP's are unique
        if not self.subnet_manager.check_unique_allocation(context,
                                                           ip_address):
            raise ipam_exc.IpAddressAlreadyAllocated(
                subnet_id=self.subnet_manager.neutron_id,
                ip=ip_address)

        # Ensure that the IP is valid on the subnet
        if not ipam_utils.check_subnet_ip(self._cidr, ip_address):
            raise ipam_exc.InvalidIpForSubnet(
                subnet_id=self.subnet_manager.neutron_id,
                ip=ip_address)
Beispiel #21
0
    def _update_gateway_port(self, agent_gateway_port, interface_name):
        if (self.agent_gateway_port and
            not self._check_for_gateway_ip_change(agent_gateway_port)):
                return

        ns_name = self.get_name()
        ipd = ip_lib.IPDevice(interface_name, namespace=ns_name)
        # If the 'fg-' device doesn't exist in the namespace then trying
        # to send advertisements or configure the default route will just
        # throw exceptions.  Unsubscribe this external network so that
        # the next call will trigger the interface to be plugged.
        if not ipd.exists():
            self.unsubscribe(agent_gateway_port['network_id'])
            LOG.warning(_LW('DVR: FIP gateway port with interface '
                            'name: %(device)s does not exist in the given '
                            'namespace: %(ns)s'), {'device': interface_name,
                                                   'ns': ns_name})
            msg = _('DVR: Gateway setup in FIP namespace failed, retry '
                    'should be attempted on next call')
            raise n_exc.FloatingIpSetupException(msg)

        for fixed_ip in agent_gateway_port['fixed_ips']:
            ip_lib.send_ip_addr_adv_notif(ns_name,
                                          interface_name,
                                          fixed_ip['ip_address'],
                                          self.agent_conf.send_arp_for_ha)

        for subnet in agent_gateway_port['subnets']:
            gw_ip = subnet.get('gateway_ip')
            if gw_ip:
                is_gateway_not_in_subnet = not ipam_utils.check_subnet_ip(
                                                subnet.get('cidr'), gw_ip)
                if is_gateway_not_in_subnet:
                    ipd.route.add_route(gw_ip, scope='link')
                ipd.route.add_gateway(gw_ip)
            else:
                current_gateway = ipd.route.get_gateway()
                if current_gateway and current_gateway.get('gateway'):
                    ipd.route.delete_gateway(current_gateway.get('gateway'))
        # Cache the agent gateway port after successfully configuring
        # the gateway, so that checking on self.agent_gateway_port
        # will be a valid check
        self.agent_gateway_port = agent_gateway_port
Beispiel #22
0
    def _add_default_gw_virtual_route(self, ex_gw_port, interface_name):
        gateway_ips = self._get_external_gw_ips(ex_gw_port)

        default_gw_rts = []
        instance = self._get_keepalived_instance()
        for subnet in ex_gw_port.get('subnets', []):
            is_gateway_not_in_subnet = (subnet['gateway_ip'] and
                                        not ipam_utils.check_subnet_ip(
                                            subnet['cidr'],
                                            subnet['gateway_ip']))
            if is_gateway_not_in_subnet:
                default_gw_rts.append(keepalived.KeepalivedVirtualRoute(
                    subnet['gateway_ip'], None, interface_name, scope='link'))
        for gw_ip in gateway_ips:
            # TODO(Carl) This is repeated everywhere.  A method would
            # be nice.
            default_gw = n_consts.IP_ANY[netaddr.IPAddress(gw_ip).version]
            default_gw_rts.append(keepalived.KeepalivedVirtualRoute(
                default_gw, gw_ip, interface_name))
        instance.virtual_routes.gateway_routes = default_gw_rts
Beispiel #23
0
    def _allocate_specific_subnet(self, request):
        with self._context.session.begin(subtransactions=True):
            self._lock_subnetpool()
            self._check_subnetpool_tenant_quota(request.tenant_id,
                                                request.prefixlen)
            cidr = request.subnet_cidr
            gateway = request.gateway_ip
            if gateway and not ipam_utils.check_subnet_ip(cidr, gateway):
                msg = _("Cannot allocate requested subnet due to bad gateway "
                        "address")
                raise n_exc.SubnetAllocationError(reason=msg)

            available = self._get_available_prefix_list()
            matched = netaddr.all_matching_cidrs(cidr, available)
            if len(matched) is 1 and matched[0].prefixlen <= cidr.prefixlen:
                return IpamSubnet(request.tenant_id,
                                  request.subnet_id,
                                  cidr,
                                  gateway_ip=gateway,
                                  allocation_pools=request.allocation_pools)
            msg = _("Cannot allocate requested subnet from the available "
                    "set of prefixes")
            raise n_exc.SubnetAllocationError(reason=msg)
Beispiel #24
0
    def _gateway_added(self, ex_gw_port, interface_name):
        """Add Floating IP gateway port."""
        LOG.debug("add gateway interface(%s)", interface_name)
        ns_name = self.get_name()
        self.driver.plug(ex_gw_port['network_id'],
                         ex_gw_port['id'],
                         interface_name,
                         ex_gw_port['mac_address'],
                         bridge=self.agent_conf.external_network_bridge,
                         namespace=ns_name,
                         prefix=FIP_EXT_DEV_PREFIX)

        ip_cidrs = common_utils.fixed_ip_cidrs(ex_gw_port['fixed_ips'])
        self.driver.init_l3(interface_name,
                            ip_cidrs,
                            namespace=ns_name,
                            clean_connections=True)

        for fixed_ip in ex_gw_port['fixed_ips']:
            ip_lib.send_ip_addr_adv_notif(ns_name, interface_name,
                                          fixed_ip['ip_address'],
                                          self.agent_conf)

        for subnet in ex_gw_port['subnets']:
            gw_ip = subnet.get('gateway_ip')
            if gw_ip:
                is_gateway_not_in_subnet = not ipam_utils.check_subnet_ip(
                    subnet.get('cidr'), gw_ip)
                ipd = ip_lib.IPDevice(interface_name, namespace=ns_name)
                if is_gateway_not_in_subnet:
                    ipd.route.add_route(gw_ip, scope='link')
                ipd.route.add_gateway(gw_ip)

        cmd = ['sysctl', '-w', 'net.ipv4.conf.%s.proxy_arp=1' % interface_name]
        # TODO(Carl) mlavelle's work has self.ip_wrapper
        ip_wrapper = ip_lib.IPWrapper(namespace=ns_name)
        ip_wrapper.netns.execute(cmd, check_exit_code=False)
 def _extract_valid_peer_ips(self, cidr, peer_ips):
     return [(peer_ip) for peer_ip in peer_ips
             if ipam_utils.check_subnet_ip(cidr, peer_ip)]
Beispiel #26
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:
            found = False
            if 'subnet_id' not in fixed:
                if 'ip_address' not in fixed:
                    msg = _('IP allocation requires subnet_id or ip_address')
                    raise n_exc.InvalidInput(error_message=msg)

                filter = {'network_id': [network_id]}
                subnets = self._get_subnets(context, filters=filter)
                for subnet in subnets:
                    if ipam_utils.check_subnet_ip(subnet['cidr'],
                                                  fixed['ip_address']):
                        found = True
                        subnet_id = subnet['id']
                        break
                if not found:
                    raise n_exc.InvalidIpForNetwork(
                        ip_address=fixed['ip_address'])
            else:
                subnet = self._get_subnet(context, fixed['subnet_id'])
                if subnet['network_id'] != network_id:
                    msg = (_("Failed to create port on network %(network_id)s"
                             ", because fixed_ips included invalid subnet "
                             "%(subnet_id)s") %
                           {'network_id': network_id,
                            'subnet_id': fixed['subnet_id']})
                    raise n_exc.InvalidInput(error_message=msg)
                subnet_id = subnet['id']

            is_auto_addr_subnet = ipv6_utils.is_auto_address_subnet(subnet)
            if 'ip_address' in fixed:
                # 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'])

                # Ensure that the IP is valid on the subnet
                if (not found and
                    not ipam_utils.check_subnet_ip(subnet['cidr'],
                                                   fixed['ip_address'])):
                    raise n_exc.InvalidIpForSubnet(
                        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 or
                    device_owner == constants.DEVICE_OWNER_ROUTER_SNAT or
                    not is_auto_addr_subnet):
                    fixed_ip_set.append({'subnet_id': subnet_id})

        if len(fixed_ip_set) > cfg.CONF.max_fixed_ips_per_port:
            msg = _('Exceeded maximim amount of fixed ips per port')
            raise n_exc.InvalidInput(error_message=msg)
        return fixed_ip_set
Beispiel #27
0
 def test_check_subnet_ip_v4_network(self):
     self.assertFalse(utils.check_subnet_ip('1.1.1.0/24', '1.1.1.0'))
Beispiel #28
0
 def _check_gateway_in_subnet(cls, cidr, gateway):
     """Validate that the gateway is on the subnet."""
     ip = netaddr.IPAddress(gateway)
     if ip.version == 4 or (ip.version == 6 and not ip.is_link_local()):
         return ipam_utils.check_subnet_ip(cidr, gateway)
     return True
Beispiel #29
0
 def test_check_subnet_ip_v4_valid(self):
     self.assertTrue(utils.check_subnet_ip('1.1.1.0/24', '1.1.1.1'))
     self.assertTrue(utils.check_subnet_ip('1.1.1.0/24', '1.1.1.254'))
Beispiel #30
0
 def _make_route_info(self, nexthop, dest_networks):
     return [(network, nexthop) for network in dest_networks
             if not ipam_utils.check_subnet_ip(network, nexthop)]
Beispiel #31
0
 def test_check_subnet_ip_v6_network(self):
     self.assertTrue(utils.check_subnet_ip('F111::0/64', 'F111::0'))
Beispiel #32
0
 def test_check_subnet_ip_v6_valid(self):
     self.assertTrue(utils.check_subnet_ip('F111::0/64', 'F111::1'))
     self.assertTrue(utils.check_subnet_ip('F111::0/64',
                                           'F111::FFFF:FFFF:FFFF:FFFF'))
Beispiel #33
0
 def test_check_subnet_ip_v4_valid(self):
     self.assertTrue(utils.check_subnet_ip('1.1.1.0/24', '1.1.1.1'))
     self.assertTrue(utils.check_subnet_ip('1.1.1.0/24', '1.1.1.254'))
Beispiel #34
0
 def test_check_subnet_ip_v4_broadcast(self):
     self.assertFalse(utils.check_subnet_ip('1.1.1.0/24', '1.1.1.255'))
Beispiel #35
0
 def test_check_subnet_ip_v4_network(self):
     self.assertFalse(utils.check_subnet_ip('1.1.1.0/24', '1.1.1.0'))
 def _make_route_info(self, nexthop, dest_networks):
     return [(network, nexthop) for network in dest_networks
             if not ipam_utils.check_subnet_ip(network, nexthop)]
 def _check_gateway_in_subnet(cls, cidr, gateway):
     """Validate that the gateway is on the subnet."""
     ip = netaddr.IPAddress(gateway)
     if ip.version == 4 or (ip.version == 6 and not ip.is_link_local()):
         return ipam_utils.check_subnet_ip(cidr, gateway)
     return True
Beispiel #38
0
 def _extract_valid_peer_ips(self, cidr, peer_ips):
     return [(peer_ip) for peer_ip in peer_ips
             if ipam_utils.check_subnet_ip(cidr, peer_ip)]
Beispiel #39
0
 def test_check_subnet_ip_v4_broadcast(self):
     self.assertFalse(utils.check_subnet_ip('1.1.1.0/24', '1.1.1.255'))
Beispiel #40
0
 def test_check_subnet_ip_v6_network(self):
     self.assertFalse(utils.check_subnet_ip('F111::0/64', 'F111::0'))
Beispiel #41
0
 def test_check_subnet_ip_v6_valid(self):
     self.assertTrue(utils.check_subnet_ip('F111::0/64', 'F111::1'))
     self.assertTrue(utils.check_subnet_ip('F111::0/64',
                                           'F111::FFFF:FFFF:FFFF:FFFF'))