mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-25 11:27:31 +00:00
- The server now limits clients that request multiple addresses to one
address per IA by default, which can be adjusted through the "limit-addrs-per-ia" configuration option. [ISC-Bugs #17271]
This commit is contained in:
parent
703873ab37
commit
b024480eba
4
RELNOTES
4
RELNOTES
@ -65,6 +65,10 @@ suggested fixes to <dhcp-users@isc.org>.
|
|||||||
order to avoid cascading renewals in the event a server elects not to
|
order to avoid cascading renewals in the event a server elects not to
|
||||||
extend one of multiple IAADDR leases.
|
extend one of multiple IAADDR leases.
|
||||||
|
|
||||||
|
- The server now limits clients that request multiple addresses to one
|
||||||
|
address per IA by default, which can be adjusted through the
|
||||||
|
"limit-addrs-per-ia" configuration option.
|
||||||
|
|
||||||
Changes since 4.0.0b2
|
Changes since 4.0.0b2
|
||||||
|
|
||||||
- Clarified error message when lease limit exceeded
|
- Clarified error message when lease limit exceeded
|
||||||
|
@ -620,6 +620,7 @@ struct lease_state {
|
|||||||
#define SV_PREFER_LIFETIME 53
|
#define SV_PREFER_LIFETIME 53
|
||||||
#define SV_DHCPV6_LEASE_FILE_NAME 54
|
#define SV_DHCPV6_LEASE_FILE_NAME 54
|
||||||
#define SV_DHCPV6_PID_FILE_NAME 55
|
#define SV_DHCPV6_PID_FILE_NAME 55
|
||||||
|
#define SV_LIMIT_ADDRS_PER_IA 56
|
||||||
|
|
||||||
#if !defined (DEFAULT_PING_TIMEOUT)
|
#if !defined (DEFAULT_PING_TIMEOUT)
|
||||||
# define DEFAULT_PING_TIMEOUT 1
|
# define DEFAULT_PING_TIMEOUT 1
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
.\" see ``http://www.vix.com''. To learn more about Nominum, Inc., see
|
.\" see ``http://www.vix.com''. To learn more about Nominum, Inc., see
|
||||||
.\" ``http://www.nominum.com''.
|
.\" ``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
|
.TH dhcpd.conf 5
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@ -2251,6 +2251,22 @@ environment variable.
|
|||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
The
|
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
|
.I dhcpv6-lease-file-name
|
||||||
statement
|
statement
|
||||||
.RS 0.25i
|
.RS 0.25i
|
||||||
|
@ -49,7 +49,8 @@ struct reply_state {
|
|||||||
|
|
||||||
/* IA level persistent state */
|
/* IA level persistent state */
|
||||||
unsigned ia_count;
|
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 *ia_na;
|
||||||
struct ia_na *old_ia;
|
struct ia_na *old_ia;
|
||||||
struct option_state *reply_ia;
|
struct option_state *reply_ia;
|
||||||
@ -1244,7 +1245,7 @@ reply_process_ia(struct reply_state *reply, struct option_cache *ia) {
|
|||||||
oc = lookup_option(&dhcpv6_universe, packet_ia, D6O_IAADDR);
|
oc = lookup_option(&dhcpv6_universe, packet_ia, D6O_IAADDR);
|
||||||
reply->valid = reply->prefer = 0xffffffff;
|
reply->valid = reply->prefer = 0xffffffff;
|
||||||
reply->client_valid = reply->client_prefer = 0;
|
reply->client_valid = reply->client_prefer = 0;
|
||||||
reply->client_addressed = ISC_FALSE;
|
reply->client_addresses = 0;
|
||||||
for (; oc != NULL ; oc = oc->next) {
|
for (; oc != NULL ; oc = oc->next) {
|
||||||
status = reply_process_addr(reply, oc);
|
status = reply_process_addr(reply, oc);
|
||||||
|
|
||||||
@ -1267,7 +1268,7 @@ reply_process_ia(struct reply_state *reply, struct option_cache *ia) {
|
|||||||
* If we fell through the above and never gave the client
|
* If we fell through the above and never gave the client
|
||||||
* an address, give it one now.
|
* 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);
|
status = find_client_address(reply);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1482,6 +1483,7 @@ reply_process_addr(struct reply_state *reply, struct option_cache *addr) {
|
|||||||
struct group *group;
|
struct group *group;
|
||||||
struct subnet *subnet;
|
struct subnet *subnet;
|
||||||
struct iaddr tmp_addr;
|
struct iaddr tmp_addr;
|
||||||
|
struct option_cache *oc;
|
||||||
struct data_string iaaddr, data;
|
struct data_string iaaddr, data;
|
||||||
isc_result_t status = ISC_R_SUCCESS;
|
isc_result_t status = ISC_R_SUCCESS;
|
||||||
|
|
||||||
@ -1689,6 +1691,47 @@ reply_process_addr(struct reply_state *reply, struct option_cache *addr) {
|
|||||||
group = reply->shared->group;
|
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);
|
status = reply_process_is_addressed(reply, scope, group);
|
||||||
if (status != ISC_R_SUCCESS)
|
if (status != ISC_R_SUCCESS)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -1889,12 +1932,10 @@ reply_process_is_addressed(struct reply_state *reply,
|
|||||||
oc = lookup_option(&server_universe, reply->opt_state,
|
oc = lookup_option(&server_universe, reply->opt_state,
|
||||||
SV_DEFAULT_LEASE_TIME);
|
SV_DEFAULT_LEASE_TIME);
|
||||||
if (oc != NULL) {
|
if (oc != NULL) {
|
||||||
if (!evaluate_option_cache(&data, reply->packet, NULL,
|
if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
|
||||||
NULL,
|
|
||||||
reply->packet->options,
|
reply->packet->options,
|
||||||
reply->opt_state,
|
reply->opt_state,
|
||||||
&reply->lease->scope,
|
scope, oc, MDL) ||
|
||||||
oc, MDL) ||
|
|
||||||
(data.len != 4)) {
|
(data.len != 4)) {
|
||||||
log_error("reply_process_ia: uanble to "
|
log_error("reply_process_ia: uanble to "
|
||||||
"evaluate default lease time");
|
"evaluate default lease time");
|
||||||
@ -1918,12 +1959,10 @@ reply_process_is_addressed(struct reply_state *reply,
|
|||||||
oc = lookup_option(&server_universe, reply->opt_state,
|
oc = lookup_option(&server_universe, reply->opt_state,
|
||||||
SV_PREFER_LIFETIME);
|
SV_PREFER_LIFETIME);
|
||||||
if (oc != NULL) {
|
if (oc != NULL) {
|
||||||
if (!evaluate_option_cache(&data, reply->packet, NULL,
|
if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
|
||||||
NULL,
|
|
||||||
reply->packet->options,
|
reply->packet->options,
|
||||||
reply->opt_state,
|
reply->opt_state,
|
||||||
&reply->lease->scope,
|
scope, oc, MDL) ||
|
||||||
oc, MDL) ||
|
|
||||||
(data.len != 4)) {
|
(data.len != 4)) {
|
||||||
log_error("reply_process_ia: unable to "
|
log_error("reply_process_ia: unable to "
|
||||||
"evaluate preferred lease time");
|
"evaluate preferred lease time");
|
||||||
@ -1989,7 +2028,7 @@ reply_process_is_addressed(struct reply_state *reply,
|
|||||||
data_string_forget(&data, MDL);
|
data_string_forget(&data, MDL);
|
||||||
|
|
||||||
if (status == ISC_R_SUCCESS)
|
if (status == ISC_R_SUCCESS)
|
||||||
reply->client_addressed = ISC_TRUE;
|
reply->client_addresses++;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -237,6 +237,7 @@ static struct option server_options[] = {
|
|||||||
{ "preferred-lifetime", "T", &server_universe, 53, 1 },
|
{ "preferred-lifetime", "T", &server_universe, 53, 1 },
|
||||||
{ "dhcpv6-lease-file-name", "t", &server_universe, 54, 1 },
|
{ "dhcpv6-lease-file-name", "t", &server_universe, 54, 1 },
|
||||||
{ "dhcpv6-pid-file-name", "t", &server_universe, 55, 1 },
|
{ "dhcpv6-pid-file-name", "t", &server_universe, 55, 1 },
|
||||||
|
{ "limit-addrs-per-ia", "L", &server_universe, 56, 1 },
|
||||||
{ NULL, NULL, NULL, 0, 0 }
|
{ NULL, NULL, NULL, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user