]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-dhcp4.c
networkd: support setting dhcp server port
[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 ret = 0;
247
248 assert(link);
249 assert(link->manager);
250
251 SET_FOREACH(route, link->manager->routes) {
252 if (route->source != NETWORK_CONFIG_SOURCE_DHCP4)
253 continue;
254 if (route->nexthop.ifindex != 0 && route->nexthop.ifindex != link->ifindex)
255 continue;
256 if (only_marked && !route_is_marked(route))
257 continue;
258
259 RET_GATHER(ret, route_remove_and_cancel(route, link->manager));
260 }
261
262 SET_FOREACH(address, link->addresses) {
263 if (address->source != NETWORK_CONFIG_SOURCE_DHCP4)
264 continue;
265 if (only_marked && !address_is_marked(address))
266 continue;
267
268 RET_GATHER(ret, address_remove_and_cancel(address, link));
269 }
270
271 return ret;
272 }
273
274 static int dhcp4_address_get(Link *link, Address **ret) {
275 Address *address;
276
277 assert(link);
278
279 SET_FOREACH(address, link->addresses) {
280 if (address->source != NETWORK_CONFIG_SOURCE_DHCP4)
281 continue;
282 if (address_is_marked(address))
283 continue;
284
285 if (ret)
286 *ret = address;
287 return 0;
288 }
289
290 return -ENOENT;
291 }
292
293 static int dhcp4_address_ready_callback(Address *address) {
294 assert(address);
295 assert(address->link);
296
297 /* Do not call this again. */
298 address->callback = NULL;
299
300 return dhcp4_check_ready(address->link);
301 }
302
303 int dhcp4_check_ready(Link *link) {
304 Address *address;
305 int r;
306
307 assert(link);
308
309 if (link->dhcp4_messages > 0) {
310 log_link_debug(link, "%s(): DHCPv4 address and routes are not set.", __func__);
311 return 0;
312 }
313
314 if (dhcp4_address_get(link, &address) < 0) {
315 log_link_debug(link, "%s(): DHCPv4 address is not set.", __func__);
316 return 0;
317 }
318
319 if (!address_is_ready(address)) {
320 log_link_debug(link, "%s(): DHCPv4 address is not ready.", __func__);
321 address->callback = dhcp4_address_ready_callback;
322 return 0;
323 }
324
325 link->dhcp4_configured = true;
326 log_link_debug(link, "DHCPv4 address and routes set.");
327
328 /* New address and routes are configured now. Let's release old lease. */
329 r = dhcp4_remove_address_and_routes(link, /* only_marked = */ true);
330 if (r < 0)
331 return r;
332
333 r = sd_ipv4ll_stop(link->ipv4ll);
334 if (r < 0)
335 return log_link_warning_errno(link, r, "Failed to drop IPv4 link-local address: %m");
336
337 link_check_ready(link);
338 return 0;
339 }
340
341 static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Route *route) {
342 int r;
343
344 assert(m);
345 assert(link);
346
347 r = route_configure_handler_internal(rtnl, m, link, route, "Could not set DHCPv4 route");
348 if (r <= 0)
349 return r;
350
351 r = dhcp4_check_ready(link);
352 if (r < 0)
353 link_enter_failed(link);
354
355 return 1;
356 }
357
358 static int dhcp4_request_route(Route *route, Link *link) {
359 struct in_addr server;
360 Route *existing;
361 int r;
362
363 assert(route);
364 assert(link);
365 assert(link->manager);
366 assert(link->network);
367 assert(link->dhcp_lease);
368
369 r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &server);
370 if (r < 0)
371 return log_link_debug_errno(link, r, "Failed to get DHCP server IP address: %m");
372
373 route->source = NETWORK_CONFIG_SOURCE_DHCP4;
374 route->provider.in = server;
375 route->family = AF_INET;
376 if (!route->protocol_set)
377 route->protocol = RTPROT_DHCP;
378 if (!route->priority_set)
379 route->priority = link->network->dhcp_route_metric;
380 if (!route->table_set)
381 route->table = link_get_dhcp4_route_table(link);
382 r = route_metric_set(&route->metric, RTAX_MTU, link->network->dhcp_route_mtu);
383 if (r < 0)
384 return r;
385 r = route_metric_set(&route->metric, RTAX_INITCWND, link->network->dhcp_initial_congestion_window);
386 if (r < 0)
387 return r;
388 r = route_metric_set(&route->metric, RTAX_INITRWND, link->network->dhcp_advertised_receive_window);
389 if (r < 0)
390 return r;
391 r = route_metric_set(&route->metric, RTAX_QUICKACK, link->network->dhcp_quickack);
392 if (r < 0)
393 return r;
394
395 r = route_adjust_nexthops(route, link);
396 if (r < 0)
397 return r;
398
399 if (route_get(link->manager, route, &existing) < 0) /* This is a new route. */
400 link->dhcp4_configured = false;
401 else
402 route_unmark(existing);
403
404 return link_request_route(link, route, &link->dhcp4_messages, dhcp4_route_handler);
405 }
406
407 static bool link_prefixroute(Link *link) {
408 return !link->network->dhcp_route_table_set ||
409 link->network->dhcp_route_table == RT_TABLE_MAIN;
410 }
411
412 static int dhcp4_request_prefix_route(Link *link) {
413 _cleanup_(route_unrefp) Route *route = NULL;
414 int r;
415
416 assert(link);
417 assert(link->dhcp_lease);
418
419 if (link_prefixroute(link))
420 /* When true, the route will be created by kernel. See dhcp4_update_address(). */
421 return 0;
422
423 r = route_new(&route);
424 if (r < 0)
425 return r;
426
427 route->scope = RT_SCOPE_LINK;
428
429 r = sd_dhcp_lease_get_prefix(link->dhcp_lease, &route->dst.in, &route->dst_prefixlen);
430 if (r < 0)
431 return r;
432
433 r = sd_dhcp_lease_get_address(link->dhcp_lease, &route->prefsrc.in);
434 if (r < 0)
435 return r;
436
437 return dhcp4_request_route(route, link);
438 }
439
440 static int dhcp4_request_route_to_gateway(Link *link, const struct in_addr *gw) {
441 _cleanup_(route_unrefp) Route *route = NULL;
442 struct in_addr address;
443 int r;
444
445 assert(link);
446 assert(link->dhcp_lease);
447 assert(gw);
448
449 r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
450 if (r < 0)
451 return r;
452
453 r = route_new(&route);
454 if (r < 0)
455 return r;
456
457 route->dst.in = *gw;
458 route->dst_prefixlen = 32;
459 route->prefsrc.in = address;
460 route->scope = RT_SCOPE_LINK;
461
462 return dhcp4_request_route(route, link);
463 }
464
465 static int dhcp4_request_route_auto(
466 Route *route,
467 Link *link,
468 const struct in_addr *gw) {
469
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->nexthop.family = AF_UNSPEC;
490 route->nexthop.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->nexthop.family = AF_UNSPEC;
501 route->nexthop.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->nexthop.family = AF_UNSPEC;
524 route->nexthop.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->nexthop.family = AF_INET;
534 route->nexthop.gw.in = *gw;
535 route->prefsrc.in = address;
536 }
537
538 return dhcp4_request_route(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_unrefp) 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(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_unrefp) 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->nexthop.family = AF_INET;
627 route->nexthop.gw.in = router;
628 route->prefsrc.in = address;
629
630 return dhcp4_request_route(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_unrefp) Route *route = NULL;
643 struct in_addr gw;
644
645 if (!rt->gateway_from_dhcp_or_ra)
646 continue;
647
648 if (rt->nexthop.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, NULL, &route);
667 if (r < 0)
668 return r;
669
670 route->nexthop.gw.in = gw;
671
672 r = dhcp4_request_route(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_unrefp) 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(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 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 RET_GATHER(r, dhcp4_remove_address_and_routes(link, /* only_marked = */ false));
853 RET_GATHER(r, dhcp_reset_mtu(link));
854 RET_GATHER(r, dhcp_reset_hostname(link));
855
856 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
857 link_dirty(link);
858
859 /* If one of the above failed. Do not request nexthops and routes. */
860 if (r < 0)
861 return r;
862
863 r = link_request_static_nexthops(link, true);
864 if (r < 0)
865 return r;
866
867 return link_request_static_routes(link, true);
868 }
869
870 static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) {
871 int r;
872
873 assert(link);
874
875 r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCPv4 address");
876 if (r <= 0)
877 return r;
878
879 r = dhcp4_check_ready(link);
880 if (r < 0)
881 link_enter_failed(link);
882
883 return 1;
884 }
885
886 static int dhcp4_request_address(Link *link, bool announce) {
887 _cleanup_(address_unrefp) Address *addr = NULL;
888 struct in_addr address, server;
889 uint8_t prefixlen;
890 Address *existing;
891 usec_t lifetime_usec;
892 int r;
893
894 assert(link);
895 assert(link->manager);
896 assert(link->network);
897 assert(link->dhcp_lease);
898
899 r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
900 if (r < 0)
901 return log_link_warning_errno(link, r, "DHCP error: no address: %m");
902
903 r = sd_dhcp_lease_get_prefix(link->dhcp_lease, NULL, &prefixlen);
904 if (r < 0)
905 return log_link_warning_errno(link, r, "DHCP error: no netmask: %m");
906
907 r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &server);
908 if (r < 0)
909 return log_link_debug_errno(link, r, "DHCP error: failed to get DHCP server IP address: %m");
910
911 if (!FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP)) {
912 r = sd_dhcp_lease_get_lifetime_timestamp(link->dhcp_lease, CLOCK_BOOTTIME, &lifetime_usec);
913 if (r < 0)
914 return log_link_warning_errno(link, r, "DHCP error: failed to get lifetime: %m");
915 } else
916 lifetime_usec = USEC_INFINITY;
917
918 if (announce) {
919 const struct in_addr *router;
920
921 r = sd_dhcp_lease_get_router(link->dhcp_lease, &router);
922 if (r < 0 && r != -ENODATA)
923 return log_link_error_errno(link, r, "DHCP error: Could not get gateway: %m");
924
925 if (r > 0 && in4_addr_is_set(&router[0]))
926 log_struct(LOG_INFO,
927 LOG_LINK_INTERFACE(link),
928 LOG_LINK_MESSAGE(link, "DHCPv4 address "IPV4_ADDRESS_FMT_STR"/%u, gateway "IPV4_ADDRESS_FMT_STR" acquired from "IPV4_ADDRESS_FMT_STR,
929 IPV4_ADDRESS_FMT_VAL(address),
930 prefixlen,
931 IPV4_ADDRESS_FMT_VAL(router[0]),
932 IPV4_ADDRESS_FMT_VAL(server)),
933 "ADDRESS="IPV4_ADDRESS_FMT_STR, IPV4_ADDRESS_FMT_VAL(address),
934 "PREFIXLEN=%u", prefixlen,
935 "GATEWAY="IPV4_ADDRESS_FMT_STR, IPV4_ADDRESS_FMT_VAL(router[0]));
936 else
937 log_struct(LOG_INFO,
938 LOG_LINK_INTERFACE(link),
939 LOG_LINK_MESSAGE(link, "DHCPv4 address "IPV4_ADDRESS_FMT_STR"/%u acquired from "IPV4_ADDRESS_FMT_STR,
940 IPV4_ADDRESS_FMT_VAL(address),
941 prefixlen,
942 IPV4_ADDRESS_FMT_VAL(server)),
943 "ADDRESS="IPV4_ADDRESS_FMT_STR, IPV4_ADDRESS_FMT_VAL(address),
944 "PREFIXLEN=%u", prefixlen);
945 }
946
947 r = address_new(&addr);
948 if (r < 0)
949 return log_oom();
950
951 addr->source = NETWORK_CONFIG_SOURCE_DHCP4;
952 addr->provider.in = server;
953 addr->family = AF_INET;
954 addr->in_addr.in.s_addr = address.s_addr;
955 addr->lifetime_preferred_usec = lifetime_usec;
956 addr->lifetime_valid_usec = lifetime_usec;
957 addr->prefixlen = prefixlen;
958 r = sd_dhcp_lease_get_broadcast(link->dhcp_lease, &addr->broadcast);
959 if (r < 0 && r != -ENODATA)
960 return log_link_warning_errno(link, r, "DHCP: failed to get broadcast address: %m");
961 SET_FLAG(addr->flags, IFA_F_NOPREFIXROUTE, !link_prefixroute(link));
962 addr->route_metric = link->network->dhcp_route_metric;
963 addr->duplicate_address_detection = link->network->dhcp_send_decline ? ADDRESS_FAMILY_IPV4 : ADDRESS_FAMILY_NO;
964
965 r = free_and_strdup_warn(&addr->label, link->network->dhcp_label);
966 if (r < 0)
967 return r;
968
969 r = free_and_strdup_warn(&addr->netlabel, link->network->dhcp_netlabel);
970 if (r < 0)
971 return r;
972
973 if (address_get(link, addr, &existing) < 0) /* The address is new. */
974 link->dhcp4_configured = false;
975 else
976 address_unmark(existing);
977
978 r = link_request_address(link, addr, &link->dhcp4_messages,
979 dhcp4_address_handler, NULL);
980 if (r < 0)
981 return log_link_error_errno(link, r, "Failed to request DHCPv4 address: %m");
982
983 return 0;
984 }
985
986 static int dhcp4_request_address_and_routes(Link *link, bool announce) {
987 int r;
988
989 assert(link);
990
991 link_mark_addresses(link, NETWORK_CONFIG_SOURCE_DHCP4);
992 manager_mark_routes(link->manager, link, NETWORK_CONFIG_SOURCE_DHCP4);
993
994 r = dhcp4_request_address(link, announce);
995 if (r < 0)
996 return r;
997
998 r = dhcp4_request_routes(link);
999 if (r < 0)
1000 return r;
1001
1002 if (!link->dhcp4_configured) {
1003 link_set_state(link, LINK_STATE_CONFIGURING);
1004 link_check_ready(link);
1005 }
1006
1007 return 0;
1008 }
1009
1010 static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) {
1011 _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *old_lease = NULL;
1012 sd_dhcp_lease *lease;
1013 int r;
1014
1015 assert(link);
1016 assert(link->network);
1017 assert(client);
1018
1019 r = sd_dhcp_client_get_lease(client, &lease);
1020 if (r < 0)
1021 return log_link_warning_errno(link, r, "DHCP error: no lease: %m");
1022
1023 old_lease = TAKE_PTR(link->dhcp_lease);
1024 link->dhcp_lease = sd_dhcp_lease_ref(lease);
1025 link_dirty(link);
1026
1027 if (link->network->dhcp_use_6rd) {
1028 if (sd_dhcp_lease_has_6rd(link->dhcp_lease)) {
1029 r = dhcp4_pd_prefix_acquired(link);
1030 if (r < 0)
1031 return log_link_warning_errno(link, r, "Failed to process 6rd option: %m");
1032 } else if (sd_dhcp_lease_has_6rd(old_lease))
1033 dhcp4_pd_prefix_lost(link);
1034 }
1035
1036 return dhcp4_request_address_and_routes(link, false);
1037 }
1038
1039 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
1040 sd_dhcp_lease *lease;
1041 int r;
1042
1043 assert(client);
1044 assert(link);
1045
1046 r = sd_dhcp_client_get_lease(client, &lease);
1047 if (r < 0)
1048 return log_link_error_errno(link, r, "DHCP error: No lease: %m");
1049
1050 sd_dhcp_lease_unref(link->dhcp_lease);
1051 link->dhcp_lease = sd_dhcp_lease_ref(lease);
1052 link_dirty(link);
1053
1054 if (link->network->dhcp_use_mtu) {
1055 uint16_t mtu;
1056
1057 r = sd_dhcp_lease_get_mtu(lease, &mtu);
1058 if (r >= 0) {
1059 r = link_request_to_set_mtu(link, mtu);
1060 if (r < 0)
1061 log_link_error_errno(link, r, "Failed to set MTU to %" PRIu16 ": %m", mtu);
1062 }
1063 }
1064
1065 if (link->network->dhcp_use_hostname) {
1066 const char *dhcpname = NULL;
1067 _cleanup_free_ char *hostname = NULL;
1068
1069 if (link->network->dhcp_hostname)
1070 dhcpname = link->network->dhcp_hostname;
1071 else
1072 (void) sd_dhcp_lease_get_hostname(lease, &dhcpname);
1073
1074 if (dhcpname) {
1075 r = shorten_overlong(dhcpname, &hostname);
1076 if (r < 0)
1077 log_link_warning_errno(link, r, "Unable to shorten overlong DHCP hostname '%s', ignoring: %m", dhcpname);
1078 if (r == 1)
1079 log_link_notice(link, "Overlong DHCP hostname received, shortened from '%s' to '%s'", dhcpname, hostname);
1080 }
1081
1082 if (hostname) {
1083 r = manager_set_hostname(link->manager, hostname);
1084 if (r < 0)
1085 log_link_error_errno(link, r, "Failed to set transient hostname to '%s': %m", hostname);
1086 }
1087 }
1088
1089 if (link->network->dhcp_use_timezone) {
1090 const char *tz = NULL;
1091
1092 (void) sd_dhcp_lease_get_timezone(link->dhcp_lease, &tz);
1093
1094 if (tz) {
1095 r = manager_set_timezone(link->manager, tz);
1096 if (r < 0)
1097 log_link_error_errno(link, r, "Failed to set timezone to '%s': %m", tz);
1098 }
1099 }
1100
1101 if (link->network->dhcp_use_6rd &&
1102 sd_dhcp_lease_has_6rd(link->dhcp_lease)) {
1103 r = dhcp4_pd_prefix_acquired(link);
1104 if (r < 0)
1105 return log_link_warning_errno(link, r, "Failed to process 6rd option: %m");
1106 }
1107
1108 return dhcp4_request_address_and_routes(link, true);
1109 }
1110
1111 static int dhcp_lease_ip_change(sd_dhcp_client *client, Link *link) {
1112 int r;
1113
1114 r = dhcp_lease_acquired(client, link);
1115 if (r < 0)
1116 (void) dhcp4_lease_lost(link);
1117
1118 return r;
1119 }
1120
1121 static int dhcp_server_is_filtered(Link *link, sd_dhcp_client *client) {
1122 sd_dhcp_lease *lease;
1123 struct in_addr addr;
1124 int r;
1125
1126 assert(link);
1127 assert(link->network);
1128 assert(client);
1129
1130 r = sd_dhcp_client_get_lease(client, &lease);
1131 if (r < 0)
1132 return log_link_error_errno(link, r, "Failed to get DHCP lease: %m");
1133
1134 r = sd_dhcp_lease_get_server_identifier(lease, &addr);
1135 if (r < 0)
1136 return log_link_debug_errno(link, r, "Failed to get DHCP server IP address: %m");
1137
1138 if (in4_address_is_filtered(&addr, link->network->dhcp_allow_listed_ip, link->network->dhcp_deny_listed_ip)) {
1139 if (DEBUG_LOGGING) {
1140 if (link->network->dhcp_allow_listed_ip)
1141 log_link_debug(link, "DHCPv4 server IP address "IPV4_ADDRESS_FMT_STR" not found in allow-list, ignoring offer.",
1142 IPV4_ADDRESS_FMT_VAL(addr));
1143 else
1144 log_link_debug(link, "DHCPv4 server IP address "IPV4_ADDRESS_FMT_STR" found in deny-list, ignoring offer.",
1145 IPV4_ADDRESS_FMT_VAL(addr));
1146 }
1147
1148 return true;
1149 }
1150
1151 return false;
1152 }
1153
1154 static int dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
1155 Link *link = ASSERT_PTR(userdata);
1156 int r;
1157
1158 assert(link->network);
1159 assert(link->manager);
1160
1161 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1162 return 0;
1163
1164 switch (event) {
1165 case SD_DHCP_CLIENT_EVENT_STOP:
1166 if (link->ipv4ll) {
1167 log_link_debug(link, "DHCP client is stopped. Acquiring IPv4 link-local address");
1168
1169 if (in4_addr_is_set(&link->network->ipv4ll_start_address)) {
1170 r = sd_ipv4ll_set_address(link->ipv4ll, &link->network->ipv4ll_start_address);
1171 if (r < 0)
1172 return log_link_warning_errno(link, r, "Could not set IPv4 link-local start address: %m");
1173 }
1174
1175 r = sd_ipv4ll_start(link->ipv4ll);
1176 if (r < 0 && r != -ESTALE) /* On exit, we cannot and should not start sd-ipv4ll. */
1177 return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
1178 }
1179
1180 if (FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP)) {
1181 log_link_notice(link, "DHCPv4 connection considered critical, ignoring request to reconfigure it.");
1182 return 0;
1183 }
1184
1185 if (link->dhcp_lease) {
1186 if (link->network->dhcp_send_release) {
1187 r = sd_dhcp_client_send_release(client);
1188 if (r < 0)
1189 log_link_full_errno(link,
1190 ERRNO_IS_DISCONNECT(r) ? LOG_DEBUG : LOG_WARNING,
1191 r, "Failed to send DHCP RELEASE, ignoring: %m");
1192 }
1193
1194 r = dhcp4_lease_lost(link);
1195 if (r < 0) {
1196 link_enter_failed(link);
1197 return r;
1198 }
1199 }
1200
1201 break;
1202 case SD_DHCP_CLIENT_EVENT_EXPIRED:
1203 if (FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP)) {
1204 log_link_notice(link, "DHCPv4 connection considered critical, ignoring request to reconfigure it.");
1205 return 0;
1206 }
1207
1208 if (link->dhcp_lease) {
1209 r = dhcp4_lease_lost(link);
1210 if (r < 0) {
1211 link_enter_failed(link);
1212 return r;
1213 }
1214 }
1215
1216 break;
1217 case SD_DHCP_CLIENT_EVENT_IP_CHANGE:
1218 if (FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP)) {
1219 log_link_notice(link, "DHCPv4 connection considered critical, ignoring request to reconfigure it.");
1220 return 0;
1221 }
1222
1223 r = dhcp_lease_ip_change(client, link);
1224 if (r < 0) {
1225 link_enter_failed(link);
1226 return r;
1227 }
1228
1229 break;
1230 case SD_DHCP_CLIENT_EVENT_RENEW:
1231 r = dhcp_lease_renew(client, link);
1232 if (r < 0) {
1233 link_enter_failed(link);
1234 return r;
1235 }
1236 break;
1237 case SD_DHCP_CLIENT_EVENT_IP_ACQUIRE:
1238 r = dhcp_lease_acquired(client, link);
1239 if (r < 0) {
1240 link_enter_failed(link);
1241 return r;
1242 }
1243 break;
1244 case SD_DHCP_CLIENT_EVENT_SELECTING:
1245 r = dhcp_server_is_filtered(link, client);
1246 if (r < 0) {
1247 link_enter_failed(link);
1248 return r;
1249 }
1250 if (r > 0)
1251 return -ENOMSG;
1252 break;
1253
1254 case SD_DHCP_CLIENT_EVENT_TRANSIENT_FAILURE:
1255 if (link->ipv4ll && !sd_ipv4ll_is_running(link->ipv4ll)) {
1256 log_link_debug(link, "Problems acquiring DHCP lease, acquiring IPv4 link-local address");
1257
1258 if (in4_addr_is_set(&link->network->ipv4ll_start_address)) {
1259 r = sd_ipv4ll_set_address(link->ipv4ll, &link->network->ipv4ll_start_address);
1260 if (r < 0)
1261 return log_link_warning_errno(link, r, "Could not set IPv4 link-local start address: %m");
1262 }
1263
1264 r = sd_ipv4ll_start(link->ipv4ll);
1265 if (r < 0)
1266 return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
1267 }
1268 break;
1269
1270 default:
1271 if (event < 0)
1272 log_link_warning_errno(link, event, "DHCP error: Client failed: %m");
1273 else
1274 log_link_warning(link, "DHCP unknown event: %i", event);
1275 break;
1276 }
1277
1278 return 0;
1279 }
1280
1281 static int dhcp4_set_hostname(Link *link) {
1282 _cleanup_free_ char *hostname = NULL;
1283 const char *hn;
1284 int r;
1285
1286 assert(link);
1287
1288 if (!link->network->dhcp_send_hostname)
1289 hn = NULL;
1290 else if (link->network->dhcp_hostname)
1291 hn = link->network->dhcp_hostname;
1292 else {
1293 r = gethostname_strict(&hostname);
1294 if (r < 0 && r != -ENXIO) /* ENXIO: no hostname set or hostname is "localhost" */
1295 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to get hostname: %m");
1296
1297 hn = hostname;
1298 }
1299
1300 r = sd_dhcp_client_set_hostname(link->dhcp_client, hn);
1301 if (r == -EINVAL && hostname)
1302 /* Ignore error when the machine's hostname is not suitable to send in DHCP packet. */
1303 log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set hostname from kernel hostname, ignoring: %m");
1304 else if (r < 0)
1305 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set hostname: %m");
1306
1307 return 0;
1308 }
1309
1310 static int dhcp4_set_client_identifier(Link *link) {
1311 int r;
1312
1313 assert(link);
1314 assert(link->network);
1315 assert(link->dhcp_client);
1316
1317 switch (link->network->dhcp_client_identifier) {
1318 case DHCP_CLIENT_ID_DUID: {
1319 /* If configured, apply user specified DUID and IAID */
1320 const DUID *duid = link_get_dhcp4_duid(link);
1321
1322 if (duid->raw_data_len == 0)
1323 switch (duid->type) {
1324 case DUID_TYPE_LLT:
1325 r = sd_dhcp_client_set_iaid_duid_llt(link->dhcp_client,
1326 link->network->dhcp_iaid_set,
1327 link->network->dhcp_iaid,
1328 duid->llt_time);
1329 break;
1330 case DUID_TYPE_LL:
1331 r = sd_dhcp_client_set_iaid_duid_ll(link->dhcp_client,
1332 link->network->dhcp_iaid_set,
1333 link->network->dhcp_iaid);
1334 break;
1335 case DUID_TYPE_EN:
1336 r = sd_dhcp_client_set_iaid_duid_en(link->dhcp_client,
1337 link->network->dhcp_iaid_set,
1338 link->network->dhcp_iaid);
1339 break;
1340 case DUID_TYPE_UUID:
1341 r = sd_dhcp_client_set_iaid_duid_uuid(link->dhcp_client,
1342 link->network->dhcp_iaid_set,
1343 link->network->dhcp_iaid);
1344 break;
1345 default:
1346 r = sd_dhcp_client_set_iaid_duid_raw(link->dhcp_client,
1347 link->network->dhcp_iaid_set,
1348 link->network->dhcp_iaid,
1349 duid->type, NULL, 0);
1350 }
1351 else
1352 r = sd_dhcp_client_set_iaid_duid_raw(link->dhcp_client,
1353 link->network->dhcp_iaid_set,
1354 link->network->dhcp_iaid,
1355 duid->type, duid->raw_data, duid->raw_data_len);
1356 if (r < 0)
1357 return r;
1358 break;
1359 }
1360 case DHCP_CLIENT_ID_MAC: {
1361 const uint8_t *hw_addr = link->hw_addr.bytes;
1362 size_t hw_addr_len = link->hw_addr.length;
1363
1364 if (link->iftype == ARPHRD_INFINIBAND && hw_addr_len == INFINIBAND_ALEN) {
1365 /* set_client_id expects only last 8 bytes of an IB address */
1366 hw_addr += INFINIBAND_ALEN - 8;
1367 hw_addr_len -= INFINIBAND_ALEN - 8;
1368 }
1369
1370 r = sd_dhcp_client_set_client_id(link->dhcp_client,
1371 link->iftype,
1372 hw_addr,
1373 hw_addr_len);
1374 if (r < 0)
1375 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set client ID: %m");
1376 break;
1377 }
1378 default:
1379 assert_not_reached();
1380 }
1381
1382 return 0;
1383 }
1384
1385 static int dhcp4_find_dynamic_address(Link *link, struct in_addr *ret) {
1386 Address *a;
1387
1388 assert(link);
1389 assert(link->network);
1390 assert(ret);
1391
1392 if (!FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
1393 return false;
1394
1395 SET_FOREACH(a, link->addresses) {
1396 if (a->source != NETWORK_CONFIG_SOURCE_FOREIGN)
1397 continue;
1398 if (a->family != AF_INET)
1399 continue;
1400 if (link_address_is_dynamic(link, a))
1401 break;
1402 }
1403
1404 if (!a)
1405 return false;
1406
1407 *ret = a->in_addr.in;
1408 return true;
1409 }
1410
1411 static int dhcp4_set_request_address(Link *link) {
1412 struct in_addr a;
1413
1414 assert(link);
1415 assert(link->network);
1416 assert(link->dhcp_client);
1417
1418 a = link->network->dhcp_request_address;
1419
1420 if (in4_addr_is_null(&a))
1421 (void) dhcp4_find_dynamic_address(link, &a);
1422
1423 if (in4_addr_is_null(&a))
1424 return 0;
1425
1426 log_link_debug(link, "DHCPv4 CLIENT: requesting %s.", IN4_ADDR_TO_STRING(&a));
1427 return sd_dhcp_client_set_request_address(link->dhcp_client, &a);
1428 }
1429
1430 static bool link_needs_dhcp_broadcast(Link *link) {
1431 const char *val;
1432 int r;
1433
1434 assert(link);
1435 assert(link->network);
1436
1437 /* Return the setting in DHCP[4].RequestBroadcast if specified. Otherwise return the device property
1438 * ID_NET_DHCP_BROADCAST setting, which may be set for interfaces requiring that the DHCPOFFER message
1439 * is being broadcast because they can't handle unicast messages while not fully configured.
1440 * If neither is set or a failure occurs, return false, which is the default for this flag.
1441 */
1442 r = link->network->dhcp_broadcast;
1443 if (r < 0 && link->dev && sd_device_get_property_value(link->dev, "ID_NET_DHCP_BROADCAST", &val) >= 0) {
1444 r = parse_boolean(val);
1445 if (r < 0)
1446 log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to parse ID_NET_DHCP_BROADCAST, ignoring: %m");
1447 else
1448 log_link_debug(link, "DHCPv4 CLIENT: Detected ID_NET_DHCP_BROADCAST='%d'.", r);
1449
1450 }
1451 return r == true;
1452 }
1453
1454 static bool link_dhcp4_ipv6_only_mode(Link *link) {
1455 assert(link);
1456 assert(link->network);
1457
1458 /* If it is explicitly specified, then honor the setting. */
1459 if (link->network->dhcp_ipv6_only_mode >= 0)
1460 return link->network->dhcp_ipv6_only_mode;
1461
1462 /* Defaults to false, until we support 464XLAT. See issue #30891. */
1463 return false;
1464 }
1465
1466 static int dhcp4_configure(Link *link) {
1467 sd_dhcp_option *send_option;
1468 void *request_options;
1469 int r;
1470
1471 assert(link);
1472 assert(link->network);
1473
1474 if (link->dhcp_client)
1475 return log_link_debug_errno(link, SYNTHETIC_ERRNO(EBUSY), "DHCPv4 client is already configured.");
1476
1477 r = sd_dhcp_client_new(&link->dhcp_client, link->network->dhcp_anonymize);
1478 if (r < 0)
1479 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to allocate DHCPv4 client: %m");
1480
1481 r = sd_dhcp_client_attach_event(link->dhcp_client, link->manager->event, 0);
1482 if (r < 0)
1483 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to attach event to DHCPv4 client: %m");
1484
1485 r = sd_dhcp_client_attach_device(link->dhcp_client, link->dev);
1486 if (r < 0)
1487 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to attach device: %m");
1488
1489 r = sd_dhcp_client_set_rapid_commit(link->dhcp_client, link->network->dhcp_use_rapid_commit);
1490 if (r < 0)
1491 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set rapid commit: %m");
1492
1493 r = sd_dhcp_client_set_mac(link->dhcp_client,
1494 link->hw_addr.bytes,
1495 link->bcast_addr.length > 0 ? link->bcast_addr.bytes : NULL,
1496 link->hw_addr.length, link->iftype);
1497 if (r < 0)
1498 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set MAC address: %m");
1499
1500 r = sd_dhcp_client_set_ifindex(link->dhcp_client, link->ifindex);
1501 if (r < 0)
1502 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set ifindex: %m");
1503
1504 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link);
1505 if (r < 0)
1506 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set callback: %m");
1507
1508 r = sd_dhcp_client_set_request_broadcast(link->dhcp_client, link_needs_dhcp_broadcast(link));
1509 if (r < 0)
1510 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for broadcast: %m");
1511
1512 r = dhcp_client_set_state_callback(link->dhcp_client, dhcp_client_callback_bus, link);
1513 if (r < 0)
1514 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set state change callback: %m");
1515
1516 if (link->mtu > 0) {
1517 r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
1518 if (r < 0)
1519 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set MTU: %m");
1520 }
1521
1522 if (!link->network->dhcp_anonymize) {
1523 r = dhcp4_set_request_address(link);
1524 if (r < 0)
1525 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set initial DHCPv4 address: %m");
1526
1527 if (link->network->dhcp_use_mtu) {
1528 r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_MTU_INTERFACE);
1529 if (r < 0)
1530 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for MTU: %m");
1531 }
1532
1533 if (link->network->dhcp_use_routes) {
1534 r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_STATIC_ROUTE);
1535 if (r < 0)
1536 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for static route: %m");
1537
1538 r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
1539 if (r < 0)
1540 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for classless static route: %m");
1541 }
1542
1543 if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
1544 r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_DOMAIN_SEARCH);
1545 if (r < 0)
1546 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for domain search list: %m");
1547 }
1548
1549 if (link->network->dhcp_use_ntp) {
1550 r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NTP_SERVER);
1551 if (r < 0)
1552 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for NTP server: %m");
1553 }
1554
1555 if (link->network->dhcp_use_sip) {
1556 r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_SIP_SERVER);
1557 if (r < 0)
1558 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for SIP server: %m");
1559 }
1560 if (link->network->dhcp_use_captive_portal) {
1561 r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_DHCP_CAPTIVE_PORTAL);
1562 if (r < 0)
1563 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for captive portal: %m");
1564 }
1565
1566 if (link->network->dhcp_use_timezone) {
1567 r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_TZDB_TIMEZONE);
1568 if (r < 0)
1569 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for timezone: %m");
1570 }
1571
1572 if (link->network->dhcp_use_6rd) {
1573 r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_6RD);
1574 if (r < 0)
1575 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for 6rd: %m");
1576 }
1577
1578 if (link_dhcp4_ipv6_only_mode(link)) {
1579 r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_IPV6_ONLY_PREFERRED);
1580 if (r < 0)
1581 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for IPv6-only preferred option: %m");
1582 }
1583
1584 SET_FOREACH(request_options, link->network->dhcp_request_options) {
1585 uint32_t option = PTR_TO_UINT32(request_options);
1586
1587 r = sd_dhcp_client_set_request_option(link->dhcp_client, option);
1588 if (r < 0)
1589 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for '%u': %m", option);
1590 }
1591
1592 ORDERED_HASHMAP_FOREACH(send_option, link->network->dhcp_client_send_options) {
1593 r = sd_dhcp_client_add_option(link->dhcp_client, send_option);
1594 if (r == -EEXIST)
1595 continue;
1596 if (r < 0)
1597 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set send option: %m");
1598 }
1599
1600 ORDERED_HASHMAP_FOREACH(send_option, link->network->dhcp_client_send_vendor_options) {
1601 r = sd_dhcp_client_add_vendor_option(link->dhcp_client, send_option);
1602 if (r == -EEXIST)
1603 continue;
1604 if (r < 0)
1605 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set send option: %m");
1606 }
1607
1608 r = dhcp4_set_hostname(link);
1609 if (r < 0)
1610 return r;
1611
1612 if (link->network->dhcp_vendor_class_identifier) {
1613 r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client,
1614 link->network->dhcp_vendor_class_identifier);
1615 if (r < 0)
1616 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set vendor class identifier: %m");
1617 }
1618
1619 if (link->network->dhcp_mudurl) {
1620 r = sd_dhcp_client_set_mud_url(link->dhcp_client, link->network->dhcp_mudurl);
1621 if (r < 0)
1622 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set MUD URL: %m");
1623 }
1624
1625 if (link->network->dhcp_user_class) {
1626 r = sd_dhcp_client_set_user_class(link->dhcp_client, link->network->dhcp_user_class);
1627 if (r < 0)
1628 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set user class: %m");
1629 }
1630 }
1631
1632 if (link->network->dhcp_client_port > 0) {
1633 r = sd_dhcp_client_set_client_port(link->dhcp_client, link->network->dhcp_client_port);
1634 if (r < 0)
1635 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set listen port: %m");
1636 }
1637 if (link->network->dhcp_port > 0) {
1638 r = sd_dhcp_client_set_port(link->dhcp_client, link->network->dhcp_port);
1639 if (r < 0)
1640 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set server port: %m");
1641 }
1642
1643 if (link->network->dhcp_max_attempts > 0) {
1644 r = sd_dhcp_client_set_max_attempts(link->dhcp_client, link->network->dhcp_max_attempts);
1645 if (r < 0)
1646 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set max attempts: %m");
1647 }
1648
1649 if (link->network->dhcp_ip_service_type >= 0) {
1650 r = sd_dhcp_client_set_service_type(link->dhcp_client, link->network->dhcp_ip_service_type);
1651 if (r < 0)
1652 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set IP service type: %m");
1653 }
1654
1655 if (link->network->dhcp_socket_priority_set) {
1656 r = sd_dhcp_client_set_socket_priority(link->dhcp_client, link->network->dhcp_socket_priority);
1657 if (r < 0)
1658 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set socket priority: %m");
1659 }
1660
1661 if (link->network->dhcp_fallback_lease_lifetime_usec > 0) {
1662 r = sd_dhcp_client_set_fallback_lease_lifetime(link->dhcp_client, link->network->dhcp_fallback_lease_lifetime_usec);
1663 if (r < 0)
1664 return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed set to lease lifetime: %m");
1665 }
1666
1667 return dhcp4_set_client_identifier(link);
1668 }
1669
1670 int dhcp4_update_mac(Link *link) {
1671 bool restart;
1672 int r;
1673
1674 assert(link);
1675
1676 if (!link->dhcp_client)
1677 return 0;
1678
1679 restart = sd_dhcp_client_is_running(link->dhcp_client);
1680
1681 r = sd_dhcp_client_stop(link->dhcp_client);
1682 if (r < 0)
1683 return r;
1684
1685 r = sd_dhcp_client_set_mac(link->dhcp_client,
1686 link->hw_addr.bytes,
1687 link->bcast_addr.length > 0 ? link->bcast_addr.bytes : NULL,
1688 link->hw_addr.length, link->iftype);
1689 if (r < 0)
1690 return r;
1691
1692 r = dhcp4_set_client_identifier(link);
1693 if (r < 0)
1694 return r;
1695
1696 if (restart) {
1697 r = dhcp4_start(link);
1698 if (r < 0)
1699 return r;
1700 }
1701
1702 return 0;
1703 }
1704
1705 int dhcp4_update_ipv6_connectivity(Link *link) {
1706 assert(link);
1707
1708 if (!link->network)
1709 return 0;
1710
1711 if (!link->network->dhcp_ipv6_only_mode)
1712 return 0;
1713
1714 if (!link->dhcp_client)
1715 return 0;
1716
1717 /* If the client is running, set the current connectivity. */
1718 if (sd_dhcp_client_is_running(link->dhcp_client))
1719 return sd_dhcp_client_set_ipv6_connectivity(link->dhcp_client, link_has_ipv6_connectivity(link));
1720
1721 /* If the client has been already stopped or not started yet, let's check the current connectivity
1722 * and start the client if necessary. */
1723 if (link_has_ipv6_connectivity(link))
1724 return 0;
1725
1726 return dhcp4_start_full(link, /* set_ipv6_connectivity = */ false);
1727 }
1728
1729 int dhcp4_start_full(Link *link, bool set_ipv6_connectivity) {
1730 int r;
1731
1732 assert(link);
1733 assert(link->network);
1734
1735 if (!link->dhcp_client)
1736 return 0;
1737
1738 if (!link_has_carrier(link))
1739 return 0;
1740
1741 if (sd_dhcp_client_is_running(link->dhcp_client) > 0)
1742 return 0;
1743
1744 r = sd_dhcp_client_start(link->dhcp_client);
1745 if (r < 0)
1746 return r;
1747
1748 if (set_ipv6_connectivity) {
1749 r = dhcp4_update_ipv6_connectivity(link);
1750 if (r < 0)
1751 return r;
1752 }
1753
1754 return 1;
1755 }
1756
1757 int dhcp4_renew(Link *link) {
1758 assert(link);
1759
1760 if (!link->dhcp_client)
1761 return 0;
1762
1763 /* The DHCPv4 client may have been stopped by the IPv6 only mode. Let's unconditionally restart the
1764 * client if it is not running. */
1765 if (!sd_dhcp_client_is_running(link->dhcp_client))
1766 return dhcp4_start(link);
1767
1768 /* The client may be waiting for IPv6 connectivity. Let's restart the client in that case. */
1769 if (dhcp_client_get_state(link->dhcp_client) != DHCP_STATE_BOUND)
1770 return sd_dhcp_client_interrupt_ipv6_only_mode(link->dhcp_client);
1771
1772 /* Otherwise, send a RENEW command. */
1773 return sd_dhcp_client_send_renew(link->dhcp_client);
1774 }
1775
1776 static int dhcp4_configure_duid(Link *link) {
1777 assert(link);
1778 assert(link->network);
1779
1780 if (link->network->dhcp_client_identifier != DHCP_CLIENT_ID_DUID)
1781 return 1;
1782
1783 return dhcp_configure_duid(link, link_get_dhcp4_duid(link));
1784 }
1785
1786 static int dhcp4_process_request(Request *req, Link *link, void *userdata) {
1787 int r;
1788
1789 assert(link);
1790
1791 if (!link_is_ready_to_configure(link, /* allow_unmanaged = */ false))
1792 return 0;
1793
1794 r = dhcp4_configure_duid(link);
1795 if (r <= 0)
1796 return r;
1797
1798 r = dhcp4_configure(link);
1799 if (r < 0)
1800 return log_link_warning_errno(link, r, "Failed to configure DHCPv4 client: %m");
1801
1802 r = dhcp4_start(link);
1803 if (r < 0)
1804 return log_link_warning_errno(link, r, "Failed to start DHCPv4 client: %m");
1805
1806 log_link_debug(link, "DHCPv4 client is configured%s.",
1807 r > 0 ? ", acquiring DHCPv4 lease" : "");
1808 return 1;
1809 }
1810
1811 int link_request_dhcp4_client(Link *link) {
1812 int r;
1813
1814 assert(link);
1815
1816 if (!link_dhcp4_enabled(link))
1817 return 0;
1818
1819 if (link->dhcp_client)
1820 return 0;
1821
1822 r = link_queue_request(link, REQUEST_TYPE_DHCP4_CLIENT, dhcp4_process_request, NULL);
1823 if (r < 0)
1824 return log_link_warning_errno(link, r, "Failed to request configuring of the DHCPv4 client: %m");
1825
1826 log_link_debug(link, "Requested configuring of the DHCPv4 client.");
1827 return 0;
1828 }
1829
1830 int config_parse_dhcp_max_attempts(
1831 const char *unit,
1832 const char *filename,
1833 unsigned line,
1834 const char *section,
1835 unsigned section_line,
1836 const char *lvalue,
1837 int ltype,
1838 const char *rvalue,
1839 void *data,
1840 void *userdata) {
1841
1842 Network *network = ASSERT_PTR(data);
1843 uint64_t a;
1844 int r;
1845
1846 assert(lvalue);
1847 assert(rvalue);
1848
1849 if (isempty(rvalue)) {
1850 network->dhcp_max_attempts = 0;
1851 return 0;
1852 }
1853
1854 if (streq(rvalue, "infinity")) {
1855 network->dhcp_max_attempts = UINT64_MAX;
1856 return 0;
1857 }
1858
1859 r = safe_atou64(rvalue, &a);
1860 if (r < 0) {
1861 log_syntax(unit, LOG_WARNING, filename, line, r,
1862 "Failed to parse DHCP maximum attempts, ignoring: %s", rvalue);
1863 return 0;
1864 }
1865
1866 if (a == 0) {
1867 log_syntax(unit, LOG_WARNING, filename, line, 0,
1868 "%s= must be positive integer or 'infinity', ignoring: %s", lvalue, rvalue);
1869 return 0;
1870 }
1871
1872 network->dhcp_max_attempts = a;
1873
1874 return 0;
1875 }
1876
1877 int config_parse_dhcp_ip_service_type(
1878 const char *unit,
1879 const char *filename,
1880 unsigned line,
1881 const char *section,
1882 unsigned section_line,
1883 const char *lvalue,
1884 int ltype,
1885 const char *rvalue,
1886 void *data,
1887 void *userdata) {
1888
1889 int *tos = ASSERT_PTR(data);
1890
1891 assert(filename);
1892 assert(lvalue);
1893 assert(rvalue);
1894
1895 if (isempty(rvalue))
1896 *tos = -1; /* use sd_dhcp_client's default (currently, CS6). */
1897 else if (streq(rvalue, "none"))
1898 *tos = 0;
1899 else if (streq(rvalue, "CS4"))
1900 *tos = IPTOS_CLASS_CS4;
1901 else if (streq(rvalue, "CS6"))
1902 *tos = IPTOS_CLASS_CS6;
1903 else
1904 log_syntax(unit, LOG_WARNING, filename, line, 0,
1905 "Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
1906
1907 return 0;
1908 }
1909
1910 int config_parse_dhcp_socket_priority(
1911 const char *unit,
1912 const char *filename,
1913 unsigned line,
1914 const char *section,
1915 unsigned section_line,
1916 const char *lvalue,
1917 int ltype,
1918 const char *rvalue,
1919 void *data,
1920 void *userdata) {
1921
1922 Network *network = ASSERT_PTR(data);
1923 int a, r;
1924
1925 assert(lvalue);
1926 assert(rvalue);
1927
1928 if (isempty(rvalue)) {
1929 network->dhcp_socket_priority_set = false;
1930 return 0;
1931 }
1932
1933 r = safe_atoi(rvalue, &a);
1934 if (r < 0) {
1935 log_syntax(unit, LOG_WARNING, filename, line, r,
1936 "Failed to parse socket priority, ignoring: %s", rvalue);
1937 return 0;
1938 }
1939
1940 network->dhcp_socket_priority_set = true;
1941 network->dhcp_socket_priority = a;
1942
1943 return 0;
1944 }
1945
1946 int config_parse_dhcp_fallback_lease_lifetime(
1947 const char *unit,
1948 const char *filename,
1949 unsigned line,
1950 const char *section,
1951 unsigned section_line,
1952 const char *lvalue,
1953 int ltype,
1954 const char *rvalue,
1955 void *data,
1956 void *userdata) {
1957
1958 Network *network = userdata;
1959
1960 assert(filename);
1961 assert(section);
1962 assert(lvalue);
1963 assert(rvalue);
1964 assert(data);
1965
1966 if (isempty(rvalue)) {
1967 network->dhcp_fallback_lease_lifetime_usec = 0;
1968 return 0;
1969 }
1970
1971 /* We accept only "forever" or "infinity". */
1972 if (!STR_IN_SET(rvalue, "forever", "infinity")) {
1973 log_syntax(unit, LOG_WARNING, filename, line, 0,
1974 "Invalid LeaseLifetime= value, ignoring: %s", rvalue);
1975 return 0;
1976 }
1977
1978 network->dhcp_fallback_lease_lifetime_usec = USEC_INFINITY;
1979
1980 return 0;
1981 }
1982
1983 int config_parse_dhcp_label(
1984 const char *unit,
1985 const char *filename,
1986 unsigned line,
1987 const char *section,
1988 unsigned section_line,
1989 const char *lvalue,
1990 int ltype,
1991 const char *rvalue,
1992 void *data,
1993 void *userdata) {
1994
1995 char **label = ASSERT_PTR(data);
1996
1997 assert(filename);
1998 assert(lvalue);
1999 assert(rvalue);
2000
2001 if (isempty(rvalue)) {
2002 *label = mfree(*label);
2003 return 0;
2004 }
2005
2006 if (!address_label_valid(rvalue)) {
2007 log_syntax(unit, LOG_WARNING, filename, line, 0,
2008 "Address label is too long or invalid, ignoring assignment: %s", rvalue);
2009 return 0;
2010 }
2011
2012 return free_and_strdup_warn(label, rvalue);
2013 }
2014
2015 static const char* const dhcp_client_identifier_table[_DHCP_CLIENT_ID_MAX] = {
2016 [DHCP_CLIENT_ID_MAC] = "mac",
2017 [DHCP_CLIENT_ID_DUID] = "duid",
2018 };
2019
2020 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier, DHCPClientIdentifier);
2021 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier, dhcp_client_identifier, DHCPClientIdentifier,
2022 "Failed to parse client identifier type");