.\" see ``http://www.vix.com''. To learn more about Nominum, Inc., see
.\" ``http://www.nominum.com''.
.\"
-.\" $Id: dhcpd.conf.5,v 1.90 2007/10/31 19:13:33 dhankins Exp $
+.\" $Id: dhcpd.conf.5,v 1.91 2007/11/20 18:34:37 dhankins Exp $
.\"
.TH dhcpd.conf 5
.SH NAME
.RE
.PP
The
+.I limit-addrs-per-ia
+statement
+.RS 0.25i
+.PP
+.B limit-addrs-per-ia \fInumber\fB;\fR
+.PP
+By default, the DHCPv6 server will limit clients to one IAADDR per IA
+option, meaning one address. If you wish to permit clients to hang onto
+multiple addresses at a time, configure a larger \fInumber\fR here.
+.PP
+Note that there is no present method to configure the server to forcibly
+configure the client with one IP address per each subnet on a shared network.
+This is left to future work.
+.RE
+.PP
+The
.I dhcpv6-lease-file-name
statement
.RS 0.25i
/* IA level persistent state */
unsigned ia_count;
- isc_boolean_t client_addressed, static_lease;
+ unsigned client_addresses;
+ isc_boolean_t static_lease;
struct ia_na *ia_na;
struct ia_na *old_ia;
struct option_state *reply_ia;
oc = lookup_option(&dhcpv6_universe, packet_ia, D6O_IAADDR);
reply->valid = reply->prefer = 0xffffffff;
reply->client_valid = reply->client_prefer = 0;
- reply->client_addressed = ISC_FALSE;
+ reply->client_addresses = 0;
for (; oc != NULL ; oc = oc->next) {
status = reply_process_addr(reply, oc);
* If we fell through the above and never gave the client
* an address, give it one now.
*/
- if ((status != ISC_R_CANCELED) && !reply->client_addressed) {
+ if ((status != ISC_R_CANCELED) && (reply->client_addresses == 0)) {
status = find_client_address(reply);
/*
struct group *group;
struct subnet *subnet;
struct iaddr tmp_addr;
+ struct option_cache *oc;
struct data_string iaaddr, data;
isc_result_t status = ISC_R_SUCCESS;
group = reply->shared->group;
}
+ /*
+ * If client_addresses is nonzero, then the reply_process_is_addressed
+ * function has executed configuration state into the reply option
+ * cache. We will use that valid cache to derive configuration for
+ * whether or not to engage in additional addresses, and similar.
+ */
+ if (reply->client_addresses != 0) {
+ unsigned limit = 1;
+
+ /*
+ * Does this client have "enough" addresses already? Default
+ * to one. Everybody gets one, and one should be enough for
+ * anybody.
+ */
+ oc = lookup_option(&server_universe, reply->opt_state,
+ SV_LIMIT_ADDRS_PER_IA);
+ if (oc != NULL) {
+ if (!evaluate_option_cache(&data, reply->packet,
+ NULL, NULL,
+ reply->packet->options,
+ reply->opt_state,
+ scope, oc, MDL) ||
+ (data.len != 4)) {
+ log_error("reply_process_ia: unable to "
+ "evaluate addrs-per-ia value.");
+ status = ISC_R_FAILURE;
+ goto cleanup;
+ }
+
+ limit = getULong(data.data);
+ data_string_forget(&data, MDL);
+ }
+
+ /*
+ * If we wish to limit the client to a certain number of
+ * addresses, then omit the address from the reply.
+ */
+ if (reply->client_addresses >= limit)
+ goto cleanup;
+ }
+
status = reply_process_is_addressed(reply, scope, group);
if (status != ISC_R_SUCCESS)
goto cleanup;
oc = lookup_option(&server_universe, reply->opt_state,
SV_DEFAULT_LEASE_TIME);
if (oc != NULL) {
- if (!evaluate_option_cache(&data, reply->packet, NULL,
- NULL,
+ if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
reply->packet->options,
reply->opt_state,
- &reply->lease->scope,
- oc, MDL) ||
+ scope, oc, MDL) ||
(data.len != 4)) {
log_error("reply_process_ia: uanble to "
"evaluate default lease time");
oc = lookup_option(&server_universe, reply->opt_state,
SV_PREFER_LIFETIME);
if (oc != NULL) {
- if (!evaluate_option_cache(&data, reply->packet, NULL,
- NULL,
+ if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
reply->packet->options,
reply->opt_state,
- &reply->lease->scope,
- oc, MDL) ||
+ scope, oc, MDL) ||
(data.len != 4)) {
log_error("reply_process_ia: unable to "
"evaluate preferred lease time");
data_string_forget(&data, MDL);
if (status == ISC_R_SUCCESS)
- reply->client_addressed = ISC_TRUE;
+ reply->client_addresses++;
return status;
}
{ "preferred-lifetime", "T", &server_universe, 53, 1 },
{ "dhcpv6-lease-file-name", "t", &server_universe, 54, 1 },
{ "dhcpv6-pid-file-name", "t", &server_universe, 55, 1 },
+ { "limit-addrs-per-ia", "L", &server_universe, 56, 1 },
{ NULL, NULL, NULL, 0, 0 }
};