853382bddd
- fixed a typo in nis-servers option name breaking the config file introduced in previous change to workaround issues in NetworkManager parser. - Update to dhcp-4.3.5 - Corrected a bug which could cause the server to sporadically crash while loading lease files with the lease-id-format is set to "hex". Our thanks to Jay Ford, University of Iowa for reporting the issue. [ISC-Bugs #43185] - Eliminated a noisy, but otherwise harmless debug log statment that may appear during server startup when building with --enable-binary-leases and configuring multiple pools in a shared network. Thanks to Fernando Soto from BlueCat Networks for reporting the issue and supplying a patch. [ISC-Bugs #43262] - Fixed util/bindvar.sh error handling. [ISC-Bugs #41973] - Correct error message in relay to use remote id length instead of circuit id length. [ISC-Bugs #42556] - Add logic to test directory Makefiles to avoid copying Attfile(s) when building within the source tree. This eliminates a noisy but otherwise harmless error message when running "make check". [ISC-Bugs #41883] - Leases are now scrubbed of certain prior use information when pool re-balancing reassigns them from one FO peer to the other. This corrects an issue where leases that were offered but not used by the client retained the client hostname from the original client. Thanks to Pavel Polacek, Jan Evangelista Purkyne University for reporting the issue. [ISC-Bugs #42008] - In the LDAP code and schema add some missing '6' characters to use the v6 instead of the v4 versions. Thanks to Denis Taranushin for OBS-URL: https://build.opensuse.org/request/show/508601 OBS-URL: https://build.opensuse.org/package/show/network:dhcp/dhcp?expand=0&rev=174
256 lines
7.1 KiB
Diff
256 lines
7.1 KiB
Diff
Author: Jiri Popelka <jpopelka@redhat.com>
|
|
References: bsc#872609, ISC-Bugs#21237
|
|
Upstream: yes
|
|
|
|
If the bound address failed DAD (is found to be in use on the link),
|
|
the dhcpv6 client sends a Decline message to the server as described
|
|
in section 18.1.7 of RFC-3315 (#559147)
|
|
(Submitted to dhcp-bugs@isc.org - [ISC-Bugs #26735])
|
|
|
|
diff --git a/client/dhc6.c b/client/dhc6.c
|
|
index c8d16e8..21d0203 100644
|
|
--- a/client/dhc6.c
|
|
+++ b/client/dhc6.c
|
|
@@ -115,6 +115,8 @@ void do_select6(void *input);
|
|
void do_refresh6(void *input);
|
|
static void do_release6(void *input);
|
|
static void start_bound(struct client_state *client);
|
|
+static void start_decline6(struct client_state *client);
|
|
+static void do_decline6(void *input);
|
|
static void start_informed(struct client_state *client);
|
|
void informed_handler(struct packet *packet, struct client_state *client);
|
|
void bound_handler(struct packet *packet, struct client_state *client);
|
|
@@ -2314,6 +2316,7 @@ start_release6(struct client_state *client)
|
|
cancel_timeout(do_select6, client);
|
|
cancel_timeout(do_refresh6, client);
|
|
cancel_timeout(do_release6, client);
|
|
+ cancel_timeout(do_decline6, client);
|
|
client->state = S_STOPPED;
|
|
|
|
/*
|
|
@@ -2968,6 +2971,7 @@ dhc6_check_reply(struct client_state *client, struct dhc6_lease *new)
|
|
break;
|
|
|
|
case S_STOPPED:
|
|
+ case S_DECLINED:
|
|
action = dhc6_stop_action;
|
|
break;
|
|
|
|
@@ -3084,6 +3088,7 @@ dhc6_check_reply(struct client_state *client, struct dhc6_lease *new)
|
|
break;
|
|
|
|
case S_STOPPED:
|
|
+ case S_DECLINED:
|
|
/* Nothing critical to do at this stage. */
|
|
break;
|
|
|
|
@@ -4214,17 +4219,23 @@ reply_handler(struct packet *packet, struct client_state *client)
|
|
cancel_timeout(do_select6, client);
|
|
cancel_timeout(do_refresh6, client);
|
|
cancel_timeout(do_release6, client);
|
|
+ cancel_timeout(do_decline6, client);
|
|
|
|
/* If this is in response to a Release/Decline, clean up and return. */
|
|
- if (client->state == S_STOPPED) {
|
|
- if (client->active_lease == NULL)
|
|
- return;
|
|
+ if ((client->state == S_STOPPED) ||
|
|
+ (client->state == S_DECLINED)) {
|
|
+
|
|
+ if (client->active_lease != NULL) {
|
|
+ dhc6_lease_destroy(&client->active_lease, MDL);
|
|
+ client->active_lease = NULL;
|
|
+ /* We should never wait for nothing!? */
|
|
+ if (stopping_finished())
|
|
+ exit(0);
|
|
+ }
|
|
+
|
|
+ if (client->state == S_DECLINED)
|
|
+ start_init6(client);
|
|
|
|
- dhc6_lease_destroy(&client->active_lease, MDL);
|
|
- client->active_lease = NULL;
|
|
- /* We should never wait for nothing!? */
|
|
- if (stopping_finished())
|
|
- exit(0);
|
|
return;
|
|
}
|
|
|
|
@@ -4798,7 +4809,11 @@ start_bound(struct client_state *client)
|
|
dhc6_marshall_values("new_", client, lease, ia, addr);
|
|
script_write_requested6(client);
|
|
|
|
- script_go(client);
|
|
+ // when script returns 3, DAD failed
|
|
+ if (script_go(client) == 3) {
|
|
+ start_decline6(client);
|
|
+ return;
|
|
+ }
|
|
}
|
|
|
|
/* XXX: maybe we should loop on the old values instead? */
|
|
@@ -4851,6 +4866,149 @@ start_bound(struct client_state *client)
|
|
dhc6_check_times(client);
|
|
}
|
|
|
|
+/*
|
|
+ * Decline addresses.
|
|
+ */
|
|
+void
|
|
+start_decline6(struct client_state *client)
|
|
+{
|
|
+ /* Cancel any pending transmissions */
|
|
+ cancel_timeout(do_confirm6, client);
|
|
+ cancel_timeout(do_select6, client);
|
|
+ cancel_timeout(do_refresh6, client);
|
|
+ cancel_timeout(do_release6, client);
|
|
+ cancel_timeout(do_decline6, client);
|
|
+ client->state = S_DECLINED;
|
|
+
|
|
+ if (client->active_lease == NULL)
|
|
+ return;
|
|
+
|
|
+ /* Set timers per RFC3315 section 18.1.7. */
|
|
+ client->IRT = DEC_TIMEOUT * 100;
|
|
+ client->MRT = 0;
|
|
+ client->MRC = DEC_MAX_RC;
|
|
+ client->MRD = 0;
|
|
+
|
|
+ dhc6_retrans_init(client);
|
|
+ client->v6_handler = reply_handler;
|
|
+
|
|
+ client->refresh_type = DHCPV6_DECLINE;
|
|
+ do_decline6(client);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * do_decline6() creates a Decline packet and transmits it.
|
|
+ */
|
|
+static void
|
|
+do_decline6(void *input)
|
|
+{
|
|
+ struct client_state *client;
|
|
+ struct data_string ds;
|
|
+ int send_ret, added;
|
|
+ struct timeval elapsed, tv;
|
|
+
|
|
+ client = input;
|
|
+
|
|
+ if ((client->active_lease == NULL) || !active_prefix(client))
|
|
+ return;
|
|
+
|
|
+ if ((client->MRC != 0) && (client->txcount > client->MRC)) {
|
|
+ log_info("Max retransmission count exceeded.");
|
|
+ goto decline_done;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Start_time starts at the first transmission.
|
|
+ */
|
|
+ if (client->txcount == 0) {
|
|
+ client->start_time.tv_sec = cur_tv.tv_sec;
|
|
+ client->start_time.tv_usec = cur_tv.tv_usec;
|
|
+ }
|
|
+
|
|
+ /* elapsed = cur - start */
|
|
+ elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
|
|
+ elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
|
|
+ if (elapsed.tv_usec < 0) {
|
|
+ elapsed.tv_sec -= 1;
|
|
+ elapsed.tv_usec += 1000000;
|
|
+ }
|
|
+
|
|
+ memset(&ds, 0, sizeof(ds));
|
|
+ if (!buffer_allocate(&ds.buffer, 4, MDL)) {
|
|
+ log_error("Unable to allocate memory for Decline.");
|
|
+ goto decline_done;
|
|
+ }
|
|
+
|
|
+ ds.data = ds.buffer->data;
|
|
+ ds.len = 4;
|
|
+ ds.buffer->data[0] = DHCPV6_DECLINE;
|
|
+ memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3);
|
|
+
|
|
+ /* Form an elapsed option. */
|
|
+ /* Maximum value is 65535 1/100s coded as 0xffff. */
|
|
+ if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
|
|
+ ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
|
|
+ client->elapsed = 0xffff;
|
|
+ } else {
|
|
+ client->elapsed = elapsed.tv_sec * 100;
|
|
+ client->elapsed += elapsed.tv_usec / 10000;
|
|
+ }
|
|
+
|
|
+ client->elapsed = htons(client->elapsed);
|
|
+
|
|
+ log_debug("XMT: Forming Decline.");
|
|
+ make_client6_options(client, &client->sent_options,
|
|
+ client->active_lease, DHCPV6_DECLINE);
|
|
+ dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL,
|
|
+ client->sent_options, &global_scope,
|
|
+ &dhcpv6_universe);
|
|
+
|
|
+ /* Append IA's (but don't release temporary addresses). */
|
|
+ if (wanted_ia_na &&
|
|
+ dhc6_add_ia_na(client, &ds, client->active_lease,
|
|
+ DHCPV6_DECLINE, 0, &added) != ISC_R_SUCCESS) {
|
|
+ data_string_forget(&ds, MDL);
|
|
+ goto decline_done;
|
|
+ }
|
|
+ if (wanted_ia_pd &&
|
|
+ dhc6_add_ia_pd(client, &ds, client->active_lease,
|
|
+ DHCPV6_DECLINE, 0, &added) != ISC_R_SUCCESS) {
|
|
+ data_string_forget(&ds, MDL);
|
|
+ goto decline_done;
|
|
+ }
|
|
+
|
|
+ /* Transmit and wait. */
|
|
+ log_info("XMT: Decline on %s, interval %ld0ms.",
|
|
+ client->name ? client->name : client->interface->name,
|
|
+ (long int)client->RT);
|
|
+
|
|
+ send_ret = send_packet6(client->interface, ds.data, ds.len,
|
|
+ &DHCPv6DestAddr);
|
|
+ if (send_ret != ds.len) {
|
|
+ log_error("dhc6: sendpacket6() sent %d of %d bytes",
|
|
+ send_ret, ds.len);
|
|
+ }
|
|
+
|
|
+ data_string_forget(&ds, MDL);
|
|
+
|
|
+ /* Wait RT */
|
|
+ tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
|
|
+ tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
|
|
+ if (tv.tv_usec >= 1000000) {
|
|
+ tv.tv_sec += 1;
|
|
+ tv.tv_usec -= 1000000;
|
|
+ }
|
|
+ add_timeout(&tv, do_decline6, client, NULL, NULL);
|
|
+ dhc6_retrans_advance(client);
|
|
+ return;
|
|
+
|
|
+decline_done:
|
|
+ dhc6_lease_destroy(&client->active_lease, MDL);
|
|
+ client->active_lease = NULL;
|
|
+ start_init6(client);
|
|
+ return;
|
|
+}
|
|
+
|
|
/* While bound, ignore packets. In the future we'll want to answer
|
|
* Reconfigure-Request messages and the like.
|
|
*/
|
|
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
|
|
index b5bec1c..6d500a3 100644
|
|
--- a/includes/dhcpd.h
|
|
+++ b/includes/dhcpd.h
|
|
@@ -1176,7 +1176,8 @@ enum dhcp_state {
|
|
S_BOUND = 5,
|
|
S_RENEWING = 6,
|
|
S_REBINDING = 7,
|
|
- S_STOPPED = 8
|
|
+ S_STOPPED = 8,
|
|
+ S_DECLINED = 9
|
|
};
|
|
|
|
/* Possible pending client operations. */
|