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