]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-dhcp4.c
network: split out common part of route or address handlers
[thirdparty/systemd.git] / src / network / networkd-dhcp4.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <netinet/in.h>
4 #include <netinet/ip.h>
5 #include <linux/if.h>
6 #include <linux/if_arp.h>
7
8 #include "escape.h"
9 #include "alloc-util.h"
10 #include "dhcp-client-internal.h"
11 #include "hostname-setup.h"
12 #include "hostname-util.h"
13 #include "parse-util.h"
14 #include "network-internal.h"
15 #include "networkd-address.h"
16 #include "networkd-dhcp4.h"
17 #include "networkd-link.h"
18 #include "networkd-manager.h"
19 #include "networkd-network.h"
20 #include "networkd-state-file.h"
21 #include "string-table.h"
22 #include "strv.h"
23 #include "sysctl-util.h"
24 #include "web-util.h"
25
26 static int dhcp4_update_address(Link *link, bool announce);
27 static int dhcp4_remove_all(Link *link);
28
29 void network_adjust_dhcp4(Network *network) {
30 assert(network);
31
32 if (!FLAGS_SET(network->dhcp, ADDRESS_FAMILY_IPV4))
33 return;
34
35 if (network->dhcp_use_gateway < 0)
36 network->dhcp_use_gateway = network->dhcp_use_routes;
37
38 /* RFC7844 section 3.: MAY contain the Client Identifier option
39 * Section 3.5: clients MUST use client identifiers based solely on the link-layer address
40 * NOTE: Using MAC, as it does not reveal extra information, and some servers might not answer
41 * if this option is not sent */
42 if (network->dhcp_anonymize &&
43 network->dhcp_client_identifier >= 0 &&
44 network->dhcp_client_identifier != DHCP_CLIENT_ID_MAC) {
45 log_warning("%s: ClientIdentifier= is set, although Anonymize=yes. Using ClientIdentifier=mac.",
46 network->filename);
47 network->dhcp_client_identifier = DHCP_CLIENT_ID_MAC;
48 }
49
50 if (network->dhcp_client_identifier < 0)
51 network->dhcp_client_identifier = network->dhcp_anonymize ? DHCP_CLIENT_ID_MAC : DHCP_CLIENT_ID_DUID;
52 }
53
54 static int dhcp4_release_old_lease(Link *link) {
55 Route *route;
56 int k, r = 0;
57
58 assert(link);
59
60 if (!link->dhcp_address_old && set_isempty(link->dhcp_routes_old))
61 return 0;
62
63 log_link_debug(link, "Removing old DHCPv4 address and routes.");
64
65 SET_FOREACH(route, link->dhcp_routes_old) {
66 k = route_remove(route, NULL, link, NULL);
67 if (k < 0)
68 r = k;
69 }
70
71 if (link->dhcp_address_old) {
72 k = address_remove(link->dhcp_address_old, link, NULL);
73 if (k < 0)
74 r = k;
75 }
76
77 return r;
78 }
79
80 static void dhcp4_check_ready(Link *link) {
81 int r;
82
83 if (link->network->dhcp_send_decline && !link->dhcp4_address_bind)
84 return;
85
86 if (link->dhcp4_messages > 0)
87 return;
88
89 link->dhcp4_configured = true;
90
91 /* New address and routes are configured now. Let's release old lease. */
92 r = dhcp4_release_old_lease(link);
93 if (r < 0) {
94 link_enter_failed(link);
95 return;
96 }
97
98 r = sd_ipv4ll_stop(link->ipv4ll);
99 if (r < 0)
100 log_link_warning_errno(link, r, "Failed to drop IPv4 link-local address, ignoring: %m");
101
102 link_check_ready(link);
103 }
104
105 static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
106 int r;
107
108 assert(link);
109 assert(link->dhcp4_messages > 0);
110
111 link->dhcp4_messages--;
112
113 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
114 return 1;
115
116 r = sd_netlink_message_get_errno(m);
117 if (r == -ENETUNREACH && !link->dhcp4_route_retrying) {
118
119 /* It seems kernel does not support that the prefix route cannot be configured with
120 * route table. Let's once drop the config and reconfigure them later. */
121
122 log_link_message_debug_errno(link, m, r, "Could not set DHCPv4 route, retrying later");
123 link->dhcp4_route_failed = true;
124 link->manager->dhcp4_prefix_root_cannot_set_table = true;
125 } else if (r < 0 && r != -EEXIST) {
126 log_link_message_warning_errno(link, m, r, "Could not set DHCPv4 route");
127 link_enter_failed(link);
128 return 1;
129 }
130
131 if (link->dhcp4_messages == 0 && link->dhcp4_route_failed) {
132 link->dhcp4_route_failed = false;
133 link->dhcp4_route_retrying = true;
134
135 r = dhcp4_remove_all(link);
136 if (r < 0)
137 link_enter_failed(link);
138 return 1;
139 }
140
141 dhcp4_check_ready(link);
142
143 return 1;
144 }
145
146 static int dhcp_route_configure(Route *route, Link *link) {
147 Route *ret;
148 int r;
149
150 assert(route);
151 assert(link);
152
153 r = route_configure(route, link, dhcp4_route_handler, &ret);
154 if (r < 0)
155 return log_link_error_errno(link, r, "Failed to set DHCPv4 route: %m");
156
157 link->dhcp4_messages++;
158
159 r = set_ensure_put(&link->dhcp_routes, &route_hash_ops, ret);
160 if (r < 0)
161 return log_link_error_errno(link, r, "Failed to store DHCPv4 route: %m");
162
163 (void) set_remove(link->dhcp_routes_old, ret);
164
165 return 0;
166 }
167
168 static bool link_prefixroute(Link *link) {
169 return !link->network->dhcp_route_table_set ||
170 link->network->dhcp_route_table == RT_TABLE_MAIN ||
171 link->manager->dhcp4_prefix_root_cannot_set_table;
172 }
173
174 static int link_set_dhcp_prefix_route(Link *link) {
175 _cleanup_(route_freep) Route *route = NULL;
176 struct in_addr address, netmask;
177 int r;
178
179 assert(link);
180 assert(link->dhcp_lease);
181
182 if (link_prefixroute(link))
183 /* When true, the route will be created by kernel. See dhcp4_update_address(). */
184 return 0;
185
186 r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
187 if (r < 0)
188 return r;
189
190 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
191 if (r < 0)
192 return r;
193
194 r = route_new(&route);
195 if (r < 0)
196 return r;
197
198 route->family = AF_INET;
199 route->dst.in.s_addr = address.s_addr & netmask.s_addr;
200 route->dst_prefixlen = in4_addr_netmask_to_prefixlen(&netmask);
201 route->prefsrc.in = address;
202 route->scope = RT_SCOPE_LINK;
203 route->protocol = RTPROT_DHCP;
204 route->table = link_get_dhcp_route_table(link);
205 route->mtu = link->network->dhcp_route_mtu;
206
207 return dhcp_route_configure(route, link);
208 }
209
210 static int link_set_dhcp_route_to_gateway(Link *link, const struct in_addr *gw) {
211 _cleanup_(route_freep) Route *route = NULL;
212 struct in_addr address;
213 int r;
214
215 assert(link);
216 assert(link->dhcp_lease);
217 assert(gw);
218
219 r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
220 if (r < 0)
221 return r;
222
223 r = route_new(&route);
224 if (r < 0)
225 return r;
226
227 route->family = AF_INET;
228 route->dst.in = *gw;
229 route->dst_prefixlen = 32;
230 route->prefsrc.in = address;
231 route->scope = RT_SCOPE_LINK;
232 route->protocol = RTPROT_DHCP;
233 route->priority = link->network->dhcp_route_metric;
234 route->table = link_get_dhcp_route_table(link);
235 route->mtu = link->network->dhcp_route_mtu;
236
237 return dhcp_route_configure(route, link);
238 }
239
240 static int dhcp_route_configure_auto(
241 Route *route,
242 Link *link,
243 const struct in_addr *gw) {
244
245 struct in_addr address, netmask, prefix;
246 uint8_t prefixlen;
247 int r;
248
249 assert(route);
250 assert(link);
251 assert(link->dhcp_lease);
252 assert(gw);
253
254 /* The route object may be reused in an iteration. All elements must be set or cleared. */
255
256 r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
257 if (r < 0)
258 return r;
259
260 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
261 if (r < 0)
262 return r;
263
264 prefix.s_addr = address.s_addr & netmask.s_addr;
265 prefixlen = in4_addr_netmask_to_prefixlen(&netmask);
266
267 if (in4_addr_is_localhost(&route->dst.in)) {
268 if (in4_addr_is_set(gw))
269 log_link_debug(link, "DHCP: requested route destination "IPV4_ADDRESS_FMT_STR"/%u is localhost, "
270 "ignoring gateway address "IPV4_ADDRESS_FMT_STR,
271 IPV4_ADDRESS_FMT_VAL(route->dst.in), route->dst_prefixlen, IPV4_ADDRESS_FMT_VAL(*gw));
272
273 route->scope = RT_SCOPE_HOST;
274 route->gw_family = AF_UNSPEC;
275 route->gw = IN_ADDR_NULL;
276 route->prefsrc = IN_ADDR_NULL;
277
278 } else if (in4_addr_equal(&route->dst.in, &address)) {
279 if (in4_addr_is_set(gw))
280 log_link_debug(link, "DHCP: requested route destination "IPV4_ADDRESS_FMT_STR"/%u is equivalent to the acquired address, "
281 "ignoring gateway address "IPV4_ADDRESS_FMT_STR,
282 IPV4_ADDRESS_FMT_VAL(route->dst.in), route->dst_prefixlen, IPV4_ADDRESS_FMT_VAL(*gw));
283
284 route->scope = RT_SCOPE_HOST;
285 route->gw_family = AF_UNSPEC;
286 route->gw = IN_ADDR_NULL;
287 route->prefsrc.in = address;
288
289 } else if (route->dst_prefixlen >= prefixlen &&
290 (route->dst.in.s_addr & netmask.s_addr) == prefix.s_addr) {
291 if (in4_addr_is_set(gw))
292 log_link_debug(link, "DHCP: requested route destination "IPV4_ADDRESS_FMT_STR"/%u is in the assigned network "
293 IPV4_ADDRESS_FMT_STR"/%u, ignoring gateway address "IPV4_ADDRESS_FMT_STR,
294 IPV4_ADDRESS_FMT_VAL(route->dst.in), route->dst_prefixlen,
295 IPV4_ADDRESS_FMT_VAL(prefix), prefixlen,
296 IPV4_ADDRESS_FMT_VAL(*gw));
297
298 route->scope = RT_SCOPE_LINK;
299 route->gw_family = AF_UNSPEC;
300 route->gw = IN_ADDR_NULL;
301 route->prefsrc.in = address;
302
303 } else {
304 if (in4_addr_is_null(gw)) {
305 log_link_debug(link, "DHCP: requested route destination "IPV4_ADDRESS_FMT_STR"/%u is not in the assigned network "
306 IPV4_ADDRESS_FMT_STR"/%u, but no gateway is specified, ignoring.",
307 IPV4_ADDRESS_FMT_VAL(route->dst.in), route->dst_prefixlen,
308 IPV4_ADDRESS_FMT_VAL(prefix), prefixlen);
309 return 0;
310 }
311
312 r = link_set_dhcp_route_to_gateway(link, gw);
313 if (r < 0)
314 return r;
315
316 route->scope = RT_SCOPE_UNIVERSE;
317 route->gw_family = AF_INET;
318 route->gw.in = *gw;
319 route->prefsrc.in = address;
320 }
321
322 return dhcp_route_configure(route, link);
323 }
324
325 static int link_set_dhcp_static_routes(Link *link, struct in_addr *ret_default_gw) {
326 _cleanup_free_ sd_dhcp_route **static_routes = NULL;
327 bool classless_route = false, static_route = false;
328 _cleanup_(route_freep) Route *route = NULL;
329 struct in_addr default_gw = {};
330 int n, r;
331
332 assert(link);
333 assert(link->dhcp_lease);
334 assert(ret_default_gw);
335
336 if (!link->network->dhcp_use_routes)
337 return 0;
338
339 n = sd_dhcp_lease_get_routes(link->dhcp_lease, &static_routes);
340 if (IN_SET(n, 0, -ENODATA)) {
341 log_link_debug(link, "DHCP: No static routes received from DHCP server.");
342 return 0;
343 }
344 if (n < 0)
345 return n;
346
347 for (int i = 0; i < n; i++) {
348 switch (sd_dhcp_route_get_option(static_routes[i])) {
349 case SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE:
350 classless_route = true;
351 break;
352 case SD_DHCP_OPTION_STATIC_ROUTE:
353 static_route = true;
354 break;
355 }
356 }
357
358 /* if the DHCP server returns both a Classless Static Routes option and a Static Routes option,
359 * the DHCP client MUST ignore the Static Routes option. */
360 if (classless_route && static_route)
361 log_link_debug(link, "Classless static routes received from DHCP server: ignoring static-route option");
362
363 r = route_new(&route);
364 if (r < 0)
365 return r;
366
367 route->family = AF_INET;
368 route->gw_family = AF_INET;
369 route->protocol = RTPROT_DHCP;
370 route->priority = link->network->dhcp_route_metric;
371 route->table = link_get_dhcp_route_table(link);
372 route->mtu = link->network->dhcp_route_mtu;
373
374 for (int i = 0; i < n; i++) {
375 struct in_addr gw;
376
377 if (sd_dhcp_route_get_option(static_routes[i]) !=
378 (classless_route ? SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE : SD_DHCP_OPTION_STATIC_ROUTE))
379 continue;
380
381 r = sd_dhcp_route_get_gateway(static_routes[i], &gw);
382 if (r < 0)
383 return r;
384
385 r = sd_dhcp_route_get_destination(static_routes[i], &route->dst.in);
386 if (r < 0)
387 return r;
388
389 r = sd_dhcp_route_get_destination_prefix_length(static_routes[i], &route->dst_prefixlen);
390 if (r < 0)
391 return r;
392
393 /* When classless static routes are provided, then router option will be ignored. To
394 * use the default gateway later in other routes, e.g., routes to dns servers, here we
395 * need to find the default gateway in the classless static routes. */
396 if (classless_route &&
397 in4_addr_is_null(&route->dst.in) && route->dst_prefixlen == 0 &&
398 in4_addr_is_null(&default_gw))
399 default_gw = gw;
400
401 r = dhcp_route_configure_auto(route, link, &gw);
402 if (r < 0)
403 return r;
404 }
405
406 *ret_default_gw = default_gw;
407 return classless_route;
408 }
409
410 static int link_set_dhcp_gateway(Link *link, struct in_addr *ret_gw) {
411 _cleanup_(route_freep) Route *route = NULL;
412 const struct in_addr *router;
413 struct in_addr address;
414 Route *rt;
415 int r;
416
417 assert(link);
418 assert(link->dhcp_lease);
419 assert(ret_gw);
420
421 if (!link->network->dhcp_use_gateway)
422 return 0;
423
424 r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
425 if (r < 0)
426 return r;
427
428 r = sd_dhcp_lease_get_router(link->dhcp_lease, &router);
429 if (IN_SET(r, 0, -ENODATA)) {
430 log_link_debug(link, "DHCP: No gateway received from DHCP server.");
431 return 0;
432 }
433 if (r < 0)
434 return r;
435 if (in4_addr_is_null(&router[0])) {
436 log_link_debug(link, "DHCP: Received gateway address is null.");
437 return 0;
438 }
439
440 /* The dhcp netmask may mask out the gateway. First, add an explicit route for the gateway host
441 * so that we can route no matter the netmask or existing kernel route tables. */
442 r = link_set_dhcp_route_to_gateway(link, &router[0]);
443 if (r < 0)
444 return r;
445
446 r = route_new(&route);
447 if (r < 0)
448 return r;
449
450 /* Next, add a default gateway. */
451 route->family = AF_INET;
452 route->gw_family = AF_INET;
453 route->gw.in = router[0];
454 route->prefsrc.in = address;
455 route->protocol = RTPROT_DHCP;
456 route->priority = link->network->dhcp_route_metric;
457 route->table = link_get_dhcp_route_table(link);
458 route->mtu = link->network->dhcp_route_mtu;
459
460 r = dhcp_route_configure(route, link);
461 if (r < 0)
462 return r;
463
464 HASHMAP_FOREACH(rt, link->network->routes_by_section) {
465 if (!rt->gateway_from_dhcp_or_ra)
466 continue;
467
468 if (rt->gw_family != AF_INET)
469 continue;
470
471 rt->gw.in = router[0];
472 if (!rt->protocol_set)
473 rt->protocol = RTPROT_DHCP;
474 if (!rt->priority_set)
475 rt->priority = link->network->dhcp_route_metric;
476 if (!rt->table_set)
477 rt->table = link_get_dhcp_route_table(link);
478 if (rt->mtu == 0)
479 rt->mtu = link->network->dhcp_route_mtu;
480
481 r = dhcp_route_configure(rt, link);
482 if (r < 0)
483 return r;
484 }
485
486 *ret_gw = router[0];
487 return 0;
488 }
489
490 static int link_set_routes_to_servers(
491 Link *link,
492 const struct in_addr *servers,
493 size_t n_servers,
494 const struct in_addr *gw) {
495
496 _cleanup_(route_freep) Route *route = NULL;
497 int r;
498
499 assert(link);
500 assert(link->dhcp_lease);
501 assert(link->network);
502 assert(servers || n_servers == 0);
503 assert(gw);
504
505 r = route_new(&route);
506 if (r < 0)
507 return r;
508
509 route->family = AF_INET;
510 route->dst_prefixlen = 32;
511 route->protocol = RTPROT_DHCP;
512 route->priority = link->network->dhcp_route_metric;
513 route->table = link_get_dhcp_route_table(link);
514 route->mtu = link->network->dhcp_route_mtu;
515
516 for (size_t i = 0; i < n_servers; i++) {
517 if (in4_addr_is_null(&servers[i]))
518 continue;
519
520 route->dst.in = servers[i];
521
522 r = dhcp_route_configure_auto(route, link, gw);
523 if (r < 0)
524 return r;
525 }
526
527 return 0;
528 }
529
530 static int link_set_routes_to_dns(Link *link, const struct in_addr *gw) {
531 const struct in_addr *dns;
532 int r;
533
534 assert(link);
535 assert(link->dhcp_lease);
536 assert(link->network);
537 assert(gw);
538
539 if (!link->network->dhcp_use_dns ||
540 !link->network->dhcp_routes_to_dns)
541 return 0;
542
543 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &dns);
544 if (IN_SET(r, 0, -ENODATA))
545 return 0;
546 if (r < 0)
547 return r;
548
549 return link_set_routes_to_servers(link, dns, r, gw);
550 }
551
552 static int link_set_routes_to_ntp(Link *link, const struct in_addr *gw) {
553 const struct in_addr *ntp;
554 int r;
555
556 assert(link);
557 assert(link->dhcp_lease);
558 assert(link->network);
559 assert(gw);
560
561 if (!link->network->dhcp_use_ntp ||
562 !link->network->dhcp_routes_to_ntp)
563 return 0;
564
565 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &ntp);
566 if (IN_SET(r, 0, -ENODATA))
567 return 0;
568 if (r < 0)
569 return r;
570
571 return link_set_routes_to_servers(link, ntp, r, gw);
572 }
573
574 static int link_set_dhcp_routes(Link *link) {
575 struct in_addr gw = {};
576 Route *rt;
577 int r;
578
579 assert(link);
580
581 if (!link->dhcp_lease) /* link went down while we configured the IP addresses? */
582 return 0;
583
584 if (!link->network) /* link went down while we configured the IP addresses? */
585 return 0;
586
587 if (!link_has_carrier(link) && !link->network->configure_without_carrier)
588 /* During configuring addresses, the link lost its carrier. As networkd is dropping
589 * the addresses now, let's not configure the routes either. */
590 return 0;
591
592 while ((rt = set_steal_first(link->dhcp_routes))) {
593 r = set_ensure_put(&link->dhcp_routes_old, &route_hash_ops, rt);
594 if (r < 0)
595 return log_link_error_errno(link, r, "Failed to store old DHCPv4 route: %m");
596 }
597
598 r = link_set_dhcp_prefix_route(link);
599 if (r < 0)
600 return log_link_error_errno(link, r, "DHCP error: Could not set prefix route: %m");
601
602 r = link_set_dhcp_static_routes(link, &gw);
603 if (r < 0)
604 return log_link_error_errno(link, r, "DHCP error: Could not set static routes: %m");
605 if (r == 0) {
606 /* According to RFC 3442: If the DHCP server returns both a Classless Static Routes option and
607 * a Router option, the DHCP client MUST ignore the Router option. */
608 r = link_set_dhcp_gateway(link, &gw);
609 if (r < 0)
610 return log_link_error_errno(link, r, "DHCP error: Could not set gateway: %m");
611 }
612
613 r = link_set_routes_to_dns(link, &gw);
614 if (r < 0)
615 return log_link_error_errno(link, r, "DHCP error: Could not set routes to DNS servers: %m");
616
617 r = link_set_routes_to_ntp(link, &gw);
618 if (r < 0)
619 return log_link_error_errno(link, r, "DHCP error: Could not set routes to NTP servers: %m");
620
621 return 0;
622 }
623
624 static int dhcp_reset_mtu(Link *link) {
625 uint16_t mtu;
626 int r;
627
628 assert(link);
629
630 if (!link->network->dhcp_use_mtu)
631 return 0;
632
633 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
634 if (r == -ENODATA)
635 return 0;
636 if (r < 0)
637 return log_link_error_errno(link, r, "DHCP error: failed to get MTU from lease: %m");
638
639 if (link->original_mtu == mtu)
640 return 0;
641
642 r = link_set_mtu(link, link->original_mtu);
643 if (r < 0)
644 return log_link_error_errno(link, r, "DHCP error: could not reset MTU: %m");
645
646 return 0;
647 }
648
649 static int dhcp_reset_hostname(Link *link) {
650 const char *hostname;
651 int r;
652
653 assert(link);
654
655 if (!link->network->dhcp_use_hostname)
656 return 0;
657
658 hostname = link->network->dhcp_hostname;
659 if (!hostname)
660 (void) sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
661
662 if (!hostname)
663 return 0;
664
665 /* If a hostname was set due to the lease, then unset it now. */
666 r = manager_set_hostname(link->manager, NULL);
667 if (r < 0)
668 return log_link_error_errno(link, r, "DHCP error: Failed to reset transient hostname: %m");
669
670 return 0;
671 }
672
673 static int dhcp4_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
674 int r;
675
676 assert(link);
677 assert(link->dhcp4_remove_messages > 0);
678
679 link->dhcp4_remove_messages--;
680
681 r = link_route_remove_handler_internal(rtnl, m, link, "Failed to remove DHCPv4 route, ignoring");
682 if (r <= 0)
683 return r;
684
685 if (link->dhcp4_remove_messages == 0) {
686 r = dhcp4_update_address(link, false);
687 if (r < 0)
688 link_enter_failed(link);
689 }
690
691 return 1;
692 }
693
694 static int dhcp4_address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
695 int r;
696
697 assert(link);
698 assert(link->dhcp4_remove_messages > 0);
699
700 link->dhcp4_remove_messages--;
701
702 r = address_remove_handler_internal(rtnl, m, link, "Failed to remove DHCPv4 address, ignoring");
703 if (r <= 0)
704 return r;
705
706 if (link->dhcp4_remove_messages == 0) {
707 r = dhcp4_update_address(link, false);
708 if (r < 0)
709 link_enter_failed(link);
710 }
711
712 return 1;
713 }
714
715 static int dhcp4_remove_all(Link *link) {
716 Route *route;
717 int k, r = 0;
718
719 assert(link);
720
721 SET_FOREACH(route, link->dhcp_routes) {
722 k = route_remove(route, NULL, link, dhcp4_route_remove_handler);
723 if (k < 0)
724 r = k;
725 else
726 link->dhcp4_remove_messages++;
727 }
728
729 if (link->dhcp_address) {
730 k = address_remove(link->dhcp_address, link, dhcp4_address_remove_handler);
731 if (k < 0)
732 r = k;
733 else
734 link->dhcp4_remove_messages++;
735 }
736
737 return r;
738 }
739
740 static int dhcp_lease_lost(Link *link) {
741 int k, r = 0;
742
743 assert(link);
744 assert(link->dhcp_lease);
745
746 log_link_info(link, "DHCP lease lost");
747
748 link->dhcp4_configured = false;
749
750 /* dhcp_lease_lost() may be called during renewing IP address. */
751 k = dhcp4_release_old_lease(link);
752 if (k < 0)
753 r = k;
754
755 k = dhcp4_remove_all(link);
756 if (k < 0)
757 r = k;
758
759 k = dhcp_reset_mtu(link);
760 if (k < 0)
761 r = k;
762
763 k = dhcp_reset_hostname(link);
764 if (k < 0)
765 r = k;
766
767 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
768 link_dirty(link);
769
770 (void) sd_ipv4acd_stop(link->dhcp_acd);
771
772 return r;
773 }
774
775 static void dhcp_address_on_acd(sd_ipv4acd *acd, int event, void *userdata) {
776 struct in_addr address;
777 Link *link;
778 int r;
779
780 assert(acd);
781 assert(userdata);
782
783 link = userdata;
784
785 switch (event) {
786 case SD_IPV4ACD_EVENT_STOP:
787 log_link_debug(link, "Stopping ACD client for DHCPv4 address.");
788 return;
789
790 case SD_IPV4ACD_EVENT_BIND:
791 if (DEBUG_LOGGING) {
792 (void) sd_dhcp_lease_get_address(link->dhcp_lease, &address);
793 log_link_debug(link, "Successfully claimed DHCPv4 address "IPV4_ADDRESS_FMT_STR, IPV4_ADDRESS_FMT_VAL(address));
794 }
795 link->dhcp4_address_bind = true;
796 dhcp4_check_ready(link);
797 break;
798
799 case SD_IPV4ACD_EVENT_CONFLICT:
800 (void) sd_dhcp_lease_get_address(link->dhcp_lease, &address);
801 log_link_warning(link, "DAD conflict. Dropping DHCPv4 address "IPV4_ADDRESS_FMT_STR, IPV4_ADDRESS_FMT_VAL(address));
802
803 r = sd_dhcp_client_send_decline(link->dhcp_client);
804 if (r < 0)
805 log_link_warning_errno(link, r, "Failed to send DHCP DECLINE, ignoring: %m");
806
807 if (link->dhcp_lease) {
808 r = dhcp_lease_lost(link);
809 if (r < 0)
810 link_enter_failed(link);
811 }
812 break;
813
814 default:
815 assert_not_reached("Invalid IPv4ACD event.");
816 }
817
818 (void) sd_ipv4acd_stop(acd);
819
820 return;
821 }
822
823 static int dhcp4_configure_dad(Link *link) {
824 int r;
825
826 assert(link);
827 assert(link->manager);
828 assert(link->network);
829
830 if (!link->network->dhcp_send_decline)
831 return 0;
832
833 if (!link->dhcp_acd) {
834 r = sd_ipv4acd_new(&link->dhcp_acd);
835 if (r < 0)
836 return r;
837
838 r = sd_ipv4acd_attach_event(link->dhcp_acd, link->manager->event, 0);
839 if (r < 0)
840 return r;
841 }
842
843 r = sd_ipv4acd_set_ifindex(link->dhcp_acd, link->ifindex);
844 if (r < 0)
845 return r;
846
847 r = sd_ipv4acd_set_mac(link->dhcp_acd, &link->hw_addr.addr.ether);
848 if (r < 0)
849 return r;
850
851 return 0;
852 }
853
854 static int dhcp4_dad_update_mac(Link *link) {
855 bool running;
856 int r;
857
858 assert(link);
859
860 if (!link->dhcp_acd)
861 return 0;
862
863 running = sd_ipv4acd_is_running(link->dhcp_acd);
864
865 r = sd_ipv4acd_stop(link->dhcp_acd);
866 if (r < 0)
867 return r;
868
869 r = sd_ipv4acd_set_mac(link->dhcp_acd, &link->hw_addr.addr.ether);
870 if (r < 0)
871 return r;
872
873 if (running) {
874 r = sd_ipv4acd_start(link->dhcp_acd, true);
875 if (r < 0)
876 return r;
877 }
878
879 return 0;
880 }
881
882 static int dhcp4_start_acd(Link *link) {
883 struct in_addr addr, old;
884 int r;
885
886 if (!link->network->dhcp_send_decline)
887 return 0;
888
889 if (!link->dhcp_lease)
890 return 0;
891
892 (void) sd_ipv4acd_stop(link->dhcp_acd);
893
894 link->dhcp4_address_bind = false;
895
896 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
897 if (r < 0)
898 return r;
899
900 r = sd_ipv4acd_get_address(link->dhcp_acd, &old);
901 if (r < 0)
902 return r;
903
904 r = sd_ipv4acd_set_address(link->dhcp_acd, &addr);
905 if (r < 0)
906 return r;
907
908 r = sd_ipv4acd_set_callback(link->dhcp_acd, dhcp_address_on_acd, link);
909 if (r < 0)
910 return r;
911
912 log_link_debug(link, "Starting IPv4ACD client. Probing DHCPv4 address "IPV4_ADDRESS_FMT_STR,
913 IPV4_ADDRESS_FMT_VAL(addr));
914
915 return sd_ipv4acd_start(link->dhcp_acd, !in4_addr_equal(&addr, &old));
916 }
917
918 static int dhcp4_address_ready_callback(Address *address) {
919 Link *link;
920 int r;
921
922 assert(address);
923
924 link = address->link;
925
926 /* Do not call this again. */
927 address->callback = NULL;
928
929 r = link_set_dhcp_routes(link);
930 if (r < 0)
931 return r;
932
933 /* Reconfigure static routes as kernel may remove some routes when lease expires. */
934 r = link_set_routes(link);
935 if (r < 0)
936 return r;
937
938 r = dhcp4_start_acd(link);
939 if (r < 0)
940 return log_link_error_errno(link, r, "Failed to start IPv4ACD for DHCP4 address: %m");
941
942 dhcp4_check_ready(link);
943 return 0;
944 }
945
946 static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
947 int r;
948
949 assert(link);
950
951 r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCPv4 address");
952 if (r <= 0)
953 return r;
954
955 if (address_is_ready(link->dhcp_address)) {
956 r = dhcp4_address_ready_callback(link->dhcp_address);
957 if (r < 0)
958 link_enter_failed(link);
959 } else
960 link->dhcp_address->callback = dhcp4_address_ready_callback;
961
962 return 1;
963 }
964
965 static int dhcp4_update_address(Link *link, bool announce) {
966 _cleanup_(address_freep) Address *addr = NULL;
967 uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME;
968 struct in_addr address, netmask;
969 unsigned prefixlen;
970 Address *ret;
971 int r;
972
973 assert(link);
974 assert(link->network);
975
976 if (!link->dhcp_lease)
977 return 0;
978
979 link_set_state(link, LINK_STATE_CONFIGURING);
980 link->dhcp4_configured = false;
981
982 /* address_handler calls link_set_routes() and link_set_nexthop(). Before they are called, the
983 * related flags must be cleared. Otherwise, the link becomes configured state before routes
984 * are configured. */
985 link->static_routes_configured = false;
986 link->static_nexthops_configured = false;
987
988 r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
989 if (r < 0)
990 return log_link_warning_errno(link, r, "DHCP error: no address: %m");
991
992 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
993 if (r < 0)
994 return log_link_warning_errno(link, r, "DHCP error: no netmask: %m");
995
996 if (!FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP)) {
997 r = sd_dhcp_lease_get_lifetime(link->dhcp_lease, &lifetime);
998 if (r < 0)
999 return log_link_warning_errno(link, r, "DHCP error: no lifetime: %m");
1000 }
1001
1002 prefixlen = in4_addr_netmask_to_prefixlen(&netmask);
1003
1004 if (announce) {
1005 const struct in_addr *router;
1006
1007 r = sd_dhcp_lease_get_router(link->dhcp_lease, &router);
1008 if (r < 0 && r != -ENODATA)
1009 return log_link_error_errno(link, r, "DHCP error: Could not get gateway: %m");
1010
1011 if (r > 0 && in4_addr_is_set(&router[0]))
1012 log_struct(LOG_INFO,
1013 LOG_LINK_INTERFACE(link),
1014 LOG_LINK_MESSAGE(link, "DHCPv4 address "IPV4_ADDRESS_FMT_STR"/%u via "IPV4_ADDRESS_FMT_STR,
1015 IPV4_ADDRESS_FMT_VAL(address),
1016 prefixlen,
1017 IPV4_ADDRESS_FMT_VAL(router[0])),
1018 "ADDRESS="IPV4_ADDRESS_FMT_STR, IPV4_ADDRESS_FMT_VAL(address),
1019 "PREFIXLEN=%u", prefixlen,
1020 "GATEWAY="IPV4_ADDRESS_FMT_STR, IPV4_ADDRESS_FMT_VAL(router[0]));
1021 else
1022 log_struct(LOG_INFO,
1023 LOG_LINK_INTERFACE(link),
1024 LOG_LINK_MESSAGE(link, "DHCPv4 address "IPV4_ADDRESS_FMT_STR"/%u",
1025 IPV4_ADDRESS_FMT_VAL(address),
1026 prefixlen),
1027 "ADDRESS="IPV4_ADDRESS_FMT_STR, IPV4_ADDRESS_FMT_VAL(address),
1028 "PREFIXLEN=%u", prefixlen);
1029 }
1030
1031 r = address_new(&addr);
1032 if (r < 0)
1033 return log_oom();
1034
1035 addr->family = AF_INET;
1036 addr->in_addr.in.s_addr = address.s_addr;
1037 addr->cinfo.ifa_prefered = lifetime;
1038 addr->cinfo.ifa_valid = lifetime;
1039 addr->prefixlen = prefixlen;
1040 if (prefixlen <= 30)
1041 addr->broadcast.s_addr = address.s_addr | ~netmask.s_addr;
1042 SET_FLAG(addr->flags, IFA_F_NOPREFIXROUTE, !link_prefixroute(link));
1043 addr->route_metric = link->network->dhcp_route_metric;
1044
1045 /* allow reusing an existing address and simply update its lifetime
1046 * in case it already exists */
1047 r = address_configure(addr, link, dhcp4_address_handler, &ret);
1048 if (r < 0)
1049 return log_link_error_errno(link, r, "Failed to set DHCPv4 address: %m");
1050
1051 if (!address_equal(link->dhcp_address, ret))
1052 link->dhcp_address_old = link->dhcp_address;
1053 link->dhcp_address = ret;
1054
1055 return 0;
1056 }
1057
1058 static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) {
1059 sd_dhcp_lease *lease;
1060 int r;
1061
1062 assert(link);
1063 assert(client);
1064
1065 r = sd_dhcp_client_get_lease(client, &lease);
1066 if (r < 0)
1067 return log_link_warning_errno(link, r, "DHCP error: no lease: %m");
1068
1069 sd_dhcp_lease_unref(link->dhcp_lease);
1070 link->dhcp_lease = sd_dhcp_lease_ref(lease);
1071 link_dirty(link);
1072
1073 return dhcp4_update_address(link, false);
1074 }
1075
1076 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
1077 sd_dhcp_lease *lease;
1078 int r;
1079
1080 assert(client);
1081 assert(link);
1082
1083 r = sd_dhcp_client_get_lease(client, &lease);
1084 if (r < 0)
1085 return log_link_error_errno(link, r, "DHCP error: No lease: %m");
1086
1087 sd_dhcp_lease_unref(link->dhcp_lease);
1088 link->dhcp_lease = sd_dhcp_lease_ref(lease);
1089 link_dirty(link);
1090
1091 if (link->network->dhcp_use_mtu) {
1092 uint16_t mtu;
1093
1094 r = sd_dhcp_lease_get_mtu(lease, &mtu);
1095 if (r >= 0) {
1096 r = link_set_mtu(link, mtu);
1097 if (r < 0)
1098 log_link_error_errno(link, r, "Failed to set MTU to %" PRIu16 ": %m", mtu);
1099 }
1100 }
1101
1102 if (link->network->dhcp_use_hostname) {
1103 const char *dhcpname = NULL;
1104 _cleanup_free_ char *hostname = NULL;
1105
1106 if (link->network->dhcp_hostname)
1107 dhcpname = link->network->dhcp_hostname;
1108 else
1109 (void) sd_dhcp_lease_get_hostname(lease, &dhcpname);
1110
1111 if (dhcpname) {
1112 r = shorten_overlong(dhcpname, &hostname);
1113 if (r < 0)
1114 log_link_warning_errno(link, r, "Unable to shorten overlong DHCP hostname '%s', ignoring: %m", dhcpname);
1115 if (r == 1)
1116 log_link_notice(link, "Overlong DHCP hostname received, shortened from '%s' to '%s'", dhcpname, hostname);
1117 }
1118
1119 if (hostname) {
1120 r = manager_set_hostname(link->manager, hostname);
1121 if (r < 0)
1122 log_link_error_errno(link, r, "Failed to set transient hostname to '%s': %m", hostname);
1123 }
1124 }
1125
1126 if (link->network->dhcp_use_timezone) {
1127 const char *tz = NULL;
1128
1129 (void) sd_dhcp_lease_get_timezone(link->dhcp_lease, &tz);
1130
1131 if (tz) {
1132 r = manager_set_timezone(link->manager, tz);
1133 if (r < 0)
1134 log_link_error_errno(link, r, "Failed to set timezone to '%s': %m", tz);
1135 }
1136 }
1137
1138 if (link->dhcp4_remove_messages == 0) {
1139 r = dhcp4_update_address(link, true);
1140 if (r < 0)
1141 return r;
1142 } else
1143 log_link_debug(link,
1144 "The link has previously assigned DHCPv4 address or routes. "
1145 "The newly assigned address and routes will set up after old ones are removed.");
1146
1147 return 0;
1148 }
1149
1150 static int dhcp_lease_ip_change(sd_dhcp_client *client, Link *link) {
1151 int r;
1152
1153 r = dhcp_lease_acquired(client, link);
1154 if (r < 0)
1155 (void) dhcp_lease_lost(link);
1156
1157 return r;
1158 }
1159
1160 static int dhcp_server_is_deny_listed(Link *link, sd_dhcp_client *client) {
1161 sd_dhcp_lease *lease;
1162 struct in_addr addr;
1163 int r;
1164
1165 assert(link);
1166 assert(link->network);
1167 assert(client);
1168
1169 r = sd_dhcp_client_get_lease(client, &lease);
1170 if (r < 0)
1171 return log_link_error_errno(link, r, "Failed to get DHCP lease: %m");
1172
1173 r = sd_dhcp_lease_get_server_identifier(lease, &addr);
1174 if (r < 0)
1175 return log_link_debug_errno(link, r, "Failed to get DHCP server IP address: %m");
1176
1177 if (set_contains(link->network->dhcp_deny_listed_ip, UINT32_TO_PTR(addr.s_addr))) {
1178 log_struct(LOG_DEBUG,
1179 LOG_LINK_INTERFACE(link),
1180 LOG_LINK_MESSAGE(link, "DHCPv4 server IP address "IPV4_ADDRESS_FMT_STR" found in deny-list, ignoring offer",
1181 IPV4_ADDRESS_FMT_VAL(addr)));
1182 return true;
1183 }
1184
1185 return false;
1186 }
1187
1188 static int dhcp_server_is_allow_listed(Link *link, sd_dhcp_client *client) {
1189 sd_dhcp_lease *lease;
1190 struct in_addr addr;
1191 int r;
1192
1193 assert(link);
1194 assert(link->network);
1195 assert(client);
1196
1197 r = sd_dhcp_client_get_lease(client, &lease);
1198 if (r < 0)
1199 return log_link_error_errno(link, r, "Failed to get DHCP lease: %m");
1200
1201 r = sd_dhcp_lease_get_server_identifier(lease, &addr);
1202 if (r < 0)
1203 return log_link_debug_errno(link, r, "Failed to get DHCP server IP address: %m");
1204
1205 if (set_contains(link->network->dhcp_allow_listed_ip, UINT32_TO_PTR(addr.s_addr))) {
1206 log_struct(LOG_DEBUG,
1207 LOG_LINK_INTERFACE(link),
1208 LOG_LINK_MESSAGE(link, "DHCPv4 server IP address "IPV4_ADDRESS_FMT_STR" found in allow-list, accepting offer",
1209 IPV4_ADDRESS_FMT_VAL(addr)));
1210 return true;
1211 }
1212
1213 return false;
1214 }
1215
1216 static int dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
1217 Link *link = userdata;
1218 int r;
1219
1220 assert(link);
1221 assert(link->network);
1222 assert(link->manager);
1223
1224 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1225 return 0;
1226
1227 switch (event) {
1228 case SD_DHCP_CLIENT_EVENT_STOP:
1229 if (link->ipv4ll) {
1230 log_link_debug(link, "DHCP client is stopped. Acquiring IPv4 link-local address");
1231
1232 r = sd_ipv4ll_start(link->ipv4ll);
1233 if (r < 0)
1234 return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
1235 }
1236
1237 if (FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP)) {
1238 log_link_notice(link, "DHCPv4 connection considered critical, ignoring request to reconfigure it.");
1239 return 0;
1240 }
1241
1242 if (link->dhcp_lease) {
1243 if (link->network->dhcp_send_release) {
1244 r = sd_dhcp_client_send_release(client);
1245 if (r < 0)
1246 log_link_full_errno(link,
1247 ERRNO_IS_DISCONNECT(r) ? LOG_DEBUG : LOG_WARNING,
1248 r, "Failed to send DHCP RELEASE, ignoring: %m");
1249 }
1250
1251 r = dhcp_lease_lost(link);
1252 if (r < 0) {
1253 link_enter_failed(link);
1254 return r;
1255 }
1256 }
1257
1258 break;
1259 case SD_DHCP_CLIENT_EVENT_EXPIRED:
1260 if (FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP)) {
1261 log_link_notice(link, "DHCPv4 connection considered critical, ignoring request to reconfigure it.");
1262 return 0;
1263 }
1264
1265 if (link->dhcp_lease) {
1266 r = dhcp_lease_lost(link);
1267 if (r < 0) {
1268 link_enter_failed(link);
1269 return r;
1270 }
1271 }
1272
1273 break;
1274 case SD_DHCP_CLIENT_EVENT_IP_CHANGE:
1275 if (FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP)) {
1276 log_link_notice(link, "DHCPv4 connection considered critical, ignoring request to reconfigure it.");
1277 return 0;
1278 }
1279
1280 r = dhcp_lease_ip_change(client, link);
1281 if (r < 0) {
1282 link_enter_failed(link);
1283 return r;
1284 }
1285
1286 break;
1287 case SD_DHCP_CLIENT_EVENT_RENEW:
1288 r = dhcp_lease_renew(client, link);
1289 if (r < 0) {
1290 link_enter_failed(link);
1291 return r;
1292 }
1293 break;
1294 case SD_DHCP_CLIENT_EVENT_IP_ACQUIRE:
1295 r = dhcp_lease_acquired(client, link);
1296 if (r < 0) {
1297 link_enter_failed(link);
1298 return r;
1299 }
1300 break;
1301 case SD_DHCP_CLIENT_EVENT_SELECTING:
1302 if (!set_isempty(link->network->dhcp_allow_listed_ip)) {
1303 r = dhcp_server_is_allow_listed(link, client);
1304 if (r < 0)
1305 return r;
1306 if (r == 0)
1307 return -ENOMSG;
1308 } else {
1309 r = dhcp_server_is_deny_listed(link, client);
1310 if (r < 0)
1311 return r;
1312 if (r != 0)
1313 return -ENOMSG;
1314 }
1315 break;
1316
1317 case SD_DHCP_CLIENT_EVENT_TRANSIENT_FAILURE:
1318 if (link->ipv4ll && !sd_ipv4ll_is_running(link->ipv4ll)) {
1319 log_link_debug(link, "Problems acquiring DHCP lease, acquiring IPv4 link-local address");
1320
1321 r = sd_ipv4ll_start(link->ipv4ll);
1322 if (r < 0)
1323 return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
1324 }
1325 break;
1326
1327 default:
1328 if (event < 0)
1329 log_link_warning_errno(link, event, "DHCP error: Client failed: %m");
1330 else
1331 log_link_warning(link, "DHCP unknown event: %i", event);
1332 break;
1333 }
1334
1335 return 0;
1336 }
1337
1338 static int dhcp4_set_hostname(Link *link) {
1339 _cleanup_free_ char *hostname = NULL;
1340 const char *hn;
1341 int r;
1342
1343 assert(link);
1344
1345 if (!link->network->dhcp_send_hostname)
1346 hn = NULL;
1347 else if (link->network->dhcp_hostname)
1348 hn = link->network->dhcp_hostname;
1349 else {
1350 r = gethostname_strict(&hostname);
1351 if (r < 0 && r != -ENXIO) /* ENXIO: no hostname set or hostname is "localhost" */
1352 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to get hostname: %m");
1353
1354 hn = hostname;
1355 }
1356
1357 r = sd_dhcp_client_set_hostname(link->dhcp_client, hn);
1358 if (r == -EINVAL && hostname)
1359 /* Ignore error when the machine's hostname is not suitable to send in DHCP packet. */
1360 log_link_debug_errno(link, r, "DHCP4 CLIENT: Failed to set hostname from kernel hostname, ignoring: %m");
1361 else if (r < 0)
1362 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set hostname: %m");
1363
1364 return 0;
1365 }
1366
1367 static int dhcp4_set_client_identifier(Link *link) {
1368 int r;
1369
1370 assert(link);
1371 assert(link->network);
1372 assert(link->dhcp_client);
1373
1374 switch (link->network->dhcp_client_identifier) {
1375 case DHCP_CLIENT_ID_DUID: {
1376 /* If configured, apply user specified DUID and IAID */
1377 const DUID *duid = link_get_dhcp4_duid(link);
1378
1379 if (duid->type == DUID_TYPE_LLT && duid->raw_data_len == 0)
1380 r = sd_dhcp_client_set_iaid_duid_llt(link->dhcp_client,
1381 link->network->dhcp_iaid_set,
1382 link->network->dhcp_iaid,
1383 duid->llt_time);
1384 else
1385 r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
1386 link->network->dhcp_iaid_set,
1387 link->network->dhcp_iaid,
1388 duid->type,
1389 duid->raw_data_len > 0 ? duid->raw_data : NULL,
1390 duid->raw_data_len);
1391 if (r < 0)
1392 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set IAID+DUID: %m");
1393 break;
1394 }
1395 case DHCP_CLIENT_ID_DUID_ONLY: {
1396 /* If configured, apply user specified DUID */
1397 const DUID *duid = link_get_dhcp4_duid(link);
1398
1399 if (duid->type == DUID_TYPE_LLT && duid->raw_data_len == 0)
1400 r = sd_dhcp_client_set_duid_llt(link->dhcp_client,
1401 duid->llt_time);
1402 else
1403 r = sd_dhcp_client_set_duid(link->dhcp_client,
1404 duid->type,
1405 duid->raw_data_len > 0 ? duid->raw_data : NULL,
1406 duid->raw_data_len);
1407 if (r < 0)
1408 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set DUID: %m");
1409 break;
1410 }
1411 case DHCP_CLIENT_ID_MAC: {
1412 const uint8_t *hw_addr = link->hw_addr.addr.bytes;
1413 size_t hw_addr_len = link->hw_addr.length;
1414
1415 if (link->iftype == ARPHRD_INFINIBAND && hw_addr_len == INFINIBAND_ALEN) {
1416 /* set_client_id expects only last 8 bytes of an IB address */
1417 hw_addr += INFINIBAND_ALEN - 8;
1418 hw_addr_len -= INFINIBAND_ALEN - 8;
1419 }
1420
1421 r = sd_dhcp_client_set_client_id(link->dhcp_client,
1422 link->iftype,
1423 hw_addr,
1424 hw_addr_len);
1425 if (r < 0)
1426 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set client ID: %m");
1427 break;
1428 }
1429 default:
1430 assert_not_reached("Unknown client identifier type.");
1431 }
1432
1433 return 0;
1434 }
1435
1436 static int dhcp4_configure_duid(Link *link) {
1437 assert(link);
1438
1439 if (!IN_SET(link->network->dhcp_client_identifier, DHCP_CLIENT_ID_DUID, DHCP_CLIENT_ID_DUID_ONLY))
1440 return 1;
1441
1442 return dhcp_configure_duid(link, link_get_dhcp4_duid(link));
1443 }
1444
1445 static int dhcp4_set_request_address(Link *link) {
1446 Address *a;
1447
1448 assert(link);
1449 assert(link->network);
1450 assert(link->dhcp_client);
1451
1452 if (!FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
1453 return 0;
1454
1455 SET_FOREACH(a, link->addresses_foreign) {
1456 if (a->family != AF_INET)
1457 continue;
1458 if (link_address_is_dynamic(link, a))
1459 break;
1460 }
1461
1462 if (!a)
1463 return 0;
1464
1465 log_link_debug(link, "DHCP4 CLIENT: requesting " IPV4_ADDRESS_FMT_STR, IPV4_ADDRESS_FMT_VAL(a->in_addr.in));
1466
1467 return sd_dhcp_client_set_request_address(link->dhcp_client, &a->in_addr.in);
1468 }
1469
1470 static bool link_needs_dhcp_broadcast(Link *link) {
1471 const char *val;
1472 int r;
1473
1474 assert(link);
1475 assert(link->network);
1476
1477 /* Return the setting in DHCP[4].RequestBroadcast if specified. Otherwise return the device property
1478 * ID_NET_DHCP_BROADCAST setting, which may be set for interfaces requiring that the DHCPOFFER message
1479 * is being broadcast because they can't handle unicast messages while not fully configured.
1480 * If neither is set or a failure occurs, return false, which is the default for this flag.
1481 */
1482 r = link->network->dhcp_broadcast;
1483 if (r < 0 && link->sd_device && sd_device_get_property_value(link->sd_device, "ID_NET_DHCP_BROADCAST", &val) >= 0) {
1484 r = parse_boolean(val);
1485 if (r < 0)
1486 log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to parse ID_NET_DHCP_BROADCAST, ignoring: %m");
1487 else
1488 log_link_debug(link, "DHCP4 CLIENT: Detected ID_NET_DHCP_BROADCAST='%d'.", r);
1489
1490 }
1491 return r == true;
1492 }
1493
1494 int dhcp4_configure(Link *link) {
1495 sd_dhcp_option *send_option;
1496 void *request_options;
1497 int r;
1498
1499 assert(link);
1500 assert(link->network);
1501
1502 if (!link_dhcp4_enabled(link))
1503 return 0;
1504
1505 if (link->dhcp_client)
1506 return -EBUSY; /* Already configured. */
1507
1508 r = dhcp4_configure_duid(link);
1509 if (r <= 0)
1510 return r;
1511
1512 r = sd_dhcp_client_new(&link->dhcp_client, link->network->dhcp_anonymize);
1513 if (r < 0)
1514 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to allocate DHCP4 client: %m");
1515
1516 r = sd_dhcp_client_attach_event(link->dhcp_client, link->manager->event, 0);
1517 if (r < 0)
1518 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to attach event to DHCP4 client: %m");
1519
1520 r = sd_dhcp_client_set_mac(link->dhcp_client,
1521 link->hw_addr.addr.bytes,
1522 link->bcast_addr.length > 0 ? link->bcast_addr.addr.bytes : NULL,
1523 link->hw_addr.length, link->iftype);
1524 if (r < 0)
1525 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set MAC address: %m");
1526
1527 r = sd_dhcp_client_set_ifindex(link->dhcp_client, link->ifindex);
1528 if (r < 0)
1529 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set ifindex: %m");
1530
1531 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link);
1532 if (r < 0)
1533 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set callback: %m");
1534
1535 r = sd_dhcp_client_set_request_broadcast(link->dhcp_client, link_needs_dhcp_broadcast(link));
1536 if (r < 0)
1537 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for broadcast: %m");
1538
1539 if (link->mtu > 0) {
1540 r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
1541 if (r < 0)
1542 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set MTU: %m");
1543 }
1544
1545 if (!link->network->dhcp_anonymize) {
1546 if (link->network->dhcp_use_mtu) {
1547 r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_INTERFACE_MTU);
1548 if (r < 0)
1549 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for MTU: %m");
1550 }
1551
1552 if (link->network->dhcp_use_routes) {
1553 r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_STATIC_ROUTE);
1554 if (r < 0)
1555 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for static route: %m");
1556
1557 r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
1558 if (r < 0)
1559 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for classless static route: %m");
1560 }
1561
1562 if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
1563 r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_DOMAIN_SEARCH_LIST);
1564 if (r < 0)
1565 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for domain search list: %m");
1566 }
1567
1568 if (link->network->dhcp_use_ntp) {
1569 r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NTP_SERVER);
1570 if (r < 0)
1571 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for NTP server: %m");
1572 }
1573
1574 if (link->network->dhcp_use_sip) {
1575 r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_SIP_SERVER);
1576 if (r < 0)
1577 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for SIP server: %m");
1578 }
1579
1580 if (link->network->dhcp_use_timezone) {
1581 r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NEW_TZDB_TIMEZONE);
1582 if (r < 0)
1583 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for timezone: %m");
1584 }
1585
1586 SET_FOREACH(request_options, link->network->dhcp_request_options) {
1587 uint32_t option = PTR_TO_UINT32(request_options);
1588
1589 r = sd_dhcp_client_set_request_option(link->dhcp_client, option);
1590 if (r < 0)
1591 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for '%u': %m", option);
1592 }
1593
1594 ORDERED_HASHMAP_FOREACH(send_option, link->network->dhcp_client_send_options) {
1595 r = sd_dhcp_client_add_option(link->dhcp_client, send_option);
1596 if (r == -EEXIST)
1597 continue;
1598 if (r < 0)
1599 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set send option: %m");
1600 }
1601
1602 ORDERED_HASHMAP_FOREACH(send_option, link->network->dhcp_client_send_vendor_options) {
1603 r = sd_dhcp_client_add_vendor_option(link->dhcp_client, send_option);
1604 if (r == -EEXIST)
1605 continue;
1606 if (r < 0)
1607 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set send option: %m");
1608 }
1609
1610 r = dhcp4_set_hostname(link);
1611 if (r < 0)
1612 return r;
1613
1614 if (link->network->dhcp_vendor_class_identifier) {
1615 r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client,
1616 link->network->dhcp_vendor_class_identifier);
1617 if (r < 0)
1618 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set vendor class identifier: %m");
1619 }
1620
1621 if (link->network->dhcp_mudurl) {
1622 r = sd_dhcp_client_set_mud_url(link->dhcp_client, link->network->dhcp_mudurl);
1623 if (r < 0)
1624 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set MUD URL: %m");
1625 }
1626
1627 if (link->network->dhcp_user_class) {
1628 r = sd_dhcp_client_set_user_class(link->dhcp_client, link->network->dhcp_user_class);
1629 if (r < 0)
1630 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set user class: %m");
1631 }
1632 }
1633
1634 if (link->network->dhcp_client_port > 0) {
1635 r = sd_dhcp_client_set_client_port(link->dhcp_client, link->network->dhcp_client_port);
1636 if (r < 0)
1637 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set listen port: %m");
1638 }
1639
1640 if (link->network->dhcp_max_attempts > 0) {
1641 r = sd_dhcp_client_set_max_attempts(link->dhcp_client, link->network->dhcp_max_attempts);
1642 if (r < 0)
1643 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set max attempts: %m");
1644 }
1645
1646 if (link->network->dhcp_ip_service_type > 0) {
1647 r = sd_dhcp_client_set_service_type(link->dhcp_client, link->network->dhcp_ip_service_type);
1648 if (r < 0)
1649 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set IP service type: %m");
1650 }
1651
1652 if (link->network->dhcp_fallback_lease_lifetime > 0) {
1653 r = sd_dhcp_client_set_fallback_lease_lifetime(link->dhcp_client, link->network->dhcp_fallback_lease_lifetime);
1654 if (r < 0)
1655 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed set to lease lifetime: %m");
1656 }
1657
1658 r = dhcp4_set_request_address(link);
1659 if (r < 0)
1660 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to set initial DHCPv4 address: %m");
1661
1662 r = dhcp4_configure_dad(link);
1663 if (r < 0)
1664 return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to configure service type: %m");
1665
1666 return dhcp4_set_client_identifier(link);
1667 }
1668
1669 int dhcp4_update_mac(Link *link) {
1670 int r;
1671
1672 assert(link);
1673
1674 if (!link->dhcp_client)
1675 return 0;
1676
1677 r = sd_dhcp_client_set_mac(link->dhcp_client, link->hw_addr.addr.bytes,
1678 link->bcast_addr.length > 0 ? link->bcast_addr.addr.bytes : NULL,
1679 link->hw_addr.length, link->iftype);
1680 if (r < 0)
1681 return r;
1682
1683 r = dhcp4_set_client_identifier(link);
1684 if (r < 0)
1685 return r;
1686
1687 r = dhcp4_dad_update_mac(link);
1688 if (r < 0)
1689 return r;
1690
1691 return 0;
1692 }
1693
1694 int dhcp4_start(Link *link) {
1695 assert(link);
1696
1697 if (!link->dhcp_client)
1698 return 0;
1699
1700 if (sd_dhcp_client_is_running(link->dhcp_client) > 0)
1701 return 0;
1702
1703 log_link_debug(link, "Acquiring DHCPv4 lease");
1704
1705 return sd_dhcp_client_start(link->dhcp_client);
1706 }
1707
1708 int config_parse_dhcp_max_attempts(
1709 const char *unit,
1710 const char *filename,
1711 unsigned line,
1712 const char *section,
1713 unsigned section_line,
1714 const char *lvalue,
1715 int ltype,
1716 const char *rvalue,
1717 void *data,
1718 void *userdata) {
1719
1720 Network *network = data;
1721 uint64_t a;
1722 int r;
1723
1724 assert(network);
1725 assert(lvalue);
1726 assert(rvalue);
1727
1728 if (isempty(rvalue)) {
1729 network->dhcp_max_attempts = 0;
1730 return 0;
1731 }
1732
1733 if (streq(rvalue, "infinity")) {
1734 network->dhcp_max_attempts = UINT64_MAX;
1735 return 0;
1736 }
1737
1738 r = safe_atou64(rvalue, &a);
1739 if (r < 0) {
1740 log_syntax(unit, LOG_WARNING, filename, line, r,
1741 "Failed to parse DHCP maximum attempts, ignoring: %s", rvalue);
1742 return 0;
1743 }
1744
1745 if (a == 0) {
1746 log_syntax(unit, LOG_WARNING, filename, line, 0,
1747 "%s= must be positive integer or 'infinity', ignoring: %s", lvalue, rvalue);
1748 return 0;
1749 }
1750
1751 network->dhcp_max_attempts = a;
1752
1753 return 0;
1754 }
1755
1756 int config_parse_dhcp_acl_ip_address(
1757 const char *unit,
1758 const char *filename,
1759 unsigned line,
1760 const char *section,
1761 unsigned section_line,
1762 const char *lvalue,
1763 int ltype,
1764 const char *rvalue,
1765 void *data,
1766 void *userdata) {
1767
1768 Network *network = data;
1769 Set **acl;
1770 int r;
1771
1772 assert(filename);
1773 assert(lvalue);
1774 assert(rvalue);
1775 assert(data);
1776
1777 acl = STR_IN_SET(lvalue, "DenyList", "BlackList") ? &network->dhcp_deny_listed_ip : &network->dhcp_allow_listed_ip;
1778
1779 if (isempty(rvalue)) {
1780 *acl = set_free(*acl);
1781 return 0;
1782 }
1783
1784 for (const char *p = rvalue;;) {
1785 _cleanup_free_ char *n = NULL;
1786 union in_addr_union ip;
1787
1788 r = extract_first_word(&p, &n, NULL, 0);
1789 if (r == -ENOMEM)
1790 return log_oom();
1791 if (r < 0) {
1792 log_syntax(unit, LOG_WARNING, filename, line, r,
1793 "Failed to parse DHCP '%s=' IP address, ignoring assignment: %s",
1794 lvalue, rvalue);
1795 return 0;
1796 }
1797 if (r == 0)
1798 return 0;
1799
1800 r = in_addr_from_string(AF_INET, n, &ip);
1801 if (r < 0) {
1802 log_syntax(unit, LOG_WARNING, filename, line, r,
1803 "DHCP '%s=' IP address is invalid, ignoring assignment: %s", lvalue, n);
1804 continue;
1805 }
1806
1807 r = set_ensure_put(acl, NULL, UINT32_TO_PTR(ip.in.s_addr));
1808 if (r < 0)
1809 log_syntax(unit, LOG_WARNING, filename, line, r,
1810 "Failed to store DHCP '%s=' IP address '%s', ignoring assignment: %m", lvalue, n);
1811 }
1812 }
1813
1814 int config_parse_dhcp_ip_service_type(
1815 const char *unit,
1816 const char *filename,
1817 unsigned line,
1818 const char *section,
1819 unsigned section_line,
1820 const char *lvalue,
1821 int ltype,
1822 const char *rvalue,
1823 void *data,
1824 void *userdata) {
1825
1826 assert(filename);
1827 assert(lvalue);
1828 assert(rvalue);
1829
1830 if (streq(rvalue, "CS4"))
1831 *((int *)data) = IPTOS_CLASS_CS4;
1832 else if (streq(rvalue, "CS6"))
1833 *((int *)data) = IPTOS_CLASS_CS6;
1834 else
1835 log_syntax(unit, LOG_WARNING, filename, line, 0,
1836 "Failed to parse IPServiceType type '%s', ignoring.", rvalue);
1837
1838 return 0;
1839 }
1840
1841 int config_parse_dhcp_mud_url(
1842 const char *unit,
1843 const char *filename,
1844 unsigned line,
1845 const char *section,
1846 unsigned section_line,
1847 const char *lvalue,
1848 int ltype,
1849 const char *rvalue,
1850 void *data,
1851 void *userdata) {
1852
1853 _cleanup_free_ char *unescaped = NULL;
1854 Network *network = data;
1855 int r;
1856
1857 assert(filename);
1858 assert(lvalue);
1859 assert(rvalue);
1860
1861 if (isempty(rvalue)) {
1862 network->dhcp_mudurl = mfree(network->dhcp_mudurl);
1863 return 0;
1864 }
1865
1866 r = cunescape(rvalue, 0, &unescaped);
1867 if (r < 0) {
1868 log_syntax(unit, LOG_WARNING, filename, line, r,
1869 "Failed to Failed to unescape MUD URL, ignoring: %s", rvalue);
1870 return 0;
1871 }
1872
1873 if (!http_url_is_valid(unescaped) || strlen(unescaped) > 255) {
1874 log_syntax(unit, LOG_WARNING, filename, line, 0,
1875 "Failed to parse MUD URL '%s', ignoring: %m", rvalue);
1876
1877 return 0;
1878 }
1879
1880 return free_and_strdup_warn(&network->dhcp_mudurl, unescaped);
1881 }
1882
1883 int config_parse_dhcp_fallback_lease_lifetime(const char *unit,
1884 const char *filename,
1885 unsigned line,
1886 const char *section,
1887 unsigned section_line,
1888 const char *lvalue,
1889 int ltype,
1890 const char *rvalue,
1891 void *data,
1892 void *userdata) {
1893 Network *network = userdata;
1894 uint32_t k;
1895
1896 assert(filename);
1897 assert(section);
1898 assert(lvalue);
1899 assert(rvalue);
1900 assert(data);
1901
1902 if (isempty(rvalue)) {
1903 network->dhcp_fallback_lease_lifetime = 0;
1904 return 0;
1905 }
1906
1907 /* We accept only "forever" or "infinity". */
1908 if (STR_IN_SET(rvalue, "forever", "infinity"))
1909 k = CACHE_INFO_INFINITY_LIFE_TIME;
1910 else {
1911 log_syntax(unit, LOG_WARNING, filename, line, 0,
1912 "Invalid LeaseLifetime= value, ignoring: %s", rvalue);
1913 return 0;
1914 }
1915
1916 network->dhcp_fallback_lease_lifetime = k;
1917
1918 return 0;
1919 }
1920
1921 static const char* const dhcp_client_identifier_table[_DHCP_CLIENT_ID_MAX] = {
1922 [DHCP_CLIENT_ID_MAC] = "mac",
1923 [DHCP_CLIENT_ID_DUID] = "duid",
1924 [DHCP_CLIENT_ID_DUID_ONLY] = "duid-only",
1925 };
1926
1927 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier, DHCPClientIdentifier);
1928 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier, dhcp_client_identifier, DHCPClientIdentifier,
1929 "Failed to parse client identifier type");