1 /* $OpenBSD: frontend.c,v 1.55 2024/11/21 13:38:15 claudio Exp $ */
2
3 /*
4 * Copyright (c) 2018 Florian Obser <florian@openbsd.org>
5 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
6 * Copyright (c) 2004 Esben Norby <norby@openbsd.org>
7 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
8 *
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 */
21
22 /*
23 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
24 * All rights reserved.
25 *
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
28 * are met:
29 * 1. Redistributions of source code must retain the above copyright
30 * notice, this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in the
33 * documentation and/or other materials provided with the distribution.
34 * 3. Neither the name of the project nor the names of its contributors
35 * may be used to endorse or promote products derived from this software
36 * without specific prior written permission.
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
39 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
42 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 */
50
51 #include <sys/types.h>
52 #include <sys/ioctl.h>
53 #include <sys/queue.h>
54 #include <sys/socket.h>
55 #include <sys/syslog.h>
56 #include <sys/uio.h>
57
58 #include <net/if.h>
59 #include <net/if_dl.h>
60 #include <net/if_types.h>
61 #include <net/route.h>
62
63 #include <arpa/inet.h>
64
65 #include <netinet/in.h>
66 #include <netinet/if_ether.h>
67 #include <netinet6/nd6.h>
68 #include <netinet6/in6_var.h>
69 #include <netinet/ip6.h>
70 #include <netinet/icmp6.h>
71
72 #include <ctype.h>
73 #include <errno.h>
74 #include <event.h>
75 #include <ifaddrs.h>
76 #include <imsg.h>
77 #include <pwd.h>
78 #include <signal.h>
79 #include <stdio.h>
80 #include <stdlib.h>
81 #include <string.h>
82 #include <unistd.h>
83
84 #include "log.h"
85 #include "rad.h"
86 #include "frontend.h"
87 #include "control.h"
88
89 #define RA_MAX_SIZE 1500
90 #define ROUTE_SOCKET_BUF_SIZE 16384
91
92 struct icmp6_ev {
93 struct event ev;
94 uint8_t answer[1500];
95 struct msghdr rcvmhdr;
96 struct iovec rcviov[1];
97 struct sockaddr_in6 from;
98 int refcnt;
99 };
100
101 struct ra_iface {
102 TAILQ_ENTRY(ra_iface) entry;
103 struct icmp6_ev *icmp6ev;
104 struct ra_prefix_conf_head prefixes;
105 struct ether_addr hw_addr;
106 char name[IF_NAMESIZE];
107 char conf_name[IF_NAMESIZE];
108 uint32_t if_index;
109 int rdomain;
110 int removed;
111 int link_state;
112 int prefix_count;
113 int ltime_decaying;
114 size_t datalen;
115 uint8_t data[RA_MAX_SIZE];
116 };
117
118 #define ND_OPT_PREF64 38
119 struct nd_opt_pref64 {
120 u_int8_t nd_opt_pref64_type;
121 u_int8_t nd_opt_pref64_len;
122 u_int16_t nd_opt_pref64_sltime_plc;
123 u_int8_t nd_opt_pref64[12];
124 };
125
126 struct nd_opt_source_link_addr {
127 u_int8_t nd_opt_source_link_addr_type;
128 u_int8_t nd_opt_source_link_addr_len;
129 struct ether_addr nd_opt_source_link_addr_hw_addr;
130 };
131
132 TAILQ_HEAD(, ra_iface) ra_interfaces;
133
134 __dead void frontend_shutdown(void);
135 void frontend_sig_handler(int, short, void *);
136 void frontend_startup(void);
137 void icmp6_receive(int, short, void *);
138 void join_all_routers_mcast_group(struct ra_iface *);
139 void leave_all_routers_mcast_group(struct ra_iface *);
140 int get_ifrdomain(char *);
141 void merge_ra_interface(char *, char *, struct ifaddrs *);
142 void merge_ra_interfaces(void);
143 struct ra_iface *find_ra_iface_by_id(uint32_t);
144 struct ra_iface *find_ra_iface_by_name(char *);
145 struct ra_iface_conf *find_ra_iface_conf(struct ra_iface_conf_head *,
146 char *);
147 struct ra_prefix_conf *find_ra_prefix_conf(struct ra_prefix_conf_head*,
148 struct in6_addr *, int);
149 struct icmp6_ev *get_icmp6ev_by_rdomain(int);
150 void unref_icmp6ev(struct ra_iface *);
151 void set_icmp6sock(int, int);
152 void add_new_prefix_to_ra_iface(struct ra_iface *r,
153 struct in6_addr *, int, struct ra_prefix_conf *,
154 uint32_t, uint32_t);
155 void free_ra_iface(struct ra_iface *);
156 int in6_mask2prefixlen(struct in6_addr *);
157 void get_interface_prefixes(struct ra_iface *,
158 struct ra_prefix_conf *, struct ifaddrs *);
159 int build_packet(struct ra_iface *);
160 void build_leaving_packet(struct ra_iface *);
161 void ra_output(struct ra_iface *, struct sockaddr_in6 *);
162 void get_rtaddrs(int, struct sockaddr *,
163 struct sockaddr **);
164 void route_receive(int, short, void *);
165 void handle_route_message(struct rt_msghdr *,
166 struct sockaddr **);
167
168 struct rad_conf *frontend_conf;
169 static struct imsgev *iev_main;
170 static struct imsgev *iev_engine;
171 struct event ev_route;
172 int ioctlsock = -1, routesock = -1;
173 struct ipv6_mreq all_routers;
174 struct msghdr sndmhdr;
175 struct iovec sndiov[2];
176
177 void
frontend_sig_handler(int sig,short event,void * bula)178 frontend_sig_handler(int sig, short event, void *bula)
179 {
180 /*
181 * Normal signal handler rules don't apply because libevent
182 * decouples for us.
183 */
184
185 switch (sig) {
186 case SIGINT:
187 case SIGTERM:
188 frontend_shutdown();
189 default:
190 fatalx("unexpected signal");
191 }
192 }
193
194 void
frontend(int debug,int verbose)195 frontend(int debug, int verbose)
196 {
197 struct event ev_sigint, ev_sigterm;
198 struct passwd *pw;
199 size_t sndcmsgbuflen;
200 uint8_t *sndcmsgbuf = NULL;
201
202 frontend_conf = config_new_empty();
203
204 log_init(debug, LOG_DAEMON);
205 log_setverbose(verbose);
206
207 if ((pw = getpwnam(RAD_USER)) == NULL)
208 fatal("getpwnam");
209
210 if (chroot(pw->pw_dir) == -1)
211 fatal("chroot");
212 if (chdir("/") == -1)
213 fatal("chdir(\"/\")");
214
215 setproctitle("%s", "frontend");
216 log_procinit("frontend");
217
218 if (setgroups(1, &pw->pw_gid) ||
219 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
220 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
221 fatal("can't drop privileges");
222
223 /* XXX pass in from main */
224 if ((ioctlsock = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0)) == -1)
225 fatal("socket");
226
227 if (pledge("stdio inet unix recvfd route mcast", NULL) == -1)
228 fatal("pledge");
229
230 event_init();
231
232 /* Setup signal handler. */
233 signal_set(&ev_sigint, SIGINT, frontend_sig_handler, NULL);
234 signal_set(&ev_sigterm, SIGTERM, frontend_sig_handler, NULL);
235 signal_add(&ev_sigint, NULL);
236 signal_add(&ev_sigterm, NULL);
237 signal(SIGPIPE, SIG_IGN);
238 signal(SIGHUP, SIG_IGN);
239
240 /* Setup pipe and event handler to the parent process. */
241 if ((iev_main = malloc(sizeof(struct imsgev))) == NULL)
242 fatal(NULL);
243 if (imsgbuf_init(&iev_main->ibuf, 3) == -1)
244 fatal(NULL);
245 imsgbuf_allow_fdpass(&iev_main->ibuf);
246 iev_main->handler = frontend_dispatch_main;
247 iev_main->events = EV_READ;
248 event_set(&iev_main->ev, iev_main->ibuf.fd, iev_main->events,
249 iev_main->handler, iev_main);
250 event_add(&iev_main->ev, NULL);
251
252 if (inet_pton(AF_INET6, "ff02::2",
253 &all_routers.ipv6mr_multiaddr.s6_addr) == -1)
254 fatal("inet_pton");
255
256 sndcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
257 CMSG_SPACE(sizeof(int));
258 if ((sndcmsgbuf = malloc(sndcmsgbuflen)) == NULL)
259 fatal("%s", __func__);
260
261 sndmhdr.msg_namelen = sizeof(struct sockaddr_in6);
262 sndmhdr.msg_iov = sndiov;
263 sndmhdr.msg_iovlen = 1;
264 sndmhdr.msg_control = sndcmsgbuf;
265 sndmhdr.msg_controllen = sndcmsgbuflen;
266
267 TAILQ_INIT(&ra_interfaces);
268
269 event_dispatch();
270
271 frontend_shutdown();
272 }
273
274 __dead void
frontend_shutdown(void)275 frontend_shutdown(void)
276 {
277 /* Close pipes. */
278 imsgbuf_write(&iev_engine->ibuf);
279 imsgbuf_clear(&iev_engine->ibuf);
280 close(iev_engine->ibuf.fd);
281 imsgbuf_write(&iev_main->ibuf);
282 imsgbuf_clear(&iev_main->ibuf);
283 close(iev_main->ibuf.fd);
284
285 config_clear(frontend_conf);
286
287 free(iev_engine);
288 free(iev_main);
289
290 log_info("frontend exiting");
291 exit(0);
292 }
293
294 int
frontend_imsg_compose_main(int type,pid_t pid,void * data,uint16_t datalen)295 frontend_imsg_compose_main(int type, pid_t pid, void *data, uint16_t datalen)
296 {
297 return (imsg_compose_event(iev_main, type, 0, pid, -1, data,
298 datalen));
299 }
300
301 int
frontend_imsg_compose_engine(int type,pid_t pid,void * data,uint16_t datalen)302 frontend_imsg_compose_engine(int type, pid_t pid, void *data, uint16_t datalen)
303 {
304 return (imsg_compose_event(iev_engine, type, 0, pid, -1, data,
305 datalen));
306 }
307
308 void
frontend_dispatch_main(int fd,short event,void * bula)309 frontend_dispatch_main(int fd, short event, void *bula)
310 {
311 static struct rad_conf *nconf;
312 static struct ra_iface_conf *ra_iface_conf;
313 static struct ra_options_conf *ra_options;
314 struct imsg imsg;
315 struct imsgev *iev = bula;
316 struct imsgbuf *ibuf = &iev->ibuf;
317 struct ra_prefix_conf *ra_prefix_conf;
318 struct ra_rdnss_conf *ra_rdnss_conf;
319 struct ra_dnssl_conf *ra_dnssl_conf;
320 struct ra_pref64_conf *pref64;
321 int n, shut = 0, icmp6sock, rdomain;
322
323 if (event & EV_READ) {
324 if ((n = imsgbuf_read(ibuf)) == -1)
325 fatal("imsgbuf_read error");
326 if (n == 0) /* Connection closed. */
327 shut = 1;
328 }
329 if (event & EV_WRITE) {
330 if (imsgbuf_write(ibuf) == -1) {
331 if (errno == EPIPE) /* connection closed */
332 shut = 1;
333 else
334 fatal("imsgbuf_write");
335 }
336 }
337
338 for (;;) {
339 if ((n = imsg_get(ibuf, &imsg)) == -1)
340 fatal("%s: imsg_get error", __func__);
341 if (n == 0) /* No more messages. */
342 break;
343
344 switch (imsg.hdr.type) {
345 case IMSG_SOCKET_IPC:
346 /*
347 * Setup pipe and event handler to the engine
348 * process.
349 */
350 if (iev_engine)
351 fatalx("%s: received unexpected imsg fd to "
352 "frontend", __func__);
353 if ((fd = imsg_get_fd(&imsg)) == -1)
354 fatalx("%s: expected to receive imsg fd to "
355 "frontend but didn't receive any",
356 __func__);
357
358 iev_engine = malloc(sizeof(struct imsgev));
359 if (iev_engine == NULL)
360 fatal(NULL);
361
362 if (imsgbuf_init(&iev_engine->ibuf, fd) == -1)
363 fatal(NULL);
364 iev_engine->handler = frontend_dispatch_engine;
365 iev_engine->events = EV_READ;
366
367 event_set(&iev_engine->ev, iev_engine->ibuf.fd,
368 iev_engine->events, iev_engine->handler, iev_engine);
369 event_add(&iev_engine->ev, NULL);
370 break;
371 case IMSG_RECONF_CONF:
372 if (nconf != NULL)
373 fatalx("%s: IMSG_RECONF_CONF already in "
374 "progress", __func__);
375 if (IMSG_DATA_SIZE(imsg) != sizeof(struct rad_conf))
376 fatalx("%s: IMSG_RECONF_CONF wrong length: %lu",
377 __func__, IMSG_DATA_SIZE(imsg));
378 if ((nconf = malloc(sizeof(struct rad_conf))) ==
379 NULL)
380 fatal(NULL);
381 memcpy(nconf, imsg.data, sizeof(struct rad_conf));
382 SIMPLEQ_INIT(&nconf->ra_iface_list);
383 SIMPLEQ_INIT(&nconf->ra_options.ra_rdnss_list);
384 SIMPLEQ_INIT(&nconf->ra_options.ra_dnssl_list);
385 SIMPLEQ_INIT(&nconf->ra_options.ra_pref64_list);
386 ra_options = &nconf->ra_options;
387 break;
388 case IMSG_RECONF_RA_IFACE:
389 if (IMSG_DATA_SIZE(imsg) != sizeof(struct
390 ra_iface_conf))
391 fatalx("%s: IMSG_RECONF_RA_IFACE wrong length: "
392 "%lu", __func__, IMSG_DATA_SIZE(imsg));
393 if ((ra_iface_conf = malloc(sizeof(struct
394 ra_iface_conf))) == NULL)
395 fatal(NULL);
396 memcpy(ra_iface_conf, imsg.data, sizeof(struct
397 ra_iface_conf));
398 ra_iface_conf->autoprefix = NULL;
399 SIMPLEQ_INIT(&ra_iface_conf->ra_prefix_list);
400 SIMPLEQ_INIT(&ra_iface_conf->ra_options.ra_rdnss_list);
401 SIMPLEQ_INIT(&ra_iface_conf->ra_options.ra_dnssl_list);
402 SIMPLEQ_INIT(&ra_iface_conf->ra_options.ra_pref64_list);
403 SIMPLEQ_INSERT_TAIL(&nconf->ra_iface_list,
404 ra_iface_conf, entry);
405 ra_options = &ra_iface_conf->ra_options;
406 break;
407 case IMSG_RECONF_RA_AUTOPREFIX:
408 if (IMSG_DATA_SIZE(imsg) != sizeof(struct
409 ra_prefix_conf))
410 fatalx("%s: IMSG_RECONF_RA_AUTOPREFIX wrong "
411 "length: %lu", __func__,
412 IMSG_DATA_SIZE(imsg));
413 if ((ra_iface_conf->autoprefix = malloc(sizeof(struct
414 ra_prefix_conf))) == NULL)
415 fatal(NULL);
416 memcpy(ra_iface_conf->autoprefix, imsg.data,
417 sizeof(struct ra_prefix_conf));
418 break;
419 case IMSG_RECONF_RA_PREFIX:
420 if (IMSG_DATA_SIZE(imsg) != sizeof(struct
421 ra_prefix_conf))
422 fatalx("%s: IMSG_RECONF_RA_PREFIX wrong "
423 "length: %lu", __func__,
424 IMSG_DATA_SIZE(imsg));
425 if ((ra_prefix_conf = malloc(sizeof(struct
426 ra_prefix_conf))) == NULL)
427 fatal(NULL);
428 memcpy(ra_prefix_conf, imsg.data,
429 sizeof(struct ra_prefix_conf));
430 SIMPLEQ_INSERT_TAIL(&ra_iface_conf->ra_prefix_list,
431 ra_prefix_conf, entry);
432 break;
433 case IMSG_RECONF_RA_RDNSS:
434 if (IMSG_DATA_SIZE(imsg) != sizeof(struct
435 ra_rdnss_conf))
436 fatalx("%s: IMSG_RECONF_RA_RDNSS wrong length: "
437 "%lu", __func__, IMSG_DATA_SIZE(imsg));
438 if ((ra_rdnss_conf = malloc(sizeof(struct
439 ra_rdnss_conf))) == NULL)
440 fatal(NULL);
441 memcpy(ra_rdnss_conf, imsg.data, sizeof(struct
442 ra_rdnss_conf));
443 SIMPLEQ_INSERT_TAIL(&ra_options->ra_rdnss_list,
444 ra_rdnss_conf, entry);
445 break;
446 case IMSG_RECONF_RA_DNSSL:
447 if (IMSG_DATA_SIZE(imsg) != sizeof(struct
448 ra_dnssl_conf))
449 fatalx("%s: IMSG_RECONF_RA_DNSSL wrong length: "
450 "%lu", __func__, IMSG_DATA_SIZE(imsg));
451 if ((ra_dnssl_conf = malloc(sizeof(struct
452 ra_dnssl_conf))) == NULL)
453 fatal(NULL);
454 memcpy(ra_dnssl_conf, imsg.data, sizeof(struct
455 ra_dnssl_conf));
456 SIMPLEQ_INSERT_TAIL(&ra_options->ra_dnssl_list,
457 ra_dnssl_conf, entry);
458 break;
459 case IMSG_RECONF_RA_PREF64:
460 if (IMSG_DATA_SIZE(imsg) != sizeof(struct
461 ra_pref64_conf))
462 fatalx("%s: IMSG_RECONF_RA_PREF64 wrong length: "
463 "%lu", __func__, IMSG_DATA_SIZE(imsg));
464 if ((pref64 = malloc(sizeof(struct ra_pref64_conf))) ==
465 NULL)
466 fatal(NULL);
467 memcpy(pref64, imsg.data, sizeof(struct ra_pref64_conf));
468 SIMPLEQ_INSERT_TAIL(&ra_options->ra_pref64_list, pref64,
469 entry);
470 break;
471 case IMSG_RECONF_END:
472 if (nconf == NULL)
473 fatalx("%s: IMSG_RECONF_END without "
474 "IMSG_RECONF_CONF", __func__);
475 merge_config(frontend_conf, nconf);
476 merge_ra_interfaces();
477 nconf = NULL;
478 break;
479 case IMSG_ICMP6SOCK:
480 if ((icmp6sock = imsg_get_fd(&imsg)) == -1)
481 fatalx("%s: expected to receive imsg "
482 "ICMPv6 fd but didn't receive any",
483 __func__);
484 if (IMSG_DATA_SIZE(imsg) != sizeof(rdomain))
485 fatalx("%s: IMSG_ICMP6SOCK wrong length: "
486 "%lu", __func__, IMSG_DATA_SIZE(imsg));
487 memcpy(&rdomain, imsg.data, sizeof(rdomain));
488 set_icmp6sock(icmp6sock, rdomain);
489 break;
490 case IMSG_ROUTESOCK:
491 if (routesock != -1)
492 fatalx("%s: received unexpected routesock fd",
493 __func__);
494 if ((routesock = imsg_get_fd(&imsg)) == -1)
495 fatalx("%s: expected to receive imsg "
496 "routesocket fd but didn't receive any",
497 __func__);
498 event_set(&ev_route, routesock, EV_READ | EV_PERSIST,
499 route_receive, NULL);
500 break;
501 case IMSG_STARTUP:
502 frontend_startup();
503 break;
504 case IMSG_CONTROLFD:
505 if ((fd = imsg_get_fd(&imsg)) == -1)
506 fatalx("%s: expected to receive imsg "
507 "control fd but didn't receive any",
508 __func__);
509 /* Listen on control socket. */
510 control_listen(fd);
511 break;
512 default:
513 log_debug("%s: error handling imsg %d", __func__,
514 imsg.hdr.type);
515 break;
516 }
517 imsg_free(&imsg);
518 }
519 if (!shut)
520 imsg_event_add(iev);
521 else {
522 /* This pipe is dead. Remove its event handler. */
523 event_del(&iev->ev);
524 event_loopexit(NULL);
525 }
526 }
527
528 void
frontend_dispatch_engine(int fd,short event,void * bula)529 frontend_dispatch_engine(int fd, short event, void *bula)
530 {
531 struct imsgev *iev = bula;
532 struct imsgbuf *ibuf = &iev->ibuf;
533 struct imsg imsg;
534 struct imsg_send_ra send_ra;
535 struct ra_iface *ra_iface;
536 uint32_t if_index;
537 int n, shut = 0;
538
539 if (event & EV_READ) {
540 if ((n = imsgbuf_read(ibuf)) == -1)
541 fatal("imsgbuf_read error");
542 if (n == 0) /* Connection closed. */
543 shut = 1;
544 }
545 if (event & EV_WRITE) {
546 if (imsgbuf_write(ibuf) == -1) {
547 if (errno == EPIPE) /* connection closed */
548 shut = 1;
549 else
550 fatal("imsgbuf_write");
551 }
552 }
553
554 for (;;) {
555 if ((n = imsg_get(ibuf, &imsg)) == -1)
556 fatal("%s: imsg_get error", __func__);
557 if (n == 0) /* No more messages. */
558 break;
559
560 switch (imsg.hdr.type) {
561 case IMSG_SEND_RA:
562 if (IMSG_DATA_SIZE(imsg) != sizeof(send_ra))
563 fatalx("%s: IMSG_SEND_RA wrong length: %lu",
564 __func__, IMSG_DATA_SIZE(imsg));
565 memcpy(&send_ra, imsg.data, sizeof(send_ra));
566 ra_iface = find_ra_iface_by_id(send_ra.if_index);
567 if (ra_iface)
568 ra_output(ra_iface, &send_ra.to);
569 break;
570 case IMSG_REMOVE_IF:
571 if (IMSG_DATA_SIZE(imsg) != sizeof(if_index))
572 fatalx("%s: IMSG_REMOVE_IF wrong length: %lu",
573 __func__, IMSG_DATA_SIZE(imsg));
574 memcpy(&if_index, imsg.data, sizeof(if_index));
575 ra_iface = find_ra_iface_by_id(if_index);
576 if (ra_iface) {
577 TAILQ_REMOVE(&ra_interfaces, ra_iface, entry);
578 free_ra_iface(ra_iface);
579 }
580 break;
581 default:
582 log_debug("%s: error handling imsg %d", __func__,
583 imsg.hdr.type);
584 break;
585 }
586 imsg_free(&imsg);
587 }
588 if (!shut)
589 imsg_event_add(iev);
590 else {
591 /* This pipe is dead. Remove its event handler. */
592 event_del(&iev->ev);
593 event_loopexit(NULL);
594 }
595 }
596
597 void
frontend_startup(void)598 frontend_startup(void)
599 {
600 if (!event_initialized(&ev_route))
601 fatalx("%s: did not receive a route socket from the main "
602 "process", __func__);
603
604 event_add(&ev_route, NULL);
605 }
606
607
608 void
icmp6_receive(int fd,short events,void * arg)609 icmp6_receive(int fd, short events, void *arg)
610 {
611 struct icmp6_ev *icmp6ev;
612 struct icmp6_hdr *icmp6_hdr;
613 struct imsg_ra_rs ra_rs;
614 struct in6_pktinfo *pi = NULL;
615 struct cmsghdr *cm;
616 ssize_t len;
617 int if_index = 0, *hlimp = NULL;
618 char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
619
620 icmp6ev = arg;
621 if ((len = recvmsg(fd, &icmp6ev->rcvmhdr, 0)) == -1) {
622 log_warn("recvmsg");
623 return;
624 }
625
626 if ((size_t)len < sizeof(struct icmp6_hdr))
627 return;
628
629 icmp6_hdr = (struct icmp6_hdr *)icmp6ev->answer;
630 if (icmp6_hdr->icmp6_type != ND_ROUTER_ADVERT &&
631 icmp6_hdr->icmp6_type != ND_ROUTER_SOLICIT)
632 return;
633
634 /* extract optional information via Advanced API */
635 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&icmp6ev->rcvmhdr); cm;
636 cm = (struct cmsghdr *)CMSG_NXTHDR(&icmp6ev->rcvmhdr, cm)) {
637 if (cm->cmsg_level == IPPROTO_IPV6 &&
638 cm->cmsg_type == IPV6_PKTINFO &&
639 cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) {
640 pi = (struct in6_pktinfo *)(CMSG_DATA(cm));
641 if_index = pi->ipi6_ifindex;
642 }
643 if (cm->cmsg_level == IPPROTO_IPV6 &&
644 cm->cmsg_type == IPV6_HOPLIMIT &&
645 cm->cmsg_len == CMSG_LEN(sizeof(int)))
646 hlimp = (int *)CMSG_DATA(cm);
647 }
648
649 if (if_index == 0) {
650 log_warnx("failed to get receiving interface");
651 return;
652 }
653
654 if (hlimp == NULL) {
655 log_warnx("failed to get receiving hop limit");
656 return;
657 }
658
659 if (*hlimp != 255) {
660 log_warnx("invalid RA or RS with hop limit of %d from %s on %s",
661 *hlimp, inet_ntop(AF_INET6, &icmp6ev->from.sin6_addr,
662 ntopbuf, INET6_ADDRSTRLEN), if_indextoname(if_index,
663 ifnamebuf));
664 return;
665 }
666
667 log_debug("RA or RS with hop limit of %d from %s on %s",
668 *hlimp, inet_ntop(AF_INET6, &icmp6ev->from.sin6_addr,
669 ntopbuf, INET6_ADDRSTRLEN), if_indextoname(if_index,
670 ifnamebuf));
671
672 if ((size_t)len > sizeof(ra_rs.packet)) {
673 log_warnx("invalid RA or RS with size %ld from %s on %s",
674 len, inet_ntop(AF_INET6, &icmp6ev->from.sin6_addr,
675 ntopbuf, INET6_ADDRSTRLEN), if_indextoname(if_index,
676 ifnamebuf));
677 return;
678 }
679
680 ra_rs.if_index = if_index;
681 memcpy(&ra_rs.from, &icmp6ev->from, sizeof(ra_rs.from));
682 ra_rs.len = len;
683 memcpy(ra_rs.packet, icmp6ev->answer, len);
684
685 frontend_imsg_compose_engine(IMSG_RA_RS, 0, &ra_rs, sizeof(ra_rs));
686 }
687
688 void
join_all_routers_mcast_group(struct ra_iface * ra_iface)689 join_all_routers_mcast_group(struct ra_iface *ra_iface)
690 {
691 if (!event_initialized(&ra_iface->icmp6ev->ev))
692 return;
693 log_debug("joining multicast group on %s", ra_iface->name);
694 all_routers.ipv6mr_interface = ra_iface->if_index;
695 if (setsockopt(EVENT_FD(&ra_iface->icmp6ev->ev), IPPROTO_IPV6,
696 IPV6_JOIN_GROUP, &all_routers, sizeof(all_routers)) == -1)
697 fatal("IPV6_JOIN_GROUP(%s)", ra_iface->name);
698 }
699
700 void
leave_all_routers_mcast_group(struct ra_iface * ra_iface)701 leave_all_routers_mcast_group(struct ra_iface *ra_iface)
702 {
703 if (!event_initialized(&ra_iface->icmp6ev->ev))
704 return;
705 log_debug("leaving multicast group on %s", ra_iface->name);
706 all_routers.ipv6mr_interface = ra_iface->if_index;
707 setsockopt(EVENT_FD(&ra_iface->icmp6ev->ev), IPPROTO_IPV6,
708 IPV6_LEAVE_GROUP, &all_routers, sizeof(all_routers));
709 }
710
711 struct ra_iface*
find_ra_iface_by_id(uint32_t if_index)712 find_ra_iface_by_id(uint32_t if_index)
713 {
714 struct ra_iface *ra_iface;
715
716 TAILQ_FOREACH(ra_iface, &ra_interfaces, entry) {
717 if (ra_iface->if_index == if_index)
718 return ra_iface;
719 }
720 return (NULL);
721 }
722
723 struct ra_iface*
find_ra_iface_by_name(char * if_name)724 find_ra_iface_by_name(char *if_name)
725 {
726 struct ra_iface *ra_iface;
727
728 TAILQ_FOREACH(ra_iface, &ra_interfaces, entry) {
729 if (strcmp(ra_iface->name, if_name) == 0)
730 return ra_iface;
731 }
732 return (NULL);
733 }
734
735 struct ra_iface_conf*
find_ra_iface_conf(struct ra_iface_conf_head * head,char * if_name)736 find_ra_iface_conf(struct ra_iface_conf_head *head, char *if_name)
737 {
738 struct ra_iface_conf *ra_iface_conf;
739
740 SIMPLEQ_FOREACH(ra_iface_conf, head, entry) {
741 if (strcmp(ra_iface_conf->name, if_name) == 0)
742 return ra_iface_conf;
743 }
744 return (NULL);
745 }
746
747 int
get_ifrdomain(char * if_name)748 get_ifrdomain(char *if_name)
749 {
750 struct ifreq ifr;
751
752 strlcpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
753 if (ioctl(ioctlsock, SIOCGIFRDOMAIN, (caddr_t)&ifr) == -1) {
754 log_warn("SIOCGIFRDOMAIN");
755 return -1;
756 }
757 return ifr.ifr_rdomainid;
758 }
759
760 void
merge_ra_interface(char * if_name,char * conf_name,struct ifaddrs * ifap)761 merge_ra_interface(char *if_name, char *conf_name, struct ifaddrs *ifap)
762 {
763 struct ra_iface *ra_iface;
764 struct ifaddrs *ifa;
765 struct sockaddr_in6 *sin6;
766 struct in6_ifreq ifr6;
767 struct sockaddr_dl *sdl;
768 struct ether_addr hw_addr;
769 uint32_t if_index;
770 int link_state = LINK_STATE_UNKNOWN;
771 int has_linklocal = 0, ifrdomain;
772 int has_hw_addr = 0;
773
774 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
775 if (ifa->ifa_addr == NULL)
776 continue;
777 if (ifa->ifa_addr->sa_family != AF_LINK &&
778 ifa->ifa_addr->sa_family != AF_INET6)
779 continue;
780 if (strcmp(if_name, ifa->ifa_name) != 0)
781 continue;
782
783 if (ifa->ifa_addr->sa_family == AF_LINK) {
784 link_state =
785 ((struct if_data*)ifa->ifa_data)->ifi_link_state;
786 sdl = (struct sockaddr_dl *)ifa->ifa_addr;
787 if (sdl != NULL && (sdl->sdl_type == IFT_ETHER ||
788 sdl->sdl_type == IFT_CARP) && sdl->sdl_alen ==
789 ETHER_ADDR_LEN) {
790 has_hw_addr = 1;
791 memcpy(&hw_addr, LLADDR(sdl), ETHER_ADDR_LEN);
792 }
793 } else if (ifa->ifa_addr->sa_family == AF_INET6) {
794 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
795
796 if (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
797 continue;
798
799 memset(&ifr6, 0, sizeof(ifr6));
800 strlcpy(ifr6.ifr_name, if_name, sizeof(ifr6.ifr_name));
801 memcpy(&ifr6.ifr_addr, sin6, sizeof(ifr6.ifr_addr));
802 if (ioctl(ioctlsock, SIOCGIFAFLAG_IN6,
803 (caddr_t)&ifr6) == -1) {
804 log_warn("SIOCGIFAFLAG_IN6");
805 continue;
806 }
807
808 if (ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_TENTATIVE |
809 IN6_IFF_DUPLICATED))
810 continue;
811 has_linklocal = 1;
812 }
813 }
814
815 ifrdomain = get_ifrdomain(if_name);
816
817 if ((ra_iface = find_ra_iface_by_name(if_name)) != NULL) {
818 ra_iface->link_state = link_state;
819 if (!LINK_STATE_IS_UP(link_state)) {
820 log_debug("%s down, removing", if_name);
821 ra_iface->removed = 1;
822 } else if (!has_linklocal) {
823 log_debug("%s has no IPv6 link-local address, "
824 "removing", if_name);
825 ra_iface->removed = 1;
826 } else if (ifrdomain == -1) {
827 log_debug("can't get rdomain for %s, removing", if_name);
828 ra_iface->removed = 1;
829 } else if (!has_hw_addr) {
830 log_debug("%s has no mac address, removing", if_name);
831 ra_iface->removed = 1;
832 } else if (ra_iface->rdomain != ifrdomain) {
833 leave_all_routers_mcast_group(ra_iface);
834 unref_icmp6ev(ra_iface);
835 ra_iface->rdomain = ifrdomain;
836 ra_iface->icmp6ev = get_icmp6ev_by_rdomain(ifrdomain);
837 join_all_routers_mcast_group(ra_iface);
838 ra_iface->removed = 0;
839 } else {
840 log_debug("keeping interface %s", if_name);
841 ra_iface->removed = 0;
842 }
843 memcpy(&ra_iface->hw_addr, &hw_addr, sizeof(hw_addr));
844 return;
845 }
846
847 if (!LINK_STATE_IS_UP(link_state)) {
848 log_debug("%s down, ignoring", if_name);
849 return;
850 }
851
852 if (!has_linklocal) {
853 log_debug("%s has no IPv6 link-local address, ignoring",
854 if_name);
855 return;
856 }
857
858 if (ifrdomain == -1) {
859 log_debug("can't get rdomain for %s, ignoring", if_name);
860 return;
861 }
862
863 if (!has_hw_addr) {
864 log_debug("%s has no mac address, ignoring", if_name);
865 return;
866 }
867
868 log_debug("new interface %s", if_name);
869 if ((if_index = if_nametoindex(if_name)) == 0)
870 return;
871
872 log_debug("adding interface %s", if_name);
873 if ((ra_iface = calloc(1, sizeof(*ra_iface))) == NULL)
874 fatal("%s", __func__);
875
876 strlcpy(ra_iface->name, if_name, sizeof(ra_iface->name));
877 strlcpy(ra_iface->conf_name, conf_name,
878 sizeof(ra_iface->conf_name));
879
880 ra_iface->if_index = if_index;
881 ra_iface->rdomain = ifrdomain;
882 memcpy(&ra_iface->hw_addr, &hw_addr, sizeof(hw_addr));
883 SIMPLEQ_INIT(&ra_iface->prefixes);
884
885 ra_iface->icmp6ev = get_icmp6ev_by_rdomain(ifrdomain);
886 join_all_routers_mcast_group(ra_iface);
887 TAILQ_INSERT_TAIL(&ra_interfaces, ra_iface, entry);
888 }
889
890 void
merge_ra_interfaces(void)891 merge_ra_interfaces(void)
892 {
893 struct ra_iface_conf *ra_iface_conf;
894 struct ra_prefix_conf *ra_prefix_conf;
895 struct ra_iface *ra_iface;
896 struct ifgroupreq ifgr;
897 struct ifg_req *ifg;
898 struct ifaddrs *ifap;
899 char *conf_name;
900 unsigned int len;
901
902 if (getifaddrs(&ifap) != 0) {
903 log_warn("getifaddrs");
904 return;
905 }
906
907 TAILQ_FOREACH(ra_iface, &ra_interfaces, entry)
908 ra_iface->removed = 1;
909
910 SIMPLEQ_FOREACH(ra_iface_conf, &frontend_conf->ra_iface_list, entry) {
911 conf_name = ra_iface_conf->name;
912
913 /* check if network interface or group */
914 if (isdigit((unsigned char)conf_name[strlen(conf_name) - 1])) {
915 merge_ra_interface(conf_name, conf_name, ifap);
916 } else {
917 log_debug("interface group %s", conf_name);
918
919 memset(&ifgr, 0, sizeof(ifgr));
920 strlcpy(ifgr.ifgr_name, conf_name,
921 sizeof(ifgr.ifgr_name));
922 if (ioctl(ioctlsock, SIOCGIFGMEMB,
923 (caddr_t)&ifgr) == -1)
924 continue;
925
926 len = ifgr.ifgr_len;
927 if ((ifgr.ifgr_groups = calloc(1, len)) == NULL)
928 fatal("%s: calloc", __func__);
929 if (ioctl(ioctlsock, SIOCGIFGMEMB,
930 (caddr_t)&ifgr) == -1) {
931 log_debug("group %s without members",
932 conf_name);
933 free(ifgr.ifgr_groups);
934 continue;
935 }
936
937 for (ifg = ifgr.ifgr_groups;
938 (ifg != NULL) && (len >= sizeof(struct ifg_req));
939 ifg++) {
940 len -= sizeof(struct ifg_req);
941 merge_ra_interface(ifg->ifgrq_member,
942 conf_name, ifap);
943 }
944 free(ifgr.ifgr_groups);
945 }
946 }
947
948 TAILQ_FOREACH(ra_iface, &ra_interfaces, entry) {
949 while ((ra_prefix_conf = SIMPLEQ_FIRST(&ra_iface->prefixes))
950 != NULL) {
951 SIMPLEQ_REMOVE_HEAD(&ra_iface->prefixes,
952 entry);
953 free(ra_prefix_conf);
954 }
955 ra_iface->prefix_count = 0;
956
957 if (ra_iface->removed) {
958 log_debug("iface removed: %s", ra_iface->name);
959 build_leaving_packet(ra_iface);
960 frontend_imsg_compose_engine(IMSG_REMOVE_IF, 0,
961 &ra_iface->if_index, sizeof(ra_iface->if_index));
962 continue;
963 }
964
965 ra_iface_conf = find_ra_iface_conf(
966 &frontend_conf->ra_iface_list, ra_iface->conf_name);
967
968 log_debug("add static prefixes for %s", ra_iface->name);
969
970 SIMPLEQ_FOREACH(ra_prefix_conf, &ra_iface_conf->ra_prefix_list,
971 entry) {
972 add_new_prefix_to_ra_iface(ra_iface,
973 &ra_prefix_conf->prefix,
974 ra_prefix_conf->prefixlen, ra_prefix_conf,
975 ND6_INFINITE_LIFETIME, ND6_INFINITE_LIFETIME);
976 }
977
978 if (ra_iface_conf->autoprefix)
979 get_interface_prefixes(ra_iface,
980 ra_iface_conf->autoprefix, ifap);
981
982 if (build_packet(ra_iface)) {
983 /* packet changed; send new advertisements */
984 if (event_initialized(&ra_iface->icmp6ev->ev))
985 frontend_imsg_compose_engine(IMSG_UPDATE_IF, 0,
986 &ra_iface->if_index,
987 sizeof(ra_iface->if_index));
988 }
989 }
990 freeifaddrs(ifap);
991 }
992
993 void
free_ra_iface(struct ra_iface * ra_iface)994 free_ra_iface(struct ra_iface *ra_iface)
995 {
996 struct ra_prefix_conf *prefix;
997
998 leave_all_routers_mcast_group(ra_iface);
999
1000 while ((prefix = SIMPLEQ_FIRST(&ra_iface->prefixes)) != NULL) {
1001 SIMPLEQ_REMOVE_HEAD(&ra_iface->prefixes, entry);
1002 free(prefix);
1003 }
1004
1005 unref_icmp6ev(ra_iface);
1006 free(ra_iface);
1007 }
1008
1009 /* from kame via ifconfig, where it's called prefix() */
1010 int
in6_mask2prefixlen(struct in6_addr * in6)1011 in6_mask2prefixlen(struct in6_addr *in6)
1012 {
1013 u_char *nam = (u_char *)in6;
1014 int byte, bit, plen = 0, size = sizeof(struct in6_addr);
1015
1016 for (byte = 0; byte < size; byte++, plen += 8)
1017 if (nam[byte] != 0xff)
1018 break;
1019 if (byte == size)
1020 return (plen);
1021 for (bit = 7; bit != 0; bit--, plen++)
1022 if (!(nam[byte] & (1 << bit)))
1023 break;
1024 for (; bit != 0; bit--)
1025 if (nam[byte] & (1 << bit))
1026 return (0);
1027 byte++;
1028 for (; byte < size; byte++)
1029 if (nam[byte])
1030 return (0);
1031 return (plen);
1032 }
1033
1034 void
get_interface_prefixes(struct ra_iface * ra_iface,struct ra_prefix_conf * autoprefix_conf,struct ifaddrs * ifap)1035 get_interface_prefixes(struct ra_iface *ra_iface, struct ra_prefix_conf
1036 *autoprefix_conf, struct ifaddrs *ifap)
1037 {
1038 struct in6_ifreq ifr6;
1039 struct ifaddrs *ifa;
1040 struct sockaddr_in6 *sin6;
1041 uint32_t decaying_vltime, decaying_pltime;
1042 int prefixlen;
1043
1044 for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
1045 if (ifa->ifa_addr == NULL ||
1046 ifa->ifa_addr->sa_family != AF_INET6)
1047 continue;
1048
1049 if (strcmp(ra_iface->name, ifa->ifa_name) != 0)
1050 continue;
1051
1052 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
1053
1054 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
1055 continue;
1056
1057 memset(&ifr6, 0, sizeof(ifr6));
1058 strlcpy(ifr6.ifr_name, ra_iface->name, sizeof(ifr6.ifr_name));
1059 memcpy(&ifr6.ifr_addr, sin6, sizeof(ifr6.ifr_addr));
1060
1061 decaying_vltime = ND6_INFINITE_LIFETIME;
1062 decaying_pltime = ND6_INFINITE_LIFETIME;
1063
1064 if (ioctl(ioctlsock, SIOCGIFALIFETIME_IN6,
1065 (caddr_t)&ifr6) != -1) {
1066 struct in6_addrlifetime *lifetime;
1067
1068 lifetime = &ifr6.ifr_ifru.ifru_lifetime;
1069 if (lifetime->ia6t_preferred)
1070 decaying_pltime = lifetime->ia6t_preferred;
1071 if (lifetime->ia6t_expire)
1072 decaying_vltime = lifetime->ia6t_expire;
1073 }
1074
1075 memset(&ifr6, 0, sizeof(ifr6));
1076 strlcpy(ifr6.ifr_name, ra_iface->name, sizeof(ifr6.ifr_name));
1077 memcpy(&ifr6.ifr_addr, sin6, sizeof(ifr6.ifr_addr));
1078
1079 if (ioctl(ioctlsock, SIOCGIFNETMASK_IN6, (caddr_t)&ifr6) == -1)
1080 continue; /* addr got deleted while we were looking */
1081
1082 prefixlen = in6_mask2prefixlen(&((struct sockaddr_in6 *)
1083 &ifr6.ifr_addr)->sin6_addr);
1084
1085 if (prefixlen == 128)
1086 continue;
1087
1088 mask_prefix(&sin6->sin6_addr, prefixlen);
1089
1090 add_new_prefix_to_ra_iface(ra_iface, &sin6->sin6_addr,
1091 prefixlen, autoprefix_conf, decaying_vltime,
1092 decaying_pltime);
1093 }
1094 }
1095
1096 struct ra_prefix_conf*
find_ra_prefix_conf(struct ra_prefix_conf_head * head,struct in6_addr * prefix,int prefixlen)1097 find_ra_prefix_conf(struct ra_prefix_conf_head* head, struct in6_addr *prefix,
1098 int prefixlen)
1099 {
1100 struct ra_prefix_conf *ra_prefix_conf;
1101
1102 SIMPLEQ_FOREACH(ra_prefix_conf, head, entry) {
1103 if (ra_prefix_conf->prefixlen == prefixlen &&
1104 memcmp(&ra_prefix_conf->prefix, prefix, sizeof(*prefix)) ==
1105 0)
1106 return (ra_prefix_conf);
1107 }
1108 return (NULL);
1109 }
1110
1111 void
add_new_prefix_to_ra_iface(struct ra_iface * ra_iface,struct in6_addr * addr,int prefixlen,struct ra_prefix_conf * ra_prefix_conf,uint32_t decaying_vltime,uint32_t decaying_pltime)1112 add_new_prefix_to_ra_iface(struct ra_iface *ra_iface, struct in6_addr *addr,
1113 int prefixlen, struct ra_prefix_conf *ra_prefix_conf,
1114 uint32_t decaying_vltime, uint32_t decaying_pltime)
1115 {
1116 struct ra_prefix_conf *new_ra_prefix_conf;
1117
1118 if ((new_ra_prefix_conf = find_ra_prefix_conf(&ra_iface->prefixes, addr,
1119 prefixlen)) != NULL) {
1120 if (decaying_vltime != ND6_INFINITE_LIFETIME ||
1121 decaying_pltime != ND6_INFINITE_LIFETIME) {
1122 ra_iface->ltime_decaying = 1;
1123 new_ra_prefix_conf->ltime_decaying = 0;
1124 if (decaying_vltime != ND6_INFINITE_LIFETIME) {
1125 new_ra_prefix_conf->vltime = decaying_vltime;
1126 new_ra_prefix_conf->ltime_decaying |=
1127 VLTIME_DECAYING;
1128 }
1129 if (decaying_pltime != ND6_INFINITE_LIFETIME) {
1130 new_ra_prefix_conf->pltime = decaying_pltime;
1131 new_ra_prefix_conf->ltime_decaying |=
1132 PLTIME_DECAYING;
1133 }
1134 } else if (new_ra_prefix_conf->ltime_decaying) {
1135 struct ra_prefix_conf *pc;
1136
1137 new_ra_prefix_conf->ltime_decaying = 0;
1138 ra_iface->ltime_decaying = 0;
1139 SIMPLEQ_FOREACH(pc, &ra_iface->prefixes, entry) {
1140 if (pc->ltime_decaying) {
1141 ra_iface->ltime_decaying = 1;
1142 break;
1143 }
1144 }
1145 } else
1146 log_debug("ignoring duplicate %s/%d prefix",
1147 in6_to_str(addr), prefixlen);
1148 return;
1149 }
1150
1151 log_debug("adding %s/%d prefix", in6_to_str(addr), prefixlen);
1152
1153 if ((new_ra_prefix_conf = calloc(1, sizeof(*ra_prefix_conf))) == NULL)
1154 fatal("%s", __func__);
1155 new_ra_prefix_conf->prefix = *addr;
1156 new_ra_prefix_conf->prefixlen = prefixlen;
1157 new_ra_prefix_conf->vltime = ra_prefix_conf->vltime;
1158 new_ra_prefix_conf->pltime = ra_prefix_conf->pltime;
1159 if (decaying_vltime != ND6_INFINITE_LIFETIME ||
1160 decaying_pltime != ND6_INFINITE_LIFETIME) {
1161 ra_iface->ltime_decaying = 1;
1162 if (decaying_vltime != ND6_INFINITE_LIFETIME) {
1163 new_ra_prefix_conf->vltime = decaying_vltime;
1164 new_ra_prefix_conf->ltime_decaying |= VLTIME_DECAYING;
1165 }
1166 if (decaying_pltime != ND6_INFINITE_LIFETIME) {
1167 new_ra_prefix_conf->pltime = decaying_pltime;
1168 new_ra_prefix_conf->ltime_decaying |= PLTIME_DECAYING;
1169 }
1170 }
1171 new_ra_prefix_conf->aflag = ra_prefix_conf->aflag;
1172 new_ra_prefix_conf->lflag = ra_prefix_conf->lflag;
1173 SIMPLEQ_INSERT_TAIL(&ra_iface->prefixes, new_ra_prefix_conf, entry);
1174 ra_iface->prefix_count++;
1175 }
1176
1177 int
build_packet(struct ra_iface * ra_iface)1178 build_packet(struct ra_iface *ra_iface)
1179 {
1180 struct nd_router_advert *ra;
1181 struct nd_opt_source_link_addr *ndopt_source_link_addr;
1182 struct nd_opt_mtu *ndopt_mtu;
1183 struct nd_opt_prefix_info *ndopt_pi;
1184 struct ra_iface_conf *ra_iface_conf;
1185 struct ra_options_conf *ra_options_conf;
1186 struct ra_prefix_conf *ra_prefix_conf;
1187 struct nd_opt_rdnss *ndopt_rdnss;
1188 struct nd_opt_dnssl *ndopt_dnssl;
1189 struct nd_opt_pref64 *ndopt_pref64;
1190 struct ra_rdnss_conf *ra_rdnss;
1191 struct ra_dnssl_conf *ra_dnssl;
1192 struct ra_pref64_conf *pref64;
1193 size_t len, label_len;
1194 time_t t;
1195 uint32_t vltime, pltime;
1196 uint8_t *p, buf[RA_MAX_SIZE];
1197 char *label_start, *label_end;
1198
1199 ra_iface_conf = find_ra_iface_conf(&frontend_conf->ra_iface_list,
1200 ra_iface->conf_name);
1201 ra_options_conf = &ra_iface_conf->ra_options;
1202 t = time(NULL);
1203 len = sizeof(*ra);
1204 if (ra_iface_conf->ra_options.source_link_addr)
1205 len += sizeof(*ndopt_source_link_addr);
1206 if (ra_options_conf->mtu > 0)
1207 len += sizeof(*ndopt_mtu);
1208 len += sizeof(*ndopt_pi) * ra_iface->prefix_count;
1209 if (ra_iface_conf->ra_options.rdnss_count > 0)
1210 len += sizeof(*ndopt_rdnss) +
1211 ra_iface_conf->ra_options.rdnss_count *
1212 sizeof(struct in6_addr);
1213
1214 if (ra_iface_conf->ra_options.dnssl_len > 0)
1215 /* round up to 8 byte boundary */
1216 len += sizeof(*ndopt_dnssl) +
1217 ((ra_iface_conf->ra_options.dnssl_len + 7) & ~7);
1218
1219 SIMPLEQ_FOREACH(pref64, &ra_iface_conf->ra_options.ra_pref64_list,
1220 entry)
1221 len += sizeof(struct nd_opt_pref64);
1222
1223 if (len > sizeof(ra_iface->data))
1224 fatalx("%s: packet too big", __func__); /* XXX send multiple */
1225
1226 p = buf;
1227
1228 ra = (struct nd_router_advert *)p;
1229
1230 memset(ra, 0, sizeof(*ra));
1231
1232 ra->nd_ra_type = ND_ROUTER_ADVERT;
1233 ra->nd_ra_curhoplimit = ra_options_conf->cur_hl;
1234 if (ra_options_conf->m_flag)
1235 ra->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED;
1236 if (ra_options_conf->o_flag)
1237 ra->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER;
1238 if (ra_iface->removed)
1239 /* tell clients that we are no longer a default router */
1240 ra->nd_ra_router_lifetime = 0;
1241 else if (ra_options_conf->dfr) {
1242 ra->nd_ra_router_lifetime =
1243 htons(ra_options_conf->router_lifetime);
1244 /*
1245 * RFC 4191
1246 * If the Router Lifetime is zero, the preference value MUST be
1247 * set to (00) by the sender and MUST be ignored by the
1248 * receiver.
1249 */
1250 if (ra_options_conf->router_lifetime > 0)
1251 ra->nd_ra_flags_reserved |= ra_options_conf->rtpref;
1252 }
1253 ra->nd_ra_reachable = htonl(ra_options_conf->reachable_time);
1254 ra->nd_ra_retransmit = htonl(ra_options_conf->retrans_timer);
1255 p += sizeof(*ra);
1256
1257 if (ra_iface_conf->ra_options.source_link_addr) {
1258 ndopt_source_link_addr = (struct nd_opt_source_link_addr *)p;
1259 ndopt_source_link_addr->nd_opt_source_link_addr_type =
1260 ND_OPT_SOURCE_LINKADDR;
1261 ndopt_source_link_addr->nd_opt_source_link_addr_len = 1;
1262 memcpy(&ndopt_source_link_addr->nd_opt_source_link_addr_hw_addr,
1263 &ra_iface->hw_addr, ETHER_ADDR_LEN);
1264 p += sizeof(*ndopt_source_link_addr);
1265 }
1266
1267 if (ra_options_conf->mtu > 0) {
1268 ndopt_mtu = (struct nd_opt_mtu *)p;
1269 ndopt_mtu->nd_opt_mtu_type = ND_OPT_MTU;
1270 ndopt_mtu->nd_opt_mtu_len = 1;
1271 ndopt_mtu->nd_opt_mtu_reserved = 0;
1272 ndopt_mtu->nd_opt_mtu_mtu = htonl(ra_options_conf->mtu);
1273 p += sizeof(*ndopt_mtu);
1274 }
1275
1276 SIMPLEQ_FOREACH(ra_prefix_conf, &ra_iface->prefixes, entry) {
1277 ndopt_pi = (struct nd_opt_prefix_info *)p;
1278 memset(ndopt_pi, 0, sizeof(*ndopt_pi));
1279 ndopt_pi->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
1280 ndopt_pi->nd_opt_pi_len = 4;
1281 ndopt_pi->nd_opt_pi_prefix_len = ra_prefix_conf->prefixlen;
1282 if (ra_prefix_conf->lflag)
1283 ndopt_pi->nd_opt_pi_flags_reserved |=
1284 ND_OPT_PI_FLAG_ONLINK;
1285 if (ra_prefix_conf->aflag)
1286 ndopt_pi->nd_opt_pi_flags_reserved |=
1287 ND_OPT_PI_FLAG_AUTO;
1288
1289 if (ra_prefix_conf->ltime_decaying & VLTIME_DECAYING)
1290 vltime = ra_prefix_conf->vltime < t ? 0 :
1291 ra_prefix_conf->vltime - t;
1292 else
1293 vltime = ra_prefix_conf->vltime;
1294 if (ra_prefix_conf->ltime_decaying & PLTIME_DECAYING)
1295 pltime = ra_prefix_conf->pltime < t ? 0 :
1296 ra_prefix_conf->pltime - t;
1297 else
1298 pltime = ra_prefix_conf->pltime;
1299
1300 ndopt_pi->nd_opt_pi_valid_time = htonl(vltime);
1301 ndopt_pi->nd_opt_pi_preferred_time = htonl(pltime);
1302 ndopt_pi->nd_opt_pi_prefix = ra_prefix_conf->prefix;
1303
1304 p += sizeof(*ndopt_pi);
1305 }
1306
1307 if (ra_iface_conf->ra_options.rdnss_count > 0) {
1308 ndopt_rdnss = (struct nd_opt_rdnss *)p;
1309 ndopt_rdnss->nd_opt_rdnss_type = ND_OPT_RDNSS;
1310 ndopt_rdnss->nd_opt_rdnss_len = 1 +
1311 ra_iface_conf->ra_options.rdnss_count * 2;
1312 ndopt_rdnss->nd_opt_rdnss_reserved = 0;
1313 ndopt_rdnss->nd_opt_rdnss_lifetime =
1314 htonl(ra_iface_conf->ra_options.rdns_lifetime);
1315 p += sizeof(struct nd_opt_rdnss);
1316 SIMPLEQ_FOREACH(ra_rdnss,
1317 &ra_iface_conf->ra_options.ra_rdnss_list, entry) {
1318 memcpy(p, &ra_rdnss->rdnss, sizeof(ra_rdnss->rdnss));
1319 p += sizeof(ra_rdnss->rdnss);
1320 }
1321 }
1322
1323 if (ra_iface_conf->ra_options.dnssl_len > 0) {
1324 ndopt_dnssl = (struct nd_opt_dnssl *)p;
1325 ndopt_dnssl->nd_opt_dnssl_type = ND_OPT_DNSSL;
1326 /* round up to 8 byte boundary */
1327 ndopt_dnssl->nd_opt_dnssl_len = 1 +
1328 ((ra_iface_conf->ra_options.dnssl_len + 7) & ~7) / 8;
1329 ndopt_dnssl->nd_opt_dnssl_reserved = 0;
1330 ndopt_dnssl->nd_opt_dnssl_lifetime =
1331 htonl(ra_iface_conf->ra_options.rdns_lifetime);
1332 p += sizeof(struct nd_opt_dnssl);
1333
1334 SIMPLEQ_FOREACH(ra_dnssl,
1335 &ra_iface_conf->ra_options.ra_dnssl_list, entry) {
1336 label_start = ra_dnssl->search;
1337 while ((label_end = strchr(label_start, '.')) != NULL) {
1338 label_len = label_end - label_start;
1339 *p++ = label_len;
1340 memcpy(p, label_start, label_len);
1341 p += label_len;
1342 label_start = label_end + 1;
1343 }
1344 *p++ = '\0'; /* last dot */
1345 }
1346 /* zero pad */
1347 while (((uintptr_t)p) % 8 != 0)
1348 *p++ = '\0';
1349 }
1350
1351 SIMPLEQ_FOREACH(pref64, &ra_iface_conf->ra_options.ra_pref64_list,
1352 entry) {
1353 uint16_t sltime_plc;
1354
1355 /* scaled lifetime in units of 8 seconds */
1356 sltime_plc = pref64->ltime / 8;
1357 sltime_plc = sltime_plc << 3;
1358 /* encode prefix length in lower 3 bits */
1359 switch (pref64->prefixlen) {
1360 case 96:
1361 sltime_plc |= 0;
1362 break;
1363 case 64:
1364 sltime_plc |= 1;
1365 break;
1366 case 56:
1367 sltime_plc |= 2;
1368 break;
1369 case 48:
1370 sltime_plc |= 3;
1371 break;
1372 case 40:
1373 sltime_plc |= 4;
1374 break;
1375 case 32:
1376 sltime_plc |= 5;
1377 break;
1378 default:
1379 fatalx("%s: invalid pref64 length: %d", __func__,
1380 pref64->prefixlen);
1381 }
1382 ndopt_pref64 = (struct nd_opt_pref64 *)p;
1383 ndopt_pref64->nd_opt_pref64_type = ND_OPT_PREF64;
1384 ndopt_pref64->nd_opt_pref64_len = 2;
1385 ndopt_pref64->nd_opt_pref64_sltime_plc = htons(sltime_plc);
1386 memcpy(ndopt_pref64->nd_opt_pref64, &pref64->prefix,
1387 sizeof(ndopt_pref64->nd_opt_pref64));
1388 p += sizeof(struct nd_opt_pref64);
1389 }
1390
1391 if (len != ra_iface->datalen || memcmp(buf, ra_iface->data, len)
1392 != 0) {
1393 memcpy(ra_iface->data, buf, len);
1394 ra_iface->datalen = len;
1395 return 1;
1396 }
1397 return 0;
1398 }
1399
1400 void
build_leaving_packet(struct ra_iface * ra_iface)1401 build_leaving_packet(struct ra_iface *ra_iface)
1402 {
1403 struct nd_router_advert ra;
1404
1405 memset(&ra, 0, sizeof(ra));
1406
1407 ra.nd_ra_type = ND_ROUTER_ADVERT;
1408
1409 memcpy(ra_iface->data, &ra, sizeof(ra));
1410 ra_iface->datalen = sizeof(ra);
1411 }
1412
1413 void
ra_output(struct ra_iface * ra_iface,struct sockaddr_in6 * to)1414 ra_output(struct ra_iface *ra_iface, struct sockaddr_in6 *to)
1415 {
1416
1417 struct cmsghdr *cm;
1418 struct in6_pktinfo *pi;
1419 ssize_t len;
1420 int hoplimit = 255;
1421
1422 if (!LINK_STATE_IS_UP(ra_iface->link_state))
1423 return;
1424
1425 if (ra_iface->ltime_decaying)
1426 /* update vltime & pltime */
1427 build_packet(ra_iface);
1428
1429 sndmhdr.msg_name = to;
1430 sndmhdr.msg_iov[0].iov_base = ra_iface->data;
1431 sndmhdr.msg_iov[0].iov_len = ra_iface->datalen;
1432
1433 cm = CMSG_FIRSTHDR(&sndmhdr);
1434 /* specify the outgoing interface */
1435 cm->cmsg_level = IPPROTO_IPV6;
1436 cm->cmsg_type = IPV6_PKTINFO;
1437 cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
1438 pi = (struct in6_pktinfo *)CMSG_DATA(cm);
1439 memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr));
1440 pi->ipi6_ifindex = ra_iface->if_index;
1441
1442 /* specify the hop limit of the packet */
1443 cm = CMSG_NXTHDR(&sndmhdr, cm);
1444 cm->cmsg_level = IPPROTO_IPV6;
1445 cm->cmsg_type = IPV6_HOPLIMIT;
1446 cm->cmsg_len = CMSG_LEN(sizeof(int));
1447 memcpy(CMSG_DATA(cm), &hoplimit, sizeof(int));
1448
1449 log_debug("send RA on %s", ra_iface->name);
1450
1451 len = sendmsg(EVENT_FD(&ra_iface->icmp6ev->ev), &sndmhdr, 0);
1452 if (len == -1)
1453 log_warn("sendmsg on %s", ra_iface->name);
1454
1455 }
1456
1457 #define ROUNDUP(a) \
1458 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
1459
1460 void
get_rtaddrs(int addrs,struct sockaddr * sa,struct sockaddr ** rti_info)1461 get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
1462 {
1463 int i;
1464
1465 for (i = 0; i < RTAX_MAX; i++) {
1466 if (addrs & (1 << i)) {
1467 rti_info[i] = sa;
1468 sa = (struct sockaddr *)((char *)(sa) +
1469 ROUNDUP(sa->sa_len));
1470 } else
1471 rti_info[i] = NULL;
1472 }
1473 }
1474
1475 void
route_receive(int fd,short events,void * arg)1476 route_receive(int fd, short events, void *arg)
1477 {
1478 static uint8_t *buf;
1479
1480 struct rt_msghdr *rtm;
1481 struct sockaddr *sa, *rti_info[RTAX_MAX];
1482 ssize_t n;
1483
1484 if (buf == NULL) {
1485 buf = malloc(ROUTE_SOCKET_BUF_SIZE);
1486 if (buf == NULL)
1487 fatal("malloc");
1488 }
1489 rtm = (struct rt_msghdr *)buf;
1490 if ((n = read(fd, buf, ROUTE_SOCKET_BUF_SIZE)) == -1) {
1491 if (errno == EAGAIN || errno == EINTR)
1492 return;
1493 log_warn("dispatch_rtmsg: read error");
1494 return;
1495 }
1496
1497 if (n == 0)
1498 fatal("routing socket closed");
1499
1500 if (n < (ssize_t)sizeof(rtm->rtm_msglen) || n < rtm->rtm_msglen) {
1501 log_warnx("partial rtm of %zd in buffer", n);
1502 return;
1503 }
1504
1505 if (rtm->rtm_version != RTM_VERSION)
1506 return;
1507
1508 sa = (struct sockaddr *)(buf + rtm->rtm_hdrlen);
1509 get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
1510
1511 handle_route_message(rtm, rti_info);
1512 }
1513
1514 void
handle_route_message(struct rt_msghdr * rtm,struct sockaddr ** rti_info)1515 handle_route_message(struct rt_msghdr *rtm, struct sockaddr **rti_info)
1516 {
1517 switch (rtm->rtm_type) {
1518 case RTM_IFINFO:
1519 case RTM_NEWADDR:
1520 case RTM_DELADDR:
1521 case RTM_CHGADDRATTR:
1522 /*
1523 * do the same thing as after a config reload when interfaces
1524 * change or IPv6 addresses show up / disappear
1525 */
1526 merge_ra_interfaces();
1527 break;
1528 default:
1529 log_debug("unexpected RTM: %d", rtm->rtm_type);
1530 break;
1531 }
1532 }
1533
1534 struct icmp6_ev*
get_icmp6ev_by_rdomain(int rdomain)1535 get_icmp6ev_by_rdomain(int rdomain)
1536 {
1537 struct ra_iface *ra_iface;
1538 struct icmp6_ev *icmp6ev = NULL;
1539
1540 TAILQ_FOREACH (ra_iface, &ra_interfaces, entry) {
1541 if (ra_iface->rdomain == rdomain) {
1542 icmp6ev = ra_iface->icmp6ev;
1543 break;
1544 }
1545 }
1546
1547 if (icmp6ev == NULL) {
1548 if ((icmp6ev = calloc(1, sizeof(*icmp6ev))) == NULL)
1549 fatal("calloc");
1550
1551 icmp6ev->rcviov[0].iov_base = (caddr_t)icmp6ev->answer;
1552 icmp6ev->rcviov[0].iov_len = sizeof(icmp6ev->answer);
1553 icmp6ev->rcvmhdr.msg_name = (caddr_t)&icmp6ev->from;
1554 icmp6ev->rcvmhdr.msg_namelen = sizeof(icmp6ev->from);
1555 icmp6ev->rcvmhdr.msg_iov = icmp6ev->rcviov;
1556 icmp6ev->rcvmhdr.msg_iovlen = 1;
1557 icmp6ev->rcvmhdr.msg_controllen =
1558 CMSG_SPACE(sizeof(struct in6_pktinfo)) +
1559 CMSG_SPACE(sizeof(int));
1560 if ((icmp6ev->rcvmhdr.msg_control = malloc(icmp6ev->
1561 rcvmhdr.msg_controllen)) == NULL)
1562 fatal("malloc");
1563 frontend_imsg_compose_main(IMSG_OPEN_ICMP6SOCK, 0,
1564 &rdomain, sizeof(rdomain));
1565 }
1566
1567 icmp6ev->refcnt++;
1568 return (icmp6ev);
1569 }
1570
1571 void
unref_icmp6ev(struct ra_iface * ra_iface)1572 unref_icmp6ev(struct ra_iface *ra_iface)
1573 {
1574 struct icmp6_ev *icmp6ev = ra_iface->icmp6ev;
1575
1576 ra_iface->icmp6ev = NULL;
1577
1578 if (icmp6ev != NULL) {
1579 icmp6ev->refcnt--;
1580 if (icmp6ev->refcnt == 0) {
1581 event_del(&icmp6ev->ev);
1582 close(EVENT_FD(&icmp6ev->ev));
1583 free(icmp6ev);
1584 }
1585 }
1586 }
1587
1588 void
set_icmp6sock(int icmp6sock,int rdomain)1589 set_icmp6sock(int icmp6sock, int rdomain)
1590 {
1591 struct ra_iface *ra_iface;
1592
1593 TAILQ_FOREACH (ra_iface, &ra_interfaces, entry) {
1594 if (!event_initialized(&ra_iface->icmp6ev->ev) &&
1595 ra_iface->rdomain == rdomain) {
1596 event_set(&ra_iface->icmp6ev->ev, icmp6sock, EV_READ |
1597 EV_PERSIST, icmp6_receive, ra_iface->icmp6ev);
1598 event_add(&ra_iface->icmp6ev->ev, NULL);
1599 icmp6sock = -1;
1600 break;
1601 }
1602 }
1603
1604 if (icmp6sock != -1) {
1605 /*
1606 * The interface disappeared or changed rdomain while we were
1607 * waiting for the parent process to open the raw socket.
1608 */
1609 close(icmp6sock);
1610 return;
1611 }
1612
1613 TAILQ_FOREACH (ra_iface, &ra_interfaces, entry) {
1614 if (ra_iface->rdomain == rdomain) {
1615 join_all_routers_mcast_group(ra_iface);
1616 frontend_imsg_compose_engine(IMSG_UPDATE_IF, 0,
1617 &ra_iface->if_index, sizeof(ra_iface->if_index));
1618 }
1619 }
1620 }
1621