8d57019
diff -up dhcp-4.1.1-P1/server/dhcpv6.c.noprefixavail dhcp-4.1.1-P1/server/dhcpv6.c
8d57019
--- dhcp-4.1.1-P1/server/dhcpv6.c.noprefixavail	2010-10-08 12:30:03.000000000 +0200
8d57019
+++ dhcp-4.1.1-P1/server/dhcpv6.c	2010-10-12 17:17:12.000000000 +0200
8d57019
@@ -1133,7 +1133,7 @@ try_client_v6_prefix(struct iasubopt **p
8d57019
 		return ISC_R_INVALIDARG;
8d57019
 	}
8d57019
 	tmp_plen = (int) requested_pref->data[0];
8d57019
-	if ((tmp_plen < 3) || (tmp_plen > 128)) {
8d57019
+	if ((tmp_plen < 3) || (tmp_plen > 128) ||((int)tmp_plen != pool->units)) {
8d57019
 		return ISC_R_FAILURE;
8d57019
 	}
8d57019
 	memcpy(&tmp_pref, requested_pref->data + 1, sizeof(tmp_pref));
8d57019
@@ -1146,9 +1146,8 @@ try_client_v6_prefix(struct iasubopt **p
8d57019
 		return ISC_R_FAILURE;
8d57019
 	}
8d57019
 
8d57019
-	if (((int)tmp_plen != pool->units) ||
8d57019
-	    !ipv6_in_pool(&tmp_pref, pool)) {
8d57019
-		return ISC_R_FAILURE;
8d57019
+	if (!ipv6_in_pool(&tmp_pref, pool)) {
8d57019
+		return ISC_R_ADDRNOTAVAIL;
8d57019
 	}
8d57019
 
8d57019
 	if (prefix6_exists(pool, &tmp_pref, tmp_plen)) {
8d57019
@@ -1402,13 +1401,6 @@ lease_to_client(struct data_string *repl
8d57019
 		if ((status != ISC_R_SUCCESS) &&
8d57019
 		    (status != ISC_R_NORESOURCES))
8d57019
 			goto exit;
8d57019
-
8d57019
-		/*
8d57019
-		 * If any prefix cannot be given to any IA_PD, then
8d57019
-		 * set the NoPrefixAvail status code.
8d57019
-		 */
8d57019
-		if (reply.client_resources == 0)
8d57019
-			no_resources_avail = ISC_TRUE;
8d57019
 	}
8d57019
 
8d57019
 	/*
8d57019
@@ -1542,36 +1534,6 @@ lease_to_client(struct data_string *repl
8d57019
 					       reply.opt_state, reply.packet,
8d57019
 					       required_opts_NAA,
8d57019
 					       NULL);
8d57019
-	} else if (no_resources_avail && (reply.ia_count == 0) &&
8d57019
-		   (reply.packet->dhcpv6_msg_type == DHCPV6_SOLICIT))
8d57019
-	{
8d57019
-		/* Set the NoPrefixAvail status code. */
8d57019
-		if (!set_status_code(STATUS_NoPrefixAvail,
8d57019
-				     "No prefixes available for this "
8d57019
-				     "interface.", reply.opt_state)) {
8d57019
-			log_error("lease_to_client: Unable to set "
8d57019
-				  "NoPrefixAvail status code.");
8d57019
-			goto exit;
8d57019
-		}
8d57019
-
8d57019
-		/* Rewind the cursor to the start. */
8d57019
-		reply.cursor = REPLY_OPTIONS_INDEX;
8d57019
-
8d57019
-		/*
8d57019
-		 * Produce an advertise that includes only:
8d57019
-		 *
8d57019
-		 * Status code.
8d57019
-		 * Server DUID.
8d57019
-		 * Client DUID.
8d57019
-		 */
8d57019
-		reply.buf.reply.msg_type = DHCPV6_ADVERTISE;
8d57019
-		reply.cursor += store_options6((char *)reply.buf.data +
8d57019
-							reply.cursor,
8d57019
-					       sizeof(reply.buf) -
8d57019
-					       		reply.cursor,
8d57019
-					       reply.opt_state, reply.packet,
8d57019
-					       required_opts_NAA,
8d57019
-					       NULL);
8d57019
 	} else {
8d57019
 		/*
8d57019
 		 * Having stored the client's IA's, store any options that
8d57019
@@ -2782,16 +2744,18 @@ find_client_temporaries(struct reply_sta
8d57019
  */
8d57019
 static isc_result_t
8d57019
 reply_process_try_addr(struct reply_state *reply, struct iaddr *addr) {
8d57019
-	isc_result_t status = ISC_R_NORESOURCES;
8d57019
+	isc_result_t status = ISC_R_ADDRNOTAVAIL;
8d57019
 	struct ipv6_pool *pool;
8d57019
 	int i;
8d57019
 	struct data_string data_addr;
8d57019
 
8d57019
 	if ((reply == NULL) || (reply->shared == NULL) ||
8d57019
-	    (reply->shared->ipv6_pools == NULL) || (addr == NULL) ||
8d57019
-	    (reply->lease != NULL))
8d57019
+	    (addr == NULL) || (reply->lease != NULL))
8d57019
 		return ISC_R_INVALIDARG;
8d57019
 
8d57019
+	if (reply->shared->ipv6_pools == NULL)
8d57019
+		return ISC_R_ADDRNOTAVAIL;
8d57019
+
8d57019
 	memset(&data_addr, 0, sizeof(data_addr));
8d57019
 	data_addr.len = addr->len;
8d57019
 	data_addr.data = addr->iabuf;
8d57019
@@ -3303,7 +3267,9 @@ reply_process_ia_pd(struct reply_state *
8d57019
 		if (status == ISC_R_CANCELED)
8d57019
 			break;
8d57019
 
8d57019
-		if ((status != ISC_R_SUCCESS) && (status != ISC_R_ADDRINUSE))
8d57019
+		if ((status != ISC_R_SUCCESS) &&
8d57019
+		    (status != ISC_R_ADDRINUSE) &&
8d57019
+		    (status != ISC_R_ADDRNOTAVAIL))
8d57019
 			goto cleanup;
8d57019
 	}
8d57019
 
8d57019
@@ -3583,7 +3549,8 @@ reply_process_prefix(struct reply_state 
8d57019
 
8d57019
 			/* Either error out or skip this prefix. */
8d57019
 			if ((status != ISC_R_SUCCESS) && 
8d57019
-			    (status != ISC_R_ADDRINUSE)) 
8d57019
+			    (status != ISC_R_ADDRINUSE) &&
8d57019
+			    (status != ISC_R_ADDRNOTAVAIL))
8d57019
 				goto cleanup;
8d57019
 
8d57019
 			if (reply->lease == NULL) {
8d57019
@@ -3762,16 +3729,18 @@ prefix_is_owned(struct reply_state *repl
8d57019
 static isc_result_t
8d57019
 reply_process_try_prefix(struct reply_state *reply,
8d57019
 			 struct iaddrcidrnet *pref) {
8d57019
-	isc_result_t status = ISC_R_NORESOURCES;
8d57019
+	isc_result_t status = ISC_R_ADDRNOTAVAIL;
8d57019
 	struct ipv6_pool *pool;
8d57019
 	int i;
8d57019
 	struct data_string data_pref;
8d57019
 
8d57019
 	if ((reply == NULL) || (reply->shared == NULL) ||
8d57019
-	    (reply->shared->ipv6_pools == NULL) || (pref == NULL) ||
8d57019
-	    (reply->lease != NULL))
8d57019
+	    (pref == NULL) || (reply->lease != NULL))
8d57019
 		return ISC_R_INVALIDARG;
8d57019
 
8d57019
+	if (reply->shared->ipv6_pools == NULL)
8d57019
+		return ISC_R_ADDRNOTAVAIL;
8d57019
+
8d57019
 	memset(&data_pref, 0, sizeof(data_pref));
8d57019
 	data_pref.len = 17;
8d57019
 	if (!buffer_allocate(&data_pref.buffer, data_pref.len, MDL)) {