'Validate a subnet spec.'

def _validate_subnet(self, context, s, cur_subnet=None):

    ip_ver = s['ip_version']
    if validators.is_attr_set(s.get('cidr')):
        self._validate_ip_version(ip_ver, s['cidr'], 'cidr')
    if cur_subnet:
        dhcp_was_enabled = cur_subnet.enable_dhcp
    else:
        dhcp_was_enabled = False
    if (s.get('enable_dhcp') and (not dhcp_was_enabled)):
        subnet_prefixlen = netaddr.IPNetwork(s['cidr']).prefixlen
        error_message = _('Subnet    has    a    prefix    length    that    is    incompatible    with    DHCP    service    enabled')
        if (((ip_ver == 4) and (subnet_prefixlen > 30)) or ((ip_ver == 6) and (subnet_prefixlen > 126))):
            raise exc.InvalidInput(error_message=error_message)
        net = netaddr.IPNetwork(s['cidr'])
        if net.is_multicast():
            error_message = _('Multicast    IP    subnet    is    not    supported    if    enable_dhcp    is    True')
            raise exc.InvalidInput(error_message=error_message)
        elif net.is_loopback():
            error_message = _('Loopback    IP    subnet    is    not    supported    if    enable_dhcp    is    True')
            raise exc.InvalidInput(error_message=error_message)
    if validators.is_attr_set(s.get('gateway_ip')):
        self._validate_ip_version(ip_ver, s['gateway_ip'], 'gateway_ip')
        is_gateway_not_valid = ipam.utils.check_gateway_invalid_in_subnet(s['cidr'], s['gateway_ip'])
        if is_gateway_not_valid:
            error_message = _('Gateway    is    not    valid    on    subnet')
            raise exc.InvalidInput(error_message=error_message)
        if (cur_subnet and (not ipv6_utils.is_ipv6_pd_enabled(s))):
            with db_api.context_manager.reader.using(context):
                ipal = models_v2.IPAllocation
                alloc_qry = context.session.query(ipal)
                alloc_qry = alloc_qry.join('port', 'routerport')
                allocated = alloc_qry.filter((ipal.ip_address == cur_subnet['gateway_ip']), (ipal.subnet_id == cur_subnet['id'])).first()
            if (allocated and allocated['port_id']):
                raise n_exc.GatewayIpInUse(ip_address=cur_subnet['gateway_ip'], port_id=allocated['port_id'])
    if validators.is_attr_set(s.get('dns_nameservers')):
        if (len(s['dns_nameservers']) > cfg.CONF.max_dns_nameservers):
            raise n_exc.DNSNameServersExhausted(subnet_id=s.get('id', _('new    subnet')), quota=cfg.CONF.max_dns_nameservers)
        for dns in s['dns_nameservers']:
            try:
                netaddr.IPAddress(dns)
            except Exception:
                raise exc.InvalidInput(error_message=(_('Error    parsing    dns    address    %s') % dns))
            self._validate_ip_version(ip_ver, dns, 'dns_nameserver')
    if validators.is_attr_set(s.get('host_routes')):
        if (len(s['host_routes']) > cfg.CONF.max_subnet_host_routes):
            raise n_exc.HostRoutesExhausted(subnet_id=s.get('id', _('new    subnet')), quota=cfg.CONF.max_subnet_host_routes)
        for rt in s['host_routes']:
            self._validate_host_route(rt, ip_ver)
    if (ip_ver == 4):
        if validators.is_attr_set(s.get('ipv6_ra_mode')):
            raise exc.InvalidInput(error_message=_('ipv6_ra_mode    is    not    valid    when    ip_version    is    4'))
        if validators.is_attr_set(s.get('ipv6_address_mode')):
            raise exc.InvalidInput(error_message=_('ipv6_address_mode    is    not    valid    when    ip_version    is    4'))
    if (ip_ver == 6):
        self._validate_ipv6_attributes(s, cur_subnet)
