xref: /dragonfly/contrib/dhcpcd/src/ipv4ll.c (revision d19ef5a2)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * dhcpcd - DHCP client daemon
4  * Copyright (c) 2006-2020 Roy Marples <roy@marples.name>
5  * All rights reserved
6 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <arpa/inet.h>
30 
31 #include <assert.h>
32 #include <errno.h>
33 #include <stdbool.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <unistd.h>
38 
39 #define ELOOP_QUEUE	IPV4LL
40 #include "config.h"
41 #include "arp.h"
42 #include "common.h"
43 #include "dhcp.h"
44 #include "eloop.h"
45 #include "if.h"
46 #include "if-options.h"
47 #include "ipv4.h"
48 #include "ipv4ll.h"
49 #include "logerr.h"
50 #include "sa.h"
51 #include "script.h"
52 
53 static const struct in_addr inaddr_llmask = {
54 	.s_addr = HTONL(LINKLOCAL_MASK)
55 };
56 static const struct in_addr inaddr_llbcast = {
57 	.s_addr = HTONL(LINKLOCAL_BCAST)
58 };
59 
60 static void
61 ipv4ll_pickaddr(struct interface *ifp)
62 {
63 	struct in_addr addr = { .s_addr = 0 };
64 	struct ipv4ll_state *state;
65 
66 	state = IPV4LL_STATE(ifp);
67 	setstate(state->randomstate);
68 
69 	do {
70 		long r;
71 
72 again:
73 		/* RFC 3927 Section 2.1 states that the first 256 and
74 		 * last 256 addresses are reserved for future use.
75 		 * See ipv4ll_start for why we don't use arc4random. */
76 		/* coverity[dont_call] */
77 		r = random();
78 		addr.s_addr = ntohl(LINKLOCAL_ADDR |
79 		    ((uint32_t)(r % 0xFD00) + 0x0100));
80 
81 		/* No point using a failed address */
82 		if (IN_ARE_ADDR_EQUAL(&addr, &state->pickedaddr))
83 			goto again;
84 		/* Ensure we don't have the address on another interface */
85 	} while (ipv4_findaddr(ifp->ctx, &addr) != NULL);
86 
87 	/* Restore the original random state */
88 	setstate(ifp->ctx->randomstate);
89 	state->pickedaddr = addr;
90 }
91 
92 int
93 ipv4ll_subnetroute(rb_tree_t *routes, struct interface *ifp)
94 {
95 	struct ipv4ll_state *state;
96 	struct rt *rt;
97 	struct in_addr in;
98 
99 	assert(ifp != NULL);
100 	if ((state = IPV4LL_STATE(ifp)) == NULL ||
101 	    state->addr == NULL)
102 		return 0;
103 
104 	if ((rt = rt_new(ifp)) == NULL)
105 		return -1;
106 
107 	in.s_addr = state->addr->addr.s_addr & state->addr->mask.s_addr;
108 	sa_in_init(&rt->rt_dest, &in);
109 	in.s_addr = state->addr->mask.s_addr;
110 	sa_in_init(&rt->rt_netmask, &in);
111 	in.s_addr = INADDR_ANY;
112 	sa_in_init(&rt->rt_gateway, &in);
113 	sa_in_init(&rt->rt_ifa, &state->addr->addr);
114 	return rt_proto_add(routes, rt) ? 1 : 0;
115 }
116 
117 int
118 ipv4ll_defaultroute(rb_tree_t *routes, struct interface *ifp)
119 {
120 	struct ipv4ll_state *state;
121 	struct rt *rt;
122 	struct in_addr in;
123 
124 	assert(ifp != NULL);
125 	if ((state = IPV4LL_STATE(ifp)) == NULL ||
126 	    state->addr == NULL)
127 		return 0;
128 
129 	if ((rt = rt_new(ifp)) == NULL)
130 		return -1;
131 
132 	in.s_addr = INADDR_ANY;
133 	sa_in_init(&rt->rt_dest, &in);
134 	sa_in_init(&rt->rt_netmask, &in);
135 	sa_in_init(&rt->rt_gateway, &in);
136 	sa_in_init(&rt->rt_ifa, &state->addr->addr);
137 	return rt_proto_add(routes, rt) ? 1 : 0;
138 }
139 
140 ssize_t
141 ipv4ll_env(FILE *fp, const char *prefix, const struct interface *ifp)
142 {
143 	const struct ipv4ll_state *state;
144 	const char *pf = prefix == NULL ? "" : "_";
145 	struct in_addr netnum;
146 
147 	assert(ifp != NULL);
148 	if ((state = IPV4LL_CSTATE(ifp)) == NULL || state->addr == NULL)
149 		return 0;
150 
151 	/* Emulate a DHCP environment */
152 	if (efprintf(fp, "%s%sip_address=%s",
153 	    prefix, pf, inet_ntoa(state->addr->addr)) == -1)
154 		return -1;
155 	if (efprintf(fp, "%s%ssubnet_mask=%s",
156 	    prefix, pf, inet_ntoa(state->addr->mask)) == -1)
157 		return -1;
158 	if (efprintf(fp, "%s%ssubnet_cidr=%d",
159 	    prefix, pf, inet_ntocidr(state->addr->mask)) == -1)
160 		return -1;
161 	if (efprintf(fp, "%s%sbroadcast_address=%s",
162 	    prefix, pf, inet_ntoa(state->addr->brd)) == -1)
163 		return -1;
164 	netnum.s_addr = state->addr->addr.s_addr & state->addr->mask.s_addr;
165 	if (efprintf(fp, "%s%snetwork_number=%s",
166 	    prefix, pf, inet_ntoa(netnum)) == -1)
167 		return -1;
168 	return 5;
169 }
170 
171 static void
172 ipv4ll_announced_arp(struct arp_state *astate)
173 {
174 	struct ipv4ll_state *state = IPV4LL_STATE(astate->iface);
175 
176 	state->conflicts = 0;
177 #ifdef KERNEL_RFC5227
178 	arp_free(astate);
179 #endif
180 }
181 
182 #ifndef KERNEL_RFC5227
183 /* This is the callback by ARP freeing */
184 static void
185 ipv4ll_free_arp(struct arp_state *astate)
186 {
187 	struct ipv4ll_state *state;
188 
189 	state = IPV4LL_STATE(astate->iface);
190 	if (state != NULL && state->arp == astate)
191 		state->arp = NULL;
192 }
193 
194 /* This is us freeing any ARP state */
195 static void
196 ipv4ll_freearp(struct interface *ifp)
197 {
198 	struct ipv4ll_state *state;
199 
200 	state = IPV4LL_STATE(ifp);
201 	if (state == NULL || state->arp == NULL)
202 		return;
203 
204 	eloop_timeout_delete(ifp->ctx->eloop, NULL, state->arp);
205 	arp_free(state->arp);
206 	state->arp = NULL;
207 }
208 #else
209 #define	ipv4ll_freearp(ifp)
210 #endif
211 
212 static void
213 ipv4ll_not_found(struct interface *ifp)
214 {
215 	struct ipv4ll_state *state;
216 	struct ipv4_addr *ia;
217 	struct arp_state *astate;
218 
219 	state = IPV4LL_STATE(ifp);
220 	ia = ipv4_iffindaddr(ifp, &state->pickedaddr, &inaddr_llmask);
221 #ifdef IN_IFF_NOTREADY
222 	if (ia == NULL || ia->addr_flags & IN_IFF_NOTREADY)
223 #endif
224 		loginfox("%s: using IPv4LL address %s",
225 		  ifp->name, inet_ntoa(state->pickedaddr));
226 	if (ia == NULL) {
227 		if (ifp->ctx->options & DHCPCD_TEST)
228 			goto test;
229 		ia = ipv4_addaddr(ifp, &state->pickedaddr,
230 		    &inaddr_llmask, &inaddr_llbcast,
231 		    DHCP_INFINITE_LIFETIME, DHCP_INFINITE_LIFETIME);
232 	}
233 	if (ia == NULL)
234 		return;
235 #ifdef IN_IFF_NOTREADY
236 	if (ia->addr_flags & IN_IFF_NOTREADY)
237 		return;
238 	logdebugx("%s: DAD completed for %s", ifp->name, ia->saddr);
239 #endif
240 
241 test:
242 	state->addr = ia;
243 	state->down = false;
244 	if (ifp->ctx->options & DHCPCD_TEST) {
245 		script_runreason(ifp, "TEST");
246 		eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS);
247 		return;
248 	}
249 	rt_build(ifp->ctx, AF_INET);
250 	astate = arp_announceaddr(ifp->ctx, &ia->addr);
251 	if (astate != NULL)
252 		astate->announced_cb = ipv4ll_announced_arp;
253 	script_runreason(ifp, "IPV4LL");
254 	dhcpcd_daemonise(ifp->ctx);
255 }
256 
257 static void
258 ipv4ll_found(struct interface *ifp)
259 {
260 	struct ipv4ll_state *state = IPV4LL_STATE(ifp);
261 
262 	ipv4ll_freearp(ifp);
263 	if (++state->conflicts == MAX_CONFLICTS)
264 		logerrx("%s: failed to acquire an IPv4LL address",
265 		    ifp->name);
266 	ipv4ll_pickaddr(ifp);
267 	eloop_timeout_add_sec(ifp->ctx->eloop,
268 	    state->conflicts >= MAX_CONFLICTS ?
269 	    RATE_LIMIT_INTERVAL : PROBE_WAIT,
270 	    ipv4ll_start, ifp);
271 }
272 
273 static void
274 ipv4ll_defend_failed(struct interface *ifp)
275 {
276 	struct ipv4ll_state *state = IPV4LL_STATE(ifp);
277 
278 	ipv4ll_freearp(ifp);
279 	ipv4_deladdr(state->addr, 1);
280 	state->addr = NULL;
281 	rt_build(ifp->ctx, AF_INET);
282 	script_runreason(ifp, "IPV4LL");
283 	ipv4ll_pickaddr(ifp);
284 	ipv4ll_start(ifp);
285 }
286 
287 #ifndef KERNEL_RFC5227
288 static void
289 ipv4ll_not_found_arp(struct arp_state *astate)
290 {
291 
292 	ipv4ll_not_found(astate->iface);
293 }
294 
295 static void
296 ipv4ll_found_arp(struct arp_state *astate, __unused const struct arp_msg *amsg)
297 {
298 
299 	ipv4ll_found(astate->iface);
300 }
301 
302 static void
303 ipv4ll_defend_failed_arp(struct arp_state *astate)
304 {
305 
306 	ipv4ll_defend_failed(astate->iface);
307 }
308 #endif
309 
310 void
311 ipv4ll_start(void *arg)
312 {
313 	struct interface *ifp = arg;
314 	struct ipv4ll_state *state;
315 	struct ipv4_addr *ia;
316 	bool repick;
317 #ifndef KERNEL_RFC5227
318 	struct arp_state *astate;
319 #endif
320 
321 	if ((state = IPV4LL_STATE(ifp)) == NULL) {
322 		ifp->if_data[IF_DATA_IPV4LL] = calloc(1, sizeof(*state));
323 		if ((state = IPV4LL_STATE(ifp)) == NULL) {
324 			logerr(__func__);
325 			return;
326 		}
327 	}
328 
329 	/* RFC 3927 Section 2.1 states that the random number generator
330 	 * SHOULD be seeded with a value derived from persistent information
331 	 * such as the IEEE 802 MAC address so that it usually picks
332 	 * the same address without persistent storage. */
333 	if (!state->seeded) {
334 		unsigned int seed;
335 		char *orig;
336 
337 		if (sizeof(seed) > ifp->hwlen) {
338 			seed = 0;
339 			memcpy(&seed, ifp->hwaddr, ifp->hwlen);
340 		} else
341 			memcpy(&seed, ifp->hwaddr + ifp->hwlen - sizeof(seed),
342 			    sizeof(seed));
343 		/* coverity[dont_call] */
344 		orig = initstate(seed,
345 		    state->randomstate, sizeof(state->randomstate));
346 
347 		/* Save the original state. */
348 		if (ifp->ctx->randomstate == NULL)
349 			ifp->ctx->randomstate = orig;
350 
351 		/* Set back the original state until we need the seeded one. */
352 		setstate(ifp->ctx->randomstate);
353 		state->seeded = true;
354 	}
355 
356 	/* Find the previosuly used address. */
357 	if (state->pickedaddr.s_addr != INADDR_ANY)
358 		ia = ipv4_iffindaddr(ifp, &state->pickedaddr, NULL);
359 	else
360 		ia = NULL;
361 
362 	/* Find an existing IPv4LL address and ensure we can work with it. */
363 	if (ia == NULL)
364 		ia = ipv4_iffindlladdr(ifp);
365 
366 	repick = false;
367 #ifdef IN_IFF_DUPLICATED
368 	if (ia != NULL && ia->addr_flags & IN_IFF_DUPLICATED) {
369 		state->pickedaddr = ia->addr; /* So it's not picked again. */
370 		repick = true;
371 		ipv4_deladdr(ia, 0);
372 		ia = NULL;
373 	}
374 #endif
375 
376 	state->addr = ia;
377 	state->down = true;
378 	if (ia != NULL) {
379 		state->pickedaddr = ia->addr;
380 #ifdef IN_IFF_TENTATIVE
381 		if (ia->addr_flags & (IN_IFF_TENTATIVE | IN_IFF_DETACHED)) {
382 			loginfox("%s: waiting for DAD to complete on %s",
383 			    ifp->name, inet_ntoa(ia->addr));
384 			return;
385 		}
386 #endif
387 #ifdef IN_IFF_DUPLICATED
388 		loginfox("%s: using IPv4LL address %s", ifp->name, ia->saddr);
389 #endif
390 	} else {
391 		loginfox("%s: probing for an IPv4LL address", ifp->name);
392 		if (repick || state->pickedaddr.s_addr == INADDR_ANY)
393 			ipv4ll_pickaddr(ifp);
394 	}
395 
396 #ifdef KERNEL_RFC5227
397 	ipv4ll_not_found(ifp);
398 #else
399 	ipv4ll_freearp(ifp);
400 	state->arp = astate = arp_new(ifp, &state->pickedaddr);
401 	if (state->arp == NULL)
402 		return;
403 
404 	astate->found_cb = ipv4ll_found_arp;
405 	astate->not_found_cb = ipv4ll_not_found_arp;
406 	astate->announced_cb = ipv4ll_announced_arp;
407 	astate->defend_failed_cb = ipv4ll_defend_failed_arp;
408 	astate->free_cb = ipv4ll_free_arp;
409 	arp_probe(astate);
410 #endif
411 }
412 
413 void
414 ipv4ll_drop(struct interface *ifp)
415 {
416 	struct ipv4ll_state *state;
417 	bool dropped = false;
418 	struct ipv4_state *istate;
419 
420 	assert(ifp != NULL);
421 
422 	ipv4ll_freearp(ifp);
423 
424 	if ((ifp->options->options & DHCPCD_NODROP) == DHCPCD_NODROP)
425 		return;
426 
427 	state = IPV4LL_STATE(ifp);
428 	if (state && state->addr != NULL) {
429 		ipv4_deladdr(state->addr, 1);
430 		state->addr = NULL;
431 		dropped = true;
432 	}
433 
434 	/* Free any other link local addresses that might exist. */
435 	if ((istate = IPV4_STATE(ifp)) != NULL) {
436 		struct ipv4_addr *ia, *ian;
437 
438 		TAILQ_FOREACH_SAFE(ia, &istate->addrs, next, ian) {
439 			if (IN_LINKLOCAL(ntohl(ia->addr.s_addr))) {
440 				ipv4_deladdr(ia, 0);
441 				dropped = true;
442 			}
443 		}
444 	}
445 
446 	if (dropped) {
447 		rt_build(ifp->ctx, AF_INET);
448 		script_runreason(ifp, "IPV4LL");
449 	}
450 }
451 
452 void
453 ipv4ll_reset(struct interface *ifp)
454 {
455 	struct ipv4ll_state *state = IPV4LL_STATE(ifp);
456 
457 	if (state == NULL)
458 		return;
459 	ipv4ll_freearp(ifp);
460 	state->pickedaddr.s_addr = INADDR_ANY;
461 	state->seeded = false;
462 }
463 
464 void
465 ipv4ll_free(struct interface *ifp)
466 {
467 
468 	assert(ifp != NULL);
469 
470 	ipv4ll_freearp(ifp);
471 	free(IPV4LL_STATE(ifp));
472 	ifp->if_data[IF_DATA_IPV4LL] = NULL;
473 }
474 
475 /* This may cause issues in BSD systems, where running as a single dhcpcd
476  * daemon would solve this issue easily. */
477 #ifdef HAVE_ROUTE_METRIC
478 int
479 ipv4ll_recvrt(__unused int cmd, const struct rt *rt)
480 {
481 	struct dhcpcd_ctx *ctx;
482 	struct interface *ifp;
483 
484 	/* Only interested in default route changes. */
485 	if (sa_is_unspecified(&rt->rt_dest))
486 		return 0;
487 
488 	/* If any interface is running IPv4LL, rebuild our routing table. */
489 	ctx = rt->rt_ifp->ctx;
490 	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
491 		if (IPV4LL_STATE_RUNNING(ifp)) {
492 			rt_build(ctx, AF_INET);
493 			break;
494 		}
495 	}
496 
497 	return 0;
498 }
499 #endif
500 
501 struct ipv4_addr *
502 ipv4ll_handleifa(int cmd, struct ipv4_addr *ia, pid_t pid)
503 {
504 	struct interface *ifp;
505 	struct ipv4ll_state *state;
506 
507 	ifp = ia->iface;
508 	state = IPV4LL_STATE(ifp);
509 	if (state == NULL)
510 		return ia;
511 
512 	if (cmd == RTM_DELADDR &&
513 	    state->addr != NULL &&
514 	    IN_ARE_ADDR_EQUAL(&state->addr->addr, &ia->addr))
515 	{
516 		loginfox("%s: pid %d deleted IP address %s",
517 		    ifp->name, pid, ia->saddr);
518 		ipv4ll_defend_failed(ifp);
519 		return ia;
520 	}
521 
522 #ifdef IN_IFF_DUPLICATED
523 	if (cmd != RTM_NEWADDR)
524 		return ia;
525 	if (!IN_ARE_ADDR_EQUAL(&state->pickedaddr, &ia->addr))
526 		return ia;
527 	if (!(ia->addr_flags & IN_IFF_NOTUSEABLE))
528 		ipv4ll_not_found(ifp);
529 	else if (ia->addr_flags & IN_IFF_DUPLICATED) {
530 		logerrx("%s: DAD detected %s", ifp->name, ia->saddr);
531 		ipv4ll_freearp(ifp);
532 		ipv4_deladdr(ia, 1);
533 		state->addr = NULL;
534 		rt_build(ifp->ctx, AF_INET);
535 		ipv4ll_found(ifp);
536 		return NULL;
537 	}
538 #endif
539 
540 	return ia;
541 }
542