1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include <linux/if_arp.h>
4 #include <linux/rtnetlink.h>
5 #include <netinet/in.h>
6 #include <netinet/ip.h>
9 #include "sd-dhcp-protocol.h"
10 #include "sd-ipv4ll.h"
12 #include "alloc-util.h"
13 #include "conf-parser.h"
14 #include "device-private.h"
15 #include "dhcp-client-internal.h"
16 #include "errno-util.h"
17 #include "hostname-setup.h"
18 #include "networkd-address.h"
19 #include "networkd-dhcp-prefix-delegation.h"
20 #include "networkd-dhcp4.h"
21 #include "networkd-dhcp4-bus.h"
22 #include "networkd-ipv4ll.h"
23 #include "networkd-link.h"
24 #include "networkd-manager.h"
25 #include "networkd-network.h"
26 #include "networkd-nexthop.h"
27 #include "networkd-ntp.h"
28 #include "networkd-queue.h"
29 #include "networkd-route.h"
30 #include "networkd-setlink.h"
31 #include "networkd-state-file.h"
32 #include "parse-util.h"
34 #include "socket-util.h"
35 #include "string-table.h"
36 #include "string-util.h"
39 void network_adjust_dhcp4(Network
*network
) {
42 if (!FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
))
45 if (network
->dhcp_use_gateway
< 0)
46 network
->dhcp_use_gateway
= network
->dhcp_use_routes
;
48 /* RFC7844 section 3.: MAY contain the Client Identifier option
49 * Section 3.5: clients MUST use client identifiers based solely on the link-layer address
50 * NOTE: Using MAC, as it does not reveal extra information, and some servers might not answer
51 * if this option is not sent */
52 if (network
->dhcp_anonymize
&&
53 network
->dhcp_client_identifier
>= 0 &&
54 network
->dhcp_client_identifier
!= DHCP_CLIENT_ID_MAC
) {
55 log_warning("%s: ClientIdentifier= is set, although Anonymize=yes. Using ClientIdentifier=mac.",
57 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
60 if (network
->dhcp_client_identifier
< 0)
61 network
->dhcp_client_identifier
= network
->dhcp_anonymize
? DHCP_CLIENT_ID_MAC
: network
->manager
->dhcp_client_identifier
;
63 /* By default, RapidCommit= is enabled when Anonymize=no and neither AllowList= nor DenyList= is specified. */
64 if (network
->dhcp_use_rapid_commit
< 0)
65 network
->dhcp_use_rapid_commit
=
66 !network
->dhcp_anonymize
&&
67 set_isempty(network
->dhcp_allow_listed_ip
) &&
68 set_isempty(network
->dhcp_deny_listed_ip
);
71 static int dhcp4_prefix_covers(
73 const struct in_addr
*in_prefix
,
74 uint8_t in_prefixlen
) {
76 struct in_addr prefix
;
81 assert(link
->dhcp_lease
);
84 /* Return true if the input address or address range is in the assigned network.
85 * E.g. if the DHCP server provides 192.168.0.100/24, then this returns true for the address or
86 * address range in 192.168.0.0/24, and returns false otherwise. */
88 r
= sd_dhcp_lease_get_prefix(link
->dhcp_lease
, &prefix
, &prefixlen
);
92 return in4_addr_prefix_covers_full(&prefix
, prefixlen
, in_prefix
, in_prefixlen
);
95 static int dhcp4_get_router(Link
*link
, struct in_addr
*ret
) {
96 const struct in_addr
*routers
;
100 assert(link
->dhcp_lease
);
103 r
= sd_dhcp_lease_get_router(link
->dhcp_lease
, &routers
);
107 /* The router option may provide multiple routers, We only use the first non-null address. */
109 FOREACH_ARRAY(router
, routers
, r
) {
110 if (in4_addr_is_null(router
))
120 static int dhcp4_get_classless_static_or_static_routes(Link
*link
, sd_dhcp_route
***ret_routes
, size_t *ret_num
) {
121 _cleanup_free_ sd_dhcp_route
**routes
= NULL
;
125 assert(link
->dhcp_lease
);
127 /* If the DHCP server returns both a Classless Static Routes option and a Static Routes option,
128 * the DHCP client MUST ignore the Static Routes option. */
130 r
= sd_dhcp_lease_get_classless_routes(link
->dhcp_lease
, &routes
);
134 *ret_routes
= TAKE_PTR(routes
);
137 return 1; /* classless */
138 } else if (r
!= -ENODATA
)
141 r
= sd_dhcp_lease_get_static_routes(link
->dhcp_lease
, &routes
);
147 *ret_routes
= TAKE_PTR(routes
);
150 return 0; /* static */
153 static int dhcp4_find_gateway_for_destination(
155 const struct in_addr
*destination
,
156 uint8_t prefixlength
,
157 struct in_addr
*ret
) {
159 _cleanup_free_ sd_dhcp_route
**routes
= NULL
;
162 uint8_t max_prefixlen
= UINT8_MAX
;
167 assert(link
->dhcp_lease
);
171 /* This tries to find the most suitable gateway for an address or address range.
172 * E.g. if the server provides the default gateway 192.168.0.1 and a classless static route for
173 * 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
174 * for 9.9.9.9/32. If the input address or address range is in the assigned network, then the null
175 * address will be returned. */
177 /* First, check with the assigned prefix, and if the destination is in the prefix, set the null
178 * address for the gateway, and return it unless more suitable static route is found. */
179 r
= dhcp4_prefix_covers(link
, destination
, prefixlength
);
183 r
= sd_dhcp_lease_get_prefix(link
->dhcp_lease
, NULL
, &max_prefixlen
);
187 gw
= (struct in_addr
) {};
190 r
= dhcp4_get_classless_static_or_static_routes(link
, &routes
, &n_routes
);
191 if (r
< 0 && r
!= -ENODATA
)
193 is_classless
= r
> 0;
195 /* First, find most suitable gateway. */
196 FOREACH_ARRAY(e
, routes
, n_routes
) {
200 r
= sd_dhcp_route_get_destination(*e
, &dst
);
204 r
= sd_dhcp_route_get_destination_prefix_length(*e
, &len
);
208 r
= in4_addr_prefix_covers_full(&dst
, len
, destination
, prefixlength
);
214 if (max_prefixlen
!= UINT8_MAX
&& max_prefixlen
> len
)
217 r
= sd_dhcp_route_get_gateway(*e
, &gw
);
224 /* The destination is reachable. Note, the gateway address returned here may be NULL. */
225 if (max_prefixlen
!= UINT8_MAX
) {
230 /* According to RFC 3442: If the DHCP server returns both a Classless Static Routes option and
231 * a Router option, the DHCP client MUST ignore the Router option. */
233 /* No matching static route is found, and the destination is not in the acquired network,
234 * falling back to the Router option. */
235 r
= dhcp4_get_router(link
, ret
);
242 return -EHOSTUNREACH
; /* Cannot reach the destination. */
245 static int dhcp4_remove_address_and_routes(Link
*link
, bool only_marked
) {
251 assert(link
->manager
);
253 SET_FOREACH(route
, link
->manager
->routes
) {
254 if (route
->source
!= NETWORK_CONFIG_SOURCE_DHCP4
)
256 if (route
->nexthop
.ifindex
!= link
->ifindex
)
258 if (only_marked
&& !route_is_marked(route
))
261 RET_GATHER(ret
, route_remove_and_cancel(route
, link
->manager
));
264 SET_FOREACH(address
, link
->addresses
) {
265 if (address
->source
!= NETWORK_CONFIG_SOURCE_DHCP4
)
267 if (only_marked
&& !address_is_marked(address
))
270 RET_GATHER(ret
, address_remove_and_cancel(address
, link
));
276 static int dhcp4_address_get(Link
*link
, Address
**ret
) {
281 SET_FOREACH(address
, link
->addresses
) {
282 if (address
->source
!= NETWORK_CONFIG_SOURCE_DHCP4
)
284 if (address_is_marked(address
))
295 static int dhcp4_address_ready_callback(Address
*address
) {
297 assert(address
->link
);
299 /* Do not call this again. */
300 address
->callback
= NULL
;
302 return dhcp4_check_ready(address
->link
);
305 int dhcp4_check_ready(Link
*link
) {
311 if (link
->dhcp4_messages
> 0) {
312 log_link_debug(link
, "%s(): DHCPv4 address and routes are not set.", __func__
);
316 if (dhcp4_address_get(link
, &address
) < 0) {
317 log_link_debug(link
, "%s(): DHCPv4 address is not set.", __func__
);
321 if (!address_is_ready(address
)) {
322 log_link_debug(link
, "%s(): DHCPv4 address is not ready.", __func__
);
323 address
->callback
= dhcp4_address_ready_callback
;
327 link
->dhcp4_configured
= true;
328 log_link_debug(link
, "DHCPv4 address and routes set.");
330 /* New address and routes are configured now. Let's release old lease. */
331 r
= dhcp4_remove_address_and_routes(link
, /* only_marked = */ true);
335 r
= link_request_stacked_netdevs(link
, NETDEV_LOCAL_ADDRESS_DHCP4
);
339 r
= sd_ipv4ll_stop(link
->ipv4ll
);
341 return log_link_warning_errno(link
, r
, "Failed to drop IPv4 link-local address: %m");
343 link_check_ready(link
);
347 static int dhcp4_route_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, Request
*req
, Link
*link
, Route
*route
) {
354 r
= route_configure_handler_internal(m
, req
, route
);
358 r
= dhcp4_check_ready(link
);
360 link_enter_failed(link
);
365 static int dhcp4_request_route(Route
*route
, Link
*link
) {
366 struct in_addr server
;
372 assert(link
->manager
);
373 assert(link
->network
);
374 assert(link
->dhcp_lease
);
376 r
= sd_dhcp_lease_get_server_identifier(link
->dhcp_lease
, &server
);
378 return log_link_debug_errno(link
, r
, "Failed to get DHCP server IP address: %m");
380 route
->source
= NETWORK_CONFIG_SOURCE_DHCP4
;
381 route
->provider
.in
= server
;
382 route
->family
= AF_INET
;
383 if (!route
->protocol_set
)
384 route
->protocol
= RTPROT_DHCP
;
385 if (!route
->priority_set
)
386 route
->priority
= link
->network
->dhcp_route_metric
;
387 if (!route
->table_set
)
388 route
->table
= link_get_dhcp4_route_table(link
);
389 r
= route_metric_set(&route
->metric
, RTAX_MTU
, link
->network
->dhcp_route_mtu
);
392 r
= route_metric_set(&route
->metric
, RTAX_INITCWND
, link
->network
->dhcp_initial_congestion_window
);
395 r
= route_metric_set(&route
->metric
, RTAX_INITRWND
, link
->network
->dhcp_advertised_receive_window
);
398 r
= route_metric_set(&route
->metric
, RTAX_QUICKACK
, link
->network
->dhcp_quickack
);
402 r
= route_adjust_nexthops(route
, link
);
406 if (route_get(link
->manager
, route
, &existing
) < 0) /* This is a new route. */
407 link
->dhcp4_configured
= false;
409 route_unmark(existing
);
411 return link_request_route(link
, route
, &link
->dhcp4_messages
, dhcp4_route_handler
);
414 static bool prefixroute_by_kernel(Link
*link
) {
415 return !link
->network
->dhcp_route_table_set
||
416 link
->network
->dhcp_route_table
== RT_TABLE_MAIN
;
419 static int dhcp4_request_prefix_route(Link
*link
, Route
*rt
) {
420 _cleanup_(route_unrefp
) Route
*route
= NULL
;
424 assert(link
->dhcp_lease
);
426 if (prefixroute_by_kernel(link
) && (!rt
|| !rt
->table_set
|| rt
->table
== RT_TABLE_MAIN
))
427 /* The prefix route in the main table will be created by the kernel. See dhcp4_update_address(). */
430 r
= route_new(&route
);
434 route
->scope
= RT_SCOPE_LINK
;
436 route
->table_set
= rt
->table_set
;
437 route
->table
= rt
->table
;
440 r
= sd_dhcp_lease_get_prefix(link
->dhcp_lease
, &route
->dst
.in
, &route
->dst_prefixlen
);
444 r
= sd_dhcp_lease_get_address(link
->dhcp_lease
, &route
->prefsrc
.in
);
448 return dhcp4_request_route(route
, link
);
451 static int dhcp4_request_route_to_gateway(Link
*link
, const Route
*rt
) {
452 _cleanup_(route_unrefp
) Route
*route
= NULL
;
453 struct in_addr address
;
457 assert(link
->dhcp_lease
);
460 if (in_addr_is_set(rt
->nexthop
.family
, &rt
->nexthop
.gw
) <= 0)
463 assert(rt
->nexthop
.family
== AF_INET
);
465 r
= sd_dhcp_lease_get_address(link
->dhcp_lease
, &address
);
469 r
= route_new(&route
);
473 route
->dst
.in
= rt
->nexthop
.gw
.in
;
474 route
->dst_prefixlen
= 32;
475 route
->prefsrc
.in
= address
;
476 route
->scope
= RT_SCOPE_LINK
;
477 route
->table
= rt
->table
;
478 route
->table_set
= rt
->table_set
;
480 return dhcp4_request_route(route
, link
);
483 static int dhcp4_request_route_auto(
486 const struct in_addr
*gw
) {
488 struct in_addr address
;
493 assert(link
->dhcp_lease
);
496 r
= sd_dhcp_lease_get_address(link
->dhcp_lease
, &address
);
500 if (in4_addr_is_localhost(&route
->dst
.in
)) {
501 if (in4_addr_is_set(gw
))
502 log_link_debug(link
, "DHCP: requested route destination "IPV4_ADDRESS_FMT_STR
"/%u is localhost, "
503 "ignoring gateway address "IPV4_ADDRESS_FMT_STR
,
504 IPV4_ADDRESS_FMT_VAL(route
->dst
.in
), route
->dst_prefixlen
, IPV4_ADDRESS_FMT_VAL(*gw
));
506 route
->scope
= RT_SCOPE_HOST
;
507 route
->nexthop
.family
= AF_UNSPEC
;
508 route
->nexthop
.gw
= IN_ADDR_NULL
;
509 route
->prefsrc
= IN_ADDR_NULL
;
511 } else if (in4_addr_equal(&route
->dst
.in
, &address
)) {
512 if (in4_addr_is_set(gw
))
513 log_link_debug(link
, "DHCP: requested route destination "IPV4_ADDRESS_FMT_STR
"/%u is equivalent to the acquired address, "
514 "ignoring gateway address "IPV4_ADDRESS_FMT_STR
,
515 IPV4_ADDRESS_FMT_VAL(route
->dst
.in
), route
->dst_prefixlen
, IPV4_ADDRESS_FMT_VAL(*gw
));
517 route
->scope
= RT_SCOPE_HOST
;
518 route
->nexthop
.family
= AF_UNSPEC
;
519 route
->nexthop
.gw
= IN_ADDR_NULL
;
520 route
->prefsrc
.in
= address
;
522 } else if (in4_addr_is_null(gw
)) {
523 r
= dhcp4_prefix_covers(link
, &route
->dst
.in
, route
->dst_prefixlen
);
526 if (r
== 0 && DEBUG_LOGGING
) {
527 struct in_addr prefix
;
530 r
= sd_dhcp_lease_get_prefix(link
->dhcp_lease
, &prefix
, &prefixlen
);
534 log_link_debug(link
, "DHCP: requested route destination "IPV4_ADDRESS_FMT_STR
"/%u is not in the assigned network "
535 IPV4_ADDRESS_FMT_STR
"/%u, but no gateway is specified, using 'link' scope.",
536 IPV4_ADDRESS_FMT_VAL(route
->dst
.in
), route
->dst_prefixlen
,
537 IPV4_ADDRESS_FMT_VAL(prefix
), prefixlen
);
540 route
->scope
= RT_SCOPE_LINK
;
541 route
->nexthop
.family
= AF_UNSPEC
;
542 route
->nexthop
.gw
= IN_ADDR_NULL
;
543 route
->prefsrc
.in
= address
;
546 route
->scope
= RT_SCOPE_UNIVERSE
;
547 route
->nexthop
.family
= AF_INET
;
548 route
->nexthop
.gw
.in
= *gw
;
549 route
->prefsrc
.in
= address
;
551 r
= dhcp4_request_route_to_gateway(link
, route
);
556 return dhcp4_request_route(route
, link
);
559 static int dhcp4_request_classless_static_or_static_routes(Link
*link
) {
560 _cleanup_free_ sd_dhcp_route
**routes
= NULL
;
565 assert(link
->dhcp_lease
);
567 if (!link
->network
->dhcp_use_routes
)
570 r
= dhcp4_get_classless_static_or_static_routes(link
, &routes
, &n_routes
);
576 FOREACH_ARRAY(e
, routes
, n_routes
) {
577 _cleanup_(route_unrefp
) Route
*route
= NULL
;
580 r
= route_new(&route
);
584 r
= sd_dhcp_route_get_gateway(*e
, &gw
);
588 r
= sd_dhcp_route_get_destination(*e
, &route
->dst
.in
);
592 r
= sd_dhcp_route_get_destination_prefix_length(*e
, &route
->dst_prefixlen
);
596 r
= dhcp4_request_route_auto(route
, link
, &gw
);
604 static int dhcp4_request_default_gateway(Link
*link
) {
605 _cleanup_(route_unrefp
) Route
*route
= NULL
;
606 struct in_addr address
, router
;
610 assert(link
->dhcp_lease
);
612 if (!link
->network
->dhcp_use_gateway
)
615 /* According to RFC 3442: If the DHCP server returns both a Classless Static Routes option and
616 * a Router option, the DHCP client MUST ignore the Router option. */
617 if (link
->network
->dhcp_use_routes
&&
618 dhcp4_get_classless_static_or_static_routes(link
, NULL
, NULL
) > 0)
621 r
= sd_dhcp_lease_get_address(link
->dhcp_lease
, &address
);
625 r
= dhcp4_get_router(link
, &router
);
627 log_link_debug(link
, "DHCP: No valid router address received from DHCP server.");
633 r
= route_new(&route
);
637 /* Next, add a default gateway. */
638 route
->nexthop
.family
= AF_INET
;
639 route
->nexthop
.gw
.in
= router
;
640 route
->prefsrc
.in
= address
;
642 /* The dhcp netmask may mask out the gateway. First, add an explicit route for the gateway host
643 * so that we can route no matter the netmask or existing kernel route tables. */
644 r
= dhcp4_request_route_to_gateway(link
, route
);
648 return dhcp4_request_route(route
, link
);
651 static int dhcp4_request_semi_static_routes(Link
*link
) {
656 assert(link
->dhcp_lease
);
657 assert(link
->network
);
659 HASHMAP_FOREACH(rt
, link
->network
->routes_by_section
) {
660 _cleanup_(route_unrefp
) Route
*route
= NULL
;
663 if (rt
->source
!= NETWORK_CONFIG_SOURCE_DHCP4
)
666 assert(rt
->family
== AF_INET
);
667 assert(rt
->nexthop
.family
== AF_INET
);
669 r
= dhcp4_find_gateway_for_destination(link
, &rt
->dst
.in
, rt
->dst_prefixlen
, &gw
);
670 if (r
== -EHOSTUNREACH
) {
671 log_link_debug_errno(link
, r
, "DHCP: Cannot find suitable gateway for destination %s of semi-static route, ignoring: %m",
672 IN4_ADDR_PREFIX_TO_STRING(&rt
->dst
.in
, rt
->dst_prefixlen
));
678 if (in4_addr_is_null(&gw
)) {
679 log_link_debug(link
, "DHCP: Destination %s of semi-static route is in the acquired network, skipping configuration.",
680 IN4_ADDR_PREFIX_TO_STRING(&rt
->dst
.in
, rt
->dst_prefixlen
));
684 r
= route_dup(rt
, NULL
, &route
);
688 route
->nexthop
.gw
.in
= gw
;
690 if (!route
->prefsrc_set
) {
691 r
= sd_dhcp_lease_get_address(link
->dhcp_lease
, &route
->prefsrc
.in
);
696 r
= dhcp4_request_prefix_route(link
, route
);
700 r
= dhcp4_request_route_to_gateway(link
, route
);
704 r
= dhcp4_request_route(route
, link
);
712 static int dhcp4_request_routes_to_servers(
714 const struct in_addr
*servers
,
720 assert(link
->dhcp_lease
);
721 assert(link
->network
);
722 assert(servers
|| n_servers
== 0);
724 FOREACH_ARRAY(dst
, servers
, n_servers
) {
725 _cleanup_(route_unrefp
) Route
*route
= NULL
;
728 if (in4_addr_is_null(dst
))
731 r
= dhcp4_find_gateway_for_destination(link
, dst
, 32, &gw
);
732 if (r
== -EHOSTUNREACH
) {
733 log_link_debug_errno(link
, r
, "DHCP: Cannot find suitable gateway for destination %s, ignoring: %m",
734 IN4_ADDR_PREFIX_TO_STRING(dst
, 32));
740 r
= route_new(&route
);
744 route
->dst
.in
= *dst
;
745 route
->dst_prefixlen
= 32;
747 r
= dhcp4_request_route_auto(route
, link
, &gw
);
755 static int dhcp4_request_routes_to_dns(Link
*link
) {
756 const struct in_addr
*dns
;
760 assert(link
->dhcp_lease
);
761 assert(link
->network
);
763 if (!link_get_use_dns(link
, NETWORK_CONFIG_SOURCE_DHCP4
) ||
764 !link
->network
->dhcp_routes_to_dns
)
767 r
= sd_dhcp_lease_get_dns(link
->dhcp_lease
, &dns
);
768 if (IN_SET(r
, 0, -ENODATA
))
773 return dhcp4_request_routes_to_servers(link
, dns
, r
);
776 static int dhcp4_request_routes_to_ntp(Link
*link
) {
777 const struct in_addr
*ntp
;
781 assert(link
->dhcp_lease
);
782 assert(link
->network
);
784 if (!link_get_use_ntp(link
, NETWORK_CONFIG_SOURCE_DHCP4
) ||
785 !link
->network
->dhcp_routes_to_ntp
)
788 r
= sd_dhcp_lease_get_ntp(link
->dhcp_lease
, &ntp
);
789 if (IN_SET(r
, 0, -ENODATA
))
794 return dhcp4_request_routes_to_servers(link
, ntp
, r
);
797 static int dhcp4_request_routes(Link
*link
) {
801 assert(link
->dhcp_lease
);
803 r
= dhcp4_request_prefix_route(link
, /* rt = */ NULL
);
805 return log_link_error_errno(link
, r
, "DHCP error: Could not request prefix route: %m");
807 r
= dhcp4_request_default_gateway(link
);
809 return log_link_error_errno(link
, r
, "DHCP error: Could not request default gateway: %m");
811 r
= dhcp4_request_classless_static_or_static_routes(link
);
813 return log_link_error_errno(link
, r
, "DHCP error: Could not request static routes: %m");
815 r
= dhcp4_request_semi_static_routes(link
);
817 return log_link_error_errno(link
, r
, "DHCP error: Could not request routes with Gateway=_dhcp4 setting: %m");
819 r
= dhcp4_request_routes_to_dns(link
);
821 return log_link_error_errno(link
, r
, "DHCP error: Could not request routes to DNS servers: %m");
823 r
= dhcp4_request_routes_to_ntp(link
);
825 return log_link_error_errno(link
, r
, "DHCP error: Could not request routes to NTP servers: %m");
830 static int dhcp_reset_mtu(Link
*link
) {
835 if (!link
->network
->dhcp_use_mtu
)
838 r
= link_request_to_set_mtu(link
, link
->original_mtu
);
840 return log_link_error_errno(link
, r
, "DHCP error: Could not queue request to reset MTU: %m");
845 static int dhcp_reset_hostname(Link
*link
) {
846 const char *hostname
;
851 if (!link
->network
->dhcp_use_hostname
)
854 hostname
= link
->network
->dhcp_hostname
;
856 (void) sd_dhcp_lease_get_hostname(link
->dhcp_lease
, &hostname
);
861 /* If a hostname was set due to the lease, then unset it now. */
862 r
= manager_set_hostname(link
->manager
, NULL
);
864 return log_link_error_errno(link
, r
, "DHCP error: Failed to reset transient hostname: %m");
869 int dhcp4_lease_lost(Link
*link
) {
873 assert(link
->dhcp_lease
);
874 assert(link
->network
);
876 log_link_info(link
, "DHCP lease lost");
878 link
->dhcp4_configured
= false;
880 if (link
->network
->dhcp_use_6rd
&&
881 sd_dhcp_lease_has_6rd(link
->dhcp_lease
))
882 dhcp4_pd_prefix_lost(link
);
884 RET_GATHER(r
, dhcp4_remove_address_and_routes(link
, /* only_marked = */ false));
885 RET_GATHER(r
, dhcp_reset_mtu(link
));
886 RET_GATHER(r
, dhcp_reset_hostname(link
));
888 link
->dhcp_lease
= sd_dhcp_lease_unref(link
->dhcp_lease
);
891 /* If one of the above failed. Do not request nexthops and routes. */
895 r
= link_request_static_nexthops(link
, true);
899 return link_request_static_routes(link
, true);
902 static int dhcp4_address_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, Request
*req
, Link
*link
, Address
*address
) {
908 r
= address_configure_handler_internal(m
, link
, address
);
912 r
= dhcp4_check_ready(link
);
914 link_enter_failed(link
);
919 static int dhcp4_request_address(Link
*link
, bool announce
) {
920 _cleanup_(address_unrefp
) Address
*addr
= NULL
;
921 struct in_addr address
, server
;
924 usec_t lifetime_usec
;
928 assert(link
->manager
);
929 assert(link
->network
);
930 assert(link
->dhcp_lease
);
932 r
= sd_dhcp_lease_get_address(link
->dhcp_lease
, &address
);
934 return log_link_warning_errno(link
, r
, "DHCP error: no address: %m");
936 r
= sd_dhcp_lease_get_prefix(link
->dhcp_lease
, NULL
, &prefixlen
);
938 return log_link_warning_errno(link
, r
, "DHCP error: no netmask: %m");
940 r
= sd_dhcp_lease_get_server_identifier(link
->dhcp_lease
, &server
);
942 return log_link_debug_errno(link
, r
, "DHCP error: failed to get DHCP server IP address: %m");
944 if (!FLAGS_SET(link
->network
->keep_configuration
, KEEP_CONFIGURATION_DYNAMIC
)) {
945 r
= sd_dhcp_lease_get_lifetime_timestamp(link
->dhcp_lease
, CLOCK_BOOTTIME
, &lifetime_usec
);
947 return log_link_warning_errno(link
, r
, "DHCP error: failed to get lifetime: %m");
949 lifetime_usec
= USEC_INFINITY
;
952 const struct in_addr
*router
;
954 r
= sd_dhcp_lease_get_router(link
->dhcp_lease
, &router
);
955 if (r
< 0 && r
!= -ENODATA
)
956 return log_link_error_errno(link
, r
, "DHCP error: Could not get gateway: %m");
958 if (r
> 0 && in4_addr_is_set(&router
[0]))
960 LOG_LINK_INTERFACE(link
),
961 LOG_LINK_MESSAGE(link
, "DHCPv4 address "IPV4_ADDRESS_FMT_STR
"/%u, gateway "IPV4_ADDRESS_FMT_STR
" acquired from "IPV4_ADDRESS_FMT_STR
,
962 IPV4_ADDRESS_FMT_VAL(address
),
964 IPV4_ADDRESS_FMT_VAL(router
[0]),
965 IPV4_ADDRESS_FMT_VAL(server
)),
966 LOG_ITEM("ADDRESS="IPV4_ADDRESS_FMT_STR
, IPV4_ADDRESS_FMT_VAL(address
)),
967 LOG_ITEM("PREFIXLEN=%u", prefixlen
),
968 LOG_ITEM("GATEWAY="IPV4_ADDRESS_FMT_STR
, IPV4_ADDRESS_FMT_VAL(router
[0])));
971 LOG_LINK_INTERFACE(link
),
972 LOG_LINK_MESSAGE(link
, "DHCPv4 address "IPV4_ADDRESS_FMT_STR
"/%u acquired from "IPV4_ADDRESS_FMT_STR
,
973 IPV4_ADDRESS_FMT_VAL(address
),
975 IPV4_ADDRESS_FMT_VAL(server
)),
976 LOG_ITEM("ADDRESS="IPV4_ADDRESS_FMT_STR
, IPV4_ADDRESS_FMT_VAL(address
)),
977 LOG_ITEM("PREFIXLEN=%u", prefixlen
));
980 r
= address_new(&addr
);
984 addr
->source
= NETWORK_CONFIG_SOURCE_DHCP4
;
985 addr
->provider
.in
= server
;
986 addr
->family
= AF_INET
;
987 addr
->in_addr
.in
.s_addr
= address
.s_addr
;
988 addr
->lifetime_preferred_usec
= lifetime_usec
;
989 addr
->lifetime_valid_usec
= lifetime_usec
;
990 addr
->prefixlen
= prefixlen
;
991 r
= sd_dhcp_lease_get_broadcast(link
->dhcp_lease
, &addr
->broadcast
);
992 if (r
< 0 && r
!= -ENODATA
)
993 return log_link_warning_errno(link
, r
, "DHCP: failed to get broadcast address: %m");
994 SET_FLAG(addr
->flags
, IFA_F_NOPREFIXROUTE
, !prefixroute_by_kernel(link
));
995 addr
->route_metric
= link
->network
->dhcp_route_metric
;
996 addr
->duplicate_address_detection
= link
->network
->dhcp_send_decline
? ADDRESS_FAMILY_IPV4
: ADDRESS_FAMILY_NO
;
998 r
= free_and_strdup_warn(&addr
->label
, link
->network
->dhcp_label
);
1002 r
= free_and_strdup_warn(&addr
->netlabel
, link
->network
->dhcp_netlabel
);
1006 if (address_get(link
, addr
, &existing
) < 0) /* The address is new. */
1007 link
->dhcp4_configured
= false;
1009 address_unmark(existing
);
1011 r
= link_request_address(link
, addr
, &link
->dhcp4_messages
,
1012 dhcp4_address_handler
, NULL
);
1014 return log_link_error_errno(link
, r
, "Failed to request DHCPv4 address: %m");
1019 static int dhcp4_request_address_and_routes(Link
*link
, bool announce
) {
1024 link_mark_addresses(link
, NETWORK_CONFIG_SOURCE_DHCP4
);
1025 manager_mark_routes(link
->manager
, link
, NETWORK_CONFIG_SOURCE_DHCP4
);
1027 r
= dhcp4_request_address(link
, announce
);
1031 r
= dhcp4_request_routes(link
);
1035 if (!link
->dhcp4_configured
) {
1036 link_set_state(link
, LINK_STATE_CONFIGURING
);
1037 link_check_ready(link
);
1043 static int dhcp_lease_renew(sd_dhcp_client
*client
, Link
*link
) {
1044 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*old_lease
= NULL
;
1045 sd_dhcp_lease
*lease
;
1049 assert(link
->network
);
1052 r
= sd_dhcp_client_get_lease(client
, &lease
);
1054 return log_link_warning_errno(link
, r
, "DHCP error: no lease: %m");
1056 old_lease
= TAKE_PTR(link
->dhcp_lease
);
1057 link
->dhcp_lease
= sd_dhcp_lease_ref(lease
);
1060 if (link
->network
->dhcp_use_6rd
) {
1061 if (sd_dhcp_lease_has_6rd(link
->dhcp_lease
)) {
1062 r
= dhcp4_pd_prefix_acquired(link
);
1064 return log_link_warning_errno(link
, r
, "Failed to process 6rd option: %m");
1065 } else if (sd_dhcp_lease_has_6rd(old_lease
))
1066 dhcp4_pd_prefix_lost(link
);
1069 return dhcp4_request_address_and_routes(link
, false);
1072 static int dhcp_lease_acquired(sd_dhcp_client
*client
, Link
*link
) {
1073 sd_dhcp_lease
*lease
;
1079 r
= sd_dhcp_client_get_lease(client
, &lease
);
1081 return log_link_error_errno(link
, r
, "DHCP error: No lease: %m");
1083 sd_dhcp_lease_unref(link
->dhcp_lease
);
1084 link
->dhcp_lease
= sd_dhcp_lease_ref(lease
);
1087 if (link
->network
->dhcp_use_mtu
) {
1090 r
= sd_dhcp_lease_get_mtu(lease
, &mtu
);
1092 r
= link_request_to_set_mtu(link
, mtu
);
1094 log_link_error_errno(link
, r
, "Failed to set MTU to %" PRIu16
": %m", mtu
);
1098 if (link
->network
->dhcp_use_hostname
) {
1099 const char *dhcpname
= NULL
;
1100 _cleanup_free_
char *hostname
= NULL
;
1102 if (link
->network
->dhcp_hostname
)
1103 dhcpname
= link
->network
->dhcp_hostname
;
1105 (void) sd_dhcp_lease_get_hostname(lease
, &dhcpname
);
1108 r
= shorten_overlong(dhcpname
, &hostname
);
1110 log_link_warning_errno(link
, r
, "Unable to shorten overlong DHCP hostname '%s', ignoring: %m", dhcpname
);
1112 log_link_notice(link
, "Overlong DHCP hostname received, shortened from '%s' to '%s'", dhcpname
, hostname
);
1116 r
= manager_set_hostname(link
->manager
, hostname
);
1118 log_link_error_errno(link
, r
, "Failed to set transient hostname to '%s': %m", hostname
);
1122 if (link
->network
->dhcp_use_timezone
) {
1123 const char *tz
= NULL
;
1125 (void) sd_dhcp_lease_get_timezone(link
->dhcp_lease
, &tz
);
1128 r
= manager_set_timezone(link
->manager
, tz
);
1130 log_link_error_errno(link
, r
, "Failed to set timezone to '%s': %m", tz
);
1134 if (link
->network
->dhcp_use_6rd
&&
1135 sd_dhcp_lease_has_6rd(link
->dhcp_lease
)) {
1136 r
= dhcp4_pd_prefix_acquired(link
);
1138 return log_link_warning_errno(link
, r
, "Failed to process 6rd option: %m");
1141 return dhcp4_request_address_and_routes(link
, true);
1144 static int dhcp_lease_ip_change(sd_dhcp_client
*client
, Link
*link
) {
1147 r
= dhcp_lease_acquired(client
, link
);
1149 (void) dhcp4_lease_lost(link
);
1154 static int dhcp_server_is_filtered(Link
*link
, sd_dhcp_client
*client
) {
1155 sd_dhcp_lease
*lease
;
1156 struct in_addr addr
;
1160 assert(link
->network
);
1163 r
= sd_dhcp_client_get_lease(client
, &lease
);
1165 return log_link_error_errno(link
, r
, "Failed to get DHCP lease: %m");
1167 r
= sd_dhcp_lease_get_server_identifier(lease
, &addr
);
1169 return log_link_debug_errno(link
, r
, "Failed to get DHCP server IP address: %m");
1171 if (in4_address_is_filtered(&addr
, link
->network
->dhcp_allow_listed_ip
, link
->network
->dhcp_deny_listed_ip
)) {
1172 if (link
->network
->dhcp_allow_listed_ip
)
1173 log_link_debug(link
, "DHCPv4 server IP address "IPV4_ADDRESS_FMT_STR
" not found in allow-list, ignoring offer.",
1174 IPV4_ADDRESS_FMT_VAL(addr
));
1176 log_link_debug(link
, "DHCPv4 server IP address "IPV4_ADDRESS_FMT_STR
" found in deny-list, ignoring offer.",
1177 IPV4_ADDRESS_FMT_VAL(addr
));
1185 static int dhcp4_handler(sd_dhcp_client
*client
, int event
, void *userdata
) {
1186 Link
*link
= ASSERT_PTR(userdata
);
1189 assert(link
->network
);
1190 assert(link
->manager
);
1192 if (IN_SET(link
->state
, LINK_STATE_FAILED
, LINK_STATE_LINGER
))
1196 case SD_DHCP_CLIENT_EVENT_STOP
:
1197 if (FLAGS_SET(link
->network
->keep_configuration
, KEEP_CONFIGURATION_DYNAMIC
)) {
1198 log_link_notice(link
, "DHCPv4 connection considered critical, ignoring request to reconfigure it.");
1202 r
= ipv4ll_start(link
);
1204 return log_link_warning_errno(link
, r
, "Could not acquire IPv4 link-local address: %m");
1206 log_link_debug(link
, "DHCP client is stopped. Acquiring IPv4 link-local address.");
1208 if (link
->dhcp_lease
) {
1209 if (link
->network
->dhcp_send_release
) {
1210 r
= sd_dhcp_client_send_release(client
);
1212 log_link_full_errno(link
,
1213 ERRNO_IS_DISCONNECT(r
) ? LOG_DEBUG
: LOG_WARNING
,
1214 r
, "Failed to send DHCP RELEASE, ignoring: %m");
1217 r
= dhcp4_lease_lost(link
);
1219 link_enter_failed(link
);
1225 case SD_DHCP_CLIENT_EVENT_EXPIRED
:
1226 if (FLAGS_SET(link
->network
->keep_configuration
, KEEP_CONFIGURATION_DYNAMIC
)) {
1227 log_link_notice(link
, "DHCPv4 connection considered critical, ignoring request to reconfigure it.");
1231 if (link
->dhcp_lease
) {
1232 r
= dhcp4_lease_lost(link
);
1234 link_enter_failed(link
);
1240 case SD_DHCP_CLIENT_EVENT_IP_CHANGE
:
1241 if (FLAGS_SET(link
->network
->keep_configuration
, KEEP_CONFIGURATION_DYNAMIC
)) {
1242 log_link_notice(link
, "DHCPv4 connection considered critical, ignoring request to reconfigure it.");
1246 r
= dhcp_lease_ip_change(client
, link
);
1248 link_enter_failed(link
);
1253 case SD_DHCP_CLIENT_EVENT_RENEW
:
1254 r
= dhcp_lease_renew(client
, link
);
1256 link_enter_failed(link
);
1260 case SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
:
1261 r
= dhcp_lease_acquired(client
, link
);
1263 link_enter_failed(link
);
1267 case SD_DHCP_CLIENT_EVENT_SELECTING
:
1268 r
= dhcp_server_is_filtered(link
, client
);
1270 link_enter_failed(link
);
1277 case SD_DHCP_CLIENT_EVENT_TRANSIENT_FAILURE
:
1278 r
= ipv4ll_start(link
);
1280 return log_link_warning_errno(link
, r
, "Could not acquire IPv4 link-local address: %m");
1282 log_link_debug(link
, "Problems acquiring DHCP lease, acquiring IPv4 link-local address");
1287 log_link_warning_errno(link
, event
, "DHCP error: Client failed: %m");
1289 log_link_warning(link
, "DHCP unknown event: %i", event
);
1295 static int dhcp4_set_hostname(Link
*link
) {
1296 _cleanup_free_
char *hostname
= NULL
;
1302 if (!link
->network
->dhcp_send_hostname
)
1304 else if (link
->network
->dhcp_hostname
)
1305 hn
= link
->network
->dhcp_hostname
;
1307 r
= gethostname_strict(&hostname
);
1308 if (r
< 0 && r
!= -ENXIO
) /* ENXIO: no hostname set or hostname is "localhost" */
1309 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to get hostname: %m");
1314 r
= sd_dhcp_client_set_hostname(link
->dhcp_client
, hn
);
1315 if (r
== -EINVAL
&& hostname
)
1316 /* Ignore error when the machine's hostname is not suitable to send in DHCP packet. */
1317 log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set hostname from kernel hostname, ignoring: %m");
1319 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set hostname: %m");
1324 static int dhcp4_set_client_identifier(Link
*link
) {
1328 assert(link
->network
);
1329 assert(link
->dhcp_client
);
1331 switch (link
->network
->dhcp_client_identifier
) {
1332 case DHCP_CLIENT_ID_DUID
: {
1333 /* If configured, apply user specified DUID and IAID */
1334 const DUID
*duid
= link_get_dhcp4_duid(link
);
1336 if (duid
->raw_data_len
== 0)
1337 switch (duid
->type
) {
1339 r
= sd_dhcp_client_set_iaid_duid_llt(link
->dhcp_client
,
1340 link
->network
->dhcp_iaid_set
,
1341 link
->network
->dhcp_iaid
,
1345 r
= sd_dhcp_client_set_iaid_duid_ll(link
->dhcp_client
,
1346 link
->network
->dhcp_iaid_set
,
1347 link
->network
->dhcp_iaid
);
1350 r
= sd_dhcp_client_set_iaid_duid_en(link
->dhcp_client
,
1351 link
->network
->dhcp_iaid_set
,
1352 link
->network
->dhcp_iaid
);
1354 case DUID_TYPE_UUID
:
1355 r
= sd_dhcp_client_set_iaid_duid_uuid(link
->dhcp_client
,
1356 link
->network
->dhcp_iaid_set
,
1357 link
->network
->dhcp_iaid
);
1360 r
= sd_dhcp_client_set_iaid_duid_raw(link
->dhcp_client
,
1361 link
->network
->dhcp_iaid_set
,
1362 link
->network
->dhcp_iaid
,
1363 duid
->type
, NULL
, 0);
1366 r
= sd_dhcp_client_set_iaid_duid_raw(link
->dhcp_client
,
1367 link
->network
->dhcp_iaid_set
,
1368 link
->network
->dhcp_iaid
,
1369 duid
->type
, duid
->raw_data
, duid
->raw_data_len
);
1374 case DHCP_CLIENT_ID_MAC
: {
1375 const uint8_t *hw_addr
= link
->hw_addr
.bytes
;
1376 size_t hw_addr_len
= link
->hw_addr
.length
;
1378 if (link
->iftype
== ARPHRD_INFINIBAND
&& hw_addr_len
== INFINIBAND_ALEN
) {
1379 /* set_client_id expects only last 8 bytes of an IB address */
1380 hw_addr
+= INFINIBAND_ALEN
- 8;
1381 hw_addr_len
-= INFINIBAND_ALEN
- 8;
1384 r
= sd_dhcp_client_set_client_id(link
->dhcp_client
,
1389 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set client ID: %m");
1393 assert_not_reached();
1399 static int dhcp4_set_request_address(Link
*link
) {
1401 assert(link
->network
);
1402 assert(link
->dhcp_client
);
1404 /* 1. Use already assigned address. */
1406 SET_FOREACH(a
, link
->addresses
) {
1407 if (a
->source
!= NETWORK_CONFIG_SOURCE_DHCP4
)
1410 assert(a
->family
== AF_INET
);
1412 log_link_debug(link
, "DHCPv4 CLIENT: requesting previously acquired address %s.",
1413 IN4_ADDR_TO_STRING(&a
->in_addr
.in
));
1414 return sd_dhcp_client_set_request_address(link
->dhcp_client
, &a
->in_addr
.in
);
1417 /* 2. If no address is assigned yet, use explicitly configured address. */
1418 if (in4_addr_is_set(&link
->network
->dhcp_request_address
)) {
1419 log_link_debug(link
, "DHCPv4 CLIENT: requesting address %s specified by RequestAddress=.",
1420 IN4_ADDR_TO_STRING(&link
->network
->dhcp_request_address
));
1421 return sd_dhcp_client_set_request_address(link
->dhcp_client
, &link
->network
->dhcp_request_address
);
1424 /* 3. If KeepConfiguration=dynamic, use a foreign dynamic address. */
1425 if (!FLAGS_SET(link
->network
->keep_configuration
, KEEP_CONFIGURATION_DYNAMIC
))
1428 SET_FOREACH(a
, link
->addresses
) {
1429 if (a
->source
!= NETWORK_CONFIG_SOURCE_FOREIGN
)
1431 if (a
->family
!= AF_INET
)
1433 if (!link_address_is_dynamic(link
, a
))
1436 log_link_debug(link
, "DHCPv4 CLIENT: requesting foreign dynamic address %s.",
1437 IN4_ADDR_TO_STRING(&a
->in_addr
.in
));
1438 return sd_dhcp_client_set_request_address(link
->dhcp_client
, &a
->in_addr
.in
);
1444 static bool link_needs_dhcp_broadcast(Link
*link
) {
1448 assert(link
->network
);
1450 /* Return the setting in DHCP[4].RequestBroadcast if specified. Otherwise return the device property
1451 * ID_NET_DHCP_BROADCAST setting, which may be set for interfaces requiring that the DHCPOFFER
1452 * message is being broadcast because they can't handle unicast messages while not fully configured.
1453 * If neither is set or a failure occurs, return false, which is the default for this flag. */
1455 r
= link
->network
->dhcp_broadcast
;
1462 r
= device_get_property_bool(link
->dev
, "ID_NET_DHCP_BROADCAST");
1465 log_link_warning_errno(link
, r
, "DHCPv4 CLIENT: Failed to get or parse ID_NET_DHCP_BROADCAST, ignoring: %m");
1470 log_link_debug(link
, "DHCPv4 CLIENT: Detected ID_NET_DHCP_BROADCAST='%d'.", r
);
1474 static bool link_dhcp4_ipv6_only_mode(Link
*link
) {
1476 assert(link
->network
);
1478 /* If it is explicitly specified, then honor the setting. */
1479 if (link
->network
->dhcp_ipv6_only_mode
>= 0)
1480 return link
->network
->dhcp_ipv6_only_mode
;
1482 /* Defaults to false, until we support 464XLAT. See issue #30891. */
1486 static int dhcp4_configure(Link
*link
) {
1487 sd_dhcp_option
*send_option
;
1488 void *request_options
;
1492 assert(link
->network
);
1494 if (link
->dhcp_client
)
1495 return log_link_debug_errno(link
, SYNTHETIC_ERRNO(EBUSY
), "DHCPv4 client is already configured.");
1497 r
= sd_dhcp_client_new(&link
->dhcp_client
, link
->network
->dhcp_anonymize
);
1499 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to allocate DHCPv4 client: %m");
1501 r
= sd_dhcp_client_set_bootp(link
->dhcp_client
, link
->network
->dhcp_use_bootp
);
1503 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to %s BOOTP: %m",
1504 enable_disable(link
->network
->dhcp_use_bootp
));
1506 r
= sd_dhcp_client_attach_event(link
->dhcp_client
, link
->manager
->event
, 0);
1508 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to attach event to DHCPv4 client: %m");
1510 r
= sd_dhcp_client_attach_device(link
->dhcp_client
, link
->dev
);
1512 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to attach device: %m");
1514 r
= sd_dhcp_client_set_rapid_commit(link
->dhcp_client
, link
->network
->dhcp_use_rapid_commit
);
1516 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set rapid commit: %m");
1518 r
= sd_dhcp_client_set_mac(link
->dhcp_client
,
1519 link
->hw_addr
.bytes
,
1520 link
->bcast_addr
.length
> 0 ? link
->bcast_addr
.bytes
: NULL
,
1521 link
->hw_addr
.length
, link
->iftype
);
1523 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set MAC address: %m");
1525 r
= sd_dhcp_client_set_ifindex(link
->dhcp_client
, link
->ifindex
);
1527 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set ifindex: %m");
1529 r
= sd_dhcp_client_set_callback(link
->dhcp_client
, dhcp4_handler
, link
);
1531 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set callback: %m");
1533 r
= sd_dhcp_client_set_request_broadcast(link
->dhcp_client
, link_needs_dhcp_broadcast(link
));
1535 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set request flag for broadcast: %m");
1537 r
= dhcp_client_set_state_callback(link
->dhcp_client
, dhcp_client_callback_bus
, link
);
1539 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set state change callback: %m");
1541 if (link
->mtu
> 0) {
1542 r
= sd_dhcp_client_set_mtu(link
->dhcp_client
, link
->mtu
);
1544 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set MTU: %m");
1547 if (!link
->network
->dhcp_anonymize
) {
1548 r
= dhcp4_set_request_address(link
);
1550 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set initial DHCPv4 address: %m");
1552 if (link
->network
->dhcp_use_mtu
) {
1553 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, SD_DHCP_OPTION_MTU_INTERFACE
);
1555 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set request flag for MTU: %m");
1558 if (link
->network
->dhcp_use_routes
) {
1559 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, SD_DHCP_OPTION_STATIC_ROUTE
);
1561 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set request flag for static route: %m");
1563 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE
);
1565 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set request flag for classless static route: %m");
1568 if (link_get_use_domains(link
, NETWORK_CONFIG_SOURCE_DHCP4
) > 0) {
1569 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, SD_DHCP_OPTION_DOMAIN_SEARCH
);
1571 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set request flag for domain search list: %m");
1574 if (link_get_use_ntp(link
, NETWORK_CONFIG_SOURCE_DHCP4
)) {
1575 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, SD_DHCP_OPTION_NTP_SERVER
);
1577 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set request flag for NTP server: %m");
1580 if (link
->network
->dhcp_use_sip
) {
1581 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, SD_DHCP_OPTION_SIP_SERVER
);
1583 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set request flag for SIP server: %m");
1586 if (link_get_use_dnr(link
, NETWORK_CONFIG_SOURCE_DHCP4
)) {
1587 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, SD_DHCP_OPTION_V4_DNR
);
1589 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set request flag for DNR: %m");
1592 if (link
->network
->dhcp_use_captive_portal
) {
1593 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, SD_DHCP_OPTION_DHCP_CAPTIVE_PORTAL
);
1595 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set request flag for captive portal: %m");
1598 if (link
->network
->dhcp_use_timezone
) {
1599 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, SD_DHCP_OPTION_TZDB_TIMEZONE
);
1601 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set request flag for timezone: %m");
1604 if (link
->network
->dhcp_use_6rd
) {
1605 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, SD_DHCP_OPTION_6RD
);
1607 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set request flag for 6rd: %m");
1610 if (link_dhcp4_ipv6_only_mode(link
)) {
1611 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, SD_DHCP_OPTION_IPV6_ONLY_PREFERRED
);
1613 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set request flag for IPv6-only preferred option: %m");
1616 SET_FOREACH(request_options
, link
->network
->dhcp_request_options
) {
1617 uint32_t option
= PTR_TO_UINT32(request_options
);
1619 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, option
);
1621 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set request flag for '%u': %m", option
);
1624 ORDERED_HASHMAP_FOREACH(send_option
, link
->network
->dhcp_client_send_options
) {
1625 r
= sd_dhcp_client_add_option(link
->dhcp_client
, send_option
);
1629 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set send option: %m");
1632 ORDERED_HASHMAP_FOREACH(send_option
, link
->network
->dhcp_client_send_vendor_options
) {
1633 r
= sd_dhcp_client_add_vendor_option(link
->dhcp_client
, send_option
);
1637 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set send option: %m");
1640 r
= dhcp4_set_hostname(link
);
1644 if (link
->network
->dhcp_vendor_class_identifier
) {
1645 r
= sd_dhcp_client_set_vendor_class_identifier(link
->dhcp_client
,
1646 link
->network
->dhcp_vendor_class_identifier
);
1648 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set vendor class identifier: %m");
1651 if (link
->network
->dhcp_mudurl
) {
1652 r
= sd_dhcp_client_set_mud_url(link
->dhcp_client
, link
->network
->dhcp_mudurl
);
1654 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set MUD URL: %m");
1657 if (link
->network
->dhcp_user_class
) {
1658 r
= sd_dhcp_client_set_user_class(link
->dhcp_client
, link
->network
->dhcp_user_class
);
1660 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set user class: %m");
1664 if (link
->network
->dhcp_client_port
> 0) {
1665 r
= sd_dhcp_client_set_client_port(link
->dhcp_client
, link
->network
->dhcp_client_port
);
1667 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set listen port: %m");
1669 if (link
->network
->dhcp_port
> 0) {
1670 r
= sd_dhcp_client_set_port(link
->dhcp_client
, link
->network
->dhcp_port
);
1672 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set server port: %m");
1675 if (link
->network
->dhcp_max_attempts
> 0) {
1676 r
= sd_dhcp_client_set_max_attempts(link
->dhcp_client
, link
->network
->dhcp_max_attempts
);
1678 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set max attempts: %m");
1681 if (link
->network
->dhcp_ip_service_type
>= 0) {
1682 r
= sd_dhcp_client_set_service_type(link
->dhcp_client
, link
->network
->dhcp_ip_service_type
);
1684 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set IP service type: %m");
1687 if (link
->network
->dhcp_socket_priority_set
) {
1688 r
= sd_dhcp_client_set_socket_priority(link
->dhcp_client
, link
->network
->dhcp_socket_priority
);
1690 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed to set socket priority: %m");
1693 if (link
->network
->dhcp_fallback_lease_lifetime_usec
> 0) {
1694 r
= sd_dhcp_client_set_fallback_lease_lifetime(link
->dhcp_client
, link
->network
->dhcp_fallback_lease_lifetime_usec
);
1696 return log_link_debug_errno(link
, r
, "DHCPv4 CLIENT: Failed set to lease lifetime: %m");
1699 return dhcp4_set_client_identifier(link
);
1702 int dhcp4_update_mac(Link
*link
) {
1708 if (!link
->dhcp_client
)
1711 restart
= sd_dhcp_client_is_running(link
->dhcp_client
);
1713 r
= sd_dhcp_client_stop(link
->dhcp_client
);
1717 r
= sd_dhcp_client_set_mac(link
->dhcp_client
,
1718 link
->hw_addr
.bytes
,
1719 link
->bcast_addr
.length
> 0 ? link
->bcast_addr
.bytes
: NULL
,
1720 link
->hw_addr
.length
, link
->iftype
);
1724 r
= dhcp4_set_client_identifier(link
);
1729 r
= dhcp4_start(link
);
1737 int dhcp4_update_ipv6_connectivity(Link
*link
) {
1743 if (!link
->network
->dhcp_ipv6_only_mode
)
1746 if (!link
->dhcp_client
)
1749 /* If the client is running, set the current connectivity. */
1750 if (sd_dhcp_client_is_running(link
->dhcp_client
))
1751 return sd_dhcp_client_set_ipv6_connectivity(link
->dhcp_client
, link_has_ipv6_connectivity(link
));
1753 /* If the client has been already stopped or not started yet, let's check the current connectivity
1754 * and start the client if necessary. */
1755 if (link_has_ipv6_connectivity(link
))
1758 return dhcp4_start_full(link
, /* set_ipv6_connectivity = */ false);
1761 int dhcp4_start_full(Link
*link
, bool set_ipv6_connectivity
) {
1765 assert(link
->network
);
1767 if (!link
->dhcp_client
)
1770 if (!link_has_carrier(link
))
1773 if (sd_dhcp_client_is_running(link
->dhcp_client
) > 0)
1776 r
= sd_dhcp_client_start(link
->dhcp_client
);
1780 if (set_ipv6_connectivity
) {
1781 r
= dhcp4_update_ipv6_connectivity(link
);
1789 int dhcp4_renew(Link
*link
) {
1792 if (!link
->dhcp_client
)
1795 /* The DHCPv4 client may have been stopped by the IPv6 only mode. Let's unconditionally restart the
1796 * client if it is not running. */
1797 if (!sd_dhcp_client_is_running(link
->dhcp_client
))
1798 return dhcp4_start(link
);
1800 /* The client may be waiting for IPv6 connectivity. Let's restart the client in that case. */
1801 if (dhcp_client_get_state(link
->dhcp_client
) != DHCP_STATE_BOUND
)
1802 return sd_dhcp_client_interrupt_ipv6_only_mode(link
->dhcp_client
);
1804 /* Otherwise, send a RENEW command. */
1805 return sd_dhcp_client_send_renew(link
->dhcp_client
);
1808 static int dhcp4_configure_duid(Link
*link
) {
1810 assert(link
->network
);
1812 if (link
->network
->dhcp_client_identifier
!= DHCP_CLIENT_ID_DUID
)
1815 return dhcp_configure_duid(link
, link_get_dhcp4_duid(link
));
1818 static int dhcp4_process_request(Request
*req
, Link
*link
, void *userdata
) {
1823 if (!link_is_ready_to_configure(link
, /* allow_unmanaged = */ false))
1826 r
= dhcp4_configure_duid(link
);
1830 r
= dhcp4_configure(link
);
1832 return log_link_warning_errno(link
, r
, "Failed to configure DHCPv4 client: %m");
1834 r
= dhcp4_start(link
);
1836 return log_link_warning_errno(link
, r
, "Failed to start DHCPv4 client: %m");
1838 log_link_debug(link
, "DHCPv4 client is configured%s.",
1839 r
> 0 ? ", acquiring DHCPv4 lease" : "");
1843 int link_request_dhcp4_client(Link
*link
) {
1848 if (!link_dhcp4_enabled(link
))
1851 if (link
->dhcp_client
)
1854 r
= link_queue_request(link
, REQUEST_TYPE_DHCP4_CLIENT
, dhcp4_process_request
, NULL
);
1856 return log_link_warning_errno(link
, r
, "Failed to request configuring of the DHCPv4 client: %m");
1858 log_link_debug(link
, "Requested configuring of the DHCPv4 client.");
1862 int link_drop_dhcp4_config(Link
*link
, Network
*network
) {
1866 assert(link
->network
);
1868 if (link
->network
== network
)
1869 return 0; /* .network file is unchanged. It is not necessary to reconfigure the client. */
1871 if (!link_dhcp4_enabled(link
)) {
1872 /* DHCP client is disabled. Stop the client if it is running and drop the lease. */
1873 ret
= sd_dhcp_client_stop(link
->dhcp_client
);
1875 /* Also explicitly drop DHCPv4 address and routes. Why? This is for the case when the DHCPv4
1876 * client was enabled on the previous invocation of networkd, but when it is restarted, a new
1877 * .network file may match to the interface, and DHCPv4 client may be disabled. In that case,
1878 * the DHCPv4 client is not running, hence sd_dhcp_client_stop() in the above does nothing. */
1879 RET_GATHER(ret
, dhcp4_remove_address_and_routes(link
, /* only_marked = */ false));
1882 if (link
->dhcp_client
&& link
->network
->dhcp_use_bootp
&&
1883 network
&& !network
->dhcp_use_bootp
&& network
->dhcp_send_release
) {
1884 /* If the client was enabled as a DHCP client, and is now enabled as a BOOTP client, release
1885 * the previous lease. Note, this can be easily fail, e.g. when the interface is down. Hence,
1886 * ignore any failures here. */
1887 r
= sd_dhcp_client_send_release(link
->dhcp_client
);
1889 log_link_full_errno(link
, ERRNO_IS_DISCONNECT(r
) ? LOG_DEBUG
: LOG_WARNING
, r
,
1890 "Failed to send DHCP RELEASE, ignoring: %m");
1893 /* Even if the client is currently enabled and also enabled in the new .network file, detailed
1894 * settings for the client may be different. Let's unref() the client. But do not unref() the lease.
1895 * it will be unref()ed later when a new lease is acquired. */
1896 link
->dhcp_client
= sd_dhcp_client_unref(link
->dhcp_client
);
1900 int config_parse_dhcp_max_attempts(
1902 const char *filename
,
1904 const char *section
,
1905 unsigned section_line
,
1912 Network
*network
= ASSERT_PTR(data
);
1919 if (isempty(rvalue
)) {
1920 network
->dhcp_max_attempts
= 0;
1924 if (streq(rvalue
, "infinity")) {
1925 network
->dhcp_max_attempts
= UINT64_MAX
;
1929 r
= safe_atou64(rvalue
, &a
);
1931 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1932 "Failed to parse DHCP maximum attempts, ignoring: %s", rvalue
);
1937 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1938 "%s= must be positive integer or 'infinity', ignoring: %s", lvalue
, rvalue
);
1942 network
->dhcp_max_attempts
= a
;
1947 int config_parse_dhcp_ip_service_type(
1949 const char *filename
,
1951 const char *section
,
1952 unsigned section_line
,
1959 int *tos
= ASSERT_PTR(data
);
1965 if (isempty(rvalue
))
1966 *tos
= -1; /* use sd_dhcp_client's default (currently, CS6). */
1967 else if (streq(rvalue
, "none"))
1969 else if (streq(rvalue
, "CS4"))
1970 *tos
= IPTOS_CLASS_CS4
;
1971 else if (streq(rvalue
, "CS6"))
1972 *tos
= IPTOS_CLASS_CS6
;
1974 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1975 "Failed to parse %s=, ignoring assignment: %s", lvalue
, rvalue
);
1980 int config_parse_dhcp_socket_priority(
1982 const char *filename
,
1984 const char *section
,
1985 unsigned section_line
,
1992 Network
*network
= ASSERT_PTR(data
);
1998 if (isempty(rvalue
)) {
1999 network
->dhcp_socket_priority_set
= false;
2003 r
= safe_atoi(rvalue
, &a
);
2005 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
2006 "Failed to parse socket priority, ignoring: %s", rvalue
);
2010 network
->dhcp_socket_priority_set
= true;
2011 network
->dhcp_socket_priority
= a
;
2016 int config_parse_dhcp_fallback_lease_lifetime(
2018 const char *filename
,
2020 const char *section
,
2021 unsigned section_line
,
2028 Network
*network
= userdata
;
2036 if (isempty(rvalue
)) {
2037 network
->dhcp_fallback_lease_lifetime_usec
= 0;
2041 /* We accept only "forever" or "infinity". */
2042 if (!STR_IN_SET(rvalue
, "forever", "infinity")) {
2043 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
2044 "Invalid LeaseLifetime= value, ignoring: %s", rvalue
);
2048 network
->dhcp_fallback_lease_lifetime_usec
= USEC_INFINITY
;
2053 int config_parse_dhcp_label(
2055 const char *filename
,
2057 const char *section
,
2058 unsigned section_line
,
2065 char **label
= ASSERT_PTR(data
);
2071 if (isempty(rvalue
)) {
2072 *label
= mfree(*label
);
2076 if (!address_label_valid(rvalue
)) {
2077 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
2078 "Address label is too long or invalid, ignoring assignment: %s", rvalue
);
2082 return free_and_strdup_warn(label
, rvalue
);
2085 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
2086 [DHCP_CLIENT_ID_MAC
] = "mac",
2087 [DHCP_CLIENT_ID_DUID
] = "duid",
2090 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
2091 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
);