1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include <netinet/in.h>
4 #include <netinet/ip.h>
6 #include <linux/if_arp.h>
9 #include "alloc-util.h"
10 #include "dhcp-client-internal.h"
11 #include "hostname-setup.h"
12 #include "hostname-util.h"
13 #include "parse-util.h"
14 #include "network-internal.h"
15 #include "networkd-address.h"
16 #include "networkd-dhcp4.h"
17 #include "networkd-link.h"
18 #include "networkd-manager.h"
19 #include "networkd-network.h"
20 #include "networkd-state-file.h"
21 #include "string-table.h"
23 #include "sysctl-util.h"
26 static int dhcp4_update_address(Link
*link
, bool announce
);
27 static int dhcp4_remove_all(Link
*link
);
29 void network_adjust_dhcp4(Network
*network
) {
32 if (!FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
))
35 if (network
->dhcp_use_gateway
< 0)
36 network
->dhcp_use_gateway
= network
->dhcp_use_routes
;
38 /* RFC7844 section 3.: MAY contain the Client Identifier option
39 * Section 3.5: clients MUST use client identifiers based solely on the link-layer address
40 * NOTE: Using MAC, as it does not reveal extra information, and some servers might not answer
41 * if this option is not sent */
42 if (network
->dhcp_anonymize
&&
43 network
->dhcp_client_identifier
>= 0 &&
44 network
->dhcp_client_identifier
!= DHCP_CLIENT_ID_MAC
) {
45 log_warning("%s: ClientIdentifier= is set, although Anonymize=yes. Using ClientIdentifier=mac.",
47 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
50 if (network
->dhcp_client_identifier
< 0)
51 network
->dhcp_client_identifier
= network
->dhcp_anonymize
? DHCP_CLIENT_ID_MAC
: DHCP_CLIENT_ID_DUID
;
54 static int dhcp4_release_old_lease(Link
*link
) {
60 if (!link
->dhcp_address_old
&& set_isempty(link
->dhcp_routes_old
))
63 log_link_debug(link
, "Removing old DHCPv4 address and routes.");
65 SET_FOREACH(route
, link
->dhcp_routes_old
) {
66 k
= route_remove(route
, NULL
, link
, NULL
);
71 if (link
->dhcp_address_old
) {
72 k
= address_remove(link
->dhcp_address_old
, link
, NULL
);
80 static void dhcp4_check_ready(Link
*link
) {
83 if (link
->network
->dhcp_send_decline
&& !link
->dhcp4_address_bind
)
86 if (link
->dhcp4_messages
> 0)
89 link
->dhcp4_configured
= true;
91 /* New address and routes are configured now. Let's release old lease. */
92 r
= dhcp4_release_old_lease(link
);
94 link_enter_failed(link
);
98 r
= sd_ipv4ll_stop(link
->ipv4ll
);
100 log_link_warning_errno(link
, r
, "Failed to drop IPv4 link-local address, ignoring: %m");
102 link_check_ready(link
);
105 static int dhcp4_route_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, Link
*link
) {
109 assert(link
->dhcp4_messages
> 0);
111 link
->dhcp4_messages
--;
113 if (IN_SET(link
->state
, LINK_STATE_FAILED
, LINK_STATE_LINGER
))
116 r
= sd_netlink_message_get_errno(m
);
117 if (r
== -ENETUNREACH
&& !link
->dhcp4_route_retrying
) {
119 /* It seems kernel does not support that the prefix route cannot be configured with
120 * route table. Let's once drop the config and reconfigure them later. */
122 log_link_message_debug_errno(link
, m
, r
, "Could not set DHCPv4 route, retrying later");
123 link
->dhcp4_route_failed
= true;
124 link
->manager
->dhcp4_prefix_root_cannot_set_table
= true;
125 } else if (r
< 0 && r
!= -EEXIST
) {
126 log_link_message_warning_errno(link
, m
, r
, "Could not set DHCPv4 route");
127 link_enter_failed(link
);
131 if (link
->dhcp4_messages
== 0 && link
->dhcp4_route_failed
) {
132 link
->dhcp4_route_failed
= false;
133 link
->dhcp4_route_retrying
= true;
135 r
= dhcp4_remove_all(link
);
137 link_enter_failed(link
);
141 dhcp4_check_ready(link
);
146 static int route_scope_from_address(const Route
*route
, const struct in_addr
*self_addr
) {
150 if (in4_addr_is_localhost(&route
->dst
.in
) ||
151 (in4_addr_is_set(self_addr
) && in4_addr_equal(&route
->dst
.in
, self_addr
)))
152 return RT_SCOPE_HOST
;
153 else if (in4_addr_is_null(&route
->gw
.in
))
154 return RT_SCOPE_LINK
;
156 return RT_SCOPE_UNIVERSE
;
159 static bool link_prefixroute(Link
*link
) {
160 return !link
->network
->dhcp_route_table_set
||
161 link
->network
->dhcp_route_table
== RT_TABLE_MAIN
||
162 link
->manager
->dhcp4_prefix_root_cannot_set_table
;
165 static int dhcp_route_configure(Route
*route
, Link
*link
) {
172 r
= route_configure(route
, link
, dhcp4_route_handler
, &ret
);
174 return log_link_error_errno(link
, r
, "Failed to set DHCPv4 route: %m");
176 link
->dhcp4_messages
++;
178 r
= set_ensure_put(&link
->dhcp_routes
, &route_hash_ops
, ret
);
180 return log_link_error_errno(link
, r
, "Failed to store DHCPv4 route: %m");
182 (void) set_remove(link
->dhcp_routes_old
, ret
);
187 static int link_set_dns_routes(Link
*link
, const struct in_addr
*address
) {
188 const struct in_addr
*dns
;
193 assert(link
->dhcp_lease
);
194 assert(link
->network
);
196 if (!link
->network
->dhcp_use_dns
||
197 !link
->network
->dhcp_routes_to_dns
)
200 n
= sd_dhcp_lease_get_dns(link
->dhcp_lease
, &dns
);
201 if (IN_SET(n
, 0, -ENODATA
))
204 return log_link_warning_errno(link
, n
, "DHCP error: could not get DNS servers: %m");
206 table
= link_get_dhcp_route_table(link
);
208 for (int i
= 0; i
< n
; i
++) {
209 _cleanup_(route_freep
) Route
*route
= NULL
;
211 r
= route_new(&route
);
213 return log_link_error_errno(link
, r
, "Could not allocate route: %m");
215 /* Set routes to DNS servers. */
217 route
->family
= AF_INET
;
218 route
->dst
.in
= dns
[i
];
219 route
->dst_prefixlen
= 32;
220 route
->prefsrc
.in
= *address
;
221 route
->scope
= RT_SCOPE_LINK
;
222 route
->protocol
= RTPROT_DHCP
;
223 route
->priority
= link
->network
->dhcp_route_metric
;
224 route
->table
= table
;
226 r
= dhcp_route_configure(route
, link
);
228 return log_link_error_errno(link
, r
, "Could not set route to DNS server: %m");
234 static int dhcp_prefix_route_from_lease(
235 const sd_dhcp_lease
*lease
,
237 const struct in_addr
*address
,
241 struct in_addr netmask
;
244 r
= sd_dhcp_lease_get_netmask((sd_dhcp_lease
*) lease
, &netmask
);
248 r
= route_new(&route
);
252 route
->family
= AF_INET
;
253 route
->dst
.in
.s_addr
= address
->s_addr
& netmask
.s_addr
;
254 route
->dst_prefixlen
= in4_addr_netmask_to_prefixlen(&netmask
);
255 route
->prefsrc
.in
= *address
;
256 route
->scope
= RT_SCOPE_LINK
;
257 route
->protocol
= RTPROT_DHCP
;
258 route
->table
= table
;
263 static int link_set_dhcp_routes(Link
*link
) {
264 _cleanup_free_ sd_dhcp_route
**static_routes
= NULL
;
265 bool classless_route
= false, static_route
= false;
266 struct in_addr address
;
273 if (!link
->dhcp_lease
) /* link went down while we configured the IP addresses? */
276 if (!link
->network
) /* link went down while we configured the IP addresses? */
279 if (!link_has_carrier(link
) && !link
->network
->configure_without_carrier
)
280 /* During configuring addresses, the link lost its carrier. As networkd is dropping
281 * the addresses now, let's not configure the routes either. */
284 while ((rt
= set_steal_first(link
->dhcp_routes
))) {
285 r
= set_ensure_put(&link
->dhcp_routes_old
, &route_hash_ops
, rt
);
287 return log_link_error_errno(link
, r
, "Failed to store old DHCPv4 route: %m");
290 table
= link_get_dhcp_route_table(link
);
292 r
= sd_dhcp_lease_get_address(link
->dhcp_lease
, &address
);
294 return log_link_warning_errno(link
, r
, "DHCP error: could not get address: %m");
296 if (!link_prefixroute(link
)) {
297 _cleanup_(route_freep
) Route
*prefix_route
= NULL
;
299 r
= dhcp_prefix_route_from_lease(link
->dhcp_lease
, table
, &address
, &prefix_route
);
301 return log_link_error_errno(link
, r
, "Could not create prefix route: %m");
303 r
= dhcp_route_configure(prefix_route
, link
);
305 return log_link_error_errno(link
, r
, "Could not set prefix route: %m");
308 n
= sd_dhcp_lease_get_routes(link
->dhcp_lease
, &static_routes
);
310 log_link_debug_errno(link
, n
, "DHCP: No routes received from DHCP server: %m");
312 return log_link_error_errno(link
, n
, "DHCP: could not get routes: %m");
314 for (int i
= 0; i
< n
; i
++) {
315 switch (sd_dhcp_route_get_option(static_routes
[i
])) {
316 case SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE
:
317 classless_route
= true;
319 case SD_DHCP_OPTION_STATIC_ROUTE
:
325 if (link
->network
->dhcp_use_routes
) {
326 /* if the DHCP server returns both a Classless Static Routes option and a Static Routes option,
327 * the DHCP client MUST ignore the Static Routes option. */
328 if (classless_route
&& static_route
)
329 log_link_warning(link
, "Classless static routes received from DHCP server: ignoring static-route option");
331 for (int i
= 0; i
< n
; i
++) {
332 _cleanup_(route_freep
) Route
*route
= NULL
;
334 if (classless_route
&&
335 sd_dhcp_route_get_option(static_routes
[i
]) != SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE
)
338 r
= route_new(&route
);
340 return log_link_error_errno(link
, r
, "Could not allocate route: %m");
342 route
->family
= AF_INET
;
343 route
->protocol
= RTPROT_DHCP
;
344 route
->gw_family
= AF_INET
;
345 assert_se(sd_dhcp_route_get_gateway(static_routes
[i
], &route
->gw
.in
) >= 0);
346 assert_se(sd_dhcp_route_get_destination(static_routes
[i
], &route
->dst
.in
) >= 0);
347 assert_se(sd_dhcp_route_get_destination_prefix_length(static_routes
[i
], &route
->dst_prefixlen
) >= 0);
348 route
->priority
= link
->network
->dhcp_route_metric
;
349 route
->table
= table
;
350 route
->mtu
= link
->network
->dhcp_route_mtu
;
351 route
->scope
= route_scope_from_address(route
, &address
);
352 if (IN_SET(route
->scope
, RT_SCOPE_LINK
, RT_SCOPE_UNIVERSE
))
353 route
->prefsrc
.in
= address
;
355 if (set_contains(link
->dhcp_routes
, route
))
358 r
= dhcp_route_configure(route
, link
);
360 return log_link_error_errno(link
, r
, "Could not set route: %m");
364 if (link
->network
->dhcp_use_gateway
) {
365 const struct in_addr
*router
;
367 r
= sd_dhcp_lease_get_router(link
->dhcp_lease
, &router
);
368 if (IN_SET(r
, 0, -ENODATA
))
369 log_link_info(link
, "DHCP: No gateway received from DHCP server.");
371 return log_link_error_errno(link
, r
, "DHCP error: could not get gateway: %m");
372 else if (in4_addr_is_null(&router
[0]))
373 log_link_info(link
, "DHCP: Received gateway is null.");
374 else if (classless_route
)
375 /* According to RFC 3442: If the DHCP server returns both a Classless Static Routes option and
376 * a Router option, the DHCP client MUST ignore the Router option. */
377 log_link_warning(link
, "Classless static routes received from DHCP server: ignoring router option");
379 _cleanup_(route_freep
) Route
*route
= NULL
, *route_gw
= NULL
;
381 r
= route_new(&route_gw
);
383 return log_link_error_errno(link
, r
, "Could not allocate route: %m");
385 /* The dhcp netmask may mask out the gateway. Add an explicit
386 * route for the gw host so that we can route no matter the
387 * netmask or existing kernel route tables. */
388 route_gw
->family
= AF_INET
;
389 route_gw
->dst
.in
= router
[0];
390 route_gw
->dst_prefixlen
= 32;
391 route_gw
->prefsrc
.in
= address
;
392 route_gw
->scope
= RT_SCOPE_LINK
;
393 route_gw
->protocol
= RTPROT_DHCP
;
394 route_gw
->priority
= link
->network
->dhcp_route_metric
;
395 route_gw
->table
= table
;
396 route_gw
->mtu
= link
->network
->dhcp_route_mtu
;
398 r
= dhcp_route_configure(route_gw
, link
);
400 return log_link_error_errno(link
, r
, "Could not set host route: %m");
402 r
= route_new(&route
);
404 return log_link_error_errno(link
, r
, "Could not allocate route: %m");
406 route
->family
= AF_INET
;
407 route
->gw_family
= AF_INET
;
408 route
->gw
.in
= router
[0];
409 route
->prefsrc
.in
= address
;
410 route
->protocol
= RTPROT_DHCP
;
411 route
->priority
= link
->network
->dhcp_route_metric
;
412 route
->table
= table
;
413 route
->mtu
= link
->network
->dhcp_route_mtu
;
415 r
= dhcp_route_configure(route
, link
);
417 return log_link_error_errno(link
, r
, "Could not set router: %m");
419 HASHMAP_FOREACH(rt
, link
->network
->routes_by_section
) {
420 if (!rt
->gateway_from_dhcp_or_ra
)
423 if (rt
->gw_family
!= AF_INET
)
426 rt
->gw
.in
= router
[0];
427 if (!rt
->protocol_set
)
428 rt
->protocol
= RTPROT_DHCP
;
429 if (!rt
->priority_set
)
430 rt
->priority
= link
->network
->dhcp_route_metric
;
434 rt
->mtu
= link
->network
->dhcp_route_mtu
;
436 r
= dhcp_route_configure(rt
, link
);
438 return log_link_error_errno(link
, r
, "Could not set gateway: %m");
443 return link_set_dns_routes(link
, &address
);
446 static int dhcp_reset_mtu(Link
*link
) {
452 if (!link
->network
->dhcp_use_mtu
)
455 r
= sd_dhcp_lease_get_mtu(link
->dhcp_lease
, &mtu
);
459 return log_link_error_errno(link
, r
, "DHCP error: failed to get MTU from lease: %m");
461 if (link
->original_mtu
== mtu
)
464 r
= link_set_mtu(link
, link
->original_mtu
);
466 return log_link_error_errno(link
, r
, "DHCP error: could not reset MTU: %m");
471 static int dhcp_reset_hostname(Link
*link
) {
472 const char *hostname
;
477 if (!link
->network
->dhcp_use_hostname
)
480 hostname
= link
->network
->dhcp_hostname
;
482 (void) sd_dhcp_lease_get_hostname(link
->dhcp_lease
, &hostname
);
487 /* If a hostname was set due to the lease, then unset it now. */
488 r
= manager_set_hostname(link
->manager
, NULL
);
490 return log_link_error_errno(link
, r
, "DHCP error: Failed to reset transient hostname: %m");
495 static int dhcp4_remove_route_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, Link
*link
) {
500 assert(link
->dhcp4_remove_messages
> 0);
502 link
->dhcp4_remove_messages
--;
504 if (IN_SET(link
->state
, LINK_STATE_FAILED
, LINK_STATE_LINGER
))
507 r
= sd_netlink_message_get_errno(m
);
508 if (r
< 0 && r
!= -ESRCH
)
509 log_link_message_warning_errno(link
, m
, r
, "Failed to remove DHCPv4 route, ignoring");
511 if (link
->dhcp4_remove_messages
== 0) {
512 r
= dhcp4_update_address(link
, false);
514 link_enter_failed(link
);
520 static int dhcp4_remove_address_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, Link
*link
) {
525 assert(link
->dhcp4_remove_messages
> 0);
527 link
->dhcp4_remove_messages
--;
529 if (IN_SET(link
->state
, LINK_STATE_FAILED
, LINK_STATE_LINGER
))
532 r
= sd_netlink_message_get_errno(m
);
533 if (r
< 0 && r
!= -EADDRNOTAVAIL
)
534 log_link_message_warning_errno(link
, m
, r
, "Failed to remove DHCPv4 address, ignoring");
536 (void) manager_rtnl_process_address(rtnl
, m
, link
->manager
);
538 if (link
->dhcp4_remove_messages
== 0) {
539 r
= dhcp4_update_address(link
, false);
541 link_enter_failed(link
);
547 static int dhcp4_remove_all(Link
*link
) {
553 SET_FOREACH(route
, link
->dhcp_routes
) {
554 k
= route_remove(route
, NULL
, link
, dhcp4_remove_route_handler
);
558 link
->dhcp4_remove_messages
++;
561 if (link
->dhcp_address
) {
562 k
= address_remove(link
->dhcp_address
, link
, dhcp4_remove_address_handler
);
566 link
->dhcp4_remove_messages
++;
572 static int dhcp_lease_lost(Link
*link
) {
576 assert(link
->dhcp_lease
);
578 log_link_info(link
, "DHCP lease lost");
580 link
->dhcp4_configured
= false;
582 /* dhcp_lease_lost() may be called during renewing IP address. */
583 k
= dhcp4_release_old_lease(link
);
587 k
= dhcp4_remove_all(link
);
591 k
= dhcp_reset_mtu(link
);
595 k
= dhcp_reset_hostname(link
);
599 link
->dhcp_lease
= sd_dhcp_lease_unref(link
->dhcp_lease
);
602 (void) sd_ipv4acd_stop(link
->dhcp_acd
);
607 static void dhcp_address_on_acd(sd_ipv4acd
*acd
, int event
, void *userdata
) {
608 _cleanup_free_
char *pretty
= NULL
;
609 union in_addr_union address
= {};
619 case SD_IPV4ACD_EVENT_STOP
:
620 log_link_debug(link
, "Stopping ACD client for DHCP4...");
623 case SD_IPV4ACD_EVENT_BIND
:
625 (void) sd_dhcp_lease_get_address(link
->dhcp_lease
, &address
.in
);
626 (void) in_addr_to_string(AF_INET
, &address
, &pretty
);
627 log_link_debug(link
, "Successfully claimed DHCP4 address %s", strna(pretty
));
629 link
->dhcp4_address_bind
= true;
630 dhcp4_check_ready(link
);
633 case SD_IPV4ACD_EVENT_CONFLICT
:
634 (void) sd_dhcp_lease_get_address(link
->dhcp_lease
, &address
.in
);
635 (void) in_addr_to_string(AF_INET
, &address
, &pretty
);
636 log_link_warning(link
, "DAD conflict. Dropping DHCP4 address %s", strna(pretty
));
638 r
= sd_dhcp_client_send_decline(link
->dhcp_client
);
640 log_link_warning_errno(link
, r
, "Failed to send DHCP DECLINE, ignoring: %m");
642 if (link
->dhcp_lease
) {
643 r
= dhcp_lease_lost(link
);
645 link_enter_failed(link
);
650 assert_not_reached("Invalid IPv4ACD event.");
653 (void) sd_ipv4acd_stop(acd
);
658 static int dhcp4_configure_dad(Link
*link
) {
662 assert(link
->manager
);
663 assert(link
->network
);
665 if (!link
->network
->dhcp_send_decline
)
668 if (!link
->dhcp_acd
) {
669 r
= sd_ipv4acd_new(&link
->dhcp_acd
);
673 r
= sd_ipv4acd_attach_event(link
->dhcp_acd
, link
->manager
->event
, 0);
678 r
= sd_ipv4acd_set_ifindex(link
->dhcp_acd
, link
->ifindex
);
682 r
= sd_ipv4acd_set_mac(link
->dhcp_acd
, &link
->hw_addr
.addr
.ether
);
689 static int dhcp4_dad_update_mac(Link
*link
) {
698 running
= sd_ipv4acd_is_running(link
->dhcp_acd
);
700 r
= sd_ipv4acd_stop(link
->dhcp_acd
);
704 r
= sd_ipv4acd_set_mac(link
->dhcp_acd
, &link
->hw_addr
.addr
.ether
);
709 r
= sd_ipv4acd_start(link
->dhcp_acd
, true);
717 static int dhcp4_start_acd(Link
*link
) {
718 union in_addr_union addr
;
722 if (!link
->network
->dhcp_send_decline
)
725 if (!link
->dhcp_lease
)
728 (void) sd_ipv4acd_stop(link
->dhcp_acd
);
730 link
->dhcp4_address_bind
= false;
732 r
= sd_dhcp_lease_get_address(link
->dhcp_lease
, &addr
.in
);
736 r
= sd_ipv4acd_get_address(link
->dhcp_acd
, &old
);
740 r
= sd_ipv4acd_set_address(link
->dhcp_acd
, &addr
.in
);
744 r
= sd_ipv4acd_set_callback(link
->dhcp_acd
, dhcp_address_on_acd
, link
);
749 _cleanup_free_
char *pretty
= NULL
;
751 (void) in_addr_to_string(AF_INET
, &addr
, &pretty
);
752 log_link_debug(link
, "Starting IPv4ACD client. Probing DHCPv4 address %s", strna(pretty
));
755 r
= sd_ipv4acd_start(link
->dhcp_acd
, !in4_addr_equal(&addr
.in
, &old
));
762 static int dhcp4_address_ready_callback(Address
*address
) {
768 link
= address
->link
;
770 /* Do not call this again. */
771 address
->callback
= NULL
;
773 r
= link_set_dhcp_routes(link
);
777 /* Reconfigure static routes as kernel may remove some routes when lease expires. */
778 r
= link_set_routes(link
);
782 r
= dhcp4_start_acd(link
);
784 return log_link_error_errno(link
, r
, "Failed to start IPv4ACD for DHCP4 address: %m");
786 dhcp4_check_ready(link
);
790 static int dhcp4_address_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, Link
*link
) {
795 if (IN_SET(link
->state
, LINK_STATE_FAILED
, LINK_STATE_LINGER
))
798 r
= sd_netlink_message_get_errno(m
);
799 if (r
< 0 && r
!= -EEXIST
) {
800 log_link_message_warning_errno(link
, m
, r
, "Could not set DHCPv4 address");
801 link_enter_failed(link
);
804 (void) manager_rtnl_process_address(rtnl
, m
, link
->manager
);
806 if (address_is_ready(link
->dhcp_address
)) {
807 r
= dhcp4_address_ready_callback(link
->dhcp_address
);
809 link_enter_failed(link
);
813 link
->dhcp_address
->callback
= dhcp4_address_ready_callback
;
818 static int dhcp4_update_address(Link
*link
, bool announce
) {
819 _cleanup_(address_freep
) Address
*addr
= NULL
;
820 uint32_t lifetime
= CACHE_INFO_INFINITY_LIFE_TIME
;
821 struct in_addr address
, netmask
;
827 assert(link
->network
);
829 if (!link
->dhcp_lease
)
832 link_set_state(link
, LINK_STATE_CONFIGURING
);
833 link
->dhcp4_configured
= false;
835 /* address_handler calls link_set_routes() and link_set_nexthop(). Before they are called, the
836 * related flags must be cleared. Otherwise, the link becomes configured state before routes
838 link
->static_routes_configured
= false;
839 link
->static_nexthops_configured
= false;
841 r
= sd_dhcp_lease_get_address(link
->dhcp_lease
, &address
);
843 return log_link_warning_errno(link
, r
, "DHCP error: no address: %m");
845 r
= sd_dhcp_lease_get_netmask(link
->dhcp_lease
, &netmask
);
847 return log_link_warning_errno(link
, r
, "DHCP error: no netmask: %m");
849 if (!FLAGS_SET(link
->network
->keep_configuration
, KEEP_CONFIGURATION_DHCP
)) {
850 r
= sd_dhcp_lease_get_lifetime(link
->dhcp_lease
, &lifetime
);
852 return log_link_warning_errno(link
, r
, "DHCP error: no lifetime: %m");
855 prefixlen
= in4_addr_netmask_to_prefixlen(&netmask
);
858 const struct in_addr
*router
;
860 r
= sd_dhcp_lease_get_router(link
->dhcp_lease
, &router
);
861 if (r
< 0 && r
!= -ENODATA
)
862 return log_link_error_errno(link
, r
, "DHCP error: Could not get gateway: %m");
864 if (r
> 0 && in4_addr_is_set(&router
[0]))
866 LOG_LINK_INTERFACE(link
),
867 LOG_LINK_MESSAGE(link
, "DHCPv4 address "IPV4_ADDRESS_FMT_STR
"/%u via "IPV4_ADDRESS_FMT_STR
,
868 IPV4_ADDRESS_FMT_VAL(address
),
870 IPV4_ADDRESS_FMT_VAL(router
[0])),
871 "ADDRESS="IPV4_ADDRESS_FMT_STR
, IPV4_ADDRESS_FMT_VAL(address
),
872 "PREFIXLEN=%u", prefixlen
,
873 "GATEWAY="IPV4_ADDRESS_FMT_STR
, IPV4_ADDRESS_FMT_VAL(router
[0]));
876 LOG_LINK_INTERFACE(link
),
877 LOG_LINK_MESSAGE(link
, "DHCPv4 address "IPV4_ADDRESS_FMT_STR
"/%u",
878 IPV4_ADDRESS_FMT_VAL(address
),
880 "ADDRESS="IPV4_ADDRESS_FMT_STR
, IPV4_ADDRESS_FMT_VAL(address
),
881 "PREFIXLEN=%u", prefixlen
);
884 r
= address_new(&addr
);
888 addr
->family
= AF_INET
;
889 addr
->in_addr
.in
.s_addr
= address
.s_addr
;
890 addr
->cinfo
.ifa_prefered
= lifetime
;
891 addr
->cinfo
.ifa_valid
= lifetime
;
892 addr
->prefixlen
= prefixlen
;
894 addr
->broadcast
.s_addr
= address
.s_addr
| ~netmask
.s_addr
;
895 SET_FLAG(addr
->flags
, IFA_F_NOPREFIXROUTE
, !link_prefixroute(link
));
896 addr
->route_metric
= link
->network
->dhcp_route_metric
;
898 /* allow reusing an existing address and simply update its lifetime
899 * in case it already exists */
900 r
= address_configure(addr
, link
, dhcp4_address_handler
, &ret
);
902 return log_link_error_errno(link
, r
, "Failed to set DHCPv4 address: %m");
904 if (!address_equal(link
->dhcp_address
, ret
))
905 link
->dhcp_address_old
= link
->dhcp_address
;
906 link
->dhcp_address
= ret
;
911 static int dhcp_lease_renew(sd_dhcp_client
*client
, Link
*link
) {
912 sd_dhcp_lease
*lease
;
918 r
= sd_dhcp_client_get_lease(client
, &lease
);
920 return log_link_warning_errno(link
, r
, "DHCP error: no lease: %m");
922 sd_dhcp_lease_unref(link
->dhcp_lease
);
923 link
->dhcp_lease
= sd_dhcp_lease_ref(lease
);
926 return dhcp4_update_address(link
, false);
929 static int dhcp_lease_acquired(sd_dhcp_client
*client
, Link
*link
) {
930 sd_dhcp_lease
*lease
;
936 r
= sd_dhcp_client_get_lease(client
, &lease
);
938 return log_link_error_errno(link
, r
, "DHCP error: No lease: %m");
940 sd_dhcp_lease_unref(link
->dhcp_lease
);
941 link
->dhcp_lease
= sd_dhcp_lease_ref(lease
);
944 if (link
->network
->dhcp_use_mtu
) {
947 r
= sd_dhcp_lease_get_mtu(lease
, &mtu
);
949 r
= link_set_mtu(link
, mtu
);
951 log_link_error_errno(link
, r
, "Failed to set MTU to %" PRIu16
": %m", mtu
);
955 if (link
->network
->dhcp_use_hostname
) {
956 const char *dhcpname
= NULL
;
957 _cleanup_free_
char *hostname
= NULL
;
959 if (link
->network
->dhcp_hostname
)
960 dhcpname
= link
->network
->dhcp_hostname
;
962 (void) sd_dhcp_lease_get_hostname(lease
, &dhcpname
);
965 r
= shorten_overlong(dhcpname
, &hostname
);
967 log_link_warning_errno(link
, r
, "Unable to shorten overlong DHCP hostname '%s', ignoring: %m", dhcpname
);
969 log_link_notice(link
, "Overlong DHCP hostname received, shortened from '%s' to '%s'", dhcpname
, hostname
);
973 r
= manager_set_hostname(link
->manager
, hostname
);
975 log_link_error_errno(link
, r
, "Failed to set transient hostname to '%s': %m", hostname
);
979 if (link
->network
->dhcp_use_timezone
) {
980 const char *tz
= NULL
;
982 (void) sd_dhcp_lease_get_timezone(link
->dhcp_lease
, &tz
);
985 r
= manager_set_timezone(link
->manager
, tz
);
987 log_link_error_errno(link
, r
, "Failed to set timezone to '%s': %m", tz
);
991 if (link
->dhcp4_remove_messages
== 0) {
992 r
= dhcp4_update_address(link
, true);
997 "The link has previously assigned DHCPv4 address or routes. "
998 "The newly assigned address and routes will set up after old ones are removed.");
1003 static int dhcp_lease_ip_change(sd_dhcp_client
*client
, Link
*link
) {
1006 r
= dhcp_lease_acquired(client
, link
);
1008 (void) dhcp_lease_lost(link
);
1013 static int dhcp_server_is_deny_listed(Link
*link
, sd_dhcp_client
*client
) {
1014 sd_dhcp_lease
*lease
;
1015 struct in_addr addr
;
1019 assert(link
->network
);
1022 r
= sd_dhcp_client_get_lease(client
, &lease
);
1024 return log_link_error_errno(link
, r
, "Failed to get DHCP lease: %m");
1026 r
= sd_dhcp_lease_get_server_identifier(lease
, &addr
);
1028 return log_link_debug_errno(link
, r
, "Failed to get DHCP server IP address: %m");
1030 if (set_contains(link
->network
->dhcp_deny_listed_ip
, UINT32_TO_PTR(addr
.s_addr
))) {
1031 log_struct(LOG_DEBUG
,
1032 LOG_LINK_INTERFACE(link
),
1033 LOG_LINK_MESSAGE(link
, "DHCPv4 server IP address "IPV4_ADDRESS_FMT_STR
" found in deny-list, ignoring offer",
1034 IPV4_ADDRESS_FMT_VAL(addr
)));
1041 static int dhcp_server_is_allow_listed(Link
*link
, sd_dhcp_client
*client
) {
1042 sd_dhcp_lease
*lease
;
1043 struct in_addr addr
;
1047 assert(link
->network
);
1050 r
= sd_dhcp_client_get_lease(client
, &lease
);
1052 return log_link_error_errno(link
, r
, "Failed to get DHCP lease: %m");
1054 r
= sd_dhcp_lease_get_server_identifier(lease
, &addr
);
1056 return log_link_debug_errno(link
, r
, "Failed to get DHCP server IP address: %m");
1058 if (set_contains(link
->network
->dhcp_allow_listed_ip
, UINT32_TO_PTR(addr
.s_addr
))) {
1059 log_struct(LOG_DEBUG
,
1060 LOG_LINK_INTERFACE(link
),
1061 LOG_LINK_MESSAGE(link
, "DHCPv4 server IP address "IPV4_ADDRESS_FMT_STR
" found in allow-list, accepting offer",
1062 IPV4_ADDRESS_FMT_VAL(addr
)));
1069 static int dhcp4_handler(sd_dhcp_client
*client
, int event
, void *userdata
) {
1070 Link
*link
= userdata
;
1074 assert(link
->network
);
1075 assert(link
->manager
);
1077 if (IN_SET(link
->state
, LINK_STATE_FAILED
, LINK_STATE_LINGER
))
1081 case SD_DHCP_CLIENT_EVENT_STOP
:
1083 log_link_debug(link
, "DHCP client is stopped. Acquiring IPv4 link-local address");
1085 r
= sd_ipv4ll_start(link
->ipv4ll
);
1087 return log_link_warning_errno(link
, r
, "Could not acquire IPv4 link-local address: %m");
1090 if (FLAGS_SET(link
->network
->keep_configuration
, KEEP_CONFIGURATION_DHCP
)) {
1091 log_link_notice(link
, "DHCPv4 connection considered critical, ignoring request to reconfigure it.");
1095 if (link
->dhcp_lease
) {
1096 if (link
->network
->dhcp_send_release
) {
1097 r
= sd_dhcp_client_send_release(client
);
1099 log_link_warning_errno(link
, r
, "Failed to send DHCP RELEASE, ignoring: %m");
1102 r
= dhcp_lease_lost(link
);
1104 link_enter_failed(link
);
1110 case SD_DHCP_CLIENT_EVENT_EXPIRED
:
1111 if (FLAGS_SET(link
->network
->keep_configuration
, KEEP_CONFIGURATION_DHCP
)) {
1112 log_link_notice(link
, "DHCPv4 connection considered critical, ignoring request to reconfigure it.");
1116 if (link
->dhcp_lease
) {
1117 r
= dhcp_lease_lost(link
);
1119 link_enter_failed(link
);
1125 case SD_DHCP_CLIENT_EVENT_IP_CHANGE
:
1126 if (FLAGS_SET(link
->network
->keep_configuration
, KEEP_CONFIGURATION_DHCP
)) {
1127 log_link_notice(link
, "DHCPv4 connection considered critical, ignoring request to reconfigure it.");
1131 r
= dhcp_lease_ip_change(client
, link
);
1133 link_enter_failed(link
);
1138 case SD_DHCP_CLIENT_EVENT_RENEW
:
1139 r
= dhcp_lease_renew(client
, link
);
1141 link_enter_failed(link
);
1145 case SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
:
1146 r
= dhcp_lease_acquired(client
, link
);
1148 link_enter_failed(link
);
1152 case SD_DHCP_CLIENT_EVENT_SELECTING
:
1153 if (!set_isempty(link
->network
->dhcp_allow_listed_ip
)) {
1154 r
= dhcp_server_is_allow_listed(link
, client
);
1160 r
= dhcp_server_is_deny_listed(link
, client
);
1168 case SD_DHCP_CLIENT_EVENT_TRANSIENT_FAILURE
:
1169 if (link
->ipv4ll
&& !sd_ipv4ll_is_running(link
->ipv4ll
)) {
1170 log_link_debug(link
, "Problems acquiring DHCP lease, acquiring IPv4 link-local address");
1172 r
= sd_ipv4ll_start(link
->ipv4ll
);
1174 return log_link_warning_errno(link
, r
, "Could not acquire IPv4 link-local address: %m");
1180 log_link_warning_errno(link
, event
, "DHCP error: Client failed: %m");
1182 log_link_warning(link
, "DHCP unknown event: %i", event
);
1189 static int dhcp4_set_hostname(Link
*link
) {
1190 _cleanup_free_
char *hostname
= NULL
;
1196 if (!link
->network
->dhcp_send_hostname
)
1198 else if (link
->network
->dhcp_hostname
)
1199 hn
= link
->network
->dhcp_hostname
;
1201 r
= gethostname_strict(&hostname
);
1202 if (r
< 0 && r
!= -ENXIO
) /* ENXIO: no hostname set or hostname is "localhost" */
1203 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to get hostname: %m");
1208 r
= sd_dhcp_client_set_hostname(link
->dhcp_client
, hn
);
1209 if (r
== -EINVAL
&& hostname
)
1210 /* Ignore error when the machine's hostname is not suitable to send in DHCP packet. */
1211 log_link_debug_errno(link
, r
, "DHCP4 CLIENT: Failed to set hostname from kernel hostname, ignoring: %m");
1213 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set hostname: %m");
1218 static int dhcp4_set_client_identifier(Link
*link
) {
1222 assert(link
->network
);
1223 assert(link
->dhcp_client
);
1225 switch (link
->network
->dhcp_client_identifier
) {
1226 case DHCP_CLIENT_ID_DUID
: {
1227 /* If configured, apply user specified DUID and IAID */
1228 const DUID
*duid
= link_get_duid(link
);
1230 if (duid
->type
== DUID_TYPE_LLT
&& duid
->raw_data_len
== 0)
1231 r
= sd_dhcp_client_set_iaid_duid_llt(link
->dhcp_client
,
1232 link
->network
->iaid_set
,
1233 link
->network
->iaid
,
1236 r
= sd_dhcp_client_set_iaid_duid(link
->dhcp_client
,
1237 link
->network
->iaid_set
,
1238 link
->network
->iaid
,
1240 duid
->raw_data_len
> 0 ? duid
->raw_data
: NULL
,
1241 duid
->raw_data_len
);
1243 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set IAID+DUID: %m");
1246 case DHCP_CLIENT_ID_DUID_ONLY
: {
1247 /* If configured, apply user specified DUID */
1248 const DUID
*duid
= link_get_duid(link
);
1250 if (duid
->type
== DUID_TYPE_LLT
&& duid
->raw_data_len
== 0)
1251 r
= sd_dhcp_client_set_duid_llt(link
->dhcp_client
,
1254 r
= sd_dhcp_client_set_duid(link
->dhcp_client
,
1256 duid
->raw_data_len
> 0 ? duid
->raw_data
: NULL
,
1257 duid
->raw_data_len
);
1259 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set DUID: %m");
1262 case DHCP_CLIENT_ID_MAC
: {
1263 const uint8_t *hw_addr
= link
->hw_addr
.addr
.bytes
;
1264 size_t hw_addr_len
= link
->hw_addr
.length
;
1266 if (link
->iftype
== ARPHRD_INFINIBAND
&& hw_addr_len
== INFINIBAND_ALEN
) {
1267 /* set_client_id expects only last 8 bytes of an IB address */
1268 hw_addr
+= INFINIBAND_ALEN
- 8;
1269 hw_addr_len
-= INFINIBAND_ALEN
- 8;
1272 r
= sd_dhcp_client_set_client_id(link
->dhcp_client
,
1277 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set client ID: %m");
1281 assert_not_reached("Unknown client identifier type.");
1287 static int dhcp4_set_request_address(Link
*link
) {
1291 assert(link
->network
);
1292 assert(link
->dhcp_client
);
1294 if (!FLAGS_SET(link
->network
->keep_configuration
, KEEP_CONFIGURATION_DHCP
))
1297 SET_FOREACH(a
, link
->addresses_foreign
) {
1298 if (a
->family
!= AF_INET
)
1300 if (link_address_is_dynamic(link
, a
))
1307 log_link_debug(link
, "DHCP4 CLIENT: requesting " IPV4_ADDRESS_FMT_STR
, IPV4_ADDRESS_FMT_VAL(a
->in_addr
.in
));
1309 return sd_dhcp_client_set_request_address(link
->dhcp_client
, &a
->in_addr
.in
);
1312 int dhcp4_configure(Link
*link
) {
1313 sd_dhcp_option
*send_option
;
1314 void *request_options
;
1318 assert(link
->network
);
1320 if (!link_dhcp4_enabled(link
))
1323 if (link
->dhcp_client
)
1324 return -EBUSY
; /* Already configured. */
1326 r
= sd_dhcp_client_new(&link
->dhcp_client
, link
->network
->dhcp_anonymize
);
1328 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to allocate DHCP4 client: %m");
1330 r
= sd_dhcp_client_attach_event(link
->dhcp_client
, link
->manager
->event
, 0);
1332 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to attach event to DHCP4 client: %m");
1334 r
= sd_dhcp_client_set_mac(link
->dhcp_client
,
1335 link
->hw_addr
.addr
.bytes
,
1336 link
->bcast_addr
.length
> 0 ? link
->bcast_addr
.addr
.bytes
: NULL
,
1337 link
->hw_addr
.length
, link
->iftype
);
1339 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set MAC address: %m");
1341 r
= sd_dhcp_client_set_ifindex(link
->dhcp_client
, link
->ifindex
);
1343 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set ifindex: %m");
1345 r
= sd_dhcp_client_set_callback(link
->dhcp_client
, dhcp4_handler
, link
);
1347 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set callback: %m");
1349 r
= sd_dhcp_client_set_request_broadcast(link
->dhcp_client
, link
->network
->dhcp_broadcast
);
1351 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set request flag for broadcast: %m");
1353 if (link
->mtu
> 0) {
1354 r
= sd_dhcp_client_set_mtu(link
->dhcp_client
, link
->mtu
);
1356 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set MTU: %m");
1359 if (!link
->network
->dhcp_anonymize
) {
1360 if (link
->network
->dhcp_use_mtu
) {
1361 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, SD_DHCP_OPTION_INTERFACE_MTU
);
1363 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set request flag for MTU: %m");
1366 if (link
->network
->dhcp_use_routes
) {
1367 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, SD_DHCP_OPTION_STATIC_ROUTE
);
1369 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set request flag for static route: %m");
1371 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE
);
1373 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set request flag for classless static route: %m");
1376 if (link
->network
->dhcp_use_domains
!= DHCP_USE_DOMAINS_NO
) {
1377 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, SD_DHCP_OPTION_DOMAIN_SEARCH_LIST
);
1379 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set request flag for domain search list: %m");
1382 if (link
->network
->dhcp_use_ntp
) {
1383 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, SD_DHCP_OPTION_NTP_SERVER
);
1385 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set request flag for NTP server: %m");
1388 if (link
->network
->dhcp_use_sip
) {
1389 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, SD_DHCP_OPTION_SIP_SERVER
);
1391 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set request flag for SIP server: %m");
1394 if (link
->network
->dhcp_use_timezone
) {
1395 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, SD_DHCP_OPTION_NEW_TZDB_TIMEZONE
);
1397 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set request flag for timezone: %m");
1400 SET_FOREACH(request_options
, link
->network
->dhcp_request_options
) {
1401 uint32_t option
= PTR_TO_UINT32(request_options
);
1403 r
= sd_dhcp_client_set_request_option(link
->dhcp_client
, option
);
1405 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set request flag for '%u': %m", option
);
1408 ORDERED_HASHMAP_FOREACH(send_option
, link
->network
->dhcp_client_send_options
) {
1409 r
= sd_dhcp_client_add_option(link
->dhcp_client
, send_option
);
1413 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set send option: %m");
1416 ORDERED_HASHMAP_FOREACH(send_option
, link
->network
->dhcp_client_send_vendor_options
) {
1417 r
= sd_dhcp_client_add_vendor_option(link
->dhcp_client
, send_option
);
1421 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set send option: %m");
1424 r
= dhcp4_set_hostname(link
);
1428 if (link
->network
->dhcp_vendor_class_identifier
) {
1429 r
= sd_dhcp_client_set_vendor_class_identifier(link
->dhcp_client
,
1430 link
->network
->dhcp_vendor_class_identifier
);
1432 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set vendor class identifier: %m");
1435 if (link
->network
->dhcp_mudurl
) {
1436 r
= sd_dhcp_client_set_mud_url(link
->dhcp_client
, link
->network
->dhcp_mudurl
);
1438 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set MUD URL: %m");
1441 if (link
->network
->dhcp_user_class
) {
1442 r
= sd_dhcp_client_set_user_class(link
->dhcp_client
, link
->network
->dhcp_user_class
);
1444 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set user class: %m");
1448 if (link
->network
->dhcp_client_port
> 0) {
1449 r
= sd_dhcp_client_set_client_port(link
->dhcp_client
, link
->network
->dhcp_client_port
);
1451 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set listen port: %m");
1454 if (link
->network
->dhcp_max_attempts
> 0) {
1455 r
= sd_dhcp_client_set_max_attempts(link
->dhcp_client
, link
->network
->dhcp_max_attempts
);
1457 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set max attempts: %m");
1460 if (link
->network
->dhcp_ip_service_type
> 0) {
1461 r
= sd_dhcp_client_set_service_type(link
->dhcp_client
, link
->network
->dhcp_ip_service_type
);
1463 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set IP service type: %m");
1466 if (link
->network
->dhcp_fallback_lease_lifetime
> 0) {
1467 r
= sd_dhcp_client_set_fallback_lease_lifetime(link
->dhcp_client
, link
->network
->dhcp_fallback_lease_lifetime
);
1469 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed set to lease lifetime: %m");
1472 r
= dhcp4_set_request_address(link
);
1474 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to set initial DHCPv4 address: %m");
1476 r
= dhcp4_configure_dad(link
);
1478 return log_link_warning_errno(link
, r
, "DHCP4 CLIENT: Failed to configure service type: %m");
1480 return dhcp4_set_client_identifier(link
);
1483 int dhcp4_update_mac(Link
*link
) {
1488 if (!link
->dhcp_client
)
1491 r
= sd_dhcp_client_set_mac(link
->dhcp_client
, link
->hw_addr
.addr
.bytes
,
1492 link
->bcast_addr
.length
> 0 ? link
->bcast_addr
.addr
.bytes
: NULL
,
1493 link
->hw_addr
.length
, link
->iftype
);
1497 r
= dhcp4_set_client_identifier(link
);
1501 r
= dhcp4_dad_update_mac(link
);
1508 int config_parse_dhcp_max_attempts(
1510 const char *filename
,
1512 const char *section
,
1513 unsigned section_line
,
1520 Network
*network
= data
;
1528 if (isempty(rvalue
)) {
1529 network
->dhcp_max_attempts
= 0;
1533 if (streq(rvalue
, "infinity")) {
1534 network
->dhcp_max_attempts
= UINT64_MAX
;
1538 r
= safe_atou64(rvalue
, &a
);
1540 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1541 "Failed to parse DHCP maximum attempts, ignoring: %s", rvalue
);
1546 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1547 "%s= must be positive integer or 'infinity', ignoring: %s", lvalue
, rvalue
);
1551 network
->dhcp_max_attempts
= a
;
1556 int config_parse_dhcp_acl_ip_address(
1558 const char *filename
,
1560 const char *section
,
1561 unsigned section_line
,
1568 Network
*network
= data
;
1577 acl
= STR_IN_SET(lvalue
, "DenyList", "BlackList") ? &network
->dhcp_deny_listed_ip
: &network
->dhcp_allow_listed_ip
;
1579 if (isempty(rvalue
)) {
1580 *acl
= set_free(*acl
);
1584 for (const char *p
= rvalue
;;) {
1585 _cleanup_free_
char *n
= NULL
;
1586 union in_addr_union ip
;
1588 r
= extract_first_word(&p
, &n
, NULL
, 0);
1592 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1593 "Failed to parse DHCP '%s=' IP address, ignoring assignment: %s",
1600 r
= in_addr_from_string(AF_INET
, n
, &ip
);
1602 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1603 "DHCP '%s=' IP address is invalid, ignoring assignment: %s", lvalue
, n
);
1607 r
= set_ensure_put(acl
, NULL
, UINT32_TO_PTR(ip
.in
.s_addr
));
1609 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1610 "Failed to store DHCP '%s=' IP address '%s', ignoring assignment: %m", lvalue
, n
);
1614 int config_parse_dhcp_ip_service_type(
1616 const char *filename
,
1618 const char *section
,
1619 unsigned section_line
,
1630 if (streq(rvalue
, "CS4"))
1631 *((int *)data
) = IPTOS_CLASS_CS4
;
1632 else if (streq(rvalue
, "CS6"))
1633 *((int *)data
) = IPTOS_CLASS_CS6
;
1635 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1636 "Failed to parse IPServiceType type '%s', ignoring.", rvalue
);
1641 int config_parse_dhcp_mud_url(
1643 const char *filename
,
1645 const char *section
,
1646 unsigned section_line
,
1653 _cleanup_free_
char *unescaped
= NULL
;
1654 Network
*network
= data
;
1661 if (isempty(rvalue
)) {
1662 network
->dhcp_mudurl
= mfree(network
->dhcp_mudurl
);
1666 r
= cunescape(rvalue
, 0, &unescaped
);
1668 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1669 "Failed to Failed to unescape MUD URL, ignoring: %s", rvalue
);
1673 if (!http_url_is_valid(unescaped
) || strlen(unescaped
) > 255) {
1674 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1675 "Failed to parse MUD URL '%s', ignoring: %m", rvalue
);
1680 return free_and_strdup_warn(&network
->dhcp_mudurl
, unescaped
);
1683 int config_parse_dhcp_fallback_lease_lifetime(const char *unit
,
1684 const char *filename
,
1686 const char *section
,
1687 unsigned section_line
,
1693 Network
*network
= userdata
;
1702 if (isempty(rvalue
)) {
1703 network
->dhcp_fallback_lease_lifetime
= 0;
1707 /* We accept only "forever" or "infinity". */
1708 if (STR_IN_SET(rvalue
, "forever", "infinity"))
1709 k
= CACHE_INFO_INFINITY_LIFE_TIME
;
1711 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1712 "Invalid LeaseLifetime= value, ignoring: %s", rvalue
);
1716 network
->dhcp_fallback_lease_lifetime
= k
;
1721 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
1722 [DHCP_CLIENT_ID_MAC
] = "mac",
1723 [DHCP_CLIENT_ID_DUID
] = "duid",
1724 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
1727 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
1728 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
,
1729 "Failed to parse client identifier type");