]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/dhcp/dhcp-sendDecline.patch
Merge remote-tracking branch 'mfischer/newt' into next
[people/pmueller/ipfire-2.x.git] / src / patches / dhcp / dhcp-sendDecline.patch
CommitLineData
c1e9ba67
MF
1diff -up dhcp-4.3.0a1/client/dhc6.c.sendDecline dhcp-4.3.0a1/client/dhc6.c
2--- dhcp-4.3.0a1/client/dhc6.c.sendDecline 2013-12-11 01:25:12.000000000 +0100
3+++ dhcp-4.3.0a1/client/dhc6.c 2013-12-19 15:56:18.297660118 +0100
4@@ -96,6 +96,8 @@ void do_select6(void *input);
78ab9b04
MT
5 void do_refresh6(void *input);
6 static void do_release6(void *input);
7 static void start_bound(struct client_state *client);
8+static void start_decline6(struct client_state *client);
9+static void do_decline6(void *input);
10 static void start_informed(struct client_state *client);
11 void informed_handler(struct packet *packet, struct client_state *client);
12 void bound_handler(struct packet *packet, struct client_state *client);
c1e9ba67 13@@ -2017,6 +2019,7 @@ start_release6(struct client_state *clie
78ab9b04
MT
14 cancel_timeout(do_select6, client);
15 cancel_timeout(do_refresh6, client);
16 cancel_timeout(do_release6, client);
17+ cancel_timeout(do_decline6, client);
18 client->state = S_STOPPED;
19
20 /*
c1e9ba67 21@@ -2650,6 +2653,7 @@ dhc6_check_reply(struct client_state *cl
78ab9b04
MT
22 break;
23
24 case S_STOPPED:
25+ case S_DECLINED:
26 action = dhc6_stop_action;
27 break;
28
c1e9ba67 29@@ -2751,6 +2755,7 @@ dhc6_check_reply(struct client_state *cl
78ab9b04
MT
30 break;
31
32 case S_STOPPED:
33+ case S_DECLINED:
34 /* Nothing critical to do at this stage. */
35 break;
36
c1e9ba67 37@@ -3741,17 +3746,23 @@ reply_handler(struct packet *packet, str
78ab9b04
MT
38 cancel_timeout(do_select6, client);
39 cancel_timeout(do_refresh6, client);
40 cancel_timeout(do_release6, client);
41+ cancel_timeout(do_decline6, client);
42
43 /* If this is in response to a Release/Decline, clean up and return. */
44- if (client->state == S_STOPPED) {
45- if (client->active_lease == NULL)
46- return;
47+ if ((client->state == S_STOPPED) ||
48+ (client->state == S_DECLINED)) {
49+
50+ if (client->active_lease != NULL) {
51+ dhc6_lease_destroy(&client->active_lease, MDL);
52+ client->active_lease = NULL;
53+ /* We should never wait for nothing!? */
54+ if (stopping_finished())
55+ exit(0);
56+ }
57+
58+ if (client->state == S_DECLINED)
59+ start_init6(client);
60
61- dhc6_lease_destroy(&client->active_lease, MDL);
62- client->active_lease = NULL;
63- /* We should never wait for nothing!? */
64- if (stopping_finished())
65- exit(0);
66 return;
67 }
68
c1e9ba67 69@@ -4279,7 +4290,11 @@ start_bound(struct client_state *client)
78ab9b04 70 dhc6_marshall_values("new_", client, lease, ia, addr);
c1e9ba67 71 script_write_requested6(client);
78ab9b04
MT
72
73- script_go(client);
74+ // when script returns 3, DAD failed
75+ if (script_go(client) == 3) {
76+ start_decline6(client);
77+ return;
78+ }
79 }
80
81 /* XXX: maybe we should loop on the old values instead? */
c1e9ba67 82@@ -4327,6 +4342,149 @@ start_bound(struct client_state *client)
78ab9b04
MT
83 dhc6_check_times(client);
84 }
85
86+/*
87+ * Decline addresses.
88+ */
89+void
90+start_decline6(struct client_state *client)
91+{
92+ /* Cancel any pending transmissions */
93+ cancel_timeout(do_confirm6, client);
94+ cancel_timeout(do_select6, client);
95+ cancel_timeout(do_refresh6, client);
96+ cancel_timeout(do_release6, client);
97+ cancel_timeout(do_decline6, client);
98+ client->state = S_DECLINED;
99+
100+ if (client->active_lease == NULL)
101+ return;
102+
103+ /* Set timers per RFC3315 section 18.1.7. */
104+ client->IRT = DEC_TIMEOUT * 100;
105+ client->MRT = 0;
106+ client->MRC = DEC_MAX_RC;
107+ client->MRD = 0;
108+
109+ dhc6_retrans_init(client);
110+ client->v6_handler = reply_handler;
111+
112+ client->refresh_type = DHCPV6_DECLINE;
113+ do_decline6(client);
114+}
115+
116+/*
117+ * do_decline6() creates a Decline packet and transmits it.
118+ */
119+static void
120+do_decline6(void *input)
121+{
122+ struct client_state *client;
123+ struct data_string ds;
124+ int send_ret;
125+ struct timeval elapsed, tv;
126+
127+ client = input;
128+
129+ if ((client->active_lease == NULL) || !active_prefix(client))
130+ return;
131+
132+ if ((client->MRC != 0) && (client->txcount > client->MRC)) {
133+ log_info("Max retransmission count exceeded.");
134+ goto decline_done;
135+ }
136+
137+ /*
138+ * Start_time starts at the first transmission.
139+ */
140+ if (client->txcount == 0) {
141+ client->start_time.tv_sec = cur_tv.tv_sec;
142+ client->start_time.tv_usec = cur_tv.tv_usec;
143+ }
144+
145+ /* elapsed = cur - start */
146+ elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
147+ elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
148+ if (elapsed.tv_usec < 0) {
149+ elapsed.tv_sec -= 1;
150+ elapsed.tv_usec += 1000000;
151+ }
152+
153+ memset(&ds, 0, sizeof(ds));
154+ if (!buffer_allocate(&ds.buffer, 4, MDL)) {
155+ log_error("Unable to allocate memory for Decline.");
156+ goto decline_done;
157+ }
158+
159+ ds.data = ds.buffer->data;
160+ ds.len = 4;
161+ ds.buffer->data[0] = DHCPV6_DECLINE;
162+ memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3);
163+
164+ /* Form an elapsed option. */
165+ /* Maximum value is 65535 1/100s coded as 0xffff. */
166+ if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
167+ ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
168+ client->elapsed = 0xffff;
169+ } else {
170+ client->elapsed = elapsed.tv_sec * 100;
171+ client->elapsed += elapsed.tv_usec / 10000;
172+ }
173+
174+ client->elapsed = htons(client->elapsed);
175+
176+ log_debug("XMT: Forming Decline.");
177+ make_client6_options(client, &client->sent_options,
178+ client->active_lease, DHCPV6_DECLINE);
179+ dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL,
180+ client->sent_options, &global_scope,
181+ &dhcpv6_universe);
182+
183+ /* Append IA's (but don't release temporary addresses). */
184+ if (wanted_ia_na &&
185+ dhc6_add_ia_na(client, &ds, client->active_lease,
186+ DHCPV6_DECLINE) != ISC_R_SUCCESS) {
187+ data_string_forget(&ds, MDL);
188+ goto decline_done;
189+ }
190+ if (wanted_ia_pd &&
191+ dhc6_add_ia_pd(client, &ds, client->active_lease,
192+ DHCPV6_DECLINE) != ISC_R_SUCCESS) {
193+ data_string_forget(&ds, MDL);
194+ goto decline_done;
195+ }
196+
197+ /* Transmit and wait. */
198+ log_info("XMT: Decline on %s, interval %ld0ms.",
199+ client->name ? client->name : client->interface->name,
200+ (long int)client->RT);
201+
202+ send_ret = send_packet6(client->interface, ds.data, ds.len,
203+ &DHCPv6DestAddr);
204+ if (send_ret != ds.len) {
205+ log_error("dhc6: sendpacket6() sent %d of %d bytes",
206+ send_ret, ds.len);
207+ }
208+
209+ data_string_forget(&ds, MDL);
210+
211+ /* Wait RT */
212+ tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
213+ tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
214+ if (tv.tv_usec >= 1000000) {
215+ tv.tv_sec += 1;
216+ tv.tv_usec -= 1000000;
217+ }
218+ add_timeout(&tv, do_decline6, client, NULL, NULL);
219+ dhc6_retrans_advance(client);
220+ return;
221+
222+decline_done:
223+ dhc6_lease_destroy(&client->active_lease, MDL);
224+ client->active_lease = NULL;
225+ start_init6(client);
226+ return;
227+}
228+
229 /* While bound, ignore packets. In the future we'll want to answer
230 * Reconfigure-Request messages and the like.
231 */