1/*	$FreeBSD$	*/
2/*	$KAME: rtadvd.c,v 1.82 2003/08/05 12:34:23 itojun Exp $	*/
3
4/*-
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
8 * Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org>
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the project nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#include <sys/param.h>
37#include <sys/ioctl.h>
38#include <sys/socket.h>
39#include <sys/uio.h>
40#include <sys/queue.h>
41#include <sys/stat.h>
42#include <sys/sysctl.h>
43
44#include <net/if.h>
45#include <net/if_types.h>
46#include <net/if_media.h>
47#include <net/if_dl.h>
48#include <net/route.h>
49#include <netinet/in.h>
50#include <netinet/ip6.h>
51#include <netinet6/ip6_var.h>
52#include <netinet/icmp6.h>
53
54#include <arpa/inet.h>
55
56#include <netinet/in_var.h>
57#include <netinet6/nd6.h>
58
59#include <time.h>
60#include <unistd.h>
61#include <stdio.h>
62#include <err.h>
63#include <errno.h>
64#include <inttypes.h>
65#include <libutil.h>
66#include <netdb.h>
67#include <signal.h>
68#include <string.h>
69#include <stdlib.h>
70#include <syslog.h>
71#include <poll.h>
72
73#include "pathnames.h"
74#include "rtadvd.h"
75#include "if.h"
76#include "rrenum.h"
77#include "advcap.h"
78#include "timer_subr.h"
79#include "timer.h"
80#include "config.h"
81#include "control.h"
82#include "control_server.h"
83
84#define RTADV_TYPE2BITMASK(type) (0x1 << type)
85
86struct msghdr rcvmhdr;
87static char *rcvcmsgbuf;
88static size_t rcvcmsgbuflen;
89static char *sndcmsgbuf = NULL;
90static size_t sndcmsgbuflen;
91struct msghdr sndmhdr;
92struct iovec rcviov[2];
93struct iovec sndiov[2];
94struct sockaddr_in6 rcvfrom;
95static const char *pidfilename = _PATH_RTADVDPID;
96const char *conffile = _PATH_RTADVDCONF;
97static struct pidfh *pfh;
98static int dflag, sflag;
99static int wait_shutdown;
100
101#define	PFD_RAWSOCK	0
102#define	PFD_RTSOCK	1
103#define	PFD_CSOCK	2
104#define	PFD_MAX		3
105
106struct railist_head_t railist =
107    TAILQ_HEAD_INITIALIZER(railist);
108struct ifilist_head_t ifilist =
109    TAILQ_HEAD_INITIALIZER(ifilist);
110
111struct nd_optlist {
112	TAILQ_ENTRY(nd_optlist)	nol_next;
113	struct nd_opt_hdr *nol_opt;
114};
115union nd_opt {
116	struct nd_opt_hdr *opt_array[9];
117	struct {
118		struct nd_opt_hdr *zero;
119		struct nd_opt_hdr *src_lladdr;
120		struct nd_opt_hdr *tgt_lladdr;
121		struct nd_opt_prefix_info *pi;
122		struct nd_opt_rd_hdr *rh;
123		struct nd_opt_mtu *mtu;
124		TAILQ_HEAD(, nd_optlist) opt_list;
125	} nd_opt_each;
126};
127#define opt_src_lladdr	nd_opt_each.src_lladdr
128#define opt_tgt_lladdr	nd_opt_each.tgt_lladdr
129#define opt_pi		nd_opt_each.pi
130#define opt_rh		nd_opt_each.rh
131#define opt_mtu		nd_opt_each.mtu
132#define opt_list	nd_opt_each.opt_list
133
134#define NDOPT_FLAG_SRCLINKADDR	(1 << 0)
135#define NDOPT_FLAG_TGTLINKADDR	(1 << 1)
136#define NDOPT_FLAG_PREFIXINFO	(1 << 2)
137#define NDOPT_FLAG_RDHDR	(1 << 3)
138#define NDOPT_FLAG_MTU		(1 << 4)
139#define NDOPT_FLAG_RDNSS	(1 << 5)
140#define NDOPT_FLAG_DNSSL	(1 << 6)
141
142static uint32_t ndopt_flags[] = {
143	[ND_OPT_SOURCE_LINKADDR]	= NDOPT_FLAG_SRCLINKADDR,
144	[ND_OPT_TARGET_LINKADDR]	= NDOPT_FLAG_TGTLINKADDR,
145	[ND_OPT_PREFIX_INFORMATION]	= NDOPT_FLAG_PREFIXINFO,
146	[ND_OPT_REDIRECTED_HEADER]	= NDOPT_FLAG_RDHDR,
147	[ND_OPT_MTU]			= NDOPT_FLAG_MTU,
148	[ND_OPT_RDNSS]			= NDOPT_FLAG_RDNSS,
149	[ND_OPT_DNSSL]			= NDOPT_FLAG_DNSSL,
150};
151
152static void	rtadvd_shutdown(void);
153static void	sock_open(struct sockinfo *);
154static void	rtsock_open(struct sockinfo *);
155static void	rtadvd_input(struct sockinfo *);
156static void	rs_input(int, struct nd_router_solicit *,
157		    struct in6_pktinfo *, struct sockaddr_in6 *);
158static void	ra_input(int, struct nd_router_advert *,
159		    struct in6_pktinfo *, struct sockaddr_in6 *);
160static int	prefix_check(struct nd_opt_prefix_info *, struct rainfo *,
161		    struct sockaddr_in6 *);
162static int	nd6_options(struct nd_opt_hdr *, int,
163		    union nd_opt *, uint32_t);
164static void	free_ndopts(union nd_opt *);
165static void	rtmsg_input(struct sockinfo *);
166static void	set_short_delay(struct ifinfo *);
167static int	check_accept_rtadv(int);
168
169static void
170usage(void)
171{
172
173	fprintf(stderr, "usage: rtadvd [-dDfRs] "
174	    "[-c configfile] [-C ctlsock] [-M ifname] [-p pidfile]\n");
175	exit(1);
176}
177
178int
179main(int argc, char *argv[])
180{
181	struct pollfd set[PFD_MAX];
182	struct timespec *timeout;
183	int i, ch;
184	int fflag = 0, logopt;
185	int error;
186	pid_t pid, otherpid;
187
188	/* get command line options and arguments */
189	while ((ch = getopt(argc, argv, "c:C:dDfhM:p:Rs")) != -1) {
190		switch (ch) {
191		case 'c':
192			conffile = optarg;
193			break;
194		case 'C':
195			ctrlsock.si_name = optarg;
196			break;
197		case 'd':
198			dflag++;
199			break;
200		case 'D':
201			dflag += 3;
202			break;
203		case 'f':
204			fflag = 1;
205			break;
206		case 'M':
207			mcastif = optarg;
208			break;
209		case 'R':
210			fprintf(stderr, "rtadvd: "
211				"the -R option is currently ignored.\n");
212			/* accept_rr = 1; */
213			/* run anyway... */
214			break;
215		case 's':
216			sflag = 1;
217			break;
218		case 'p':
219			pidfilename = optarg;
220			break;
221		default:
222			usage();
223		}
224	}
225	argc -= optind;
226	argv += optind;
227
228	logopt = LOG_NDELAY | LOG_PID;
229	if (fflag)
230		logopt |= LOG_PERROR;
231	openlog("rtadvd", logopt, LOG_DAEMON);
232
233	/* set log level */
234	if (dflag > 2)
235		(void)setlogmask(LOG_UPTO(LOG_DEBUG));
236	else if (dflag > 1)
237		(void)setlogmask(LOG_UPTO(LOG_INFO));
238	else if (dflag > 0)
239		(void)setlogmask(LOG_UPTO(LOG_NOTICE));
240	else
241		(void)setlogmask(LOG_UPTO(LOG_ERR));
242
243	/* timer initialization */
244	rtadvd_timer_init();
245
246	pfh = pidfile_open(pidfilename, 0600, &otherpid);
247	if (pfh == NULL) {
248		if (errno == EEXIST)
249			errx(1, "%s already running, pid: %d",
250			    getprogname(), otherpid);
251		syslog(LOG_ERR,
252		    "failed to open the pid file %s, run anyway.",
253		    pidfilename);
254	}
255	if (!fflag)
256		daemon(1, 0);
257
258	sock_open(&sock);
259
260	update_ifinfo(&ifilist, UPDATE_IFINFO_ALL);
261	for (i = 0; i < argc; i++)
262		update_persist_ifinfo(&ifilist, argv[i]);
263
264	csock_open(&ctrlsock, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
265	if (ctrlsock.si_fd == -1) {
266		syslog(LOG_ERR, "cannot open control socket: %s",
267		    strerror(errno));
268		exit(1);
269	}
270
271	/* record the current PID */
272	pid = getpid();
273	pidfile_write(pfh);
274
275	set[PFD_RAWSOCK].fd = sock.si_fd;
276	set[PFD_RAWSOCK].events = POLLIN;
277	if (sflag == 0) {
278		rtsock_open(&rtsock);
279		set[PFD_RTSOCK].fd = rtsock.si_fd;
280		set[PFD_RTSOCK].events = POLLIN;
281	} else
282		set[PFD_RTSOCK].fd = -1;
283	set[PFD_CSOCK].fd = ctrlsock.si_fd;
284	set[PFD_CSOCK].events = POLLIN;
285	signal(SIGTERM, set_do_shutdown);
286	signal(SIGINT, set_do_shutdown);
287	signal(SIGHUP, set_do_reload);
288
289	error = csock_listen(&ctrlsock);
290	if (error) {
291		syslog(LOG_ERR, "cannot listen control socket: %s",
292		    strerror(errno));
293		exit(1);
294	}
295
296	/* load configuration file */
297	set_do_reload(0);
298
299	while (1) {
300		if (is_do_shutdown())
301			rtadvd_shutdown();
302
303		if (is_do_reload()) {
304			loadconfig_ifname(reload_ifname());
305			if (reload_ifname() == NULL)
306				syslog(LOG_INFO,
307				    "configuration file reloaded.");
308			else
309				syslog(LOG_INFO,
310				    "configuration file for %s reloaded.",
311				    reload_ifname());
312			reset_do_reload();
313		}
314
315		/* timeout handler update for active interfaces */
316		rtadvd_update_timeout_handler();
317
318		/* timer expiration check and reset the timer */
319		timeout = rtadvd_check_timer();
320
321		if (timeout != NULL) {
322			syslog(LOG_DEBUG,
323			    "<%s> set timer to %ld:%ld. waiting for "
324			    "inputs or timeout", __func__,
325			    (long int)timeout->tv_sec,
326			    (long int)timeout->tv_nsec / 1000);
327		} else {
328			syslog(LOG_DEBUG,
329			    "<%s> there's no timer. waiting for inputs",
330			    __func__);
331		}
332		if ((i = poll(set, sizeof(set)/sizeof(set[0]),
333			    timeout ? (timeout->tv_sec * 1000 +
334				timeout->tv_nsec / 1000 / 1000) : INFTIM)) < 0) {
335
336			/* EINTR would occur if a signal was delivered */
337			if (errno != EINTR)
338				syslog(LOG_ERR, "poll() failed: %s",
339				    strerror(errno));
340			continue;
341		}
342		if (i == 0)	/* timeout */
343			continue;
344		if (rtsock.si_fd != -1 && set[PFD_RTSOCK].revents & POLLIN)
345			rtmsg_input(&rtsock);
346
347		if (set[PFD_RAWSOCK].revents & POLLIN)
348			rtadvd_input(&sock);
349
350		if (set[PFD_CSOCK].revents & POLLIN) {
351			int fd;
352
353			fd = csock_accept(&ctrlsock);
354			if (fd == -1)
355				syslog(LOG_ERR,
356				    "cannot accept() control socket: %s",
357				    strerror(errno));
358			else {
359				cm_handler_server(fd);
360				close(fd);
361			}
362		}
363	}
364	exit(0);		/* NOTREACHED */
365}
366
367static void
368rtadvd_shutdown(void)
369{
370	struct ifinfo *ifi;
371	struct rainfo *rai;
372	struct rdnss *rdn;
373	struct dnssl *dns;
374
375	if (wait_shutdown) {
376		syslog(LOG_INFO,
377		    "waiting expiration of the all RA timers.");
378
379		TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
380			/*
381			 * Ignore !IFF_UP interfaces in waiting for shutdown.
382			 */
383			if (!(ifi->ifi_flags & IFF_UP) &&
384			    ifi->ifi_ra_timer != NULL) {
385				ifi->ifi_state = IFI_STATE_UNCONFIGURED;
386				rtadvd_remove_timer(ifi->ifi_ra_timer);
387				ifi->ifi_ra_timer = NULL;
388				syslog(LOG_DEBUG, "<%s> %s(idx=%d) is down. "
389				    "Timer removed and marked as UNCONFIGURED.",
390				     __func__, ifi->ifi_ifname,
391				    ifi->ifi_ifindex);
392			}
393		}
394		TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
395			if (ifi->ifi_ra_timer != NULL)
396				break;
397		}
398		if (ifi == NULL) {
399			syslog(LOG_NOTICE, "gracefully terminated.");
400			exit(0);
401		}
402
403		sleep(1);
404		return;
405	}
406
407	syslog(LOG_DEBUG, "<%s> cease to be an advertising router",
408	    __func__);
409
410	wait_shutdown = 1;
411
412	TAILQ_FOREACH(rai, &railist, rai_next) {
413		rai->rai_lifetime = 0;
414		TAILQ_FOREACH(rdn, &rai->rai_rdnss, rd_next)
415			rdn->rd_ltime = 0;
416		TAILQ_FOREACH(dns, &rai->rai_dnssl, dn_next)
417			dns->dn_ltime = 0;
418	}
419	TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
420		if (!ifi->ifi_persist)
421			continue;
422		if (ifi->ifi_state == IFI_STATE_UNCONFIGURED)
423			continue;
424		if (ifi->ifi_ra_timer == NULL)
425			continue;
426		if (ifi->ifi_ra_lastsent.tv_sec == 0 &&
427		    ifi->ifi_ra_lastsent.tv_nsec == 0 &&
428		    ifi->ifi_ra_timer != NULL) {
429			/*
430			 * When RA configured but never sent,
431			 * ignore the IF immediately.
432			 */
433			rtadvd_remove_timer(ifi->ifi_ra_timer);
434			ifi->ifi_ra_timer = NULL;
435			ifi->ifi_state = IFI_STATE_UNCONFIGURED;
436			continue;
437		}
438
439		ifi->ifi_state = IFI_STATE_TRANSITIVE;
440
441		/* Mark as the shut-down state. */
442		ifi->ifi_rainfo_trans = ifi->ifi_rainfo;
443		ifi->ifi_rainfo = NULL;
444
445		ifi->ifi_burstcount = MAX_FINAL_RTR_ADVERTISEMENTS;
446		ifi->ifi_burstinterval = MIN_DELAY_BETWEEN_RAS;
447
448		ra_timer_update(ifi, &ifi->ifi_ra_timer->rat_tm);
449		rtadvd_set_timer(&ifi->ifi_ra_timer->rat_tm,
450		    ifi->ifi_ra_timer);
451	}
452	syslog(LOG_NOTICE, "final RA transmission started.");
453
454	pidfile_remove(pfh);
455	csock_close(&ctrlsock);
456}
457
458static void
459rtmsg_input(struct sockinfo *s)
460{
461	int n, type, ifindex = 0, plen;
462	size_t len;
463	char msg[2048], *next, *lim;
464	char ifname[IFNAMSIZ];
465	struct if_announcemsghdr *ifan;
466	struct rt_msghdr *rtm;
467	struct prefix *pfx;
468	struct rainfo *rai;
469	struct in6_addr *addr;
470	struct ifinfo *ifi;
471	char addrbuf[INET6_ADDRSTRLEN];
472	int prefixchange = 0;
473
474	if (s == NULL) {
475		syslog(LOG_ERR, "<%s> internal error", __func__);
476		exit(1);
477	}
478	n = read(s->si_fd, msg, sizeof(msg));
479	rtm = (struct rt_msghdr *)msg;
480	syslog(LOG_DEBUG, "<%s> received a routing message "
481	    "(type = %d, len = %d)", __func__, rtm->rtm_type, n);
482
483	if (n > rtm->rtm_msglen) {
484		/*
485		 * This usually won't happen for messages received on
486		 * a routing socket.
487		 */
488		syslog(LOG_DEBUG,
489		    "<%s> received data length is larger than "
490		    "1st routing message len. multiple messages? "
491		    "read %d bytes, but 1st msg len = %d",
492		    __func__, n, rtm->rtm_msglen);
493#if 0
494		/* adjust length */
495		n = rtm->rtm_msglen;
496#endif
497	}
498
499	lim = msg + n;
500	for (next = msg; next < lim; next += len) {
501		int oldifflags;
502
503		next = get_next_msg(next, lim, 0, &len,
504		    RTADV_TYPE2BITMASK(RTM_ADD) |
505		    RTADV_TYPE2BITMASK(RTM_DELETE) |
506		    RTADV_TYPE2BITMASK(RTM_NEWADDR) |
507		    RTADV_TYPE2BITMASK(RTM_DELADDR) |
508		    RTADV_TYPE2BITMASK(RTM_IFINFO) |
509		    RTADV_TYPE2BITMASK(RTM_IFANNOUNCE));
510		if (len == 0)
511			break;
512		type = ((struct rt_msghdr *)next)->rtm_type;
513		switch (type) {
514		case RTM_ADD:
515		case RTM_DELETE:
516			ifindex = get_rtm_ifindex(next);
517			break;
518		case RTM_NEWADDR:
519		case RTM_DELADDR:
520			ifindex = (int)((struct ifa_msghdr *)next)->ifam_index;
521			break;
522		case RTM_IFINFO:
523			ifindex = (int)((struct if_msghdr *)next)->ifm_index;
524			break;
525		case RTM_IFANNOUNCE:
526			ifan = (struct if_announcemsghdr *)next;
527			switch (ifan->ifan_what) {
528			case IFAN_ARRIVAL:
529			case IFAN_DEPARTURE:
530				break;
531			default:
532				syslog(LOG_DEBUG,
533				    "<%s:%d> unknown ifan msg (ifan_what=%d)",
534				   __func__, __LINE__, ifan->ifan_what);
535				continue;
536			}
537
538			syslog(LOG_DEBUG, "<%s>: if_announcemsg (idx=%d:%d)",
539			       __func__, ifan->ifan_index, ifan->ifan_what);
540			switch (ifan->ifan_what) {
541			case IFAN_ARRIVAL:
542				syslog(LOG_NOTICE,
543				    "interface added (idx=%d)",
544				    ifan->ifan_index);
545				update_ifinfo(&ifilist, ifan->ifan_index);
546				loadconfig_index(ifan->ifan_index);
547				break;
548			case IFAN_DEPARTURE:
549				syslog(LOG_NOTICE,
550				    "interface removed (idx=%d)",
551				    ifan->ifan_index);
552				rm_ifinfo_index(ifan->ifan_index);
553
554				/* Clear ifi_ifindex */
555				TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
556					if (ifi->ifi_ifindex
557					    == ifan->ifan_index) {
558						ifi->ifi_ifindex = 0;
559						break;
560					}
561				}
562				update_ifinfo(&ifilist, ifan->ifan_index);
563				break;
564			}
565			continue;
566		default:
567			/* should not reach here */
568			syslog(LOG_DEBUG,
569			       "<%s:%d> unknown rtmsg %d on %s",
570			       __func__, __LINE__, type,
571			       if_indextoname(ifindex, ifname));
572			continue;
573		}
574		ifi = if_indextoifinfo(ifindex);
575		if (ifi == NULL) {
576			syslog(LOG_DEBUG,
577			    "<%s> ifinfo not found for idx=%d.  Why?",
578			    __func__, ifindex);
579			continue;
580		}
581		rai = ifi->ifi_rainfo;
582		if (rai == NULL) {
583			syslog(LOG_DEBUG,
584			    "<%s> route changed on "
585			    "non advertising interface(%s)",
586			    __func__, ifi->ifi_ifname);
587			continue;
588		}
589
590		oldifflags = ifi->ifi_flags;
591		/* init ifflags because it may have changed */
592		update_ifinfo(&ifilist, ifindex);
593
594		switch (type) {
595		case RTM_ADD:
596			if (sflag)
597				break;	/* we aren't interested in prefixes  */
598
599			addr = get_addr(msg);
600			plen = get_prefixlen(msg);
601			/* sanity check for plen */
602			/* as RFC2373, prefixlen is at least 4 */
603			if (plen < 4 || plen > 127) {
604				syslog(LOG_INFO, "<%s> new interface route's"
605				    "plen %d is invalid for a prefix",
606				    __func__, plen);
607				break;
608			}
609			pfx = find_prefix(rai, addr, plen);
610			if (pfx) {
611				if (pfx->pfx_timer) {
612					/*
613					 * If the prefix has been invalidated,
614					 * make it available again.
615					 */
616					update_prefix(pfx);
617					prefixchange = 1;
618				} else
619					syslog(LOG_DEBUG,
620					    "<%s> new prefix(%s/%d) "
621					    "added on %s, "
622					    "but it was already in list",
623					    __func__,
624					    inet_ntop(AF_INET6, addr,
625						(char *)addrbuf,
626						sizeof(addrbuf)),
627					    plen, ifi->ifi_ifname);
628				break;
629			}
630			make_prefix(rai, ifindex, addr, plen);
631			prefixchange = 1;
632			break;
633		case RTM_DELETE:
634			if (sflag)
635				break;
636
637			addr = get_addr(msg);
638			plen = get_prefixlen(msg);
639			/* sanity check for plen */
640			/* as RFC2373, prefixlen is at least 4 */
641			if (plen < 4 || plen > 127) {
642				syslog(LOG_INFO,
643				    "<%s> deleted interface route's "
644				    "plen %d is invalid for a prefix",
645				    __func__, plen);
646				break;
647			}
648			pfx = find_prefix(rai, addr, plen);
649			if (pfx == NULL) {
650				syslog(LOG_DEBUG,
651				    "<%s> prefix(%s/%d) was deleted on %s, "
652				    "but it was not in list",
653				    __func__, inet_ntop(AF_INET6, addr,
654					(char *)addrbuf, sizeof(addrbuf)),
655					plen, ifi->ifi_ifname);
656				break;
657			}
658			invalidate_prefix(pfx);
659			prefixchange = 1;
660			break;
661		case RTM_NEWADDR:
662		case RTM_DELADDR:
663		case RTM_IFINFO:
664			break;
665		default:
666			/* should not reach here */
667			syslog(LOG_DEBUG,
668			    "<%s:%d> unknown rtmsg %d on %s",
669			    __func__, __LINE__, type,
670			    if_indextoname(ifindex, ifname));
671			return;
672		}
673
674		/* check if an interface flag is changed */
675		if ((oldifflags & IFF_UP) && /* UP to DOWN */
676		    !(ifi->ifi_flags & IFF_UP)) {
677			syslog(LOG_NOTICE,
678			    "<interface %s becomes down. stop timer.",
679			    ifi->ifi_ifname);
680			rtadvd_remove_timer(ifi->ifi_ra_timer);
681			ifi->ifi_ra_timer = NULL;
682		} else if (!(oldifflags & IFF_UP) && /* DOWN to UP */
683		    (ifi->ifi_flags & IFF_UP)) {
684			syslog(LOG_NOTICE,
685			    "interface %s becomes up. restart timer.",
686			    ifi->ifi_ifname);
687
688			ifi->ifi_state = IFI_STATE_TRANSITIVE;
689			ifi->ifi_burstcount =
690			    MAX_INITIAL_RTR_ADVERTISEMENTS;
691			ifi->ifi_burstinterval =
692			    MAX_INITIAL_RTR_ADVERT_INTERVAL;
693
694			ifi->ifi_ra_timer = rtadvd_add_timer(ra_timeout,
695			    ra_timer_update, ifi, ifi);
696			ra_timer_update(ifi, &ifi->ifi_ra_timer->rat_tm);
697			rtadvd_set_timer(&ifi->ifi_ra_timer->rat_tm,
698			    ifi->ifi_ra_timer);
699		} else if (prefixchange &&
700		    (ifi->ifi_flags & IFF_UP)) {
701			/*
702			 * An advertised prefix has been added or invalidated.
703			 * Will notice the change in a short delay.
704			 */
705			set_short_delay(ifi);
706		}
707	}
708
709	return;
710}
711
712void
713rtadvd_input(struct sockinfo *s)
714{
715	ssize_t i;
716	int *hlimp = NULL;
717#ifdef OLDRAWSOCKET
718	struct ip6_hdr *ip;
719#endif
720	struct icmp6_hdr *icp;
721	int ifindex = 0;
722	struct cmsghdr *cm;
723	struct in6_pktinfo *pi = NULL;
724	char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
725	struct in6_addr dst = in6addr_any;
726	struct ifinfo *ifi;
727
728	syslog(LOG_DEBUG, "<%s> enter", __func__);
729
730	if (s == NULL) {
731		syslog(LOG_ERR, "<%s> internal error", __func__);
732		exit(1);
733	}
734	/*
735	 * Get message. We reset msg_controllen since the field could
736	 * be modified if we had received a message before setting
737	 * receive options.
738	 */
739	rcvmhdr.msg_controllen = rcvcmsgbuflen;
740	if ((i = recvmsg(s->si_fd, &rcvmhdr, 0)) < 0)
741		return;
742
743	/* extract optional information via Advanced API */
744	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&rcvmhdr);
745	     cm;
746	     cm = (struct cmsghdr *)CMSG_NXTHDR(&rcvmhdr, cm)) {
747		if (cm->cmsg_level == IPPROTO_IPV6 &&
748		    cm->cmsg_type == IPV6_PKTINFO &&
749		    cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) {
750			pi = (struct in6_pktinfo *)(CMSG_DATA(cm));
751			ifindex = pi->ipi6_ifindex;
752			dst = pi->ipi6_addr;
753		}
754		if (cm->cmsg_level == IPPROTO_IPV6 &&
755		    cm->cmsg_type == IPV6_HOPLIMIT &&
756		    cm->cmsg_len == CMSG_LEN(sizeof(int)))
757			hlimp = (int *)CMSG_DATA(cm);
758	}
759	if (ifindex == 0) {
760		syslog(LOG_ERR, "failed to get receiving interface");
761		return;
762	}
763	if (hlimp == NULL) {
764		syslog(LOG_ERR, "failed to get receiving hop limit");
765		return;
766	}
767
768	/*
769	 * If we happen to receive data on an interface which is now gone
770	 * or down, just discard the data.
771	 */
772	ifi = if_indextoifinfo(pi->ipi6_ifindex);
773	if (ifi == NULL || !(ifi->ifi_flags & IFF_UP)) {
774		syslog(LOG_INFO,
775		    "<%s> received data on a disabled interface (%s)",
776		    __func__,
777		    (ifi == NULL) ? "[gone]" : ifi->ifi_ifname);
778		return;
779	}
780
781#ifdef OLDRAWSOCKET
782	if ((size_t)i < sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr)) {
783		syslog(LOG_ERR,
784		    "packet size(%d) is too short", i);
785		return;
786	}
787
788	ip = (struct ip6_hdr *)rcvmhdr.msg_iov[0].iov_base;
789	icp = (struct icmp6_hdr *)(ip + 1); /* XXX: ext. hdr? */
790#else
791	if ((size_t)i < sizeof(struct icmp6_hdr)) {
792		syslog(LOG_ERR, "packet size(%zd) is too short", i);
793		return;
794	}
795
796	icp = (struct icmp6_hdr *)rcvmhdr.msg_iov[0].iov_base;
797#endif
798
799	switch (icp->icmp6_type) {
800	case ND_ROUTER_SOLICIT:
801		/*
802		 * Message verification - RFC 4861 6.1.1
803		 * XXX: these checks must be done in the kernel as well,
804		 *      but we can't completely rely on them.
805		 */
806		if (*hlimp != 255) {
807			syslog(LOG_NOTICE,
808			    "RS with invalid hop limit(%d) "
809			    "received from %s on %s",
810			    *hlimp,
811			    inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
812			    sizeof(ntopbuf)),
813			    if_indextoname(pi->ipi6_ifindex, ifnamebuf));
814			return;
815		}
816		if (icp->icmp6_code) {
817			syslog(LOG_NOTICE,
818			    "RS with invalid ICMP6 code(%d) "
819			    "received from %s on %s",
820			    icp->icmp6_code,
821			    inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
822			    sizeof(ntopbuf)),
823			    if_indextoname(pi->ipi6_ifindex, ifnamebuf));
824			return;
825		}
826		if ((size_t)i < sizeof(struct nd_router_solicit)) {
827			syslog(LOG_NOTICE,
828			    "RS from %s on %s does not have enough "
829			    "length (len = %zd)",
830			    inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
831			    sizeof(ntopbuf)),
832			    if_indextoname(pi->ipi6_ifindex, ifnamebuf), i);
833			return;
834		}
835		rs_input(i, (struct nd_router_solicit *)icp, pi, &rcvfrom);
836		break;
837	case ND_ROUTER_ADVERT:
838		/*
839		 * Message verification - RFC 4861 6.1.2
840		 * XXX: there's the same dilemma as above...
841		 */
842		if (!IN6_IS_ADDR_LINKLOCAL(&rcvfrom.sin6_addr)) {
843			syslog(LOG_NOTICE,
844			    "RA with non-linklocal source address "
845			    "received from %s on %s",
846			    inet_ntop(AF_INET6, &rcvfrom.sin6_addr,
847			    ntopbuf, sizeof(ntopbuf)),
848			    if_indextoname(pi->ipi6_ifindex, ifnamebuf));
849			return;
850		}
851		if (*hlimp != 255) {
852			syslog(LOG_NOTICE,
853			    "RA with invalid hop limit(%d) "
854			    "received from %s on %s",
855			    *hlimp,
856			    inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
857			    sizeof(ntopbuf)),
858			    if_indextoname(pi->ipi6_ifindex, ifnamebuf));
859			return;
860		}
861		if (icp->icmp6_code) {
862			syslog(LOG_NOTICE,
863			    "RA with invalid ICMP6 code(%d) "
864			    "received from %s on %s",
865			    icp->icmp6_code,
866			    inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
867			    sizeof(ntopbuf)),
868			    if_indextoname(pi->ipi6_ifindex, ifnamebuf));
869			return;
870		}
871		if ((size_t)i < sizeof(struct nd_router_advert)) {
872			syslog(LOG_NOTICE,
873			    "RA from %s on %s does not have enough "
874			    "length (len = %zd)",
875			    inet_ntop(AF_INET6, &rcvfrom.sin6_addr, ntopbuf,
876			    sizeof(ntopbuf)),
877			    if_indextoname(pi->ipi6_ifindex, ifnamebuf), i);
878			return;
879		}
880		ra_input(i, (struct nd_router_advert *)icp, pi, &rcvfrom);
881		break;
882	case ICMP6_ROUTER_RENUMBERING:
883		if (mcastif == NULL) {
884			syslog(LOG_ERR, "received a router renumbering "
885			    "message, but not allowed to be accepted");
886			break;
887		}
888		rr_input(i, (struct icmp6_router_renum *)icp, pi, &rcvfrom,
889		    &dst);
890		break;
891	default:
892		/*
893		 * Note that this case is POSSIBLE, especially just
894		 * after invocation of the daemon. This is because we
895		 * could receive message after opening the socket and
896		 * before setting ICMP6 type filter(see sock_open()).
897		 */
898		syslog(LOG_ERR, "invalid icmp type(%d)", icp->icmp6_type);
899		return;
900	}
901
902	return;
903}
904
905static void
906rs_input(int len, struct nd_router_solicit *rs,
907	 struct in6_pktinfo *pi, struct sockaddr_in6 *from)
908{
909	char ntopbuf[INET6_ADDRSTRLEN];
910	char ifnamebuf[IFNAMSIZ];
911	union nd_opt ndopts;
912	struct rainfo *rai;
913	struct ifinfo *ifi;
914	struct soliciter *sol;
915
916	syslog(LOG_DEBUG,
917	    "<%s> RS received from %s on %s",
918	    __func__,
919	    inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf, sizeof(ntopbuf)),
920	    if_indextoname(pi->ipi6_ifindex, ifnamebuf));
921
922	/* ND option check */
923	memset(&ndopts, 0, sizeof(ndopts));
924	TAILQ_INIT(&ndopts.opt_list);
925	if (nd6_options((struct nd_opt_hdr *)(rs + 1),
926			len - sizeof(struct nd_router_solicit),
927			&ndopts, NDOPT_FLAG_SRCLINKADDR)) {
928		syslog(LOG_INFO,
929		    "<%s> ND option check failed for an RS from %s on %s",
930		    __func__,
931		    inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
932			sizeof(ntopbuf)),
933		    if_indextoname(pi->ipi6_ifindex, ifnamebuf));
934		return;
935	}
936
937	/*
938	 * If the IP source address is the unspecified address, there
939	 * must be no source link-layer address option in the message.
940	 * (RFC 4861 6.1.1)
941	 */
942	if (IN6_IS_ADDR_UNSPECIFIED(&from->sin6_addr) &&
943	    ndopts.opt_src_lladdr) {
944		syslog(LOG_INFO,
945		    "<%s> RS from unspecified src on %s has a link-layer"
946		    " address option",
947		    __func__, if_indextoname(pi->ipi6_ifindex, ifnamebuf));
948		goto done;
949	}
950
951	ifi = if_indextoifinfo(pi->ipi6_ifindex);
952	if (ifi == NULL) {
953		syslog(LOG_INFO,
954		    "<%s> if (idx=%d) not found.  Why?",
955		    __func__, pi->ipi6_ifindex);
956		goto done;
957	}
958	rai = ifi->ifi_rainfo;
959	if (rai == NULL) {
960		syslog(LOG_INFO,
961		       "<%s> RS received on non advertising interface(%s)",
962		       __func__,
963		       if_indextoname(pi->ipi6_ifindex, ifnamebuf));
964		goto done;
965	}
966
967	rai->rai_ifinfo->ifi_rsinput++;
968
969	/*
970	 * Decide whether to send RA according to the rate-limit
971	 * consideration.
972	 */
973
974	/* record sockaddr waiting for RA, if possible */
975	sol = (struct soliciter *)malloc(sizeof(*sol));
976	if (sol) {
977		sol->sol_addr = *from;
978		/* XXX RFC 2553 need clarification on flowinfo */
979		sol->sol_addr.sin6_flowinfo = 0;
980		TAILQ_INSERT_TAIL(&rai->rai_soliciter, sol, sol_next);
981	}
982
983	/*
984	 * If there is already a waiting RS packet, don't
985	 * update the timer.
986	 */
987	if (ifi->ifi_rs_waitcount++)
988		goto done;
989
990	set_short_delay(ifi);
991
992  done:
993	free_ndopts(&ndopts);
994	return;
995}
996
997static void
998set_short_delay(struct ifinfo *ifi)
999{
1000	long delay;	/* must not be greater than 1000000 */
1001	struct timespec interval, now, min_delay, tm_tmp, *rest;
1002
1003	if (ifi->ifi_ra_timer == NULL)
1004		return;
1005	/*
1006	 * Compute a random delay. If the computed value
1007	 * corresponds to a time later than the time the next
1008	 * multicast RA is scheduled to be sent, ignore the random
1009	 * delay and send the advertisement at the
1010	 * already-scheduled time. RFC 4861 6.2.6
1011	 */
1012	delay = arc4random_uniform(MAX_RA_DELAY_TIME);
1013	interval.tv_sec = 0;
1014	interval.tv_nsec = delay * 1000;
1015	rest = rtadvd_timer_rest(ifi->ifi_ra_timer);
1016	if (TS_CMP(rest, &interval, <)) {
1017		syslog(LOG_DEBUG, "<%s> random delay is larger than "
1018		    "the rest of the current timer", __func__);
1019		interval = *rest;
1020	}
1021
1022	/*
1023	 * If we sent a multicast Router Advertisement within
1024	 * the last MIN_DELAY_BETWEEN_RAS seconds, schedule
1025	 * the advertisement to be sent at a time corresponding to
1026	 * MIN_DELAY_BETWEEN_RAS plus the random value after the
1027	 * previous advertisement was sent.
1028	 */
1029	clock_gettime(CLOCK_MONOTONIC_FAST, &now);
1030	TS_SUB(&now, &ifi->ifi_ra_lastsent, &tm_tmp);
1031	min_delay.tv_sec = MIN_DELAY_BETWEEN_RAS;
1032	min_delay.tv_nsec = 0;
1033	if (TS_CMP(&tm_tmp, &min_delay, <)) {
1034		TS_SUB(&min_delay, &tm_tmp, &min_delay);
1035		TS_ADD(&min_delay, &interval, &interval);
1036	}
1037	rtadvd_set_timer(&interval, ifi->ifi_ra_timer);
1038}
1039
1040static int
1041check_accept_rtadv(int idx)
1042{
1043	struct ifinfo *ifi;
1044
1045	TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
1046		if (ifi->ifi_ifindex == idx)
1047			break;
1048	}
1049	if (ifi == NULL) {
1050		syslog(LOG_DEBUG,
1051		    "<%s> if (idx=%d) not found.  Why?",
1052		    __func__, idx);
1053		return (0);
1054	}
1055
1056	/*
1057	 * RA_RECV: ND6_IFF_ACCEPT_RTADV
1058	 * RA_SEND: ip6.forwarding
1059	 */
1060	if (update_ifinfo_nd_flags(ifi) != 0) {
1061		syslog(LOG_ERR, "cannot get nd6 flags (idx=%d)", idx);
1062		return (0);
1063	}
1064
1065	return (ifi->ifi_nd_flags & ND6_IFF_ACCEPT_RTADV);
1066}
1067
1068static void
1069ra_input(int len, struct nd_router_advert *nra,
1070	 struct in6_pktinfo *pi, struct sockaddr_in6 *from)
1071{
1072	struct rainfo *rai;
1073	struct ifinfo *ifi;
1074	char ntopbuf[INET6_ADDRSTRLEN];
1075	char ifnamebuf[IFNAMSIZ];
1076	union nd_opt ndopts;
1077	const char *on_off[] = {"OFF", "ON"};
1078	uint32_t reachabletime, retranstimer, mtu;
1079	int inconsistent = 0;
1080	int error;
1081
1082	syslog(LOG_DEBUG, "<%s> RA received from %s on %s", __func__,
1083	    inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf, sizeof(ntopbuf)),
1084	    if_indextoname(pi->ipi6_ifindex, ifnamebuf));
1085
1086	/* ND option check */
1087	memset(&ndopts, 0, sizeof(ndopts));
1088	TAILQ_INIT(&ndopts.opt_list);
1089	error = nd6_options((struct nd_opt_hdr *)(nra + 1),
1090	    len - sizeof(struct nd_router_advert), &ndopts,
1091	    NDOPT_FLAG_SRCLINKADDR | NDOPT_FLAG_PREFIXINFO | NDOPT_FLAG_MTU |
1092	    NDOPT_FLAG_RDNSS | NDOPT_FLAG_DNSSL);
1093	if (error) {
1094		syslog(LOG_INFO,
1095		    "<%s> ND option check failed for an RA from %s on %s",
1096		    __func__,
1097		    inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
1098			sizeof(ntopbuf)), if_indextoname(pi->ipi6_ifindex,
1099			ifnamebuf));
1100		return;
1101	}
1102
1103	/*
1104	 * RA consistency check according to RFC 4861 6.2.7
1105	 */
1106	ifi = if_indextoifinfo(pi->ipi6_ifindex);
1107	if (ifi->ifi_rainfo == NULL) {
1108		syslog(LOG_INFO,
1109		    "<%s> received RA from %s on non-advertising"
1110		    " interface(%s)",
1111		    __func__,
1112		    inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
1113			sizeof(ntopbuf)), if_indextoname(pi->ipi6_ifindex,
1114			ifnamebuf));
1115		goto done;
1116	}
1117	rai = ifi->ifi_rainfo;
1118	ifi->ifi_rainput++;
1119	syslog(LOG_DEBUG, "<%s> ifi->ifi_rainput = %" PRIu64, __func__,
1120	    ifi->ifi_rainput);
1121
1122	/* Cur Hop Limit value */
1123	if (nra->nd_ra_curhoplimit && rai->rai_hoplimit &&
1124	    nra->nd_ra_curhoplimit != rai->rai_hoplimit) {
1125		syslog(LOG_NOTICE,
1126		    "CurHopLimit inconsistent on %s:"
1127		    " %d from %s, %d from us",
1128		    ifi->ifi_ifname, nra->nd_ra_curhoplimit,
1129		    inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
1130			sizeof(ntopbuf)), rai->rai_hoplimit);
1131		inconsistent++;
1132	}
1133	/* M flag */
1134	if ((nra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) !=
1135	    rai->rai_managedflg) {
1136		syslog(LOG_NOTICE,
1137		    "M flag inconsistent on %s:"
1138		    " %s from %s, %s from us",
1139		    ifi->ifi_ifname, on_off[!rai->rai_managedflg],
1140		    inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
1141			sizeof(ntopbuf)), on_off[rai->rai_managedflg]);
1142		inconsistent++;
1143	}
1144	/* O flag */
1145	if ((nra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) !=
1146	    rai->rai_otherflg) {
1147		syslog(LOG_NOTICE,
1148		    "O flag inconsistent on %s:"
1149		    " %s from %s, %s from us",
1150		    ifi->ifi_ifname, on_off[!rai->rai_otherflg],
1151		    inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
1152			sizeof(ntopbuf)), on_off[rai->rai_otherflg]);
1153		inconsistent++;
1154	}
1155#ifdef DRAFT_IETF_6MAN_IPV6ONLY_FLAG
1156	/* S "IPv6-Only" (Six, Silence-IPv4) flag */
1157	if ((nra->nd_ra_flags_reserved & ND_RA_FLAG_IPV6_ONLY) !=
1158	    rai->rai_ipv6onlyflg) {
1159		syslog(LOG_NOTICE,
1160		    "S flag inconsistent on %s:"
1161		    " %s from %s, %s from us",
1162		    ifi->ifi_ifname, on_off[!rai->rai_ipv6onlyflg],
1163		    inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
1164			sizeof(ntopbuf)), on_off[rai->rai_ipv6onlyflg]);
1165		inconsistent++;
1166	}
1167#endif
1168	/* Reachable Time */
1169	reachabletime = ntohl(nra->nd_ra_reachable);
1170	if (reachabletime && rai->rai_reachabletime &&
1171	    reachabletime != rai->rai_reachabletime) {
1172		syslog(LOG_NOTICE,
1173		    "ReachableTime inconsistent on %s:"
1174		    " %d from %s, %d from us",
1175		    ifi->ifi_ifname, reachabletime,
1176		    inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
1177			sizeof(ntopbuf)), rai->rai_reachabletime);
1178		inconsistent++;
1179	}
1180	/* Retrans Timer */
1181	retranstimer = ntohl(nra->nd_ra_retransmit);
1182	if (retranstimer && rai->rai_retranstimer &&
1183	    retranstimer != rai->rai_retranstimer) {
1184		syslog(LOG_NOTICE,
1185		    "RetranceTimer inconsistent on %s:"
1186		    " %d from %s, %d from us",
1187		    ifi->ifi_ifname, retranstimer,
1188		    inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
1189			sizeof(ntopbuf)), rai->rai_retranstimer);
1190		inconsistent++;
1191	}
1192	/* Values in the MTU options */
1193	if (ndopts.opt_mtu) {
1194		mtu = ntohl(ndopts.opt_mtu->nd_opt_mtu_mtu);
1195		if (mtu && rai->rai_linkmtu && mtu != rai->rai_linkmtu) {
1196			syslog(LOG_NOTICE,
1197			    "MTU option value inconsistent on %s:"
1198			    " %d from %s, %d from us",
1199			    ifi->ifi_ifname, mtu,
1200			    inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
1201				sizeof(ntopbuf)), rai->rai_linkmtu);
1202			inconsistent++;
1203		}
1204	}
1205	/* Preferred and Valid Lifetimes for prefixes */
1206	{
1207		struct nd_optlist *nol;
1208
1209		if (ndopts.opt_pi)
1210			if (prefix_check(ndopts.opt_pi, rai, from))
1211				inconsistent++;
1212
1213		TAILQ_FOREACH(nol, &ndopts.opt_list, nol_next)
1214			if (prefix_check((struct nd_opt_prefix_info *)nol->nol_opt,
1215				rai, from))
1216				inconsistent++;
1217	}
1218
1219	if (inconsistent)
1220		ifi->ifi_rainconsistent++;
1221
1222  done:
1223	free_ndopts(&ndopts);
1224	return;
1225}
1226
1227static uint32_t
1228udiff(uint32_t u, uint32_t v)
1229{
1230	return (u >= v ? u - v : v - u);
1231}
1232
1233/* return a non-zero value if the received prefix is inconsistent with ours */
1234static int
1235prefix_check(struct nd_opt_prefix_info *pinfo,
1236	struct rainfo *rai, struct sockaddr_in6 *from)
1237{
1238	struct ifinfo *ifi;
1239	uint32_t preferred_time, valid_time;
1240	struct prefix *pfx;
1241	int inconsistent = 0;
1242	char ntopbuf[INET6_ADDRSTRLEN];
1243	char prefixbuf[INET6_ADDRSTRLEN];
1244	struct timespec now;
1245
1246#if 0				/* impossible */
1247	if (pinfo->nd_opt_pi_type != ND_OPT_PREFIX_INFORMATION)
1248		return (0);
1249#endif
1250	ifi = rai->rai_ifinfo;
1251	/*
1252	 * log if the adveritsed prefix has link-local scope(sanity check?)
1253	 */
1254	if (IN6_IS_ADDR_LINKLOCAL(&pinfo->nd_opt_pi_prefix))
1255		syslog(LOG_INFO,
1256		    "<%s> link-local prefix %s/%d is advertised "
1257		    "from %s on %s",
1258		    __func__,
1259		    inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, prefixbuf,
1260			sizeof(prefixbuf)),
1261		    pinfo->nd_opt_pi_prefix_len,
1262		    inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
1263			sizeof(ntopbuf)), ifi->ifi_ifname);
1264
1265	if ((pfx = find_prefix(rai, &pinfo->nd_opt_pi_prefix,
1266		pinfo->nd_opt_pi_prefix_len)) == NULL) {
1267		syslog(LOG_INFO,
1268		    "<%s> prefix %s/%d from %s on %s is not in our list",
1269		    __func__,
1270		    inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, prefixbuf,
1271			sizeof(prefixbuf)),
1272		    pinfo->nd_opt_pi_prefix_len,
1273		    inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
1274			sizeof(ntopbuf)), ifi->ifi_ifname);
1275		return (0);
1276	}
1277
1278	preferred_time = ntohl(pinfo->nd_opt_pi_preferred_time);
1279	if (pfx->pfx_pltimeexpire) {
1280		/*
1281		 * The lifetime is decremented in real time, so we should
1282		 * compare the expiration time.
1283		 * (RFC 2461 Section 6.2.7.)
1284		 * XXX: can we really expect that all routers on the link
1285		 * have synchronized clocks?
1286		 */
1287		clock_gettime(CLOCK_MONOTONIC_FAST, &now);
1288		preferred_time += now.tv_sec;
1289
1290		if (!pfx->pfx_timer && rai->rai_clockskew &&
1291		    udiff(preferred_time, pfx->pfx_pltimeexpire) > rai->rai_clockskew) {
1292			syslog(LOG_INFO,
1293			    "<%s> preferred lifetime for %s/%d"
1294			    " (decr. in real time) inconsistent on %s:"
1295			    " %" PRIu32 " from %s, %" PRIu32 " from us",
1296			    __func__,
1297			    inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, prefixbuf,
1298				sizeof(prefixbuf)),
1299			    pinfo->nd_opt_pi_prefix_len,
1300			    ifi->ifi_ifname, preferred_time,
1301			    inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
1302				sizeof(ntopbuf)), pfx->pfx_pltimeexpire);
1303			inconsistent++;
1304		}
1305	} else if (!pfx->pfx_timer && preferred_time != pfx->pfx_preflifetime)
1306		syslog(LOG_INFO,
1307		    "<%s> preferred lifetime for %s/%d"
1308		    " inconsistent on %s:"
1309		    " %d from %s, %d from us",
1310		    __func__,
1311		    inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, prefixbuf,
1312			sizeof(prefixbuf)),
1313		    pinfo->nd_opt_pi_prefix_len,
1314		    ifi->ifi_ifname, preferred_time,
1315		    inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
1316			sizeof(ntopbuf)), pfx->pfx_preflifetime);
1317
1318	valid_time = ntohl(pinfo->nd_opt_pi_valid_time);
1319	if (pfx->pfx_vltimeexpire) {
1320		clock_gettime(CLOCK_MONOTONIC_FAST, &now);
1321		valid_time += now.tv_sec;
1322
1323		if (!pfx->pfx_timer && rai->rai_clockskew &&
1324		    udiff(valid_time, pfx->pfx_vltimeexpire) > rai->rai_clockskew) {
1325			syslog(LOG_INFO,
1326			    "<%s> valid lifetime for %s/%d"
1327			    " (decr. in real time) inconsistent on %s:"
1328			    " %d from %s, %" PRIu32 " from us",
1329			    __func__,
1330			    inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, prefixbuf,
1331				sizeof(prefixbuf)),
1332			    pinfo->nd_opt_pi_prefix_len,
1333			    ifi->ifi_ifname, preferred_time,
1334			    inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
1335				sizeof(ntopbuf)), pfx->pfx_vltimeexpire);
1336			inconsistent++;
1337		}
1338	} else if (!pfx->pfx_timer && valid_time != pfx->pfx_validlifetime) {
1339		syslog(LOG_INFO,
1340		    "<%s> valid lifetime for %s/%d"
1341		    " inconsistent on %s:"
1342		    " %d from %s, %d from us",
1343		    __func__,
1344		    inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, prefixbuf,
1345			sizeof(prefixbuf)),
1346		    pinfo->nd_opt_pi_prefix_len,
1347		    ifi->ifi_ifname, valid_time,
1348		    inet_ntop(AF_INET6, &from->sin6_addr, ntopbuf,
1349			sizeof(ntopbuf)), pfx->pfx_validlifetime);
1350		inconsistent++;
1351	}
1352
1353	return (inconsistent);
1354}
1355
1356struct prefix *
1357find_prefix(struct rainfo *rai, struct in6_addr *prefix, int plen)
1358{
1359	struct prefix *pfx;
1360	int bytelen, bitlen;
1361	char bitmask;
1362
1363	TAILQ_FOREACH(pfx, &rai->rai_prefix, pfx_next) {
1364		if (plen != pfx->pfx_prefixlen)
1365			continue;
1366
1367		bytelen = plen / 8;
1368		bitlen = plen % 8;
1369		bitmask = 0xff << (8 - bitlen);
1370
1371		if (memcmp((void *)prefix, (void *)&pfx->pfx_prefix, bytelen))
1372			continue;
1373
1374		if (bitlen == 0 ||
1375		    ((prefix->s6_addr[bytelen] & bitmask) ==
1376		     (pfx->pfx_prefix.s6_addr[bytelen] & bitmask))) {
1377			return (pfx);
1378		}
1379	}
1380
1381	return (NULL);
1382}
1383
1384/* check if p0/plen0 matches p1/plen1; return 1 if matches, otherwise 0. */
1385int
1386prefix_match(struct in6_addr *p0, int plen0,
1387	struct in6_addr *p1, int plen1)
1388{
1389	int bytelen, bitlen;
1390	char bitmask;
1391
1392	if (plen0 < plen1)
1393		return (0);
1394
1395	bytelen = plen1 / 8;
1396	bitlen = plen1 % 8;
1397	bitmask = 0xff << (8 - bitlen);
1398
1399	if (memcmp((void *)p0, (void *)p1, bytelen))
1400		return (0);
1401
1402	if (bitlen == 0 ||
1403	    ((p0->s6_addr[bytelen] & bitmask) ==
1404	     (p1->s6_addr[bytelen] & bitmask))) {
1405		return (1);
1406	}
1407
1408	return (0);
1409}
1410
1411static int
1412nd6_options(struct nd_opt_hdr *hdr, int limit,
1413	union nd_opt *ndopts, uint32_t optflags)
1414{
1415	int optlen = 0;
1416
1417	for (; limit > 0; limit -= optlen) {
1418		if ((size_t)limit < sizeof(struct nd_opt_hdr)) {
1419			syslog(LOG_INFO, "<%s> short option header", __func__);
1420			goto bad;
1421		}
1422
1423		hdr = (struct nd_opt_hdr *)((caddr_t)hdr + optlen);
1424		if (hdr->nd_opt_len == 0) {
1425			syslog(LOG_INFO,
1426			    "<%s> bad ND option length(0) (type = %d)",
1427			    __func__, hdr->nd_opt_type);
1428			goto bad;
1429		}
1430		optlen = hdr->nd_opt_len << 3;
1431		if (optlen > limit) {
1432			syslog(LOG_INFO, "<%s> short option", __func__);
1433			goto bad;
1434		}
1435
1436		if (hdr->nd_opt_type > ND_OPT_MTU &&
1437		    hdr->nd_opt_type != ND_OPT_RDNSS &&
1438		    hdr->nd_opt_type != ND_OPT_DNSSL) {
1439			syslog(LOG_INFO, "<%s> unknown ND option(type %d)",
1440			    __func__, hdr->nd_opt_type);
1441			continue;
1442		}
1443
1444		if ((ndopt_flags[hdr->nd_opt_type] & optflags) == 0) {
1445			syslog(LOG_INFO, "<%s> unexpected ND option(type %d)",
1446			    __func__, hdr->nd_opt_type);
1447			continue;
1448		}
1449
1450		/*
1451		 * Option length check.  Do it here for all fixed-length
1452		 * options.
1453		 */
1454		switch (hdr->nd_opt_type) {
1455		case ND_OPT_MTU:
1456			if (optlen == sizeof(struct nd_opt_mtu))
1457				break;
1458			goto skip;
1459		case ND_OPT_RDNSS:
1460			if (optlen >= 24 &&
1461			    (optlen - sizeof(struct nd_opt_rdnss)) % 16 == 0)
1462				break;
1463			goto skip;
1464		case ND_OPT_DNSSL:
1465			if (optlen >= 16 &&
1466			    (optlen - sizeof(struct nd_opt_dnssl)) % 8 == 0)
1467				break;
1468			goto skip;
1469		case ND_OPT_PREFIX_INFORMATION:
1470			if (optlen == sizeof(struct nd_opt_prefix_info))
1471				break;
1472skip:
1473			syslog(LOG_INFO, "<%s> invalid option length",
1474			    __func__);
1475			continue;
1476		}
1477
1478		switch (hdr->nd_opt_type) {
1479		case ND_OPT_TARGET_LINKADDR:
1480		case ND_OPT_REDIRECTED_HEADER:
1481		case ND_OPT_RDNSS:
1482		case ND_OPT_DNSSL:
1483			break;	/* we don't care about these options */
1484		case ND_OPT_SOURCE_LINKADDR:
1485		case ND_OPT_MTU:
1486			if (ndopts->opt_array[hdr->nd_opt_type]) {
1487				syslog(LOG_INFO,
1488				    "<%s> duplicated ND option (type = %d)",
1489				    __func__, hdr->nd_opt_type);
1490			}
1491			ndopts->opt_array[hdr->nd_opt_type] = hdr;
1492			break;
1493		case ND_OPT_PREFIX_INFORMATION:
1494		{
1495			struct nd_optlist *nol;
1496
1497			if (ndopts->opt_pi == 0) {
1498				ndopts->opt_pi =
1499				    (struct nd_opt_prefix_info *)hdr;
1500				continue;
1501			}
1502			nol = malloc(sizeof(*nol));
1503			if (nol == NULL) {
1504				syslog(LOG_ERR, "<%s> can't allocate memory",
1505				    __func__);
1506				goto bad;
1507			}
1508			nol->nol_opt = hdr;
1509			TAILQ_INSERT_TAIL(&(ndopts->opt_list), nol, nol_next);
1510
1511			break;
1512		}
1513		default:	/* impossible */
1514			break;
1515		}
1516	}
1517
1518	return (0);
1519
1520  bad:
1521	free_ndopts(ndopts);
1522
1523	return (-1);
1524}
1525
1526static void
1527free_ndopts(union nd_opt *ndopts)
1528{
1529	struct nd_optlist *nol;
1530
1531	while ((nol = TAILQ_FIRST(&ndopts->opt_list)) != NULL) {
1532		TAILQ_REMOVE(&ndopts->opt_list, nol, nol_next);
1533		free(nol);
1534	}
1535}
1536
1537void
1538sock_open(struct sockinfo *s)
1539{
1540	struct icmp6_filter filt;
1541	int on;
1542	/* XXX: should be max MTU attached to the node */
1543	static char answer[1500];
1544
1545	syslog(LOG_DEBUG, "<%s> enter", __func__);
1546
1547	if (s == NULL) {
1548		syslog(LOG_ERR, "<%s> internal error", __func__);
1549		exit(1);
1550	}
1551	rcvcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
1552	    CMSG_SPACE(sizeof(int));
1553	rcvcmsgbuf = (char *)malloc(rcvcmsgbuflen);
1554	if (rcvcmsgbuf == NULL) {
1555		syslog(LOG_ERR, "<%s> not enough core", __func__);
1556		exit(1);
1557	}
1558
1559	sndcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
1560	    CMSG_SPACE(sizeof(int));
1561	sndcmsgbuf = (char *)malloc(sndcmsgbuflen);
1562	if (sndcmsgbuf == NULL) {
1563		syslog(LOG_ERR, "<%s> not enough core", __func__);
1564		exit(1);
1565	}
1566
1567	if ((s->si_fd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
1568		syslog(LOG_ERR, "<%s> socket: %s", __func__, strerror(errno));
1569		exit(1);
1570	}
1571	/* specify to tell receiving interface */
1572	on = 1;
1573	if (setsockopt(s->si_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
1574	    sizeof(on)) < 0) {
1575		syslog(LOG_ERR, "<%s> IPV6_RECVPKTINFO: %s", __func__,
1576		    strerror(errno));
1577		exit(1);
1578	}
1579	on = 1;
1580	/* specify to tell value of hoplimit field of received IP6 hdr */
1581	if (setsockopt(s->si_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
1582		sizeof(on)) < 0) {
1583		syslog(LOG_ERR, "<%s> IPV6_RECVHOPLIMIT: %s", __func__,
1584		    strerror(errno));
1585		exit(1);
1586	}
1587	ICMP6_FILTER_SETBLOCKALL(&filt);
1588	ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filt);
1589	ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt);
1590	if (mcastif != NULL)
1591		ICMP6_FILTER_SETPASS(ICMP6_ROUTER_RENUMBERING, &filt);
1592
1593	if (setsockopt(s->si_fd, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
1594	    sizeof(filt)) < 0) {
1595		syslog(LOG_ERR, "<%s> IICMP6_FILTER: %s",
1596		    __func__, strerror(errno));
1597		exit(1);
1598	}
1599
1600	/* initialize msghdr for receiving packets */
1601	rcviov[0].iov_base = (caddr_t)answer;
1602	rcviov[0].iov_len = sizeof(answer);
1603	rcvmhdr.msg_name = (caddr_t)&rcvfrom;
1604	rcvmhdr.msg_namelen = sizeof(rcvfrom);
1605	rcvmhdr.msg_iov = rcviov;
1606	rcvmhdr.msg_iovlen = 1;
1607	rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf;
1608	rcvmhdr.msg_controllen = rcvcmsgbuflen;
1609
1610	/* initialize msghdr for sending packets */
1611	sndmhdr.msg_namelen = sizeof(struct sockaddr_in6);
1612	sndmhdr.msg_iov = sndiov;
1613	sndmhdr.msg_iovlen = 1;
1614	sndmhdr.msg_control = (caddr_t)sndcmsgbuf;
1615	sndmhdr.msg_controllen = sndcmsgbuflen;
1616
1617	return;
1618}
1619
1620/* open a routing socket to watch the routing table */
1621static void
1622rtsock_open(struct sockinfo *s)
1623{
1624	if (s == NULL) {
1625		syslog(LOG_ERR, "<%s> internal error", __func__);
1626		exit(1);
1627	}
1628	if ((s->si_fd = socket(PF_ROUTE, SOCK_RAW, 0)) < 0) {
1629		syslog(LOG_ERR,
1630		    "<%s> socket: %s", __func__, strerror(errno));
1631		exit(1);
1632	}
1633}
1634
1635struct ifinfo *
1636if_indextoifinfo(int idx)
1637{
1638	struct ifinfo *ifi;
1639	char *name, name0[IFNAMSIZ];
1640
1641	/* Check if the interface has a valid name or not. */
1642	if (if_indextoname(idx, name0) == NULL)
1643		return (NULL);
1644
1645	TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
1646		if (ifi->ifi_ifindex == idx)
1647			return (ifi);
1648	}
1649
1650	if (ifi != NULL)
1651		syslog(LOG_DEBUG, "<%s> ifi found (idx=%d)",
1652		    __func__, idx);
1653	else
1654		syslog(LOG_DEBUG, "<%s> ifi not found (idx=%d)",
1655		    __func__, idx);
1656
1657	return (NULL);		/* search failed */
1658}
1659
1660void
1661ra_output(struct ifinfo *ifi)
1662{
1663	int i;
1664	struct cmsghdr *cm;
1665	struct in6_pktinfo *pi;
1666	struct soliciter *sol;
1667	struct rainfo *rai;
1668
1669	switch (ifi->ifi_state) {
1670	case IFI_STATE_CONFIGURED:
1671		rai = ifi->ifi_rainfo;
1672		break;
1673	case IFI_STATE_TRANSITIVE:
1674		rai = ifi->ifi_rainfo_trans;
1675		break;
1676	case IFI_STATE_UNCONFIGURED:
1677		syslog(LOG_DEBUG, "<%s> %s is unconfigured.  "
1678		    "Skip sending RAs.",
1679		    __func__, ifi->ifi_ifname);
1680		return;
1681	default:
1682		rai = NULL;
1683	}
1684	if (rai == NULL) {
1685		syslog(LOG_DEBUG, "<%s> rainfo is NULL on %s."
1686		    "Skip sending RAs.",
1687		    __func__, ifi->ifi_ifname);
1688		return;
1689	}
1690	if (!(ifi->ifi_flags & IFF_UP)) {
1691		syslog(LOG_DEBUG, "<%s> %s is not up.  "
1692		    "Skip sending RAs.",
1693		    __func__, ifi->ifi_ifname);
1694		return;
1695	}
1696	/*
1697	 * Check lifetime, ACCEPT_RTADV flag, and ip6.forwarding.
1698	 *
1699	 * (lifetime == 0) = output
1700	 * (lifetime != 0 && (check_accept_rtadv()) = no output
1701	 *
1702	 * Basically, hosts MUST NOT send Router Advertisement
1703	 * messages at any time (RFC 4861, Section 6.2.3). However, it
1704	 * would sometimes be useful to allow hosts to advertise some
1705	 * parameters such as prefix information and link MTU. Thus,
1706	 * we allow hosts to invoke rtadvd only when router lifetime
1707	 * (on every advertising interface) is explicitly set
1708	 * zero. (see also the above section)
1709	 */
1710	syslog(LOG_DEBUG,
1711	    "<%s> check lifetime=%d, ACCEPT_RTADV=%d, ip6.forwarding=%d "
1712	    "on %s", __func__,
1713	    rai->rai_lifetime,
1714	    check_accept_rtadv(ifi->ifi_ifindex),
1715	    getinet6sysctl(IPV6CTL_FORWARDING),
1716	    ifi->ifi_ifname);
1717
1718	if (rai->rai_lifetime != 0) {
1719		if (getinet6sysctl(IPV6CTL_FORWARDING) == 0) {
1720			syslog(LOG_ERR,
1721			    "non-zero lifetime RA "
1722			    "but net.inet6.ip6.forwarding=0.  "
1723			    "Ignored.");
1724			return;
1725		}
1726		if (check_accept_rtadv(ifi->ifi_ifindex)) {
1727			syslog(LOG_ERR,
1728			    "non-zero lifetime RA "
1729			    "on RA receiving interface %s."
1730			    "  Ignored.", ifi->ifi_ifname);
1731			return;
1732		}
1733	}
1734
1735	make_packet(rai);	/* XXX: inefficient */
1736
1737	sndmhdr.msg_name = (caddr_t)&sin6_linklocal_allnodes;
1738	sndmhdr.msg_iov[0].iov_base = (caddr_t)rai->rai_ra_data;
1739	sndmhdr.msg_iov[0].iov_len = rai->rai_ra_datalen;
1740
1741	cm = CMSG_FIRSTHDR(&sndmhdr);
1742	/* specify the outgoing interface */
1743	cm->cmsg_level = IPPROTO_IPV6;
1744	cm->cmsg_type = IPV6_PKTINFO;
1745	cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
1746	pi = (struct in6_pktinfo *)CMSG_DATA(cm);
1747	memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr));	/*XXX*/
1748	pi->ipi6_ifindex = ifi->ifi_ifindex;
1749
1750	/* specify the hop limit of the packet */
1751	{
1752		int hoplimit = 255;
1753
1754		cm = CMSG_NXTHDR(&sndmhdr, cm);
1755		cm->cmsg_level = IPPROTO_IPV6;
1756		cm->cmsg_type = IPV6_HOPLIMIT;
1757		cm->cmsg_len = CMSG_LEN(sizeof(int));
1758		memcpy(CMSG_DATA(cm), &hoplimit, sizeof(int));
1759	}
1760
1761	syslog(LOG_DEBUG,
1762	    "<%s> send RA on %s, # of RS waitings = %d",
1763	    __func__, ifi->ifi_ifname, ifi->ifi_rs_waitcount);
1764
1765	i = sendmsg(sock.si_fd, &sndmhdr, 0);
1766
1767	if (i < 0 || (size_t)i != rai->rai_ra_datalen)  {
1768		if (i < 0) {
1769			syslog(LOG_ERR, "<%s> sendmsg on %s: %s",
1770			    __func__, ifi->ifi_ifname,
1771			    strerror(errno));
1772		}
1773	}
1774
1775	/*
1776	 * unicast advertisements
1777	 * XXX commented out.  reason: though spec does not forbit it, unicast
1778	 * advert does not really help
1779	 */
1780	while ((sol = TAILQ_FIRST(&rai->rai_soliciter)) != NULL) {
1781		TAILQ_REMOVE(&rai->rai_soliciter, sol, sol_next);
1782		free(sol);
1783	}
1784
1785	/* update timestamp */
1786	clock_gettime(CLOCK_MONOTONIC_FAST, &ifi->ifi_ra_lastsent);
1787
1788	/* update counter */
1789	ifi->ifi_rs_waitcount = 0;
1790	ifi->ifi_raoutput++;
1791
1792	switch (ifi->ifi_state) {
1793	case IFI_STATE_CONFIGURED:
1794		if (ifi->ifi_burstcount > 0)
1795			ifi->ifi_burstcount--;
1796		break;
1797	case IFI_STATE_TRANSITIVE:
1798		ifi->ifi_burstcount--;
1799		if (ifi->ifi_burstcount == 0) {
1800			if (ifi->ifi_rainfo == ifi->ifi_rainfo_trans) {
1801				/* Initial burst finished. */
1802				if (ifi->ifi_rainfo_trans != NULL)
1803					ifi->ifi_rainfo_trans = NULL;
1804			}
1805
1806			/* Remove burst RA information */
1807			if (ifi->ifi_rainfo_trans != NULL) {
1808				rm_rainfo(ifi->ifi_rainfo_trans);
1809				ifi->ifi_rainfo_trans = NULL;
1810			}
1811
1812			if (ifi->ifi_rainfo != NULL) {
1813				/*
1814				 * TRANSITIVE -> CONFIGURED
1815				 *
1816				 * After initial burst or transition from
1817				 * one configuration to another,
1818				 * ifi_rainfo always points to the next RA
1819				 * information.
1820				 */
1821				ifi->ifi_state = IFI_STATE_CONFIGURED;
1822				syslog(LOG_DEBUG,
1823				    "<%s> ifname=%s marked as "
1824				    "CONFIGURED.", __func__,
1825				    ifi->ifi_ifname);
1826			} else {
1827				/*
1828				 * TRANSITIVE -> UNCONFIGURED
1829				 *
1830				 * If ifi_rainfo points to NULL, this
1831				 * interface is shutting down.
1832				 *
1833				 */
1834				int error;
1835
1836				ifi->ifi_state = IFI_STATE_UNCONFIGURED;
1837				syslog(LOG_DEBUG,
1838				    "<%s> ifname=%s marked as "
1839				    "UNCONFIGURED.", __func__,
1840				    ifi->ifi_ifname);
1841				error = sock_mc_leave(&sock,
1842				    ifi->ifi_ifindex);
1843				if (error)
1844					exit(1);
1845			}
1846		}
1847		break;
1848	}
1849}
1850
1851/* process RA timer */
1852struct rtadvd_timer *
1853ra_timeout(void *arg)
1854{
1855	struct ifinfo *ifi;
1856
1857	ifi = (struct ifinfo *)arg;
1858	syslog(LOG_DEBUG, "<%s> RA timer on %s is expired",
1859	    __func__, ifi->ifi_ifname);
1860
1861	ra_output(ifi);
1862
1863	return (ifi->ifi_ra_timer);
1864}
1865
1866/* update RA timer */
1867void
1868ra_timer_update(void *arg, struct timespec *tm)
1869{
1870	uint16_t interval;
1871	struct rainfo *rai;
1872	struct ifinfo *ifi;
1873
1874	ifi = (struct ifinfo *)arg;
1875	rai = ifi->ifi_rainfo;
1876	interval = 0;
1877
1878	switch (ifi->ifi_state) {
1879	case IFI_STATE_UNCONFIGURED:
1880		return;
1881		break;
1882	case IFI_STATE_CONFIGURED:
1883		/*
1884		 * Whenever a multicast advertisement is sent from
1885		 * an interface, the timer is reset to a
1886		 * uniformly-distributed random value between the
1887		 * interface's configured MinRtrAdvInterval and
1888		 * MaxRtrAdvInterval (RFC4861 6.2.4).
1889		 */
1890		interval = rai->rai_mininterval;
1891		interval += arc4random_uniform(rai->rai_maxinterval -
1892		    rai->rai_mininterval);
1893		break;
1894	case IFI_STATE_TRANSITIVE:
1895		/*
1896		 * For the first few advertisements (up to
1897		 * MAX_INITIAL_RTR_ADVERTISEMENTS), if the randomly chosen
1898		 * interval is greater than
1899		 * MAX_INITIAL_RTR_ADVERT_INTERVAL, the timer SHOULD be
1900		 * set to MAX_INITIAL_RTR_ADVERT_INTERVAL instead.  (RFC
1901		 * 4861 6.2.4)
1902		 *
1903		 * In such cases, the router SHOULD transmit one or more
1904		 * (but not more than MAX_FINAL_RTR_ADVERTISEMENTS) final
1905		 * multicast Router Advertisements on the interface with a
1906		 * Router Lifetime field of zero.  (RFC 4861 6.2.5)
1907		 */
1908		interval = ifi->ifi_burstinterval;
1909		break;
1910	}
1911
1912	tm->tv_sec = interval;
1913	tm->tv_nsec = 0;
1914
1915	syslog(LOG_DEBUG,
1916	    "<%s> RA timer on %s is set to %ld:%ld",
1917	    __func__, ifi->ifi_ifname,
1918	    (long int)tm->tv_sec, (long int)tm->tv_nsec / 1000);
1919
1920	return;
1921}
1922