]> git.proxmox.com Git - systemd.git/blob - src/network/networkd-ndisc.c
New upstream version 249~rc1
[systemd.git] / src / network / networkd-ndisc.c
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 <net/if_arp.h>
9 #include <linux/if.h>
10
11 #include "sd-ndisc.h"
12
13 #include "missing_network.h"
14 #include "networkd-address.h"
15 #include "networkd-dhcp6.h"
16 #include "networkd-manager.h"
17 #include "networkd-ndisc.h"
18 #include "networkd-queue.h"
19 #include "networkd-state-file.h"
20 #include "string-table.h"
21 #include "string-util.h"
22 #include "strv.h"
23
24 #define NDISC_DNSSL_MAX 64U
25 #define NDISC_RDNSS_MAX 64U
26
27 #define DAD_CONFLICTS_IDGEN_RETRIES_RFC7217 3
28
29 /* https://tools.ietf.org/html/rfc5453 */
30 /* https://www.iana.org/assignments/ipv6-interface-ids/ipv6-interface-ids.xml */
31
32 #define SUBNET_ROUTER_ANYCAST_ADDRESS_RFC4291 ((struct in6_addr) { .s6_addr = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } })
33 #define SUBNET_ROUTER_ANYCAST_PREFIXLEN 8
34 #define RESERVED_IPV6_INTERFACE_IDENTIFIERS_ADDRESS_RFC4291 ((struct in6_addr) { .s6_addr = { 0x02, 0x00, 0x5E, 0xFF, 0xFE } })
35 #define RESERVED_IPV6_INTERFACE_IDENTIFIERS_PREFIXLEN 5
36 #define RESERVED_SUBNET_ANYCAST_ADDRESSES_RFC4291 ((struct in6_addr) { .s6_addr = { 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } })
37 #define RESERVED_SUBNET_ANYCAST_PREFIXLEN 7
38
39 #define NDISC_APP_ID SD_ID128_MAKE(13,ac,81,a7,d5,3f,49,78,92,79,5d,0c,29,3a,bc,7e)
40
41 bool link_ipv6_accept_ra_enabled(Link *link) {
42 assert(link);
43
44 if (!socket_ipv6_is_supported())
45 return false;
46
47 if (link->flags & IFF_LOOPBACK)
48 return false;
49
50 if (!link->network)
51 return false;
52
53 if (!link_ipv6ll_enabled(link))
54 return false;
55
56 assert(link->network->ipv6_accept_ra >= 0);
57 return link->network->ipv6_accept_ra;
58 }
59
60 void network_adjust_ipv6_accept_ra(Network *network) {
61 assert(network);
62
63 if (!FLAGS_SET(network->link_local, ADDRESS_FAMILY_IPV6)) {
64 if (network->ipv6_accept_ra > 0)
65 log_warning("%s: IPv6AcceptRA= is enabled but IPv6 link local addressing is disabled or not supported. "
66 "Disabling IPv6AcceptRA=.", network->filename);
67 network->ipv6_accept_ra = false;
68 }
69
70 if (network->ipv6_accept_ra < 0)
71 /* default to accept RA if ip_forward is disabled and ignore RA if ip_forward is enabled */
72 network->ipv6_accept_ra = !FLAGS_SET(network->ip_forward, ADDRESS_FAMILY_IPV6);
73
74 /* When RouterAllowList=, PrefixAllowList= or RouteAllowList= are specified, then
75 * RouterDenyList=, PrefixDenyList= or RouteDenyList= are ignored, respectively. */
76 if (!set_isempty(network->ndisc_allow_listed_router))
77 network->ndisc_deny_listed_router = set_free_free(network->ndisc_deny_listed_router);
78 if (!set_isempty(network->ndisc_allow_listed_prefix))
79 network->ndisc_deny_listed_prefix = set_free_free(network->ndisc_deny_listed_prefix);
80 if (!set_isempty(network->ndisc_allow_listed_route_prefix))
81 network->ndisc_deny_listed_route_prefix = set_free_free(network->ndisc_deny_listed_route_prefix);
82 }
83
84 static int ndisc_remove_old_one(Link *link, const struct in6_addr *router, bool force);
85
86 static int ndisc_address_callback(Address *address) {
87 struct in6_addr router = {};
88 NDiscAddress *n;
89
90 assert(address);
91 assert(address->link);
92 assert(address->family == AF_INET6);
93
94 SET_FOREACH(n, address->link->ndisc_addresses)
95 if (n->address == address) {
96 router = n->router;
97 break;
98 }
99
100 if (in6_addr_is_null(&router)) {
101 _cleanup_free_ char *buf = NULL;
102
103 (void) in6_addr_prefix_to_string(&address->in_addr.in6, address->prefixlen, &buf);
104 log_link_debug(address->link, "%s is called for %s, but it is already removed, ignoring.",
105 __func__, strna(buf));
106 return 0;
107 }
108
109 /* Make this called only once */
110 SET_FOREACH(n, address->link->ndisc_addresses)
111 if (in6_addr_equal(&n->router, &router))
112 n->address->callback = NULL;
113
114 return ndisc_remove_old_one(address->link, &router, true);
115 }
116
117 static int ndisc_remove_old_one(Link *link, const struct in6_addr *router, bool force) {
118 NDiscAddress *na;
119 NDiscRoute *nr;
120 NDiscDNSSL *dnssl;
121 NDiscRDNSS *rdnss;
122 int k, r = 0;
123 bool updated = false;
124
125 assert(link);
126 assert(router);
127
128 if (!force) {
129 bool set_callback = false;
130
131 if (!link->ndisc_addresses_configured || !link->ndisc_routes_configured)
132 return 0;
133
134 SET_FOREACH(na, link->ndisc_addresses)
135 if (!na->marked && in6_addr_equal(&na->router, router)) {
136 set_callback = true;
137 break;
138 }
139
140 if (set_callback)
141 SET_FOREACH(na, link->ndisc_addresses)
142 if (!na->marked && address_is_ready(na->address)) {
143 set_callback = false;
144 break;
145 }
146
147 if (set_callback) {
148 SET_FOREACH(na, link->ndisc_addresses)
149 if (!na->marked && in6_addr_equal(&na->router, router))
150 na->address->callback = ndisc_address_callback;
151
152 if (DEBUG_LOGGING) {
153 _cleanup_free_ char *buf = NULL;
154
155 (void) in6_addr_to_string(router, &buf);
156 log_link_debug(link, "No SLAAC address obtained from %s is ready. "
157 "The old NDisc information will be removed later.",
158 strna(buf));
159 }
160 return 0;
161 }
162 }
163
164 if (DEBUG_LOGGING) {
165 _cleanup_free_ char *buf = NULL;
166
167 (void) in6_addr_to_string(router, &buf);
168 log_link_debug(link, "Removing old NDisc information obtained from %s.", strna(buf));
169 }
170
171 SET_FOREACH(na, link->ndisc_addresses)
172 if (na->marked && in6_addr_equal(&na->router, router)) {
173 k = address_remove(na->address, link);
174 if (k < 0)
175 r = k;
176 }
177
178 SET_FOREACH(nr, link->ndisc_routes)
179 if (nr->marked && in6_addr_equal(&nr->router, router)) {
180 k = route_remove(nr->route, NULL, link);
181 if (k < 0)
182 r = k;
183 }
184
185 SET_FOREACH(rdnss, link->ndisc_rdnss)
186 if (rdnss->marked && in6_addr_equal(&rdnss->router, router)) {
187 free(set_remove(link->ndisc_rdnss, rdnss));
188 updated = true;
189 }
190
191 SET_FOREACH(dnssl, link->ndisc_dnssl)
192 if (dnssl->marked && in6_addr_equal(&dnssl->router, router)) {
193 free(set_remove(link->ndisc_dnssl, dnssl));
194 updated = true;
195 }
196
197 if (updated)
198 link_dirty(link);
199
200 return r;
201 }
202
203 static int ndisc_remove_old(Link *link) {
204 _cleanup_set_free_free_ Set *routers = NULL;
205 _cleanup_free_ struct in6_addr *router = NULL;
206 struct in6_addr *a;
207 NDiscAddress *na;
208 NDiscRoute *nr;
209 NDiscDNSSL *dnssl;
210 NDiscRDNSS *rdnss;
211 int k, r;
212
213 assert(link);
214
215 routers = set_new(&in6_addr_hash_ops);
216 if (!routers)
217 return -ENOMEM;
218
219 SET_FOREACH(na, link->ndisc_addresses)
220 if (!set_contains(routers, &na->router)) {
221 router = newdup(struct in6_addr, &na->router, 1);
222 if (!router)
223 return -ENOMEM;
224
225 r = set_put(routers, router);
226 if (r < 0)
227 return r;
228
229 assert(r > 0);
230 TAKE_PTR(router);
231 }
232
233 SET_FOREACH(nr, link->ndisc_routes)
234 if (!set_contains(routers, &nr->router)) {
235 router = newdup(struct in6_addr, &nr->router, 1);
236 if (!router)
237 return -ENOMEM;
238
239 r = set_put(routers, router);
240 if (r < 0)
241 return r;
242
243 assert(r > 0);
244 TAKE_PTR(router);
245 }
246
247 SET_FOREACH(rdnss, link->ndisc_rdnss)
248 if (!set_contains(routers, &rdnss->router)) {
249 router = newdup(struct in6_addr, &rdnss->router, 1);
250 if (!router)
251 return -ENOMEM;
252
253 r = set_put(routers, router);
254 if (r < 0)
255 return r;
256
257 assert(r > 0);
258 TAKE_PTR(router);
259 }
260
261 SET_FOREACH(dnssl, link->ndisc_dnssl)
262 if (!set_contains(routers, &dnssl->router)) {
263 router = newdup(struct in6_addr, &dnssl->router, 1);
264 if (!router)
265 return -ENOMEM;
266
267 r = set_put(routers, router);
268 if (r < 0)
269 return r;
270
271 assert(r > 0);
272 TAKE_PTR(router);
273 }
274
275 r = 0;
276 SET_FOREACH(a, routers) {
277 k = ndisc_remove_old_one(link, a, false);
278 if (k < 0)
279 r = k;
280 }
281
282 return r;
283 }
284
285 static void ndisc_route_hash_func(const NDiscRoute *x, struct siphash *state) {
286 route_hash_func(x->route, state);
287 }
288
289 static int ndisc_route_compare_func(const NDiscRoute *a, const NDiscRoute *b) {
290 return route_compare_func(a->route, b->route);
291 }
292
293 DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
294 ndisc_route_hash_ops,
295 NDiscRoute,
296 ndisc_route_hash_func,
297 ndisc_route_compare_func,
298 free);
299
300 static int ndisc_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
301 int r;
302
303 assert(link);
304 assert(link->ndisc_routes_messages > 0);
305
306 link->ndisc_routes_messages--;
307
308 r = route_configure_handler_internal(rtnl, m, link, "Could not set NDisc route");
309 if (r <= 0)
310 return r;
311
312 if (link->ndisc_routes_messages == 0) {
313 log_link_debug(link, "NDisc routes set.");
314 link->ndisc_routes_configured = true;
315
316 r = ndisc_remove_old(link);
317 if (r < 0) {
318 link_enter_failed(link);
319 return 1;
320 }
321
322 link_check_ready(link);
323 }
324
325 return 1;
326 }
327
328 static int ndisc_after_route_configure(Request *req, void *object) {
329 _cleanup_free_ NDiscRoute *nr = NULL;
330 NDiscRoute *nr_exist;
331 struct in6_addr router;
332 Route *route = object;
333 sd_ndisc_router *rt;
334 Link *link;
335 int r;
336
337 assert(req);
338 assert(req->link);
339 assert(req->type == REQUEST_TYPE_ROUTE);
340 assert(req->userdata);
341 assert(route);
342
343 link = req->link;
344 rt = req->userdata;
345
346 r = sd_ndisc_router_get_address(rt, &router);
347 if (r < 0)
348 return log_link_error_errno(link, r, "Failed to get router address from RA: %m");
349
350 nr = new(NDiscRoute, 1);
351 if (!nr)
352 return log_oom();
353
354 *nr = (NDiscRoute) {
355 .router = router,
356 .route = route,
357 };
358
359 nr_exist = set_get(link->ndisc_routes, nr);
360 if (nr_exist) {
361 nr_exist->marked = false;
362 nr_exist->router = router;
363 return 0;
364 }
365
366 r = set_ensure_put(&link->ndisc_routes, &ndisc_route_hash_ops, nr);
367 if (r < 0)
368 return log_link_error_errno(link, r, "Failed to store NDisc SLAAC route: %m");
369 assert(r > 0);
370 TAKE_PTR(nr);
371
372 return 0;
373 }
374
375 static void ndisc_request_on_free(Request *req) {
376 assert(req);
377
378 sd_ndisc_router_unref(req->userdata);
379 }
380
381 static int ndisc_request_route(Route *in, Link *link, sd_ndisc_router *rt) {
382 _cleanup_(route_freep) Route *route = in;
383 Request *req;
384 int r;
385
386 assert(route);
387 assert(link);
388 assert(rt);
389
390 r = link_has_route(link, route);
391 if (r < 0)
392 return r;
393 if (r == 0)
394 link->ndisc_routes_configured = false;
395
396 r = link_request_route(link, TAKE_PTR(route), true, &link->ndisc_routes_messages,
397 ndisc_route_handler, &req);
398 if (r <= 0)
399 return r;
400
401 req->userdata = sd_ndisc_router_ref(rt);
402 req->after_configure = ndisc_after_route_configure;
403 req->on_free = ndisc_request_on_free;
404
405 return 0;
406 }
407
408 static void ndisc_address_hash_func(const NDiscAddress *x, struct siphash *state) {
409 address_hash_func(x->address, state);
410 }
411
412 static int ndisc_address_compare_func(const NDiscAddress *a, const NDiscAddress *b) {
413 return address_compare_func(a->address, b->address);
414 }
415
416 DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
417 ndisc_address_hash_ops,
418 NDiscAddress,
419 ndisc_address_hash_func,
420 ndisc_address_compare_func,
421 free);
422
423 static int ndisc_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
424 int r;
425
426 assert(link);
427 assert(link->ndisc_addresses_messages > 0);
428
429 link->ndisc_addresses_messages--;
430
431 r = address_configure_handler_internal(rtnl, m, link, "Could not set NDisc address");
432 if (r <= 0)
433 return r;
434
435 if (link->ndisc_addresses_messages == 0) {
436 log_link_debug(link, "NDisc SLAAC addresses set.");
437 link->ndisc_addresses_configured = true;
438
439 r = ndisc_remove_old(link);
440 if (r < 0) {
441 link_enter_failed(link);
442 return 1;
443 }
444 }
445
446 return 1;
447 }
448
449 static int ndisc_after_address_configure(Request *req, void *object) {
450 _cleanup_free_ NDiscAddress *na = NULL;
451 NDiscAddress *na_exist;
452 struct in6_addr router;
453 sd_ndisc_router *rt;
454 Address *address = object;
455 Link *link;
456 int r;
457
458 assert(req);
459 assert(req->link);
460 assert(req->type == REQUEST_TYPE_ADDRESS);
461 assert(req->userdata);
462 assert(address);
463
464 link = req->link;
465 rt = req->userdata;
466
467 r = sd_ndisc_router_get_address(rt, &router);
468 if (r < 0)
469 return log_link_error_errno(link, r, "Failed to get router address from RA: %m");
470
471 na = new(NDiscAddress, 1);
472 if (!na)
473 return log_oom();
474
475 *na = (NDiscAddress) {
476 .router = router,
477 .address = address,
478 };
479
480 na_exist = set_get(link->ndisc_addresses, na);
481 if (na_exist) {
482 na_exist->marked = false;
483 na_exist->router = router;
484 return 0;
485 }
486
487 r = set_ensure_put(&link->ndisc_addresses, &ndisc_address_hash_ops, na);
488 if (r < 0)
489 return log_link_error_errno(link, r, "Failed to store NDisc SLAAC address: %m");
490 assert(r > 0);
491 TAKE_PTR(na);
492
493 return 0;
494 }
495
496 static int ndisc_request_address(Address *in, Link *link, sd_ndisc_router *rt) {
497 _cleanup_(address_freep) Address *address = in;
498 Request *req;
499 int r;
500
501 assert(address);
502 assert(link);
503 assert(rt);
504
505 if (address_get(link, address, NULL) < 0)
506 link->ndisc_addresses_configured = false;
507
508 r = link_request_address(link, TAKE_PTR(address), true, &link->ndisc_addresses_messages,
509 ndisc_address_handler, &req);
510 if (r <= 0)
511 return r;
512
513 req->userdata = sd_ndisc_router_ref(rt);
514 req->after_configure = ndisc_after_address_configure;
515 req->on_free = ndisc_request_on_free;
516
517 return 0;
518 }
519
520 static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
521 _cleanup_(route_freep) Route *route = NULL;
522 struct in6_addr gateway;
523 uint16_t lifetime;
524 unsigned preference;
525 uint32_t table, mtu;
526 usec_t time_now;
527 int r;
528
529 assert(link);
530 assert(rt);
531
532 r = sd_ndisc_router_get_lifetime(rt, &lifetime);
533 if (r < 0)
534 return log_link_error_errno(link, r, "Failed to get gateway lifetime from RA: %m");
535
536 if (lifetime == 0) /* not a default router */
537 return 0;
538
539 r = sd_ndisc_router_get_address(rt, &gateway);
540 if (r < 0)
541 return log_link_error_errno(link, r, "Failed to get gateway address from RA: %m");
542
543 if (link_get_ipv6_address(link, &gateway, NULL) >= 0) {
544 if (DEBUG_LOGGING) {
545 _cleanup_free_ char *buffer = NULL;
546
547 (void) in6_addr_to_string(&gateway, &buffer);
548 log_link_debug(link, "No NDisc route added, gateway %s matches local address",
549 strna(buffer));
550 }
551 return 0;
552 }
553
554 r = sd_ndisc_router_get_preference(rt, &preference);
555 if (r < 0)
556 return log_link_error_errno(link, r, "Failed to get default router preference from RA: %m");
557
558 r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
559 if (r < 0)
560 return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");
561
562 r = sd_ndisc_router_get_mtu(rt, &mtu);
563 if (r == -ENODATA)
564 mtu = 0;
565 else if (r < 0)
566 return log_link_error_errno(link, r, "Failed to get default router MTU from RA: %m");
567
568 table = link_get_ipv6_accept_ra_route_table(link);
569
570 r = route_new(&route);
571 if (r < 0)
572 return log_oom();
573
574 route->family = AF_INET6;
575 route->table = table;
576 route->priority = link->network->ipv6_accept_ra_route_metric;
577 route->protocol = RTPROT_RA;
578 route->pref = preference;
579 route->gw_family = AF_INET6;
580 route->gw.in6 = gateway;
581 route->lifetime = usec_add(time_now, lifetime * USEC_PER_SEC);
582 route->mtu = mtu;
583
584 r = ndisc_request_route(TAKE_PTR(route), link, rt);
585 if (r < 0)
586 return log_link_error_errno(link, r, "Could not request default route: %m");
587
588 Route *route_gw;
589 HASHMAP_FOREACH(route_gw, link->network->routes_by_section) {
590 if (!route_gw->gateway_from_dhcp_or_ra)
591 continue;
592
593 if (route_gw->gw_family != AF_INET6)
594 continue;
595
596 r = route_dup(route_gw, &route);
597 if (r < 0)
598 return r;
599
600 route->gw.in6 = gateway;
601 if (!route->table_set)
602 route->table = table;
603 if (!route->priority_set)
604 route->priority = link->network->ipv6_accept_ra_route_metric;
605 if (!route->protocol_set)
606 route->protocol = RTPROT_RA;
607 if (!route->pref_set)
608 route->pref = preference;
609 route->lifetime = usec_add(time_now, lifetime * USEC_PER_SEC);
610 if (route->mtu == 0)
611 route->mtu = mtu;
612
613 r = ndisc_request_route(TAKE_PTR(route), link, rt);
614 if (r < 0)
615 return log_link_error_errno(link, r, "Could not request gateway: %m");
616 }
617
618 return 0;
619 }
620
621 static bool stableprivate_address_is_valid(const struct in6_addr *addr) {
622 assert(addr);
623
624 /* According to rfc4291, generated address should not be in the following ranges. */
625
626 if (memcmp(addr, &SUBNET_ROUTER_ANYCAST_ADDRESS_RFC4291, SUBNET_ROUTER_ANYCAST_PREFIXLEN) == 0)
627 return false;
628
629 if (memcmp(addr, &RESERVED_IPV6_INTERFACE_IDENTIFIERS_ADDRESS_RFC4291, RESERVED_IPV6_INTERFACE_IDENTIFIERS_PREFIXLEN) == 0)
630 return false;
631
632 if (memcmp(addr, &RESERVED_SUBNET_ANYCAST_ADDRESSES_RFC4291, RESERVED_SUBNET_ANYCAST_PREFIXLEN) == 0)
633 return false;
634
635 return true;
636 }
637
638 static int make_stableprivate_address(Link *link, const struct in6_addr *prefix, uint8_t prefix_len, uint8_t dad_counter, struct in6_addr **ret) {
639 _cleanup_free_ struct in6_addr *addr = NULL;
640 sd_id128_t secret_key;
641 struct siphash state;
642 uint64_t rid;
643 size_t l;
644 int r;
645
646 /* According to rfc7217 section 5.1
647 * RID = F(Prefix, Net_Iface, Network_ID, DAD_Counter, secret_key) */
648
649 r = sd_id128_get_machine_app_specific(NDISC_APP_ID, &secret_key);
650 if (r < 0)
651 return log_error_errno(r, "Failed to generate key: %m");
652
653 siphash24_init(&state, secret_key.bytes);
654
655 l = MAX(DIV_ROUND_UP(prefix_len, 8), 8);
656 siphash24_compress(prefix, l, &state);
657 siphash24_compress_string(link->ifname, &state);
658 /* Only last 8 bytes of IB MAC are stable */
659 if (link->iftype == ARPHRD_INFINIBAND)
660 siphash24_compress(&link->hw_addr.infiniband[12], 8, &state);
661 else
662 siphash24_compress(link->hw_addr.bytes, link->hw_addr.length, &state);
663 siphash24_compress(&dad_counter, sizeof(uint8_t), &state);
664
665 rid = htole64(siphash24_finalize(&state));
666
667 addr = new(struct in6_addr, 1);
668 if (!addr)
669 return log_oom();
670
671 memcpy(addr->s6_addr, prefix->s6_addr, l);
672 memcpy(addr->s6_addr + l, &rid, 16 - l);
673
674 if (!stableprivate_address_is_valid(addr)) {
675 *ret = NULL;
676 return 0;
677 }
678
679 *ret = TAKE_PTR(addr);
680 return 1;
681 }
682
683 static int ndisc_router_generate_addresses(Link *link, struct in6_addr *address, uint8_t prefixlen, Set **ret) {
684 _cleanup_set_free_free_ Set *addresses = NULL;
685 IPv6Token *j;
686 int r;
687
688 assert(link);
689 assert(address);
690 assert(ret);
691
692 addresses = set_new(&in6_addr_hash_ops);
693 if (!addresses)
694 return log_oom();
695
696 ORDERED_SET_FOREACH(j, link->network->ipv6_tokens) {
697 _cleanup_free_ struct in6_addr *new_address = NULL;
698
699 if (j->address_generation_type == IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE
700 && (in6_addr_is_null(&j->prefix) || in6_addr_equal(&j->prefix, address))) {
701 /* While this loop uses dad_counter and a retry limit as specified in RFC 7217, the loop
702 * does not actually attempt Duplicate Address Detection; the counter will be incremented
703 * only when the address generation algorithm produces an invalid address, and the loop
704 * may exit with an address which ends up being unusable due to duplication on the link. */
705 for (; j->dad_counter < DAD_CONFLICTS_IDGEN_RETRIES_RFC7217; j->dad_counter++) {
706 r = make_stableprivate_address(link, address, prefixlen, j->dad_counter, &new_address);
707 if (r < 0)
708 return r;
709 if (r > 0)
710 break;
711 }
712 } else if (j->address_generation_type == IPV6_TOKEN_ADDRESS_GENERATION_STATIC) {
713 new_address = new(struct in6_addr, 1);
714 if (!new_address)
715 return log_oom();
716
717 memcpy(new_address->s6_addr, address->s6_addr, 8);
718 memcpy(new_address->s6_addr + 8, j->prefix.s6_addr + 8, 8);
719 }
720
721 if (new_address) {
722 r = set_put(addresses, new_address);
723 if (r < 0)
724 return log_link_error_errno(link, r, "Failed to store SLAAC address: %m");
725 else if (r == 0)
726 log_link_debug_errno(link, r, "Generated SLAAC address is duplicated, ignoring.");
727 else
728 TAKE_PTR(new_address);
729 }
730 }
731
732 /* fall back to EUI-64 if no tokens provided addresses */
733 if (set_isempty(addresses)) {
734 _cleanup_free_ struct in6_addr *new_address = NULL;
735
736 new_address = newdup(struct in6_addr, address, 1);
737 if (!new_address)
738 return log_oom();
739
740 r = generate_ipv6_eui_64_address(link, new_address);
741 if (r < 0)
742 return log_link_error_errno(link, r, "Failed to generate EUI64 address: %m");
743
744 r = set_put(addresses, new_address);
745 if (r < 0)
746 return log_link_error_errno(link, r, "Failed to store SLAAC address: %m");
747
748 TAKE_PTR(new_address);
749 }
750
751 *ret = TAKE_PTR(addresses);
752
753 return 0;
754 }
755
756 static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *rt) {
757 uint32_t lifetime_valid, lifetime_preferred;
758 _cleanup_set_free_free_ Set *addresses = NULL;
759 struct in6_addr addr, *a;
760 unsigned prefixlen;
761 usec_t time_now;
762 int r;
763
764 assert(link);
765 assert(rt);
766
767 r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
768 if (r < 0)
769 return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");
770
771 r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen);
772 if (r < 0)
773 return log_link_error_errno(link, r, "Failed to get prefix length: %m");
774
775 r = sd_ndisc_router_prefix_get_valid_lifetime(rt, &lifetime_valid);
776 if (r < 0)
777 return log_link_error_errno(link, r, "Failed to get prefix valid lifetime: %m");
778
779 if (lifetime_valid == 0) {
780 log_link_debug(link, "Ignoring prefix as its valid lifetime is zero.");
781 return 0;
782 }
783
784 r = sd_ndisc_router_prefix_get_preferred_lifetime(rt, &lifetime_preferred);
785 if (r < 0)
786 return log_link_error_errno(link, r, "Failed to get prefix preferred lifetime: %m");
787
788 /* The preferred lifetime is never greater than the valid lifetime */
789 if (lifetime_preferred > lifetime_valid)
790 return 0;
791
792 r = sd_ndisc_router_prefix_get_address(rt, &addr);
793 if (r < 0)
794 return log_link_error_errno(link, r, "Failed to get prefix address: %m");
795
796 r = ndisc_router_generate_addresses(link, &addr, prefixlen, &addresses);
797 if (r < 0)
798 return r;
799
800 SET_FOREACH(a, addresses) {
801 _cleanup_(address_freep) Address *address = NULL;
802 Address *e;
803
804 r = address_new(&address);
805 if (r < 0)
806 return log_oom();
807
808 address->family = AF_INET6;
809 address->in_addr.in6 = *a;
810 address->prefixlen = prefixlen;
811 address->flags = IFA_F_NOPREFIXROUTE|IFA_F_MANAGETEMPADDR;
812 address->cinfo.ifa_valid = lifetime_valid;
813 address->cinfo.ifa_prefered = lifetime_preferred;
814
815 /* See RFC4862, section 5.5.3.e. But the following logic is deviated from RFC4862 by
816 * honoring all valid lifetimes to improve the reaction of SLAAC to renumbering events.
817 * See draft-ietf-6man-slaac-renum-02, section 4.2. */
818 r = address_get(link, address, &e);
819 if (r > 0) {
820 /* If the address is already assigned, but not valid anymore, then refuse to
821 * update the address. */
822 if (e->cinfo.tstamp / 100 + e->cinfo.ifa_valid < time_now / USEC_PER_SEC)
823 continue;
824 }
825
826 r = ndisc_request_address(TAKE_PTR(address), link, rt);
827 if (r < 0)
828 return log_link_error_errno(link, r, "Could not request SLAAC address: %m");
829 }
830
831 return 0;
832 }
833
834 static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) {
835 _cleanup_(route_freep) Route *route = NULL;
836 usec_t time_now;
837 uint32_t lifetime;
838 unsigned prefixlen;
839 int r;
840
841 assert(link);
842 assert(rt);
843
844 r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
845 if (r < 0)
846 return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");
847
848 r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen);
849 if (r < 0)
850 return log_link_error_errno(link, r, "Failed to get prefix length: %m");
851
852 r = sd_ndisc_router_prefix_get_valid_lifetime(rt, &lifetime);
853 if (r < 0)
854 return log_link_error_errno(link, r, "Failed to get prefix lifetime: %m");
855
856 r = route_new(&route);
857 if (r < 0)
858 return log_oom();
859
860 route->family = AF_INET6;
861 route->table = link_get_ipv6_accept_ra_route_table(link);
862 route->priority = link->network->ipv6_accept_ra_route_metric;
863 route->protocol = RTPROT_RA;
864 route->flags = RTM_F_PREFIX;
865 route->dst_prefixlen = prefixlen;
866 route->lifetime = usec_add(time_now, lifetime * USEC_PER_SEC);
867
868 r = sd_ndisc_router_prefix_get_address(rt, &route->dst.in6);
869 if (r < 0)
870 return log_link_error_errno(link, r, "Failed to get prefix address: %m");
871
872 r = ndisc_request_route(TAKE_PTR(route), link, rt);
873 if (r < 0)
874 return log_link_error_errno(link, r, "Could not request prefix route: %m");;
875
876 return 0;
877 }
878
879 static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
880 _cleanup_(route_freep) Route *route = NULL;
881 struct in6_addr gateway, dst;
882 uint32_t lifetime;
883 unsigned preference, prefixlen;
884 usec_t time_now;
885 int r;
886
887 assert(link);
888
889 r = sd_ndisc_router_route_get_lifetime(rt, &lifetime);
890 if (r < 0)
891 return log_link_error_errno(link, r, "Failed to get route lifetime from RA: %m");
892
893 if (lifetime == 0)
894 return 0;
895
896 r = sd_ndisc_router_route_get_address(rt, &dst);
897 if (r < 0)
898 return log_link_error_errno(link, r, "Failed to get route destination address: %m");
899
900 if ((!set_isempty(link->network->ndisc_allow_listed_route_prefix) &&
901 !set_contains(link->network->ndisc_allow_listed_route_prefix, &dst)) ||
902 set_contains(link->network->ndisc_deny_listed_route_prefix, &dst)) {
903 if (DEBUG_LOGGING) {
904 _cleanup_free_ char *buf = NULL;
905
906 (void) in6_addr_to_string(&dst, &buf);
907 if (!set_isempty(link->network->ndisc_allow_listed_route_prefix))
908 log_link_debug(link, "Route prefix '%s' is not in allow list, ignoring", strna(buf));
909 else
910 log_link_debug(link, "Route prefix '%s' is in deny list, ignoring", strna(buf));
911 }
912 return 0;
913 }
914
915 r = sd_ndisc_router_get_address(rt, &gateway);
916 if (r < 0)
917 return log_link_error_errno(link, r, "Failed to get gateway address from RA: %m");
918
919 if (link_get_ipv6_address(link, &gateway, NULL) >= 0) {
920 if (DEBUG_LOGGING) {
921 _cleanup_free_ char *buf = NULL;
922
923 (void) in6_addr_to_string(&gateway, &buf);
924 log_link_debug(link, "Advertised route gateway %s is local to the link, ignoring route", strna(buf));
925 }
926 return 0;
927 }
928
929 r = sd_ndisc_router_route_get_prefixlen(rt, &prefixlen);
930 if (r < 0)
931 return log_link_error_errno(link, r, "Failed to get route prefix length: %m");
932
933 r = sd_ndisc_router_route_get_preference(rt, &preference);
934 if (r < 0)
935 return log_link_error_errno(link, r, "Failed to get default router preference from RA: %m");
936
937 r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
938 if (r < 0)
939 return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");
940
941 r = route_new(&route);
942 if (r < 0)
943 return log_oom();
944
945 route->family = AF_INET6;
946 route->table = link_get_ipv6_accept_ra_route_table(link);
947 route->priority = link->network->ipv6_accept_ra_route_metric;
948 route->protocol = RTPROT_RA;
949 route->pref = preference;
950 route->gw.in6 = gateway;
951 route->gw_family = AF_INET6;
952 route->dst.in6 = dst;
953 route->dst_prefixlen = prefixlen;
954 route->lifetime = usec_add(time_now, lifetime * USEC_PER_SEC);
955
956 r = ndisc_request_route(TAKE_PTR(route), link, rt);
957 if (r < 0)
958 return log_link_error_errno(link, r, "Could not request additional route: %m");
959
960 return 0;
961 }
962
963 static void ndisc_rdnss_hash_func(const NDiscRDNSS *x, struct siphash *state) {
964 siphash24_compress(&x->address, sizeof(x->address), state);
965 }
966
967 static int ndisc_rdnss_compare_func(const NDiscRDNSS *a, const NDiscRDNSS *b) {
968 return memcmp(&a->address, &b->address, sizeof(a->address));
969 }
970
971 DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
972 ndisc_rdnss_hash_ops,
973 NDiscRDNSS,
974 ndisc_rdnss_hash_func,
975 ndisc_rdnss_compare_func,
976 free);
977
978 static int ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) {
979 uint32_t lifetime;
980 const struct in6_addr *a;
981 struct in6_addr router;
982 NDiscRDNSS *rdnss;
983 usec_t time_now;
984 bool updated = false;
985 int n, r;
986
987 assert(link);
988 assert(rt);
989
990 r = sd_ndisc_router_get_address(rt, &router);
991 if (r < 0)
992 return log_link_error_errno(link, r, "Failed to get router address from RA: %m");
993
994 r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
995 if (r < 0)
996 return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");
997
998 r = sd_ndisc_router_rdnss_get_lifetime(rt, &lifetime);
999 if (r < 0)
1000 return log_link_error_errno(link, r, "Failed to get RDNSS lifetime: %m");
1001
1002 n = sd_ndisc_router_rdnss_get_addresses(rt, &a);
1003 if (n < 0)
1004 return log_link_error_errno(link, n, "Failed to get RDNSS addresses: %m");
1005
1006 SET_FOREACH(rdnss, link->ndisc_rdnss)
1007 if (in6_addr_equal(&rdnss->router, &router))
1008 rdnss->marked = true;
1009
1010 if (lifetime == 0)
1011 return 0;
1012
1013 if (n >= (int) NDISC_RDNSS_MAX) {
1014 log_link_warning(link, "Too many RDNSS records per link. Only first %i records will be used.", NDISC_RDNSS_MAX);
1015 n = NDISC_RDNSS_MAX;
1016 }
1017
1018 for (int j = 0; j < n; j++) {
1019 _cleanup_free_ NDiscRDNSS *x = NULL;
1020 NDiscRDNSS d = {
1021 .address = a[j],
1022 };
1023
1024 rdnss = set_get(link->ndisc_rdnss, &d);
1025 if (rdnss) {
1026 rdnss->marked = false;
1027 rdnss->router = router;
1028 rdnss->valid_until = time_now + lifetime * USEC_PER_SEC;
1029 continue;
1030 }
1031
1032 x = new(NDiscRDNSS, 1);
1033 if (!x)
1034 return log_oom();
1035
1036 *x = (NDiscRDNSS) {
1037 .address = a[j],
1038 .router = router,
1039 .valid_until = time_now + lifetime * USEC_PER_SEC,
1040 };
1041
1042 r = set_ensure_consume(&link->ndisc_rdnss, &ndisc_rdnss_hash_ops, TAKE_PTR(x));
1043 if (r < 0)
1044 return log_oom();
1045 assert(r > 0);
1046
1047 updated = true;
1048 }
1049
1050 if (updated)
1051 link_dirty(link);
1052
1053 return 0;
1054 }
1055
1056 static void ndisc_dnssl_hash_func(const NDiscDNSSL *x, struct siphash *state) {
1057 siphash24_compress_string(NDISC_DNSSL_DOMAIN(x), state);
1058 }
1059
1060 static int ndisc_dnssl_compare_func(const NDiscDNSSL *a, const NDiscDNSSL *b) {
1061 return strcmp(NDISC_DNSSL_DOMAIN(a), NDISC_DNSSL_DOMAIN(b));
1062 }
1063
1064 DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
1065 ndisc_dnssl_hash_ops,
1066 NDiscDNSSL,
1067 ndisc_dnssl_hash_func,
1068 ndisc_dnssl_compare_func,
1069 free);
1070
1071 static int ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) {
1072 _cleanup_strv_free_ char **l = NULL;
1073 struct in6_addr router;
1074 uint32_t lifetime;
1075 usec_t time_now;
1076 NDiscDNSSL *dnssl;
1077 bool updated = false;
1078 char **j;
1079 int r;
1080
1081 assert(link);
1082 assert(rt);
1083
1084 r = sd_ndisc_router_get_address(rt, &router);
1085 if (r < 0)
1086 return log_link_error_errno(link, r, "Failed to get router address from RA: %m");
1087
1088 r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
1089 if (r < 0)
1090 return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");
1091
1092 r = sd_ndisc_router_dnssl_get_lifetime(rt, &lifetime);
1093 if (r < 0)
1094 return log_link_error_errno(link, r, "Failed to get DNSSL lifetime: %m");
1095
1096 r = sd_ndisc_router_dnssl_get_domains(rt, &l);
1097 if (r < 0)
1098 return log_link_error_errno(link, r, "Failed to get DNSSL addresses: %m");
1099
1100 SET_FOREACH(dnssl, link->ndisc_dnssl)
1101 if (in6_addr_equal(&dnssl->router, &router))
1102 dnssl->marked = true;
1103
1104 if (lifetime == 0)
1105 return 0;
1106
1107 if (strv_length(l) >= NDISC_DNSSL_MAX) {
1108 log_link_warning(link, "Too many DNSSL records per link. Only first %i records will be used.", NDISC_DNSSL_MAX);
1109 STRV_FOREACH(j, l + NDISC_DNSSL_MAX)
1110 *j = mfree(*j);
1111 }
1112
1113 STRV_FOREACH(j, l) {
1114 _cleanup_free_ NDiscDNSSL *s = NULL;
1115
1116 s = malloc0(ALIGN(sizeof(NDiscDNSSL)) + strlen(*j) + 1);
1117 if (!s)
1118 return log_oom();
1119
1120 strcpy(NDISC_DNSSL_DOMAIN(s), *j);
1121
1122 dnssl = set_get(link->ndisc_dnssl, s);
1123 if (dnssl) {
1124 dnssl->marked = false;
1125 dnssl->router = router;
1126 dnssl->valid_until = time_now + lifetime * USEC_PER_SEC;
1127 continue;
1128 }
1129
1130 s->router = router;
1131 s->valid_until = time_now + lifetime * USEC_PER_SEC;
1132
1133 r = set_ensure_consume(&link->ndisc_dnssl, &ndisc_dnssl_hash_ops, TAKE_PTR(s));
1134 if (r < 0)
1135 return log_oom();
1136 assert(r > 0);
1137
1138 updated = true;
1139 }
1140
1141 if (updated)
1142 link_dirty(link);
1143
1144 return 0;
1145 }
1146
1147 static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt) {
1148 assert(link);
1149 assert(link->network);
1150 assert(rt);
1151
1152 for (int r = sd_ndisc_router_option_rewind(rt); ; r = sd_ndisc_router_option_next(rt)) {
1153 uint8_t type;
1154
1155 if (r < 0)
1156 return log_link_error_errno(link, r, "Failed to iterate through options: %m");
1157 if (r == 0) /* EOF */
1158 return 0;
1159
1160 r = sd_ndisc_router_option_get_type(rt, &type);
1161 if (r < 0)
1162 return log_link_error_errno(link, r, "Failed to get RA option type: %m");
1163
1164 switch (type) {
1165
1166 case SD_NDISC_OPTION_PREFIX_INFORMATION: {
1167 struct in6_addr a;
1168 uint8_t flags;
1169
1170 r = sd_ndisc_router_prefix_get_address(rt, &a);
1171 if (r < 0)
1172 return log_link_error_errno(link, r, "Failed to get prefix address: %m");
1173
1174 if ((!set_isempty(link->network->ndisc_allow_listed_prefix) &&
1175 !set_contains(link->network->ndisc_allow_listed_prefix, &a)) ||
1176 set_contains(link->network->ndisc_deny_listed_prefix, &a)) {
1177 if (DEBUG_LOGGING) {
1178 _cleanup_free_ char *b = NULL;
1179
1180 (void) in6_addr_to_string(&a, &b);
1181 if (!set_isempty(link->network->ndisc_allow_listed_prefix))
1182 log_link_debug(link, "Prefix '%s' is not in allow list, ignoring", strna(b));
1183 else
1184 log_link_debug(link, "Prefix '%s' is in deny list, ignoring", strna(b));
1185 }
1186 break;
1187 }
1188
1189 r = sd_ndisc_router_prefix_get_flags(rt, &flags);
1190 if (r < 0)
1191 return log_link_error_errno(link, r, "Failed to get RA prefix flags: %m");
1192
1193 if (link->network->ipv6_accept_ra_use_onlink_prefix &&
1194 FLAGS_SET(flags, ND_OPT_PI_FLAG_ONLINK)) {
1195 r = ndisc_router_process_onlink_prefix(link, rt);
1196 if (r < 0)
1197 return r;
1198 }
1199
1200 if (link->network->ipv6_accept_ra_use_autonomous_prefix &&
1201 FLAGS_SET(flags, ND_OPT_PI_FLAG_AUTO)) {
1202 r = ndisc_router_process_autonomous_prefix(link, rt);
1203 if (r < 0)
1204 return r;
1205 }
1206 break;
1207 }
1208
1209 case SD_NDISC_OPTION_ROUTE_INFORMATION:
1210 r = ndisc_router_process_route(link, rt);
1211 if (r < 0)
1212 return r;
1213 break;
1214
1215 case SD_NDISC_OPTION_RDNSS:
1216 if (link->network->ipv6_accept_ra_use_dns) {
1217 r = ndisc_router_process_rdnss(link, rt);
1218 if (r < 0)
1219 return r;
1220 }
1221 break;
1222
1223 case SD_NDISC_OPTION_DNSSL:
1224 if (link->network->ipv6_accept_ra_use_dns) {
1225 r = ndisc_router_process_dnssl(link, rt);
1226 if (r < 0)
1227 return r;
1228 }
1229 break;
1230 }
1231 }
1232 }
1233
1234 static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
1235 struct in6_addr router;
1236 uint64_t flags;
1237 NDiscAddress *na;
1238 NDiscRoute *nr;
1239 int r;
1240
1241 assert(link);
1242 assert(link->network);
1243 assert(link->manager);
1244 assert(rt);
1245
1246 r = sd_ndisc_router_get_address(rt, &router);
1247 if (r < 0)
1248 return log_link_error_errno(link, r, "Failed to get router address from RA: %m");
1249
1250 if ((!set_isempty(link->network->ndisc_allow_listed_router) &&
1251 !set_contains(link->network->ndisc_allow_listed_router, &router)) ||
1252 set_contains(link->network->ndisc_deny_listed_router, &router)) {
1253 if (DEBUG_LOGGING) {
1254 _cleanup_free_ char *buf = NULL;
1255
1256 (void) in6_addr_to_string(&router, &buf);
1257 if (!set_isempty(link->network->ndisc_allow_listed_router))
1258 log_link_debug(link, "Router '%s' is not in allow list, ignoring", strna(buf));
1259 else
1260 log_link_debug(link, "Router '%s' is in deny list, ignoring", strna(buf));
1261 }
1262 return 0;
1263 }
1264
1265 SET_FOREACH(na, link->ndisc_addresses)
1266 if (in6_addr_equal(&na->router, &router))
1267 na->marked = true;
1268
1269 SET_FOREACH(nr, link->ndisc_routes)
1270 if (in6_addr_equal(&nr->router, &router))
1271 nr->marked = true;
1272
1273 r = sd_ndisc_router_get_flags(rt, &flags);
1274 if (r < 0)
1275 return log_link_error_errno(link, r, "Failed to get RA flags: %m");
1276
1277 if ((flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER) &&
1278 link->network->ipv6_accept_ra_start_dhcp6_client != IPV6_ACCEPT_RA_START_DHCP6_CLIENT_NO) ||
1279 link->network->ipv6_accept_ra_start_dhcp6_client == IPV6_ACCEPT_RA_START_DHCP6_CLIENT_ALWAYS) {
1280
1281 if (flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER))
1282 /* (re)start DHCPv6 client in stateful or stateless mode according to RA flags */
1283 r = dhcp6_request_information(link, !(flags & ND_RA_FLAG_MANAGED));
1284 else
1285 /* When IPv6AcceptRA.DHCPv6Client=always, start dhcp6 client in managed mode
1286 * even if router does not have M or O flag. */
1287 r = dhcp6_request_information(link, false);
1288 if (r < 0 && r != -EBUSY)
1289 return log_link_error_errno(link, r, "Could not acquire DHCPv6 lease on NDisc request: %m");
1290 else
1291 log_link_debug(link, "Acquiring DHCPv6 lease on NDisc request");
1292 }
1293
1294 r = ndisc_router_process_default(link, rt);
1295 if (r < 0)
1296 return r;
1297 r = ndisc_router_process_options(link, rt);
1298 if (r < 0)
1299 return r;
1300
1301 if (link->ndisc_addresses_messages == 0)
1302 link->ndisc_addresses_configured = true;
1303 else
1304 log_link_debug(link, "Setting SLAAC addresses.");
1305
1306 if (link->ndisc_routes_messages == 0)
1307 link->ndisc_routes_configured = true;
1308 else
1309 log_link_debug(link, "Setting NDisc routes.");
1310
1311 r = ndisc_remove_old(link);
1312 if (r < 0)
1313 return r;
1314
1315 if (!link->ndisc_addresses_configured || !link->ndisc_routes_configured)
1316 link_set_state(link, LINK_STATE_CONFIGURING);
1317
1318 link_check_ready(link);
1319 return 0;
1320 }
1321
1322 static void ndisc_handler(sd_ndisc *nd, sd_ndisc_event_t event, sd_ndisc_router *rt, void *userdata) {
1323 Link *link = userdata;
1324 int r;
1325
1326 assert(link);
1327
1328 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1329 return;
1330
1331 switch (event) {
1332
1333 case SD_NDISC_EVENT_ROUTER:
1334 r = ndisc_router_handler(link, rt);
1335 if (r < 0) {
1336 link_enter_failed(link);
1337 return;
1338 }
1339 break;
1340
1341 case SD_NDISC_EVENT_TIMEOUT:
1342 log_link_debug(link, "NDisc handler get timeout event");
1343 if (link->ndisc_addresses_messages == 0 && link->ndisc_routes_messages == 0) {
1344 link->ndisc_addresses_configured = true;
1345 link->ndisc_routes_configured = true;
1346 link_check_ready(link);
1347 }
1348 break;
1349 default:
1350 assert_not_reached("Unknown NDisc event");
1351 }
1352 }
1353
1354 int ndisc_configure(Link *link) {
1355 int r;
1356
1357 assert(link);
1358
1359 if (!link_ipv6_accept_ra_enabled(link))
1360 return 0;
1361
1362 if (link->ndisc)
1363 return -EBUSY; /* Already configured. */
1364
1365 r = sd_ndisc_new(&link->ndisc);
1366 if (r < 0)
1367 return r;
1368
1369 r = sd_ndisc_attach_event(link->ndisc, link->manager->event, 0);
1370 if (r < 0)
1371 return r;
1372
1373 r = sd_ndisc_set_mac(link->ndisc, &link->hw_addr.ether);
1374 if (r < 0)
1375 return r;
1376
1377 r = sd_ndisc_set_ifindex(link->ndisc, link->ifindex);
1378 if (r < 0)
1379 return r;
1380
1381 r = sd_ndisc_set_callback(link->ndisc, ndisc_handler, link);
1382 if (r < 0)
1383 return r;
1384
1385 return 0;
1386 }
1387
1388 int ndisc_start(Link *link) {
1389 assert(link);
1390
1391 if (!link->ndisc || !link->dhcp6_client)
1392 return 0;
1393
1394 log_link_debug(link, "Discovering IPv6 routers");
1395
1396 return sd_ndisc_start(link->ndisc);
1397 }
1398
1399 void ndisc_vacuum(Link *link) {
1400 NDiscRDNSS *r;
1401 NDiscDNSSL *d;
1402 usec_t time_now;
1403
1404 assert(link);
1405
1406 /* Removes all RDNSS and DNSSL entries whose validity time has passed */
1407
1408 time_now = now(clock_boottime_or_monotonic());
1409
1410 SET_FOREACH(r, link->ndisc_rdnss)
1411 if (r->valid_until < time_now)
1412 free(set_remove(link->ndisc_rdnss, r));
1413
1414 SET_FOREACH(d, link->ndisc_dnssl)
1415 if (d->valid_until < time_now)
1416 free(set_remove(link->ndisc_dnssl, d));
1417 }
1418
1419 void ndisc_flush(Link *link) {
1420 assert(link);
1421
1422 /* Removes all RDNSS and DNSSL entries, without exception */
1423
1424 link->ndisc_rdnss = set_free(link->ndisc_rdnss);
1425 link->ndisc_dnssl = set_free(link->ndisc_dnssl);
1426 }
1427
1428 int ipv6token_new(IPv6Token **ret) {
1429 IPv6Token *p;
1430
1431 p = new(IPv6Token, 1);
1432 if (!p)
1433 return -ENOMEM;
1434
1435 *p = (IPv6Token) {
1436 .address_generation_type = IPV6_TOKEN_ADDRESS_GENERATION_NONE,
1437 };
1438
1439 *ret = TAKE_PTR(p);
1440
1441 return 0;
1442 }
1443
1444 static void ipv6_token_hash_func(const IPv6Token *p, struct siphash *state) {
1445 siphash24_compress(&p->address_generation_type, sizeof(p->address_generation_type), state);
1446 siphash24_compress(&p->prefix, sizeof(p->prefix), state);
1447 }
1448
1449 static int ipv6_token_compare_func(const IPv6Token *a, const IPv6Token *b) {
1450 int r;
1451
1452 r = CMP(a->address_generation_type, b->address_generation_type);
1453 if (r != 0)
1454 return r;
1455
1456 return memcmp(&a->prefix, &b->prefix, sizeof(struct in6_addr));
1457 }
1458
1459 DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(
1460 ipv6_token_hash_ops,
1461 IPv6Token,
1462 ipv6_token_hash_func,
1463 ipv6_token_compare_func,
1464 free);
1465
1466 int config_parse_ndisc_address_filter(
1467 const char *unit,
1468 const char *filename,
1469 unsigned line,
1470 const char *section,
1471 unsigned section_line,
1472 const char *lvalue,
1473 int ltype,
1474 const char *rvalue,
1475 void *data,
1476 void *userdata) {
1477
1478 Set **list = data;
1479 int r;
1480
1481 assert(filename);
1482 assert(lvalue);
1483 assert(rvalue);
1484 assert(data);
1485
1486 if (isempty(rvalue)) {
1487 *list = set_free_free(*list);
1488 return 0;
1489 }
1490
1491 for (const char *p = rvalue;;) {
1492 _cleanup_free_ char *n = NULL;
1493 _cleanup_free_ struct in6_addr *a = NULL;
1494 union in_addr_union ip;
1495
1496 r = extract_first_word(&p, &n, NULL, 0);
1497 if (r == -ENOMEM)
1498 return log_oom();
1499 if (r < 0) {
1500 log_syntax(unit, LOG_WARNING, filename, line, r,
1501 "Failed to parse NDisc %s=, ignoring assignment: %s",
1502 lvalue, rvalue);
1503 return 0;
1504 }
1505 if (r == 0)
1506 return 0;
1507
1508 r = in_addr_from_string(AF_INET6, n, &ip);
1509 if (r < 0) {
1510 log_syntax(unit, LOG_WARNING, filename, line, r,
1511 "NDisc %s= entry is invalid, ignoring assignment: %s",
1512 lvalue, n);
1513 continue;
1514 }
1515
1516 a = newdup(struct in6_addr, &ip.in6, 1);
1517 if (!a)
1518 return log_oom();
1519
1520 r = set_ensure_consume(list, &in6_addr_hash_ops, TAKE_PTR(a));
1521 if (r < 0)
1522 return log_oom();
1523 if (r == 0)
1524 log_syntax(unit, LOG_WARNING, filename, line, 0,
1525 "NDisc %s= entry is duplicated, ignoring assignment: %s",
1526 lvalue, n);
1527 }
1528 }
1529
1530 int config_parse_address_generation_type(
1531 const char *unit,
1532 const char *filename,
1533 unsigned line,
1534 const char *section,
1535 unsigned section_line,
1536 const char *lvalue,
1537 int ltype,
1538 const char *rvalue,
1539 void *data,
1540 void *userdata) {
1541
1542 _cleanup_free_ IPv6Token *token = NULL;
1543 union in_addr_union buffer;
1544 Network *network = data;
1545 const char *p;
1546 int r;
1547
1548 assert(filename);
1549 assert(lvalue);
1550 assert(rvalue);
1551 assert(data);
1552
1553 if (isempty(rvalue)) {
1554 network->ipv6_tokens = ordered_set_free(network->ipv6_tokens);
1555 return 0;
1556 }
1557
1558 r = ipv6token_new(&token);
1559 if (r < 0)
1560 return log_oom();
1561
1562 if ((p = startswith(rvalue, "prefixstable"))) {
1563 token->address_generation_type = IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE;
1564 if (*p == ':')
1565 p++;
1566 else if (*p == '\0')
1567 p = NULL;
1568 else {
1569 log_syntax(unit, LOG_WARNING, filename, line, 0,
1570 "Invalid IPv6 token mode in %s=, ignoring assignment: %s",
1571 lvalue, rvalue);
1572 return 0;
1573 }
1574 } else {
1575 token->address_generation_type = IPV6_TOKEN_ADDRESS_GENERATION_STATIC;
1576 p = startswith(rvalue, "static:");
1577 if (!p)
1578 p = rvalue;
1579 }
1580
1581 if (p) {
1582 r = in_addr_from_string(AF_INET6, p, &buffer);
1583 if (r < 0) {
1584 log_syntax(unit, LOG_WARNING, filename, line, r,
1585 "Failed to parse IP address in %s=, ignoring assignment: %s",
1586 lvalue, rvalue);
1587 return 0;
1588 }
1589 if (token->address_generation_type == IPV6_TOKEN_ADDRESS_GENERATION_STATIC &&
1590 in_addr_is_null(AF_INET6, &buffer)) {
1591 log_syntax(unit, LOG_WARNING, filename, line, 0,
1592 "IPv6 address in %s= cannot be the ANY address, ignoring assignment: %s",
1593 lvalue, rvalue);
1594 return 0;
1595 }
1596 token->prefix = buffer.in6;
1597 }
1598
1599 r = ordered_set_ensure_put(&network->ipv6_tokens, &ipv6_token_hash_ops, token);
1600 if (r == -ENOMEM)
1601 return log_oom();
1602 if (r == -EEXIST)
1603 log_syntax(unit, LOG_DEBUG, filename, line, r,
1604 "IPv6 token '%s' is duplicated, ignoring: %m", rvalue);
1605 else if (r < 0)
1606 log_syntax(unit, LOG_WARNING, filename, line, r,
1607 "Failed to store IPv6 token '%s', ignoring: %m", rvalue);
1608 else
1609 TAKE_PTR(token);
1610
1611 return 0;
1612 }
1613
1614 DEFINE_CONFIG_PARSE_ENUM(config_parse_ipv6_accept_ra_use_domains, dhcp_use_domains, DHCPUseDomains,
1615 "Failed to parse UseDomains= setting");
1616 DEFINE_CONFIG_PARSE_ENUM(config_parse_ipv6_accept_ra_start_dhcp6_client, ipv6_accept_ra_start_dhcp6_client, IPv6AcceptRAStartDHCP6Client,
1617 "Failed to parse DHCPv6Client= setting");
1618 static const char* const ipv6_accept_ra_start_dhcp6_client_table[_IPV6_ACCEPT_RA_START_DHCP6_CLIENT_MAX] = {
1619 [IPV6_ACCEPT_RA_START_DHCP6_CLIENT_NO] = "no",
1620 [IPV6_ACCEPT_RA_START_DHCP6_CLIENT_ALWAYS] = "always",
1621 [IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES] = "yes",
1622 };
1623
1624 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_accept_ra_start_dhcp6_client, IPv6AcceptRAStartDHCP6Client, IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES);