From 19a4d0910cc5fd0114db0eb45030cdf155c624a3 Mon Sep 17 00:00:00 2001 From: itojun Date: Thu, 6 Jul 2000 12:37:56 +0000 Subject: [PATCH] sync with sys/netinet/icmp6.h change (no bitfield for router renumber). more logging. improve error handling/garbage collection. sync with kame. --- usr.sbin/rtadvd/dump.c | 11 ++- usr.sbin/rtadvd/if.c | 12 ++- usr.sbin/rtadvd/if.h | 5 +- usr.sbin/rtadvd/rrenum.c | 54 +++++++------ usr.sbin/rtadvd/rtadvd.8 | 16 ++-- usr.sbin/rtadvd/rtadvd.c | 146 +++++++++++++++++++++++++++------- usr.sbin/rtadvd/rtadvd.conf.5 | 6 +- usr.sbin/rtadvd/rtadvd.h | 12 ++- usr.sbin/rtadvd/timer.c | 20 ++++- usr.sbin/rtadvd/timer.h | 5 +- 10 files changed, 210 insertions(+), 77 deletions(-) diff --git a/usr.sbin/rtadvd/dump.c b/usr.sbin/rtadvd/dump.c index d3a106b05ab9..b92f9ef5904e 100644 --- a/usr.sbin/rtadvd/dump.c +++ b/usr.sbin/rtadvd/dump.c @@ -1,5 +1,5 @@ -/* $NetBSD: dump.c,v 1.1 2000/05/23 11:37:58 itojun Exp $ */ -/* $KAME: dump.c,v 1.10 2000/05/23 11:31:25 itojun Exp $ */ +/* $NetBSD: dump.c,v 1.2 2000/07/06 12:37:56 itojun Exp $ */ +/* $KAME: dump.c,v 1.11 2000/05/27 11:30:43 jinmei Exp $ */ /* * Copyright (C) 2000 WIDE Project. @@ -55,6 +55,7 @@ #include "rtadvd.h" #include "timer.h" +#include "if.h" #include "dump.h" static FILE *fp; @@ -100,6 +101,10 @@ if_dump() for (rai = ralist; rai; rai = rai->next) { fprintf(fp, "%s:\n", rai->ifname); + fprintf(fp, " Status: %s\n", + (iflist[rai->ifindex]->ifm_flags & IFF_UP) ? "UP" : + "DOWN"); + /* control information */ if (rai->lastsent.tv_sec) { /* note that ctime() appends CR by itself */ @@ -110,6 +115,8 @@ if_dump() fprintf(fp, " Next RA will be sent: %s", ctime((time_t *)&rai->timer->tm.tv_sec)); } + else + fprintf(fp, " RA timer is stopped"); fprintf(fp, " waits: %d, initcount: %d\n", rai->waiting, rai->initcounter); diff --git a/usr.sbin/rtadvd/if.c b/usr.sbin/rtadvd/if.c index 3078fa4ba100..aa9c6b68828f 100644 --- a/usr.sbin/rtadvd/if.c +++ b/usr.sbin/rtadvd/if.c @@ -1,5 +1,5 @@ -/* $NetBSD: if.c,v 1.5 2000/05/23 11:37:59 itojun Exp $ */ -/* $KAME: if.c,v 1.8 2000/05/22 22:04:37 itojun Exp $ */ +/* $NetBSD: if.c,v 1.6 2000/07/06 12:37:56 itojun Exp $ */ +/* $KAME: if.c,v 1.11 2000/07/06 08:20:04 jinmei Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -39,9 +39,7 @@ #ifdef __FreeBSD__ # include #endif -#ifdef __bsdi__ -# include -#endif +#include #ifdef __NetBSD__ #include #endif @@ -149,7 +147,7 @@ if_nametosdl(char *name) int if_getmtu(char *name) { -#ifndef __bsdi__ +#if 0 struct ifreq ifr; int s; @@ -207,6 +205,7 @@ if_getflags(int ifindex, int oifflags) close(s); return (oifflags & ~IFF_UP); } + close(s); return (ifr.ifr_flags); } @@ -589,5 +588,4 @@ init_iflist() /* make list of pointers to each if_msghdr */ parse_iflist(&iflist, ifblock, ifblock_size); - } diff --git a/usr.sbin/rtadvd/if.h b/usr.sbin/rtadvd/if.h index 22acd235124e..78317a29eb24 100644 --- a/usr.sbin/rtadvd/if.h +++ b/usr.sbin/rtadvd/if.h @@ -1,5 +1,5 @@ -/* $NetBSD: if.h,v 1.3 2000/05/23 11:37:59 itojun Exp $ */ -/* $KAME: if.h,v 1.2 2000/05/16 13:34:13 itojun Exp $ */ +/* $NetBSD: if.h,v 1.4 2000/07/06 12:37:56 itojun Exp $ */ +/* $KAME: if.h,v 1.3 2000/05/27 11:47:09 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. @@ -36,6 +36,7 @@ extern struct if_msghdr **iflist; extern size_t ifblock_size; extern char *ifblock; +struct nd_opt_hdr; struct sockaddr_dl *if_nametosdl __P((char *name)); int if_getmtu __P((char *name)); int if_getflags __P((int ifindex, int oifflags)); diff --git a/usr.sbin/rtadvd/rrenum.c b/usr.sbin/rtadvd/rrenum.c index fbfef6c24c01..32d99f389ff4 100644 --- a/usr.sbin/rtadvd/rrenum.c +++ b/usr.sbin/rtadvd/rrenum.c @@ -1,10 +1,10 @@ -/* $NetBSD: rrenum.c,v 1.4 2000/05/23 11:37:59 itojun Exp $ */ -/* $KAME: rrenum.c,v 1.3 2000/05/16 13:34:14 itojun Exp $ */ +/* $NetBSD: rrenum.c,v 1.5 2000/07/06 12:37:56 itojun Exp $ */ +/* $KAME: rrenum.c,v 1.4 2000/07/03 02:51:08 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -16,7 +16,7 @@ * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -65,11 +65,12 @@ struct rr_operation { static struct rr_operation rro; static int rr_rcvifindex; -static int rrcmd2pco[RPM_PCO_MAX] = {0, - SIOCAIFPREFIX_IN6, - SIOCCIFPREFIX_IN6, - SIOCSGIFPREFIX_IN6 - }; +static int rrcmd2pco[RPM_PCO_MAX] = { + 0, + SIOCAIFPREFIX_IN6, + SIOCCIFPREFIX_IN6, + SIOCSGIFPREFIX_IN6 +}; static int s = -1; /* @@ -81,7 +82,7 @@ rr_pco_check(int len, struct rr_pco_match *rpm) { struct rr_pco_use *rpu, *rpulim; int checklen; - + /* rpm->rpm_len must be (4N * 3) as router-renum-05.txt */ if ((rpm->rpm_len - 3) < 0 || /* must be at least 3 */ (rpm->rpm_len - 3) & 0x3) { /* must be multiple of 4 */ @@ -171,14 +172,20 @@ do_use_prefix(int len, struct rr_pco_match *rpm, struct in6_rrenumreq *irr) { /* init in6_rrenumreq fields */ irr->irr_u_uselen = rpu->rpu_uselen; irr->irr_u_keeplen = rpu->rpu_keeplen; - irr->irr_raf_mask_onlink = rpu->rpu_mask_onlink; - irr->irr_raf_mask_auto = rpu->rpu_mask_autonomous; + irr->irr_raf_mask_onlink = + (rpu->rpu_ramask & ICMP6_RR_PCOUSE_RAFLAGS_ONLINK); + irr->irr_raf_mask_auto = + (rpu->rpu_ramask & ICMP6_RR_PCOUSE_RAFLAGS_AUTO); irr->irr_vltime = rpu->rpu_vltime; irr->irr_pltime = rpu->rpu_pltime; - irr->irr_raf_onlink = rpu->rpu_onlink; - irr->irr_raf_auto = rpu->rpu_autonomous; - irr->irr_rrf_decrvalid = rpu->rpu_decr_vltime; - irr->irr_rrf_decrprefd = rpu->rpu_decr_pltime; + irr->irr_raf_onlink = + (rpu->rpu_raflags & ICMP6_RR_PCOUSE_RAFLAGS_ONLINK); + irr->irr_raf_auto = + (rpu->rpu_raflags & ICMP6_RR_PCOUSE_RAFLAGS_AUTO); + irr->irr_rrf_decrvalid = + (rpu->rpu_flags & ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME); + irr->irr_rrf_decrprefd = + (rpu->rpu_flags & ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME); irr->irr_useprefix.sin6_len = sizeof(irr->irr_useprefix); irr->irr_useprefix.sin6_family = AF_INET6; irr->irr_useprefix.sin6_addr = rpu->rpu_prefix; @@ -220,10 +227,10 @@ do_pco(struct icmp6_router_renum *rr, int len, struct rr_pco_match *rpm) while (if_indextoname(++ifindex, irr.irr_name)) { /* - * if rr_forceapply(A flag) is 0 and IFF_UP is off, + * if ICMP6_RR_FLAGS_FORCEAPPLY(A flag) is 0 and IFF_UP is off, * the interface is not applied */ - if (!rr->rr_forceapply && + if ((rr->rr_flags & ICMP6_RR_FLAGS_FORCEAPPLY) == 0 && (iflist[ifindex]->ifm_flags & IFF_UP) == 0) continue; /* TODO: interface scope check */ @@ -240,7 +247,7 @@ do_pco(struct icmp6_router_renum *rr, int len, struct rr_pco_match *rpm) } /* - * call do_pco() for each Prefix Control Operations(PCOs) in a received + * call do_pco() for each Prefix Control Operations(PCOs) in a received * Router Renumbering Command packet. * return 0 on success, 1 on failure */ @@ -321,9 +328,9 @@ rr_command_check(int len, struct icmp6_router_renum *rr, struct in6_addr *from, return 1; } if (rro.rro_seqnum == rr->rr_seqnum && - rr->rr_test == 0 && + (rr->rr_flags & ICMP6_RR_FLAGS_TEST) == 0 && RR_ISSET_SEGNUM(rro.rro_segnum_bits, rr->rr_segnum)) { - if (rr->rr_reqresult) + if ((rr->rr_flags & ICMP6_RR_FLAGS_REQRESULT) != 0) syslog(LOG_WARNING, "<%s> rcvd duped segnum %d from %s", __FUNCTION__, rr->rr_segnum, @@ -333,7 +340,7 @@ rr_command_check(int len, struct icmp6_router_renum *rr, struct in6_addr *from, } /* update seqnum */ - if (rro.rro_seqnum != rr->rr_seqnum) { + if (rro.rro_seqnum != rr->rr_seqnum) { /* then must be "<" */ /* init rro_segnum_bits */ @@ -352,7 +359,8 @@ rr_command_input(int len, struct icmp6_router_renum *rr, /* rr_command validity check */ if (rr_command_check(len, rr, from, dst)) goto failed; - if (rr->rr_test && !rr->rr_reqresult) + if ((rr->rr_flags & (ICMP6_RR_FLAGS_TEST|ICMP6_RR_FLAGS_REQRESULT)) == + ICMP6_RR_FLAGS_TEST) return; /* do router renumbering */ diff --git a/usr.sbin/rtadvd/rtadvd.8 b/usr.sbin/rtadvd/rtadvd.8 index 98c5821ca9ae..b794c76d4d01 100644 --- a/usr.sbin/rtadvd/rtadvd.8 +++ b/usr.sbin/rtadvd/rtadvd.8 @@ -1,5 +1,5 @@ -.\" $NetBSD: rtadvd.8,v 1.8 2000/05/23 11:37:59 itojun Exp $ -.\" $KAME: rtadvd.8,v 1.8 2000/05/22 22:12:11 itojun Exp $ +.\" $NetBSD: rtadvd.8,v 1.9 2000/07/06 12:37:56 itojun Exp $ +.\" $KAME: rtadvd.8,v 1.9 2000/05/27 13:37:01 jinmei Exp $ .\" .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. .\" All rights reserved. @@ -64,13 +64,18 @@ them as on-link prefixes. .Nm also watches the routing table. By default, if an interface direct route is -added/deleted on an advertising interface, +added/deleted on an advertising interface and no static prefixes are +specified by the configuration file, .Nm adds/deletes the corresponding prefix to/from its advertising list, respectively. The .Ic Fl s -command line option may be used to disable this behavior. +may be used to disable this behavior. +Moreover, if the status of an advertising interface changes, +.Nm +will start or stop sending router advertisements according +to the latest status. .Pp The command line options are: .Bl -tag -width indent @@ -96,7 +101,8 @@ Foreground mode (useful when debugging). Accept router renumbering requests. If you enable it, certain IPsec setup is suggested for security reasons. .It Fl s -Do not monitor routing table changes (static prefix). +Do not add or delete prefixes dynamically. +Only statically configured prefixes, if any, will be advertised. .El .Pp Upon receipt of signal diff --git a/usr.sbin/rtadvd/rtadvd.c b/usr.sbin/rtadvd/rtadvd.c index 7c5b33a520b4..5f5a3363108c 100644 --- a/usr.sbin/rtadvd/rtadvd.c +++ b/usr.sbin/rtadvd/rtadvd.c @@ -1,5 +1,5 @@ -/* $NetBSD: rtadvd.c,v 1.9 2000/05/23 11:37:59 itojun Exp $ */ -/* $KAME: rtadvd.c,v 1.26 2000/05/23 11:31:26 itojun Exp $ */ +/* $NetBSD: rtadvd.c,v 1.10 2000/07/06 12:37:56 itojun Exp $ */ +/* $KAME: rtadvd.c,v 1.31 2000/06/23 06:34:51 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -243,12 +243,10 @@ main(argc, argv) FD_ZERO(&fdset); FD_SET(sock, &fdset); maxfd = sock; - if (sflag == 0) { - rtsock_open(); - FD_SET(rtsock, &fdset); - if (rtsock > sock) + rtsock_open(); + FD_SET(rtsock, &fdset); + if (rtsock > sock) maxfd = rtsock; - } signal(SIGTERM, (void *)die); signal(SIGUSR1, (void *)rtadvd_set_dump_file); @@ -264,11 +262,18 @@ main(argc, argv) /* timer expiration check and reset the timer */ timeout = rtadvd_check_timer(); - syslog(LOG_DEBUG, - "<%s> set timer to %ld:%ld. waiting for inputs " - "or timeout", - __FUNCTION__, - (long int)timeout->tv_sec, (long int)timeout->tv_usec); + if (timeout != NULL) { + syslog(LOG_DEBUG, + "<%s> set timer to %ld:%ld. waiting for " + "inputs or timeout", + __FUNCTION__, + (long int)timeout->tv_sec, + (long int)timeout->tv_usec); + } else { + syslog(LOG_DEBUG, + "<%s> there's no timer. waiting for inputs", + __FUNCTION__); + } if ((i = select(maxfd + 1, &select_fd, NULL, NULL, timeout)) < 0) { @@ -343,7 +348,7 @@ rtmsg_input() if (n > rtmsg_len(msg)) { /* * This usually won't happen for messages received on - * an routing socket. + * a routing socket. */ if (dflag > 1) syslog(LOG_DEBUG, @@ -359,6 +364,8 @@ rtmsg_input() lim = msg + n; for (next = msg; next < lim; next += len) { + int oldifflags; + next = get_next_msg(next, lim, 0, &len, RTADV_TYPE2BITMASK(RTM_ADD) | RTADV_TYPE2BITMASK(RTM_DELETE) | @@ -388,7 +395,7 @@ rtmsg_input() __FUNCTION__, __LINE__, type, if_indextoname(ifindex, ifname)); } - return; + continue; } if ((rai = if_indextorainfo(ifindex)) == NULL) { @@ -399,16 +406,20 @@ rtmsg_input() __FUNCTION__, if_indextoname(ifindex, ifname)); } - return; + continue; } + oldifflags = iflist[ifindex]->ifm_flags; switch(type) { case RTM_ADD: - /* init iffalgs because it may have changed */ + /* init ifflags because it may have changed */ iflist[ifindex]->ifm_flags = if_getflags(ifindex, iflist[ifindex]->ifm_flags); + if (sflag) + break; /* we aren't interested in prefixes */ + addr = get_addr(msg); plen = get_prefixlen(msg); /* sanity check for plen */ @@ -417,7 +428,7 @@ rtmsg_input() syslog(LOG_INFO, "<%s> new interface route's" "plen %d is invalid for a prefix", __FUNCTION__, plen); - return; + break; } prefix = find_prefix(rai, addr, plen); if (prefix) { @@ -433,7 +444,7 @@ rtmsg_input() plen, rai->ifname); } - return; + break; } make_prefix(rai, ifindex, addr, plen); break; @@ -443,6 +454,9 @@ rtmsg_input() if_getflags(ifindex, iflist[ifindex]->ifm_flags); + if (sflag) + break; + addr = get_addr(msg); plen = get_prefixlen(msg); /* sanity check for plen */ @@ -452,7 +466,7 @@ rtmsg_input() "route's" "plen %d is invalid for a prefix", __FUNCTION__, plen); - return; + break; } prefix = find_prefix(rai, addr, plen); if (prefix == NULL) { @@ -468,7 +482,7 @@ rtmsg_input() plen, rai->ifname); } - return; + break; } delete_prefix(rai, prefix); break; @@ -492,6 +506,29 @@ rtmsg_input() } return; } + + /* check if an interface flag is changed */ + if ((oldifflags & IFF_UP) != 0 && /* UP to DOWN */ + (iflist[ifindex]->ifm_flags & IFF_UP) == 0) { + syslog(LOG_INFO, + "<%s> interface %s becomes down. stop timer.", + __FUNCTION__, rai->ifname); + rtadvd_remove_timer(&rai->timer); + } + else if ((oldifflags & IFF_UP) == 0 && /* DOWN to UP */ + (iflist[ifindex]->ifm_flags & IFF_UP) != 0) { + syslog(LOG_INFO, + "<%s> interface %s becomes up. restart timer.", + __FUNCTION__, rai->ifname); + + rai->initcounter = 0; /* reset the counter */ + rai->waiting = 0; /* XXX */ + rai->timer = rtadvd_add_timer(ra_timeout, + ra_timer_update, + rai, rai); + ra_timer_update((void *)rai, &rai->timer->tm); + rtadvd_set_timer(&rai->timer->tm, rai->timer); + } } return; @@ -550,6 +587,18 @@ rtadvd_input() return; } + /* + * If we happen to receive data on an interface which is now down, + * just discard the data. + */ + if ((iflist[pi->ipi6_ifindex]->ifm_flags & IFF_UP) == 0) { + syslog(LOG_INFO, + "<%s> received data on a disabled interface (%s)", + __FUNCTION__, + if_indextoname(pi->ipi6_ifindex, ifnamebuf)); + return; + } + #ifdef OLDRAWSOCKET if (i < sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr)) { syslog(LOG_ERR, @@ -569,7 +618,7 @@ rtadvd_input() } icp = (struct icmp6_hdr *)rcvmhdr.msg_iov[0].iov_base; -#endif +#endif switch(icp->icmp6_type) { case ND_ROUTER_SOLICIT: @@ -741,6 +790,19 @@ rs_input(int len, struct nd_router_solicit *rs, { long delay; /* must not be greater than 1000000 */ struct timeval interval, now, min_delay, tm_tmp, *rest; + struct soliciter *sol; + + /* + * record sockaddr waiting for RA, if possible + */ + sol = (struct soliciter *)malloc(sizeof(*sol)); + if (sol) { + sol->addr = *from; + /*XXX RFC2553 need clarification on flowinfo */ + sol->addr.sin6_flowinfo = 0; + sol->next = ra->soliciter; + ra->soliciter = sol->next; + } /* * If there is already a waiting RS packet, don't @@ -784,7 +846,7 @@ rs_input(int len, struct nd_router_solicit *rs, TIMEVAL_ADD(&min_delay, &interval, &interval); } rtadvd_set_timer(&interval, ra->timer); - goto done; + goto done; } done: @@ -1298,9 +1360,15 @@ ra_output(rainfo) struct rainfo *rainfo; { int i; - struct cmsghdr *cm; struct in6_pktinfo *pi; + struct soliciter *sol, *nextsol; + + if ((iflist[rainfo->ifindex]->ifm_flags & IFF_UP) == 0) { + syslog(LOG_DEBUG, "<%s> %s is not up, skip sending RA", + __FUNCTION__, rainfo->ifname); + return; + } sndmhdr.msg_name = (caddr_t)&sin6_allnodes; sndmhdr.msg_iov[0].iov_base = (caddr_t)rainfo->ra_data; @@ -1340,6 +1408,32 @@ struct rainfo *rainfo; } } + /* + * unicast advertisements + * XXX commented out. reason: though spec does not forbit it, unicast + * advert does not really help + */ + for (sol = rainfo->soliciter; sol; sol = nextsol) { + nextsol = sol->next; + +#if 0 + sndmhdr.msg_name = (caddr_t)&sol->addr; + i = sendmsg(sock, &sndmhdr, 0); + if (i < 0 || i != rainfo->ra_datalen) { + if (i < 0) { + syslog(LOG_ERR, + "<%s> unicast sendmsg on %s: %s", + __FUNCTION__, rainfo->ifname, + strerror(errno)); + } + } +#endif + + sol->next = NULL; + free(sol); + } + rainfo->soliciter = NULL; + /* update counter */ if (rainfo->initcounter < MAX_INITIAL_RTR_ADVERTISEMENTS) rainfo->initcounter++; @@ -1366,11 +1460,7 @@ ra_timeout(void *data) "<%s> RA timer on %s is expired", __FUNCTION__, rai->ifname); - if (iflist[rai->ifindex]->ifm_flags & IFF_UP) - ra_output(rai); - else - syslog(LOG_DEBUG, "<%s> %s is not up, skip sending RA", - __FUNCTION__, rai->ifname); + ra_output(rai); } /* update RA timer */ diff --git a/usr.sbin/rtadvd/rtadvd.conf.5 b/usr.sbin/rtadvd/rtadvd.conf.5 index 4c9bf4e3dcd9..c3df9f329d76 100644 --- a/usr.sbin/rtadvd/rtadvd.conf.5 +++ b/usr.sbin/rtadvd/rtadvd.conf.5 @@ -1,5 +1,5 @@ -.\" $NetBSD: rtadvd.conf.5,v 1.3 2000/05/23 11:37:59 itojun Exp $ -.\" $KAME: rtadvd.conf.5,v 1.5 2000/05/22 22:22:56 itojun Exp $ +.\" $NetBSD: rtadvd.conf.5,v 1.4 2000/07/06 12:37:56 itojun Exp $ +.\" $KAME: rtadvd.conf.5,v 1.6 2000/05/26 10:54:58 jinmei Exp $ .\" .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. .\" All rights reserved. @@ -134,7 +134,7 @@ for each item below. Indices vary from 0 to N-1, where N is the value of .Ic addrs . -Each index shall follows the name of each item, e.g., +Each index shall follow the name of each item, e.g., .Dq prefixlen2 . .It Cm \&prefixlen (num) Prefix length field. diff --git a/usr.sbin/rtadvd/rtadvd.h b/usr.sbin/rtadvd/rtadvd.h index 4b5720bbe728..036b8a1d2b85 100644 --- a/usr.sbin/rtadvd/rtadvd.h +++ b/usr.sbin/rtadvd/rtadvd.h @@ -1,5 +1,5 @@ -/* $NetBSD: rtadvd.h,v 1.4 2000/05/23 11:37:59 itojun Exp $ */ -/* $KAME: rtadvd.h,v 1.8 2000/05/16 13:34:14 itojun Exp $ */ +/* $NetBSD: rtadvd.h,v 1.5 2000/07/06 12:37:56 itojun Exp $ */ +/* $KAME: rtadvd.h,v 1.9 2000/06/22 20:16:13 itojun Exp $ */ /* * Copyright (C) 1998 WIDE Project. @@ -85,6 +85,11 @@ struct prefix { struct in6_addr prefix; }; +struct soliciter { + struct soliciter *next; + struct sockaddr_in6 addr; +}; + struct rainfo { /* pointer for list */ struct rainfo *next; @@ -132,6 +137,9 @@ struct rainfo { u_quad_t rainput; /* number of RAs received */ u_quad_t rainconsistent; /* number of RAs inconsistent with ours */ u_quad_t rsinput; /* number of RSs received */ + + /* info about soliciter */ + struct soliciter *soliciter; /* recent solication source */ }; void ra_timeout __P((void *)); diff --git a/usr.sbin/rtadvd/timer.c b/usr.sbin/rtadvd/timer.c index b0a2d6e4c7d3..5b800f63dc12 100644 --- a/usr.sbin/rtadvd/timer.c +++ b/usr.sbin/rtadvd/timer.c @@ -1,5 +1,5 @@ -/* $NetBSD: timer.c,v 1.3 2000/05/23 11:37:59 itojun Exp $ */ -/* $KAME: timer.c,v 1.3 2000/05/22 22:23:07 itojun Exp $ */ +/* $NetBSD: timer.c,v 1.4 2000/07/06 12:37:56 itojun Exp $ */ +/* $KAME: timer.c,v 1.4 2000/05/27 11:30:43 jinmei Exp $ */ /* * Copyright (C) 1998 WIDE Project. @@ -44,6 +44,8 @@ static struct rtadvd_timer timer_head; #define MILLION 1000000 +#define TIMEVAL_EQUAL(t1,t2) ((t1)->tv_sec == (t2)->tv_sec &&\ + (t1)->tv_usec == (t2)->tv_usec) static struct timeval tm_max = {0x7fffffff, 0x7fffffff}; @@ -93,6 +95,14 @@ rtadvd_add_timer(void (*timeout) __P((void *)), return(newtimer); } +void +rtadvd_remove_timer(struct rtadvd_timer **timer) +{ + remque(*timer); + free(*timer); + *timer = NULL; +} + void rtadvd_set_timer(struct timeval *tm, struct rtadvd_timer *timer) { @@ -139,7 +149,11 @@ rtadvd_check_timer() tm = tm->next; } - if (TIMEVAL_LT(timer_head.tm, now)) { + if (TIMEVAL_EQUAL(&tm_max, &timer_head.tm)) { + /* no need to timeout */ + return(NULL); + } + else if (TIMEVAL_LT(timer_head.tm, now)) { /* this may occur when the interval is too small */ returnval.tv_sec = returnval.tv_usec = 0; } diff --git a/usr.sbin/rtadvd/timer.h b/usr.sbin/rtadvd/timer.h index 2ddf1abb57b2..be7c5dc0c3b8 100644 --- a/usr.sbin/rtadvd/timer.h +++ b/usr.sbin/rtadvd/timer.h @@ -1,5 +1,5 @@ -/* $NetBSD: timer.h,v 1.3 2000/05/23 11:37:59 itojun Exp $ */ -/* $KAME: timer.h,v 1.2 2000/05/16 13:34:14 itojun Exp $ */ +/* $NetBSD: timer.h,v 1.4 2000/07/06 12:37:56 itojun Exp $ */ +/* $KAME: timer.h,v 1.3 2000/05/27 11:30:43 jinmei Exp $ */ /* * Copyright (C) 1998 WIDE Project. @@ -56,6 +56,7 @@ void rtadvd_timer_init __P((void)); struct rtadvd_timer *rtadvd_add_timer __P((void (*) __P((void *)), void (*) __P((void *, struct timeval *)), void *, void *)); void rtadvd_set_timer __P((struct timeval *, struct rtadvd_timer *)); +void rtadvd_remove_timer __P((struct rtadvd_timer **)); struct timeval * rtadvd_check_timer __P((void)); struct timeval * rtadvd_timer_rest __P((struct rtadvd_timer *)); void TIMEVAL_ADD __P((struct timeval *, struct timeval *,