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