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