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