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