1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 /***
3   Copyright © 2014 Intel Corporation. All rights reserved.
4 ***/
5 
6 #include <arpa/inet.h>
7 #include <netinet/icmp6.h>
8 #include <linux/if.h>
9 #include <linux/if_arp.h>
10 
11 #include "sd-ndisc.h"
12 
13 #include "missing_network.h"
14 #include "networkd-address-generation.h"
15 #include "networkd-address.h"
16 #include "networkd-dhcp6.h"
17 #include "networkd-manager.h"
18 #include "networkd-ndisc.h"
19 #include "networkd-queue.h"
20 #include "networkd-route.h"
21 #include "networkd-state-file.h"
22 #include "string-table.h"
23 #include "string-util.h"
24 #include "strv.h"
25 
26 #define NDISC_DNSSL_MAX 64U
27 #define NDISC_RDNSS_MAX 64U
28 
link_ipv6_accept_ra_enabled(Link * link)29 bool link_ipv6_accept_ra_enabled(Link *link) {
30         assert(link);
31 
32         if (!socket_ipv6_is_supported())
33                 return false;
34 
35         if (link->flags & IFF_LOOPBACK)
36                 return false;
37 
38         if (link->iftype == ARPHRD_CAN)
39                 return false;
40 
41         if (link->hw_addr.length != ETH_ALEN && !streq_ptr(link->kind, "wwan"))
42                 /* Currently, only interfaces whose MAC address length is ETH_ALEN are supported.
43                  * Note, wwan interfaces may be assigned MAC address slightly later.
44                  * Hence, let's wait for a while.*/
45                 return false;
46 
47         if (!link->network)
48                 return false;
49 
50         if (!link_may_have_ipv6ll(link))
51                 return false;
52 
53         assert(link->network->ipv6_accept_ra >= 0);
54         return link->network->ipv6_accept_ra;
55 }
56 
network_adjust_ipv6_accept_ra(Network * network)57 void network_adjust_ipv6_accept_ra(Network *network) {
58         assert(network);
59 
60         if (!FLAGS_SET(network->link_local, ADDRESS_FAMILY_IPV6)) {
61                 if (network->ipv6_accept_ra > 0)
62                         log_warning("%s: IPv6AcceptRA= is enabled but IPv6 link-local addressing is disabled or not supported. "
63                                     "Disabling IPv6AcceptRA=.", network->filename);
64                 network->ipv6_accept_ra = false;
65         }
66 
67         if (network->ipv6_accept_ra < 0)
68                 /* default to accept RA if ip_forward is disabled and ignore RA if ip_forward is enabled */
69                 network->ipv6_accept_ra = !FLAGS_SET(network->ip_forward, ADDRESS_FAMILY_IPV6);
70 
71         /* When RouterAllowList=, PrefixAllowList= or RouteAllowList= are specified, then
72          * RouterDenyList=, PrefixDenyList= or RouteDenyList= are ignored, respectively. */
73         if (!set_isempty(network->ndisc_allow_listed_router))
74                 network->ndisc_deny_listed_router = set_free_free(network->ndisc_deny_listed_router);
75         if (!set_isempty(network->ndisc_allow_listed_prefix))
76                 network->ndisc_deny_listed_prefix = set_free_free(network->ndisc_deny_listed_prefix);
77         if (!set_isempty(network->ndisc_allow_listed_route_prefix))
78                 network->ndisc_deny_listed_route_prefix = set_free_free(network->ndisc_deny_listed_route_prefix);
79 }
80 
ndisc_remove(Link * link,struct in6_addr * router)81 static int ndisc_remove(Link *link, struct in6_addr *router) {
82         bool updated = false;
83         NDiscDNSSL *dnssl;
84         NDiscRDNSS *rdnss;
85         Address *address;
86         Route *route;
87         int k, r = 0;
88 
89         assert(link);
90 
91         SET_FOREACH(route, link->routes) {
92                 if (route->source != NETWORK_CONFIG_SOURCE_NDISC)
93                         continue;
94                 if (!route_is_marked(route))
95                         continue;
96                 if (router && !in6_addr_equal(router, &route->provider.in6))
97                         continue;
98 
99                 k = route_remove(route);
100                 if (k < 0)
101                         r = k;
102 
103                 route_cancel_request(route, link);
104         }
105 
106         SET_FOREACH(address, link->addresses) {
107                 if (address->source != NETWORK_CONFIG_SOURCE_NDISC)
108                         continue;
109                 if (!address_is_marked(address))
110                         continue;
111                 if (router && !in6_addr_equal(router, &address->provider.in6))
112                         continue;
113 
114                 k = address_remove(address);
115                 if (k < 0)
116                         r = k;
117 
118                 address_cancel_request(address);
119         }
120 
121         SET_FOREACH(rdnss, link->ndisc_rdnss) {
122                 if (!rdnss->marked)
123                         continue;
124                 if (router && !in6_addr_equal(router, &rdnss->router))
125                         continue;
126 
127                 free(set_remove(link->ndisc_rdnss, rdnss));
128                 updated = true;
129         }
130 
131         SET_FOREACH(dnssl, link->ndisc_dnssl) {
132                 if (!dnssl->marked)
133                         continue;
134                 if (router && !in6_addr_equal(router, &dnssl->router))
135                         continue;
136 
137                 free(set_remove(link->ndisc_dnssl, dnssl));
138                 updated = true;
139         }
140 
141         if (updated)
142                 link_dirty(link);
143 
144         return r;
145 }
146 
147 static int ndisc_check_ready(Link *link);
148 
ndisc_address_ready_callback(Address * address)149 static int ndisc_address_ready_callback(Address *address) {
150         Address *a;
151 
152         assert(address);
153         assert(address->link);
154 
155         SET_FOREACH(a, address->link->addresses)
156                 if (a->source == NETWORK_CONFIG_SOURCE_NDISC)
157                         a->callback = NULL;
158 
159         return ndisc_check_ready(address->link);
160 }
161 
ndisc_check_ready(Link * link)162 static int ndisc_check_ready(Link *link) {
163         bool found = false, ready = false;
164         Address *address;
165         int r;
166 
167         assert(link);
168 
169         if (link->ndisc_messages > 0) {
170                 log_link_debug(link, "%s(): SLAAC addresses and routes are not set.", __func__);
171                 return 0;
172         }
173 
174         SET_FOREACH(address, link->addresses) {
175                 if (address->source != NETWORK_CONFIG_SOURCE_NDISC)
176                         continue;
177 
178                 found = true;
179 
180                 if (address_is_ready(address)) {
181                         ready = true;
182                         break;
183                 }
184         }
185 
186         if (found && !ready) {
187                 SET_FOREACH(address, link->addresses)
188                         if (address->source == NETWORK_CONFIG_SOURCE_NDISC)
189                                 address->callback = ndisc_address_ready_callback;
190 
191                 log_link_debug(link, "%s(): no SLAAC address is ready.", __func__);
192                 return 0;
193         }
194 
195         link->ndisc_configured = true;
196         log_link_debug(link, "SLAAC addresses and routes set.");
197 
198         r = ndisc_remove(link, NULL);
199         if (r < 0)
200                 return r;
201 
202         link_check_ready(link);
203         return 0;
204 }
205 
ndisc_route_handler(sd_netlink * rtnl,sd_netlink_message * m,Request * req,Link * link,Route * route)206 static int ndisc_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Route *route) {
207         int r;
208 
209         assert(link);
210 
211         r = route_configure_handler_internal(rtnl, m, link, "Could not set NDisc route");
212         if (r <= 0)
213                 return r;
214 
215         r = ndisc_check_ready(link);
216         if (r < 0)
217                 link_enter_failed(link);
218 
219         return 1;
220 }
221 
ndisc_request_route(Route * in,Link * link,sd_ndisc_router * rt)222 static int ndisc_request_route(Route *in, Link *link, sd_ndisc_router *rt) {
223         _cleanup_(route_freep) Route *route = in;
224         struct in6_addr router;
225         Route *existing;
226         int r;
227 
228         assert(route);
229         assert(link);
230         assert(rt);
231 
232         r = sd_ndisc_router_get_address(rt, &router);
233         if (r < 0)
234                 return r;
235 
236         route->source = NETWORK_CONFIG_SOURCE_NDISC;
237         route->provider.in6 = router;
238         if (!route->table_set)
239                 route->table = link_get_ipv6_accept_ra_route_table(link);
240         if (!route->priority_set)
241                 route->priority = link->network->ipv6_accept_ra_route_metric;
242         if (!route->protocol_set)
243                 route->protocol = RTPROT_RA;
244 
245         if (route_get(NULL, link, route, &existing) < 0)
246                 link->ndisc_configured = false;
247         else
248                 route_unmark(existing);
249 
250         return link_request_route(link, TAKE_PTR(route), true, &link->ndisc_messages,
251                                   ndisc_route_handler, NULL);
252 }
253 
ndisc_address_handler(sd_netlink * rtnl,sd_netlink_message * m,Request * req,Link * link,Address * address)254 static int ndisc_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) {
255         int r;
256 
257         assert(link);
258 
259         r = address_configure_handler_internal(rtnl, m, link, "Could not set NDisc address");
260         if (r <= 0)
261                 return r;
262 
263         r = ndisc_check_ready(link);
264         if (r < 0)
265                 link_enter_failed(link);
266 
267         return 1;
268 }
269 
ndisc_request_address(Address * in,Link * link,sd_ndisc_router * rt)270 static int ndisc_request_address(Address *in, Link *link, sd_ndisc_router *rt) {
271         _cleanup_(address_freep) Address *address = in;
272         struct in6_addr router;
273         Address *existing;
274         int r;
275 
276         assert(address);
277         assert(link);
278         assert(rt);
279 
280         r = sd_ndisc_router_get_address(rt, &router);
281         if (r < 0)
282                 return r;
283 
284         address->source = NETWORK_CONFIG_SOURCE_NDISC;
285         address->provider.in6 = router;
286 
287         if (address_get(link, address, &existing) < 0)
288                 link->ndisc_configured = false;
289         else
290                 address_unmark(existing);
291 
292         return link_request_address(link, TAKE_PTR(address), true, &link->ndisc_messages,
293                                  ndisc_address_handler, NULL);
294 }
295 
ndisc_router_process_default(Link * link,sd_ndisc_router * rt)296 static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
297         usec_t lifetime_usec, timestamp_usec;
298         struct in6_addr gateway;
299         uint16_t lifetime_sec;
300         unsigned preference;
301         uint32_t mtu = 0;
302         int r;
303 
304         assert(link);
305         assert(link->network);
306         assert(rt);
307 
308         if (!link->network->ipv6_accept_ra_use_gateway &&
309             hashmap_isempty(link->network->routes_by_section))
310                 return 0;
311 
312         r = sd_ndisc_router_get_lifetime(rt, &lifetime_sec);
313         if (r < 0)
314                 return log_link_error_errno(link, r, "Failed to get gateway lifetime from RA: %m");
315 
316         if (lifetime_sec == 0) /* not a default router */
317                 return 0;
318 
319         r = sd_ndisc_router_get_timestamp(rt, CLOCK_BOOTTIME, &timestamp_usec);
320         if (r < 0)
321                 return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");
322 
323         lifetime_usec = usec_add(timestamp_usec, lifetime_sec * USEC_PER_SEC);
324 
325         r = sd_ndisc_router_get_address(rt, &gateway);
326         if (r < 0)
327                 return log_link_error_errno(link, r, "Failed to get gateway address from RA: %m");
328 
329         if (link_get_ipv6_address(link, &gateway, 0, NULL) >= 0) {
330                 if (DEBUG_LOGGING) {
331                         _cleanup_free_ char *buffer = NULL;
332 
333                         (void) in6_addr_to_string(&gateway, &buffer);
334                         log_link_debug(link, "No NDisc route added, gateway %s matches local address",
335                                        strna(buffer));
336                 }
337                 return 0;
338         }
339 
340         r = sd_ndisc_router_get_preference(rt, &preference);
341         if (r < 0)
342                 return log_link_error_errno(link, r, "Failed to get default router preference from RA: %m");
343 
344         if (link->network->ipv6_accept_ra_use_mtu) {
345                 r = sd_ndisc_router_get_mtu(rt, &mtu);
346                 if (r < 0 && r != -ENODATA)
347                         return log_link_error_errno(link, r, "Failed to get default router MTU from RA: %m");
348         }
349 
350         if (link->network->ipv6_accept_ra_use_gateway) {
351                 _cleanup_(route_freep) Route *route = NULL;
352 
353                 r = route_new(&route);
354                 if (r < 0)
355                         return log_oom();
356 
357                 route->family = AF_INET6;
358                 route->pref = preference;
359                 route->gw_family = AF_INET6;
360                 route->gw.in6 = gateway;
361                 route->lifetime_usec = lifetime_usec;
362                 route->mtu = mtu;
363 
364                 r = ndisc_request_route(TAKE_PTR(route), link, rt);
365                 if (r < 0)
366                         return log_link_error_errno(link, r, "Could not request default route: %m");
367         }
368 
369         Route *route_gw;
370         HASHMAP_FOREACH(route_gw, link->network->routes_by_section) {
371                 _cleanup_(route_freep) Route *route = NULL;
372 
373                 if (!route_gw->gateway_from_dhcp_or_ra)
374                         continue;
375 
376                 if (route_gw->gw_family != AF_INET6)
377                         continue;
378 
379                 r = route_dup(route_gw, &route);
380                 if (r < 0)
381                         return r;
382 
383                 route->gw.in6 = gateway;
384                 if (!route->pref_set)
385                         route->pref = preference;
386                 route->lifetime_usec = lifetime_usec;
387                 if (route->mtu == 0)
388                         route->mtu = mtu;
389 
390                 r = ndisc_request_route(TAKE_PTR(route), link, rt);
391                 if (r < 0)
392                         return log_link_error_errno(link, r, "Could not request gateway: %m");
393         }
394 
395         return 0;
396 }
397 
ndisc_router_process_autonomous_prefix(Link * link,sd_ndisc_router * rt)398 static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *rt) {
399         uint32_t lifetime_valid_sec, lifetime_preferred_sec;
400         usec_t lifetime_valid_usec, lifetime_preferred_usec, timestamp_usec;
401         _cleanup_set_free_ Set *addresses = NULL;
402         struct in6_addr prefix, *a;
403         unsigned prefixlen;
404         int r;
405 
406         assert(link);
407         assert(link->network);
408         assert(rt);
409 
410         if (!link->network->ipv6_accept_ra_use_autonomous_prefix)
411                 return 0;
412 
413         r = sd_ndisc_router_get_timestamp(rt, CLOCK_BOOTTIME, &timestamp_usec);
414         if (r < 0)
415                 return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");
416 
417         r = sd_ndisc_router_prefix_get_address(rt, &prefix);
418         if (r < 0)
419                 return log_link_error_errno(link, r, "Failed to get prefix address: %m");
420 
421         r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen);
422         if (r < 0)
423                 return log_link_error_errno(link, r, "Failed to get prefix length: %m");
424 
425         /* ndisc_generate_addresses() below requires the prefix length <= 64. */
426         if (prefixlen > 64) {
427                 _cleanup_free_ char *buf = NULL;
428 
429                 (void) in6_addr_prefix_to_string(&prefix, prefixlen, &buf);
430                 log_link_debug(link, "Prefix is longer than 64, ignoring autonomous prefix %s.", strna(buf));
431                 return 0;
432         }
433 
434         r = sd_ndisc_router_prefix_get_valid_lifetime(rt, &lifetime_valid_sec);
435         if (r < 0)
436                 return log_link_error_errno(link, r, "Failed to get prefix valid lifetime: %m");
437 
438         if (lifetime_valid_sec == 0) {
439                 log_link_debug(link, "Ignoring prefix as its valid lifetime is zero.");
440                 return 0;
441         }
442 
443         r = sd_ndisc_router_prefix_get_preferred_lifetime(rt, &lifetime_preferred_sec);
444         if (r < 0)
445                 return log_link_error_errno(link, r, "Failed to get prefix preferred lifetime: %m");
446 
447         /* The preferred lifetime is never greater than the valid lifetime */
448         if (lifetime_preferred_sec > lifetime_valid_sec)
449                 return 0;
450 
451         lifetime_valid_usec = usec_add(lifetime_valid_sec * USEC_PER_SEC, timestamp_usec);
452         lifetime_preferred_usec = usec_add(lifetime_preferred_sec * USEC_PER_SEC, timestamp_usec);
453 
454         r = ndisc_generate_addresses(link, &prefix, prefixlen, &addresses);
455         if (r < 0)
456                 return log_link_error_errno(link, r, "Failed to generate SLAAC addresses: %m");
457 
458         SET_FOREACH(a, addresses) {
459                 _cleanup_(address_freep) Address *address = NULL;
460                 Address *e;
461 
462                 r = address_new(&address);
463                 if (r < 0)
464                         return log_oom();
465 
466                 address->family = AF_INET6;
467                 address->in_addr.in6 = *a;
468                 address->prefixlen = prefixlen;
469                 address->flags = IFA_F_NOPREFIXROUTE|IFA_F_MANAGETEMPADDR;
470                 address->lifetime_valid_usec = lifetime_valid_usec;
471                 address->lifetime_preferred_usec = lifetime_preferred_usec;
472 
473                 /* See RFC4862, section 5.5.3.e. But the following logic is deviated from RFC4862 by
474                  * honoring all valid lifetimes to improve the reaction of SLAAC to renumbering events.
475                  * See draft-ietf-6man-slaac-renum-02, section 4.2. */
476                 r = address_get(link, address, &e);
477                 if (r > 0) {
478                         /* If the address is already assigned, but not valid anymore, then refuse to
479                          * update the address, and it will be removed. */
480                         if (e->lifetime_valid_usec < timestamp_usec)
481                                 continue;
482                 }
483 
484                 r = ndisc_request_address(TAKE_PTR(address), link, rt);
485                 if (r < 0)
486                         return log_link_error_errno(link, r, "Could not request SLAAC address: %m");
487         }
488 
489         return 0;
490 }
491 
ndisc_router_process_onlink_prefix(Link * link,sd_ndisc_router * rt)492 static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) {
493         _cleanup_(route_freep) Route *route = NULL;
494         usec_t timestamp_usec;
495         uint32_t lifetime_sec;
496         unsigned prefixlen;
497         int r;
498 
499         assert(link);
500         assert(link->network);
501         assert(rt);
502 
503         if (!link->network->ipv6_accept_ra_use_onlink_prefix)
504                 return 0;
505 
506         r = sd_ndisc_router_prefix_get_valid_lifetime(rt, &lifetime_sec);
507         if (r < 0)
508                 return log_link_error_errno(link, r, "Failed to get prefix lifetime: %m");
509 
510         if (lifetime_sec == 0)
511                 return 0;
512 
513         r = sd_ndisc_router_get_timestamp(rt, CLOCK_BOOTTIME, &timestamp_usec);
514         if (r < 0)
515                 return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");
516 
517         r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen);
518         if (r < 0)
519                 return log_link_error_errno(link, r, "Failed to get prefix length: %m");
520 
521         r = route_new(&route);
522         if (r < 0)
523                 return log_oom();
524 
525         route->family = AF_INET6;
526         route->flags = RTM_F_PREFIX;
527         route->dst_prefixlen = prefixlen;
528         route->lifetime_usec = usec_add(timestamp_usec, lifetime_sec * USEC_PER_SEC);
529 
530         r = sd_ndisc_router_prefix_get_address(rt, &route->dst.in6);
531         if (r < 0)
532                 return log_link_error_errno(link, r, "Failed to get prefix address: %m");
533 
534         r = ndisc_request_route(TAKE_PTR(route), link, rt);
535         if (r < 0)
536                 return log_link_error_errno(link, r, "Could not request prefix route: %m");;
537 
538         return 0;
539 }
540 
ndisc_router_process_prefix(Link * link,sd_ndisc_router * rt)541 static int ndisc_router_process_prefix(Link *link, sd_ndisc_router *rt) {
542         unsigned prefixlen;
543         struct in6_addr a;
544         uint8_t flags;
545         int r;
546 
547         assert(link);
548         assert(link->network);
549         assert(rt);
550 
551         r = sd_ndisc_router_prefix_get_address(rt, &a);
552         if (r < 0)
553                 return log_link_error_errno(link, r, "Failed to get prefix address: %m");
554 
555         r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen);
556         if (r < 0)
557                 return log_link_error_errno(link, r, "Failed to get prefix length: %m");
558 
559         if (in6_prefix_is_filtered(&a, prefixlen, link->network->ndisc_allow_listed_prefix, link->network->ndisc_deny_listed_prefix)) {
560                 if (DEBUG_LOGGING) {
561                         _cleanup_free_ char *b = NULL;
562 
563                         (void) in6_addr_prefix_to_string(&a, prefixlen, &b);
564                         if (!set_isempty(link->network->ndisc_allow_listed_prefix))
565                                 log_link_debug(link, "Prefix '%s' is not in allow list, ignoring", strna(b));
566                         else
567                                 log_link_debug(link, "Prefix '%s' is in deny list, ignoring", strna(b));
568                 }
569                 return 0;
570         }
571 
572         r = sd_ndisc_router_prefix_get_flags(rt, &flags);
573         if (r < 0)
574                 return log_link_error_errno(link, r, "Failed to get RA prefix flags: %m");
575 
576         if (FLAGS_SET(flags, ND_OPT_PI_FLAG_ONLINK)) {
577                 r = ndisc_router_process_onlink_prefix(link, rt);
578                 if (r < 0)
579                         return r;
580         }
581 
582         if (FLAGS_SET(flags, ND_OPT_PI_FLAG_AUTO)) {
583                 r = ndisc_router_process_autonomous_prefix(link, rt);
584                 if (r < 0)
585                         return r;
586         }
587 
588         return 0;
589 }
590 
ndisc_router_process_route(Link * link,sd_ndisc_router * rt)591 static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
592         _cleanup_(route_freep) Route *route = NULL;
593         unsigned preference, prefixlen;
594         struct in6_addr gateway, dst;
595         uint32_t lifetime_sec;
596         usec_t timestamp_usec;
597         int r;
598 
599         assert(link);
600 
601         if (!link->network->ipv6_accept_ra_use_route_prefix)
602                 return 0;
603 
604         r = sd_ndisc_router_route_get_lifetime(rt, &lifetime_sec);
605         if (r < 0)
606                 return log_link_error_errno(link, r, "Failed to get route lifetime from RA: %m");
607 
608         if (lifetime_sec == 0)
609                 return 0;
610 
611         r = sd_ndisc_router_route_get_address(rt, &dst);
612         if (r < 0)
613                 return log_link_error_errno(link, r, "Failed to get route destination address: %m");
614 
615         r = sd_ndisc_router_route_get_prefixlen(rt, &prefixlen);
616         if (r < 0)
617                 return log_link_error_errno(link, r, "Failed to get route prefix length: %m");
618 
619         if (in6_addr_is_null(&dst) && prefixlen == 0) {
620                 log_link_debug(link, "Route prefix is ::/0, ignoring");
621                 return 0;
622         }
623 
624         if (in6_prefix_is_filtered(&dst, prefixlen, link->network->ndisc_allow_listed_route_prefix, link->network->ndisc_deny_listed_route_prefix)) {
625                 if (DEBUG_LOGGING) {
626                         _cleanup_free_ char *buf = NULL;
627 
628                         (void) in6_addr_prefix_to_string(&dst, prefixlen, &buf);
629                         if (!set_isempty(link->network->ndisc_allow_listed_route_prefix))
630                                 log_link_debug(link, "Route prefix '%s' is not in allow list, ignoring", strna(buf));
631                         else
632                                 log_link_debug(link, "Route prefix '%s' is in deny list, ignoring", strna(buf));
633                 }
634                 return 0;
635         }
636 
637         r = sd_ndisc_router_get_address(rt, &gateway);
638         if (r < 0)
639                 return log_link_error_errno(link, r, "Failed to get gateway address from RA: %m");
640 
641         if (link_get_ipv6_address(link, &gateway, 0, NULL) >= 0) {
642                 if (DEBUG_LOGGING) {
643                         _cleanup_free_ char *buf = NULL;
644 
645                         (void) in6_addr_to_string(&gateway, &buf);
646                         log_link_debug(link, "Advertised route gateway %s is local to the link, ignoring route", strna(buf));
647                 }
648                 return 0;
649         }
650 
651         r = sd_ndisc_router_route_get_preference(rt, &preference);
652         if (r < 0)
653                 return log_link_error_errno(link, r, "Failed to get default router preference from RA: %m");
654 
655         r = sd_ndisc_router_get_timestamp(rt, CLOCK_BOOTTIME, &timestamp_usec);
656         if (r < 0)
657                 return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");
658 
659         r = route_new(&route);
660         if (r < 0)
661                 return log_oom();
662 
663         route->family = AF_INET6;
664         route->pref = preference;
665         route->gw.in6 = gateway;
666         route->gw_family = AF_INET6;
667         route->dst.in6 = dst;
668         route->dst_prefixlen = prefixlen;
669         route->lifetime_usec = usec_add(timestamp_usec, lifetime_sec * USEC_PER_SEC);
670 
671         r = ndisc_request_route(TAKE_PTR(route), link, rt);
672         if (r < 0)
673                 return log_link_error_errno(link, r, "Could not request additional route: %m");
674 
675         return 0;
676 }
677 
ndisc_rdnss_hash_func(const NDiscRDNSS * x,struct siphash * state)678 static void ndisc_rdnss_hash_func(const NDiscRDNSS *x, struct siphash *state) {
679         siphash24_compress(&x->address, sizeof(x->address), state);
680 }
681 
ndisc_rdnss_compare_func(const NDiscRDNSS * a,const NDiscRDNSS * b)682 static int ndisc_rdnss_compare_func(const NDiscRDNSS *a, const NDiscRDNSS *b) {
683         return memcmp(&a->address, &b->address, sizeof(a->address));
684 }
685 
686 DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
687                 ndisc_rdnss_hash_ops,
688                 NDiscRDNSS,
689                 ndisc_rdnss_hash_func,
690                 ndisc_rdnss_compare_func,
691                 free);
692 
ndisc_router_process_rdnss(Link * link,sd_ndisc_router * rt)693 static int ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) {
694         usec_t lifetime_usec, timestamp_usec;
695         uint32_t lifetime_sec;
696         const struct in6_addr *a;
697         struct in6_addr router;
698         bool updated = false;
699         int n, r;
700 
701         assert(link);
702         assert(link->network);
703         assert(rt);
704 
705         if (!link->network->ipv6_accept_ra_use_dns)
706                 return 0;
707 
708         r = sd_ndisc_router_get_address(rt, &router);
709         if (r < 0)
710                 return log_link_error_errno(link, r, "Failed to get router address from RA: %m");
711 
712         r = sd_ndisc_router_get_timestamp(rt, CLOCK_BOOTTIME, &timestamp_usec);
713         if (r < 0)
714                 return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");
715 
716         r = sd_ndisc_router_rdnss_get_lifetime(rt, &lifetime_sec);
717         if (r < 0)
718                 return log_link_error_errno(link, r, "Failed to get RDNSS lifetime: %m");
719 
720         if (lifetime_sec == 0)
721                 return 0;
722 
723         lifetime_usec = usec_add(timestamp_usec, lifetime_sec * USEC_PER_SEC);
724 
725         n = sd_ndisc_router_rdnss_get_addresses(rt, &a);
726         if (n < 0)
727                 return log_link_error_errno(link, n, "Failed to get RDNSS addresses: %m");
728 
729         if (n >= (int) NDISC_RDNSS_MAX) {
730                 log_link_warning(link, "Too many RDNSS records per link. Only first %i records will be used.", NDISC_RDNSS_MAX);
731                 n = NDISC_RDNSS_MAX;
732         }
733 
734         for (int j = 0; j < n; j++) {
735                 _cleanup_free_ NDiscRDNSS *x = NULL;
736                 NDiscRDNSS *rdnss, d = {
737                         .address = a[j],
738                 };
739 
740                 rdnss = set_get(link->ndisc_rdnss, &d);
741                 if (rdnss) {
742                         rdnss->marked = false;
743                         rdnss->router = router;
744                         rdnss->lifetime_usec = lifetime_usec;
745                         continue;
746                 }
747 
748                 x = new(NDiscRDNSS, 1);
749                 if (!x)
750                         return log_oom();
751 
752                 *x = (NDiscRDNSS) {
753                         .address = a[j],
754                         .router = router,
755                         .lifetime_usec = lifetime_usec,
756                 };
757 
758                 r = set_ensure_consume(&link->ndisc_rdnss, &ndisc_rdnss_hash_ops, TAKE_PTR(x));
759                 if (r < 0)
760                         return log_oom();
761                 assert(r > 0);
762 
763                 updated = true;
764         }
765 
766         if (updated)
767                 link_dirty(link);
768 
769         return 0;
770 }
771 
ndisc_dnssl_hash_func(const NDiscDNSSL * x,struct siphash * state)772 static void ndisc_dnssl_hash_func(const NDiscDNSSL *x, struct siphash *state) {
773         siphash24_compress_string(NDISC_DNSSL_DOMAIN(x), state);
774 }
775 
ndisc_dnssl_compare_func(const NDiscDNSSL * a,const NDiscDNSSL * b)776 static int ndisc_dnssl_compare_func(const NDiscDNSSL *a, const NDiscDNSSL *b) {
777         return strcmp(NDISC_DNSSL_DOMAIN(a), NDISC_DNSSL_DOMAIN(b));
778 }
779 
780 DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
781                 ndisc_dnssl_hash_ops,
782                 NDiscDNSSL,
783                 ndisc_dnssl_hash_func,
784                 ndisc_dnssl_compare_func,
785                 free);
786 
ndisc_router_process_dnssl(Link * link,sd_ndisc_router * rt)787 static int ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) {
788         _cleanup_strv_free_ char **l = NULL;
789         usec_t lifetime_usec, timestamp_usec;
790         struct in6_addr router;
791         uint32_t lifetime_sec;
792         bool updated = false;
793         int r;
794 
795         assert(link);
796         assert(link->network);
797         assert(rt);
798 
799         if (link->network->ipv6_accept_ra_use_domains == DHCP_USE_DOMAINS_NO)
800                 return 0;
801 
802         r = sd_ndisc_router_get_address(rt, &router);
803         if (r < 0)
804                 return log_link_error_errno(link, r, "Failed to get router address from RA: %m");
805 
806         r = sd_ndisc_router_get_timestamp(rt, CLOCK_BOOTTIME, &timestamp_usec);
807         if (r < 0)
808                 return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");
809 
810         r = sd_ndisc_router_dnssl_get_lifetime(rt, &lifetime_sec);
811         if (r < 0)
812                 return log_link_error_errno(link, r, "Failed to get DNSSL lifetime: %m");
813 
814         if (lifetime_sec == 0)
815                 return 0;
816 
817         lifetime_usec = usec_add(timestamp_usec, lifetime_sec * USEC_PER_SEC);
818 
819         r = sd_ndisc_router_dnssl_get_domains(rt, &l);
820         if (r < 0)
821                 return log_link_error_errno(link, r, "Failed to get DNSSL addresses: %m");
822 
823         if (strv_length(l) >= NDISC_DNSSL_MAX) {
824                 log_link_warning(link, "Too many DNSSL records per link. Only first %i records will be used.", NDISC_DNSSL_MAX);
825                 STRV_FOREACH(j, l + NDISC_DNSSL_MAX)
826                         *j = mfree(*j);
827         }
828 
829         STRV_FOREACH(j, l) {
830                 _cleanup_free_ NDiscDNSSL *s = NULL;
831                 NDiscDNSSL *dnssl;
832 
833                 s = malloc0(ALIGN(sizeof(NDiscDNSSL)) + strlen(*j) + 1);
834                 if (!s)
835                         return log_oom();
836 
837                 strcpy(NDISC_DNSSL_DOMAIN(s), *j);
838 
839                 dnssl = set_get(link->ndisc_dnssl, s);
840                 if (dnssl) {
841                         dnssl->marked = false;
842                         dnssl->router = router;
843                         dnssl->lifetime_usec = lifetime_usec;
844                         continue;
845                 }
846 
847                 s->router = router;
848                 s->lifetime_usec = lifetime_usec;
849 
850                 r = set_ensure_consume(&link->ndisc_dnssl, &ndisc_dnssl_hash_ops, TAKE_PTR(s));
851                 if (r < 0)
852                         return log_oom();
853                 assert(r > 0);
854 
855                 updated = true;
856         }
857 
858         if (updated)
859                 link_dirty(link);
860 
861         return 0;
862 }
863 
ndisc_router_process_options(Link * link,sd_ndisc_router * rt)864 static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt) {
865         int r;
866 
867         assert(link);
868         assert(link->network);
869         assert(rt);
870 
871         for (r = sd_ndisc_router_option_rewind(rt); ; r = sd_ndisc_router_option_next(rt)) {
872                 uint8_t type;
873 
874                 if (r < 0)
875                         return log_link_error_errno(link, r, "Failed to iterate through options: %m");
876                 if (r == 0) /* EOF */
877                         return 0;
878 
879                 r = sd_ndisc_router_option_get_type(rt, &type);
880                 if (r < 0)
881                         return log_link_error_errno(link, r, "Failed to get RA option type: %m");
882 
883                 switch (type) {
884 
885                 case SD_NDISC_OPTION_PREFIX_INFORMATION:
886                         r = ndisc_router_process_prefix(link, rt);
887                         if (r < 0)
888                                 return r;
889                         break;
890 
891                 case SD_NDISC_OPTION_ROUTE_INFORMATION:
892                         r = ndisc_router_process_route(link, rt);
893                         if (r < 0)
894                                 return r;
895                         break;
896 
897                 case SD_NDISC_OPTION_RDNSS:
898                         r = ndisc_router_process_rdnss(link, rt);
899                         if (r < 0)
900                                 return r;
901                         break;
902 
903                 case SD_NDISC_OPTION_DNSSL:
904                         r = ndisc_router_process_dnssl(link, rt);
905                         if (r < 0)
906                                 return r;
907                         break;
908                 }
909         }
910 }
911 
ndisc_mark(Link * link,const struct in6_addr * router)912 static void ndisc_mark(Link *link, const struct in6_addr *router) {
913         NDiscRDNSS *rdnss;
914         NDiscDNSSL *dnssl;
915 
916         assert(link);
917         assert(router);
918 
919         link_mark_addresses(link, NETWORK_CONFIG_SOURCE_NDISC, router);
920         link_mark_routes(link, NETWORK_CONFIG_SOURCE_NDISC, router);
921 
922         SET_FOREACH(rdnss, link->ndisc_rdnss)
923                 if (in6_addr_equal(&rdnss->router, router))
924                         rdnss->marked = true;
925 
926         SET_FOREACH(dnssl, link->ndisc_dnssl)
927                 if (in6_addr_equal(&dnssl->router, router))
928                         dnssl->marked = true;
929 }
930 
ndisc_start_dhcp6_client(Link * link,sd_ndisc_router * rt)931 static int ndisc_start_dhcp6_client(Link *link, sd_ndisc_router *rt) {
932         int r;
933 
934         assert(link);
935         assert(link->network);
936 
937         switch (link->network->ipv6_accept_ra_start_dhcp6_client) {
938         case IPV6_ACCEPT_RA_START_DHCP6_CLIENT_NO:
939                 return 0;
940 
941         case IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES: {
942                 uint64_t flags;
943 
944                 r = sd_ndisc_router_get_flags(rt, &flags);
945                 if (r < 0)
946                         return log_link_warning_errno(link, r, "Failed to get RA flags: %m");
947 
948                 if ((flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER)) == 0)
949                         return 0;
950 
951                 /* (re)start DHCPv6 client in stateful or stateless mode according to RA flags.
952                  * Note, if both "managed" and "other configuration" bits are set, then ignore
953                  * "other configuration" bit. See RFC 4861. */
954                 r = dhcp6_start_on_ra(link, !(flags & ND_RA_FLAG_MANAGED));
955                 break;
956         }
957         case IPV6_ACCEPT_RA_START_DHCP6_CLIENT_ALWAYS:
958                 /* When IPv6AcceptRA.DHCPv6Client=always, start dhcp6 client in solicit mode
959                  * even if the router flags have neither M nor O flags. */
960                 r = dhcp6_start_on_ra(link, /* information_request = */ false);
961                 break;
962 
963         default:
964                 assert_not_reached();
965         }
966 
967         if (r < 0)
968                 return log_link_error_errno(link, r, "Could not acquire DHCPv6 lease on NDisc request: %m");
969 
970         log_link_debug(link, "Acquiring DHCPv6 lease on NDisc request");
971         return 0;
972 }
973 
ndisc_router_handler(Link * link,sd_ndisc_router * rt)974 static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
975         struct in6_addr router;
976         int r;
977 
978         assert(link);
979         assert(link->network);
980         assert(link->manager);
981         assert(rt);
982 
983         r = sd_ndisc_router_get_address(rt, &router);
984         if (r < 0)
985                 return log_link_error_errno(link, r, "Failed to get router address from RA: %m");
986 
987         if (in6_prefix_is_filtered(&router, 128, link->network->ndisc_allow_listed_router, link->network->ndisc_deny_listed_router)) {
988                 if (DEBUG_LOGGING) {
989                         _cleanup_free_ char *buf = NULL;
990 
991                         (void) in6_addr_to_string(&router, &buf);
992                         if (!set_isempty(link->network->ndisc_allow_listed_router))
993                                 log_link_debug(link, "Router '%s' is not in allow list, ignoring", strna(buf));
994                         else
995                                 log_link_debug(link, "Router '%s' is in deny list, ignoring", strna(buf));
996                 }
997                 return 0;
998         }
999 
1000         ndisc_mark(link, &router);
1001 
1002         r = ndisc_start_dhcp6_client(link, rt);
1003         if (r < 0)
1004                 return r;
1005 
1006         r = ndisc_router_process_default(link, rt);
1007         if (r < 0)
1008                 return r;
1009 
1010         r = ndisc_router_process_options(link, rt);
1011         if (r < 0)
1012                 return r;
1013 
1014         if (link->ndisc_messages == 0) {
1015                 link->ndisc_configured = true;
1016 
1017                 r = ndisc_remove(link, &router);
1018                 if (r < 0)
1019                         return r;
1020         } else
1021                 log_link_debug(link, "Setting SLAAC addresses and router.");
1022 
1023         if (!link->ndisc_configured)
1024                 link_set_state(link, LINK_STATE_CONFIGURING);
1025 
1026         link_check_ready(link);
1027         return 0;
1028 }
1029 
ndisc_handler(sd_ndisc * nd,sd_ndisc_event_t event,sd_ndisc_router * rt,void * userdata)1030 static void ndisc_handler(sd_ndisc *nd, sd_ndisc_event_t event, sd_ndisc_router *rt, void *userdata) {
1031         Link *link = userdata;
1032         int r;
1033 
1034         assert(link);
1035 
1036         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1037                 return;
1038 
1039         switch (event) {
1040 
1041         case SD_NDISC_EVENT_ROUTER:
1042                 r = ndisc_router_handler(link, rt);
1043                 if (r < 0) {
1044                         link_enter_failed(link);
1045                         return;
1046                 }
1047                 break;
1048 
1049         case SD_NDISC_EVENT_TIMEOUT:
1050                 log_link_debug(link, "NDisc handler get timeout event");
1051                 if (link->ndisc_messages == 0) {
1052                         link->ndisc_configured = true;
1053                         link_check_ready(link);
1054                 }
1055                 break;
1056         default:
1057                 assert_not_reached();
1058         }
1059 }
1060 
ndisc_configure(Link * link)1061 static int ndisc_configure(Link *link) {
1062         int r;
1063 
1064         assert(link);
1065 
1066         if (!link_ipv6_accept_ra_enabled(link))
1067                 return 0;
1068 
1069         if (link->ndisc)
1070                 return -EBUSY; /* Already configured. */
1071 
1072         r = sd_ndisc_new(&link->ndisc);
1073         if (r < 0)
1074                 return r;
1075 
1076         r = sd_ndisc_attach_event(link->ndisc, link->manager->event, 0);
1077         if (r < 0)
1078                 return r;
1079 
1080         r = sd_ndisc_set_mac(link->ndisc, &link->hw_addr.ether);
1081         if (r < 0)
1082                 return r;
1083 
1084         r = sd_ndisc_set_ifindex(link->ndisc, link->ifindex);
1085         if (r < 0)
1086                 return r;
1087 
1088         r = sd_ndisc_set_callback(link->ndisc, ndisc_handler, link);
1089         if (r < 0)
1090                 return r;
1091 
1092         return 0;
1093 }
1094 
ndisc_start(Link * link)1095 int ndisc_start(Link *link) {
1096         int r;
1097 
1098         assert(link);
1099 
1100         if (!link->ndisc || !link->dhcp6_client)
1101                 return 0;
1102 
1103         if (!link_has_carrier(link))
1104                 return 0;
1105 
1106         if (in6_addr_is_null(&link->ipv6ll_address))
1107                 return 0;
1108 
1109         log_link_debug(link, "Discovering IPv6 routers");
1110 
1111         r = sd_ndisc_start(link->ndisc);
1112         if (r < 0)
1113                 return r;
1114 
1115         return 1;
1116 }
1117 
ndisc_process_request(Request * req,Link * link,void * userdata)1118 static int ndisc_process_request(Request *req, Link *link, void *userdata) {
1119         int r;
1120 
1121         assert(link);
1122 
1123         if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
1124                 return 0;
1125 
1126         if (link->hw_addr.length != ETH_ALEN || hw_addr_is_null(&link->hw_addr))
1127                 /* No MAC address is assigned to the hardware, or non-supported MAC address length. */
1128                 return 0;
1129 
1130         r = ndisc_configure(link);
1131         if (r < 0)
1132                 return log_link_warning_errno(link, r, "Failed to configure IPv6 Router Discovery: %m");
1133 
1134         r = ndisc_start(link);
1135         if (r < 0)
1136                 return log_link_warning_errno(link, r, "Failed to start IPv6 Router Discovery: %m");
1137 
1138         log_link_debug(link, "IPv6 Router Discovery is configured%s.",
1139                        r > 0 ? " and started" : "");
1140         return 1;
1141 }
1142 
link_request_ndisc(Link * link)1143 int link_request_ndisc(Link *link) {
1144         int r;
1145 
1146         assert(link);
1147 
1148         if (!link_ipv6_accept_ra_enabled(link))
1149                 return 0;
1150 
1151         if (link->ndisc)
1152                 return 0;
1153 
1154         r = link_queue_request(link, REQUEST_TYPE_NDISC, ndisc_process_request, NULL);
1155         if (r < 0)
1156                 return log_link_warning_errno(link, r, "Failed to request configuring of the IPv6 Router Discovery: %m");
1157 
1158         log_link_debug(link, "Requested configuring of the IPv6 Router Discovery.");
1159         return 0;
1160 }
1161 
ndisc_vacuum(Link * link)1162 void ndisc_vacuum(Link *link) {
1163         NDiscRDNSS *r;
1164         NDiscDNSSL *d;
1165         usec_t time_now;
1166 
1167         assert(link);
1168 
1169         /* Removes all RDNSS and DNSSL entries whose validity time has passed */
1170 
1171         time_now = now(CLOCK_BOOTTIME);
1172 
1173         SET_FOREACH(r, link->ndisc_rdnss)
1174                 if (r->lifetime_usec < time_now)
1175                         free(set_remove(link->ndisc_rdnss, r));
1176 
1177         SET_FOREACH(d, link->ndisc_dnssl)
1178                 if (d->lifetime_usec < time_now)
1179                         free(set_remove(link->ndisc_dnssl, d));
1180 }
1181 
ndisc_flush(Link * link)1182 void ndisc_flush(Link *link) {
1183         assert(link);
1184 
1185         /* Removes all RDNSS and DNSSL entries, without exception */
1186 
1187         link->ndisc_rdnss = set_free(link->ndisc_rdnss);
1188         link->ndisc_dnssl = set_free(link->ndisc_dnssl);
1189 }
1190 
1191 static const char* const ipv6_accept_ra_start_dhcp6_client_table[_IPV6_ACCEPT_RA_START_DHCP6_CLIENT_MAX] = {
1192         [IPV6_ACCEPT_RA_START_DHCP6_CLIENT_NO]     = "no",
1193         [IPV6_ACCEPT_RA_START_DHCP6_CLIENT_ALWAYS] = "always",
1194         [IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES]    = "yes",
1195 };
1196 
1197 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(ipv6_accept_ra_start_dhcp6_client, IPv6AcceptRAStartDHCP6Client, IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES);
1198 
1199 DEFINE_CONFIG_PARSE_ENUM(config_parse_ipv6_accept_ra_use_domains, dhcp_use_domains, DHCPUseDomains,
1200                          "Failed to parse UseDomains= setting");
1201 DEFINE_CONFIG_PARSE_ENUM(config_parse_ipv6_accept_ra_start_dhcp6_client, ipv6_accept_ra_start_dhcp6_client, IPv6AcceptRAStartDHCP6Client,
1202                          "Failed to parse DHCPv6Client= setting");
1203