]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blame - src/patches/dhcp-4.2.0-UseMulticast.patch
kernel: update to 3.10.23.
[people/teissler/ipfire-2.x.git] / src / patches / dhcp-4.2.0-UseMulticast.patch
CommitLineData
78ab9b04
MT
1diff -up dhcp-4.2.0/server/dhcpv6.c.UseMulticast dhcp-4.2.0/server/dhcpv6.c
2--- dhcp-4.2.0/server/dhcpv6.c.UseMulticast 2010-06-01 19:30:00.000000000 +0200
3+++ dhcp-4.2.0/server/dhcpv6.c 2010-07-21 16:17:30.000000000 +0200
4@@ -346,6 +346,48 @@ generate_new_server_duid(void) {
5 }
6
7 /*
8+ * Is the D6O_UNICAST option defined in dhcpd.conf ?
9+ */
10+static isc_boolean_t unicast_option_defined;
11+
12+/*
13+ * Did we already search dhcpd.conf for D6O_UNICAST option ?
14+ * We need to store it here to not parse dhcpd.conf repeatedly.
15+ */
16+static isc_boolean_t unicast_option_parsed = ISC_FALSE;
17+
18+
19+/*
20+ * Is the D6O_UNICAST option defined in dhcpd.conf ?
21+ */
22+isc_boolean_t
23+is_unicast_option_defined(void) {
24+ struct option_state *opt_state;
25+ struct option_cache *oc;
26+
27+ /*
28+ * If we are looking for the unicast option for the first time
29+ */
30+ if (unicast_option_parsed == ISC_FALSE) {
31+ unicast_option_parsed = ISC_TRUE;
32+ opt_state = NULL;
33+ if (!option_state_allocate(&opt_state, MDL)) {
34+ log_fatal("No memory for option state.");
35+ }
36+
37+ execute_statements_in_scope(NULL, NULL, NULL, NULL, NULL,
38+ opt_state, &global_scope, root_group, NULL);
39+
40+ oc = lookup_option(&dhcpv6_universe, opt_state, D6O_UNICAST);
41+ unicast_option_defined = (oc != NULL);
42+
43+ option_state_dereference(&opt_state, MDL);
44+ }
45+
46+ return (unicast_option_defined);
47+}
48+
49+/*
50 * Get the client identifier from the packet.
51 */
52 isc_result_t
53@@ -1405,6 +1447,56 @@ lease_to_client(struct data_string *repl
54 reply.shared->group);
55 }
56
57+ /* reject unicast message, unless we set unicast option */
58+ if ((packet->unicast == ISC_TRUE) && !is_unicast_option_defined())
59+ /*
60+ * RFC3315 section 18.2.1 (Request):
61+ *
62+ * When the server receives a Request message via unicast from a client
63+ * to which the server has not sent a unicast option, the server
64+ * discards the Request message and responds with a Reply message
65+ * containing a Status Code option with the value UseMulticast, a Server
66+ * Identifier option containing the server's DUID, the Client Identifier
67+ * option from the client message, and no other options.
68+ *
69+ * Section 18.2.3 (Renew):
70+ *
71+ * When the server receives a Renew message via unicast from a client to
72+ * which the server has not sent a unicast option, the server discards
73+ * the Renew message and responds with a Reply message containing a
74+ * Status Code option with the value UseMulticast, a Server Identifier
75+ * option containing the server's DUID, the Client Identifier option
76+ * from the client message, and no other options.
77+ */
78+ {
79+ /* Set the UseMulticast status code. */
80+ if (!set_status_code(STATUS_UseMulticast,
81+ "Unicast not allowed by server.",
82+ reply.opt_state)) {
83+ log_error("lease_to_client: Unable to set "
84+ "UseMulticast status code.");
85+ goto exit;
86+ }
87+
88+ /* Rewind the cursor to the start. */
89+ reply.cursor = REPLY_OPTIONS_INDEX;
90+
91+ /*
92+ * Produce an reply that includes only:
93+ *
94+ * Status code.
95+ * Server DUID.
96+ * Client DUID.
97+ */
98+ reply.cursor += store_options6((char *)reply.buf.data +
99+ reply.cursor,
100+ sizeof(reply.buf) -
101+ reply.cursor,
102+ reply.opt_state, reply.packet,
103+ required_opts_NAA,
104+ NULL);
105+ } else if (no_resources_avail && (reply.ia_count != 0) &&
106+ (reply.packet->dhcpv6_msg_type == DHCPV6_SOLICIT))
107 /*
108 * RFC3315 section 17.2.2 (Solicit):
109 *
110@@ -1429,8 +1521,6 @@ lease_to_client(struct data_string *repl
111 * the server.
112 * Sends a Renew/Rebind if the IA is not in the Reply message.
113 */
114- if (no_resources_avail && (reply.ia_count != 0) &&
115- (reply.packet->dhcpv6_msg_type == DHCPV6_SOLICIT))
116 {
117 /* Set the NoAddrsAvail status code. */
118 if (!set_status_code(STATUS_NoAddrsAvail,
119@@ -4128,7 +4218,6 @@ dhcpv6_solicit(struct data_string *reply
120 * Very similar to Solicit handling, except the server DUID is required.
121 */
122
123-/* TODO: reject unicast messages, unless we set unicast option */
124 static void
125 dhcpv6_request(struct data_string *reply_ret, struct packet *packet) {
126 struct data_string client_id;
127@@ -4443,7 +4532,6 @@ exit:
128 * except for the error code of when addresses don't match.
129 */
130
131-/* TODO: reject unicast messages, unless we set unicast option */
132 static void
133 dhcpv6_renew(struct data_string *reply, struct packet *packet) {
134 struct data_string client_id;
135@@ -4688,18 +4776,60 @@ iterate_over_ia_na(struct data_string *r
136 goto exit;
137 }
138
139- snprintf(status_msg, sizeof(status_msg), "%s received.", packet_type);
140- if (!set_status_code(STATUS_Success, status_msg, opt_state)) {
141- goto exit;
142- }
143+ /* reject unicast message, unless we set unicast option */
144+ if ((packet->unicast == ISC_TRUE) && !is_unicast_option_defined()) {
145+ /*
146+ * RFC3315 section 18.2.6 (Release):
147+ *
148+ * When the server receives a Release message via unicast from a client
149+ * to which the server has not sent a unicast option, the server
150+ * discards the Release message and responds with a Reply message
151+ * containing a Status Code option with value UseMulticast, a Server
152+ * Identifier option containing the server's DUID, the Client Identifier
153+ * option from the client message, and no other options.
154+ *
155+ * Section 18.2.7 (Decline):
156+ *
157+ * When the server receives a Decline message via unicast from a client
158+ * to which the server has not sent a unicast option, the server
159+ * discards the Decline message and responds with a Reply message
160+ * containing a Status Code option with the value UseMulticast, a Server
161+ * Identifier option containing the server's DUID, the Client Identifier
162+ * option from the client message, and no other options.
163+ */
164+ snprintf(status_msg, sizeof(status_msg),
165+ "%s received unicast.", packet_type);
166+ if (!set_status_code(STATUS_UseMulticast, status_msg, opt_state)) {
167+ goto exit;
168+ }
169
170- /*
171- * Add our options that are not associated with any IA_NA or IA_TA.
172- */
173- reply_ofs += store_options6(reply_data+reply_ofs,
174- sizeof(reply_data)-reply_ofs,
175+ /*
176+ * Produce an reply that includes only:
177+ *
178+ * Status code.
179+ * Server DUID.
180+ * Client DUID.
181+ */
182+ reply_ofs += store_options6(reply_data+reply_ofs,
183+ sizeof(reply_data)-reply_ofs,
184 opt_state, packet,
185- required_opts, NULL);
186+ required_opts_NAA, NULL);
187+
188+ goto return_reply;
189+ } else {
190+ snprintf(status_msg, sizeof(status_msg), "%s received.", packet_type);
191+ if (!set_status_code(STATUS_Success, status_msg, opt_state)) {
192+ goto exit;
193+ }
194+
195+ /*
196+ * Add our options that are not associated with any IA_NA or IA_TA.
197+ */
198+ reply_ofs += store_options6(reply_data+reply_ofs,
199+ sizeof(reply_data)-reply_ofs,
200+ opt_state, packet,
201+ required_opts, NULL);
202+ }
203
204 /*
205 * Loop through the IA_NA reported by the client, and deal with
206@@ -4838,6 +4968,7 @@ iterate_over_ia_na(struct data_string *r
207 /*
208 * Return our reply to the caller.
209 */
210+return_reply:
211 reply_ret->len = reply_ofs;
212 reply_ret->buffer = NULL;
213 if (!buffer_allocate(&reply_ret->buffer, reply_ofs, MDL)) {
214@@ -4883,7 +5014,6 @@ exit:
215 * we still need to be aware of this possibility.
216 */
217
218-/* TODO: reject unicast messages, unless we set unicast option */
219 /* TODO: IA_TA */
220 static void
221 dhcpv6_decline(struct data_string *reply, struct packet *packet) {
222@@ -5355,7 +5485,6 @@ exit:
223 * Release means a client is done with the leases.
224 */
225
226-/* TODO: reject unicast messages, unless we set unicast option */
227 static void
228 dhcpv6_release(struct data_string *reply, struct packet *packet) {
229 struct data_string client_id;