From owner-svn-src-head@FreeBSD.ORG Sun Jul 17 19:24:54 2011 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6C8A41065670; Sun, 17 Jul 2011 19:24:54 +0000 (UTC) (envelope-from hrs@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 599378FC0A; Sun, 17 Jul 2011 19:24:54 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p6HJOsgg086748; Sun, 17 Jul 2011 19:24:54 GMT (envelope-from hrs@svn.freebsd.org) Received: (from hrs@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p6HJOsxZ086740; Sun, 17 Jul 2011 19:24:54 GMT (envelope-from hrs@svn.freebsd.org) Message-Id: <201107171924.p6HJOsxZ086740@svn.freebsd.org> From: Hiroki Sato Date: Sun, 17 Jul 2011 19:24:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r224144 - in head/usr.sbin: . rtadvctl rtadvd X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 17 Jul 2011 19:24:54 -0000 Author: hrs Date: Sun Jul 17 19:24:54 2011 New Revision: 224144 URL: http://svn.freebsd.org/changeset/base/224144 Log: - Improve interface list handling. The rtadvd(8) now supports dynamically- added/removed interfaces in a more consistent manner and reloading the configuration file. - Implement burst unsolicited RA sending into the internal RA timer framework when AdvSendAdvertisements and/or configuration entries are changed as described in RFC 4861 6.2.4. This fixes issues that make termination of the rtadvd(8) daemon take very long time. An interface now has three internal states, UNCONFIGURED, TRANSITIVE, or CONFIGURED, and the burst unsolicited sending happens in TRANSITIVE. See rtadvd.h for the details. - rtadvd(8) now accepts non-existent interfaces as well in the command line. - Add control socket support and rtadvctl(8) utility to show the RA information in rtadvd(8). Dumping by SIGUSR1 has been removed in favor of it. Added: - copied from r224006, user/hrs/ipv6/usr.sbin/rtadvctl/ head/usr.sbin/rtadvd/control.c (contents, props changed) - copied, changed from r224006, user/hrs/ipv6/usr.sbin/rtadvd/control.c - copied unchanged from r224006, user/hrs/ipv6/usr.sbin/rtadvd/control.h - copied unchanged from r224006, user/hrs/ipv6/usr.sbin/rtadvd/control_client.c - copied unchanged from r224006, user/hrs/ipv6/usr.sbin/rtadvd/control_client.h head/usr.sbin/rtadvd/control_server.c (contents, props changed) - copied, changed from r224006, user/hrs/ipv6/usr.sbin/rtadvd/control_server.c head/usr.sbin/rtadvd/control_server.h (contents, props changed) - copied, changed from r224006, user/hrs/ipv6/usr.sbin/rtadvd/control_server.h head/usr.sbin/rtadvd/timer_subr.c (contents, props changed) - copied, changed from r224006, user/hrs/ipv6/usr.sbin/rtadvd/timer_subr.c head/usr.sbin/rtadvd/timer_subr.h (contents, props changed) - copied, changed from r224006, user/hrs/ipv6/usr.sbin/rtadvd/timer_subr.h Directory Properties: head/usr.sbin/rtadvctl/ (props changed) head/usr.sbin/rtadvd/control.h (props changed) head/usr.sbin/rtadvd/control_client.c (props changed) head/usr.sbin/rtadvd/control_client.h (props changed) Deleted: head/usr.sbin/rtadvd/dump.c head/usr.sbin/rtadvd/dump.h Modified: head/usr.sbin/Makefile head/usr.sbin/rtadvctl/Makefile (contents, props changed) head/usr.sbin/rtadvctl/rtadvctl.8 (contents, props changed) head/usr.sbin/rtadvctl/rtadvctl.c (contents, props changed) head/usr.sbin/rtadvd/Makefile head/usr.sbin/rtadvd/config.c head/usr.sbin/rtadvd/config.h head/usr.sbin/rtadvd/if.c head/usr.sbin/rtadvd/if.h head/usr.sbin/rtadvd/pathnames.h head/usr.sbin/rtadvd/rrenum.c head/usr.sbin/rtadvd/rtadvd.8 head/usr.sbin/rtadvd/rtadvd.c head/usr.sbin/rtadvd/rtadvd.h head/usr.sbin/rtadvd/timer.c head/usr.sbin/rtadvd/timer.h Directory Properties: head/usr.sbin/rtadvd/ (props changed) Modified: head/usr.sbin/Makefile ============================================================================== --- head/usr.sbin/Makefile Sun Jul 17 18:51:51 2011 (r224143) +++ head/usr.sbin/Makefile Sun Jul 17 19:24:54 2011 (r224144) @@ -178,6 +178,7 @@ SUBDIR+= ndp SUBDIR+= rip6query SUBDIR+= route6d SUBDIR+= rrenumd +SUBDIR+= rtadvctl SUBDIR+= rtadvd SUBDIR+= rtsold SUBDIR+= traceroute6 Modified: head/usr.sbin/rtadvctl/Makefile ============================================================================== --- user/hrs/ipv6/usr.sbin/rtadvctl/Makefile Thu Jul 14 10:09:58 2011 (r224006) +++ head/usr.sbin/rtadvctl/Makefile Sun Jul 17 19:24:54 2011 (r224144) @@ -7,7 +7,7 @@ MAN= rtadvctl.8 SRCS= rtadvctl.c control.c control_client.c if.c timer_subr.c -CFLAGS+= -DROUTEINFO -I${.CURDIR} -I${.CURDIR}/../rtadvd -WARNS?= 3 +CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../rtadvd +WARNS?= 1 .include Modified: head/usr.sbin/rtadvctl/rtadvctl.8 ============================================================================== --- user/hrs/ipv6/usr.sbin/rtadvctl/rtadvctl.8 Thu Jul 14 10:09:58 2011 (r224006) +++ head/usr.sbin/rtadvctl/rtadvctl.8 Sun Jul 17 19:24:54 2011 (r224144) @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 14, 2011 +.Dd July 16, 2011 .Dt RTADVCTL 8 .Os .Sh NAME @@ -39,54 +39,65 @@ .Op Ar interface ... .Sh DESCRIPTION .Nm -is a utility that communicates +is a utility that communicates with .Xr rtadvd 8 -daemon and displays information on Router Advertisement messages being -sent on each interfaces. +daemon and displays information about Router Advertisement messages being +sent on each interface. .Pp This utility provides several options and subcommands. The options are as follows: .Bl -tag -width indent .\" .It Fl v -Increase verbose level. When specified once, the +Increase verbosity level. +When specified once, the .Nm -utility shows additional information on prefixes, RDNSS, and DNSSL +utility shows additional information about prefixes, RDNSS, and DNSSL options. -When twice, it shows information on inactive interfaces and -some statistics. +When given twice, it additionally shows information about +inactive interfaces and some statistics. .El .Pp The subcommands are as follows: .Bl -tag -width indent .\" -.It reload -Specifies reloading the configuration file. +.It reload Op interfaces... +Specifies to reload the configuration file. If one or more +.Ar interface +is specified, configuration entries for the interfaces will be reloaded +selectively. +.It enable interfaces... +Specifies to mark the interface as enable and to try to reload the +configuration entry. +This subcommand is useful for dynamically-added interfaces. +.Pp +The +.Xr rtadvd 8 +daemon marks an interface as enable if the interface exists and the +configuration file has a valid entry for that when it is invoked. +.It disable interfaces... +Specifies to mark the interface as disable. .It shutdown -Makes +Makes the +.Xr rtadvd 8 +daemon shut down. +Note that the .Xr rtadvd 8 -daemon shut down immediately. +daemon will send several RAs with zero lifetime to invalidate the old +information on each interface. +It will take at most nine seconds. .It show Op interfaces... Displays information on Router Advertisement messages being sent -on each interfaces. +on each interface. .Sh SEE ALSO -.Xr rtadv 8 , +.Xr rtadvd 8 , .Xr rtadvd.conf 5 .Sh HISTORY The .Nm command first appeared in .Fx 9.0 . -.Sh BUGS -The -.Xr rtadvd 8 -daemon stops responding to -.Nm -for a while just after reloading the configuration file by the reload -subcommand. -This is because in the current implementation it cannot communicate -with +.Sh AUTHORS .Nm -during sending some additional RAs for graceful transition from one -configuration to another. -It will take at most nine seconds for each interface. +was written by +.An "Hiroki Sato" Aq hrs@FreeBSD.org . Modified: head/usr.sbin/rtadvctl/rtadvctl.c ============================================================================== --- user/hrs/ipv6/usr.sbin/rtadvctl/rtadvctl.c Thu Jul 14 10:09:58 2011 (r224006) +++ head/usr.sbin/rtadvctl/rtadvctl.c Sun Jul 17 19:24:54 2011 (r224144) @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -60,6 +61,7 @@ #include "rtadvd.h" #include "if.h" #include "timer_subr.h" +#include "timer.h" #include "control.h" #include "control_client.h" @@ -84,9 +86,7 @@ static int action_shutdown(int, char **) static int action_show(int, char **); static int action_show_prefix(struct prefix *); -#ifdef ROUTEINFO static int action_show_rtinfo(struct rtinfo *); -#endif static int action_show_rdnss(void *); static int action_show_dnssl(void *); @@ -108,14 +108,17 @@ static struct dispatch_table { { "show", action_show }, { "reload", action_reload }, { "shutdown", action_shutdown }, - { NULL, NULL }, { "enable", action_enable }, { "disable", action_disable }, + { NULL, NULL }, { "echo", action_echo }, { "version", action_version }, { NULL, NULL }, }; +static char errmsgbuf[1024]; +static char *errmsg = NULL; + static void mysyslog(int priority, const char * restrict fmt, ...) { @@ -177,13 +180,17 @@ main(int argc, char *argv[]) } } - if (action != NULL) { - error = (dtable[i].dt_act)(--argc, ++argv); - if (error) - fprintf(stderr, "%s failed.\n", dtable[i].dt_comm); - } else + if (action == NULL) usage(); + error = (dtable[i].dt_act)(--argc, ++argv); + if (error) { + fprintf(stderr, "%s failed", dtable[i].dt_comm); + if (errmsg != NULL) + fprintf(stderr, ": %s", errmsg); + fprintf(stderr, ".\n"); + } + return (error); } @@ -295,33 +302,69 @@ action_propset(char *argv) return (action_plgeneric(CM_TYPE_REQ_SET_PROP, argv, buf)); } -/* XXX */ static int -action_enable(int argc, char **argv) +action_disable(int argc, char **argv) { - argc = argc; - argv = argv; + char *action_argv; + char argv_disable[IFNAMSIZ + sizeof(":disable=")]; + int i; + int error; - return (0); + if (argc < 1) + return (1); + + error = 0; + for (i = 0; i < argc; i++) { + sprintf(argv_disable, "%s:disable=", argv[i]); + action_argv = argv_disable; + error += action_propset(action_argv); + } + + return (error); } -/* XXX */ static int -action_disable(int argc, char **argv) +action_enable(int argc, char **argv) { - argc = argc; - argv = argv; + char *action_argv; + char argv_enable[IFNAMSIZ + sizeof(":enable=")]; + int i; + int error; - return (0); + if (argc < 1) + return (1); + + error = 0; + for (i = 0; i < argc; i++) { + sprintf(argv_enable, "%s:enable=", argv[i]); + action_argv = argv_enable; + error += action_propset(action_argv); + } + + return (error); } static int -action_reload(int argc __unused, char **argv __unused) +action_reload(int argc, char **argv) { char *action_argv; + char argv_reload[IFNAMSIZ + sizeof(":reload=")]; + int i; + int error; - action_argv = strdup("reload"); - return(action_propset(action_argv)); + if (argc == 0) { + action_argv = strdup(":reload="); + return (action_propset(action_argv)); + } + + error = 0; + for (i = 0; i < argc; i++) { + sprintf(argv_reload, "%s:reload=", argv[i]); + action_argv = argv_reload; + error += action_propset(action_argv); + } + + return (error); } static int @@ -330,7 +373,7 @@ action_echo(int argc __unused, char **ar char *action_argv; action_argv = strdup("echo"); - return(action_propset(action_argv)); + return (action_propset(action_argv)); } static int @@ -339,7 +382,7 @@ action_shutdown(int argc __unused, char char *action_argv; action_argv = strdup("shutdown"); - return(action_propset(action_argv)); + return (action_propset(action_argv)); } /* XXX */ @@ -366,10 +409,9 @@ action_show(int argc, char **argv) char argv_ifilist[sizeof(":ifilist=")] = ":ifilist="; char argv_ifi[IFNAMSIZ + sizeof(":ifi=")]; char argv_rai[IFNAMSIZ + sizeof(":rai=")]; -#ifdef ROUTEINFO char argv_rti[IFNAMSIZ + sizeof(":rti=")]; -#endif char argv_pfx[IFNAMSIZ + sizeof(":pfx=")]; + char argv_ifi_ra_timer[IFNAMSIZ + sizeof(":ifi_ra_timer=")]; char argv_rdnss[IFNAMSIZ + sizeof(":rdnss=")]; char argv_dnssl[IFNAMSIZ + sizeof(":dnssl=")]; char ssbuf[SSBUFLEN]; @@ -394,7 +436,7 @@ action_show(int argc, char **argv) while (p < endp) { ifi = malloc(sizeof(*ifi)); if (ifi == NULL) - exit(1); + return (1); memset(ifi, 0, sizeof(*ifi)); strcpy(ifi->ifi_ifname, p); @@ -406,23 +448,27 @@ action_show(int argc, char **argv) for (i = 0; i < argc; i++) { ifi = malloc(sizeof(*ifi)); if (ifi == NULL) - exit(1); + return (1); memset(ifi, 0, sizeof(*ifi)); strcpy(ifi->ifi_ifname, argv[i]); ifi->ifi_ifindex = if_nametoindex(ifi->ifi_ifname); - if (ifi->ifi_ifindex == 0) - exit(1); + if (ifi->ifi_ifindex == 0) { + sprintf(errmsgbuf, "invalid interface %s", + ifi->ifi_ifname); + errmsg = errmsgbuf; + return (1); + } + TAILQ_INSERT_TAIL(&ifl, ifi, ifi_next); } } TAILQ_FOREACH(ifi, &ifl, ifi_next) { struct ifinfo *ifi_s; + struct rtadvd_timer *rat; struct rainfo *rai; -#ifdef ROUTEINFO struct rtinfo *rti; -#endif struct prefix *pfx; int c; int ra_ifstatus; @@ -439,33 +485,52 @@ action_show(int argc, char **argv) printf("%s: flags=<", ifi->ifi_ifname); - /* - * RA_RECV = UP + CONFIGURED + ACCEPT_RTADV - * RA_SEND = UP + CONFIGURED + IPV6FORWARDING - */ - c = 0; if (ifi_s->ifi_ifindex == 0) c += printf("NONEXISTENT"); else c += printf("%s", (ifi_s->ifi_flags & IFF_UP) ? "UP" : "DOWN"); - if (ifi_s->ifi_state == IFI_STATE_CONFIGURED) + switch (ifi_s->ifi_state) { + case IFI_STATE_CONFIGURED: c += printf("%s%s", (c) ? "," : "", "CONFIGURED"); - + break; + case IFI_STATE_TRANSITIVE: + c += printf("%s%s", (c) ? "," : "", "TRANSITIVE"); + break; + } if (ifi_s->ifi_persist) c += printf("%s%s", (c) ? "," : "", "PERSIST"); printf(">"); ra_ifstatus = RA_IFSTATUS_INACTIVE; if ((ifi_s->ifi_flags & IFF_UP) && - (ifi_s->ifi_state == IFI_STATE_CONFIGURED)) { + ((ifi_s->ifi_state == IFI_STATE_CONFIGURED) || + (ifi_s->ifi_state == IFI_STATE_TRANSITIVE))) { +#if (__FreeBSD_version < 900000) + /* + * RA_RECV: !ip6.forwarding && ip6.accept_rtadv + * RA_SEND: ip6.forwarding + */ + if (getinet6sysctl(IPV6CTL_FORWARDING) == 0) { + if (getinet6sysctl(IPV6CTL_ACCEPT_RTADV)) + ra_ifstatus = RA_IFSTATUS_RA_RECV; + else + ra_ifstatus = RA_IFSTATUS_INACTIVE; + } else + ra_ifstatus = RA_IFSTATUS_RA_SEND; +#else + /* + * RA_RECV: ND6_IFF_ACCEPT_RTADV + * RA_SEND: ip6.forwarding + */ if (ifi_s->ifi_nd_flags & ND6_IFF_ACCEPT_RTADV) ra_ifstatus = RA_IFSTATUS_RA_RECV; else if (getinet6sysctl(IPV6CTL_FORWARDING)) ra_ifstatus = RA_IFSTATUS_RA_SEND; else ra_ifstatus = RA_IFSTATUS_INACTIVE; +#endif } c = 0; @@ -478,7 +543,11 @@ action_show(int argc, char **argv) printf("%s%s", (c) ? "," : "", "RA_SEND"); printf("> "); - if (ifi_s->ifi_state != IFI_STATE_CONFIGURED) { + switch (ifi_s->ifi_state) { + case IFI_STATE_CONFIGURED: + case IFI_STATE_TRANSITIVE: + break; + default: printf("\n"); continue; } @@ -533,14 +602,33 @@ action_show(int argc, char **argv) rai->rai_hoplimit); printf("\tAdvIfPrefixes: %s\n", rai->rai_advifprefix ? "yes" : "no"); + + /* RA timer */ + rat = NULL; + if (ifi_s->ifi_ra_timer != NULL) { + sprintf(argv_ifi_ra_timer, "%s:ifi_ra_timer=", + ifi->ifi_ifname); + action_argv = argv_ifi_ra_timer; + + error = action_propget(action_argv, &cp); + if (error) + return (error); + + rat = (struct rtadvd_timer *)cp.cp_val; + } + printf("\tNext RA send: %s", + (rat == NULL) ? "never\n" : + ctime((time_t *)&rat->rat_tm.tv_sec)); + printf("\tLast RA sent: %s", + (ifi_s->ifi_ra_lastsent.tv_sec == 0) ? "never\n" : + ctime((time_t *)&ifi_s->ifi_ra_lastsent.tv_sec)); if (rai->rai_clockskew) - printf("\tClock skew: %ldsec\n", + printf("\tClock skew: %" PRIu16 "sec\n", rai->rai_clockskew); if (vflag < LOG_WARNING) continue; -#ifdef ROUTEINFO /* route information */ sprintf(argv_rti, "%s:rti=", ifi->ifi_ifname); action_argv = argv_rti; @@ -556,7 +644,7 @@ action_show(int argc, char **argv) for (i = 0; i < len; i++) action_show_rtinfo(&rti[i]); } -#endif + /* prefix information */ sprintf(argv_pfx, "%s:pfx=", ifi->ifi_ifname); action_argv = argv_pfx; @@ -583,7 +671,7 @@ action_show(int argc, char **argv) if (error) continue; - len = *((u_int16_t *)cp.cp_val); + len = *((uint16_t *)cp.cp_val); if (len > 0) { printf("\tRDNSS entries:\n"); @@ -598,7 +686,7 @@ action_show(int argc, char **argv) if (error) continue; - len = *((u_int16_t *)cp.cp_val); + len = *((uint16_t *)cp.cp_val); if (len > 0) { printf("\tDNSSL entries:\n"); @@ -610,28 +698,34 @@ action_show(int argc, char **argv) printf("\n"); - printf("\tLast RA sent: %s", - (rai->rai_lastsent.tv_sec == 0) ? "never\n" : - ctime((time_t *)&rai->rai_lastsent.tv_sec)); - printf("\tRA initcounts/waits: %d/%d\n", - rai->rai_initcounter, - rai->rai_waiting); - printf("\tRA out/in/inconsistent: %llu/%llu/%llu\n", - ifi_s->ifi_raoutput, + printf("\tCounters\n" + "\t RA burst counts: %" PRIu16 " (interval: %s)\n" + "\t RS wait counts: %" PRIu16 "\n", + ifi_s->ifi_burstcount, + sec2str(ifi_s->ifi_burstinterval, ssbuf), + ifi_s->ifi_rs_waitcount); + + printf("\tOutputs\n" + "\t RA: %" PRIu64 "\n", ifi_s->ifi_raoutput); + + printf("\tInputs\n" + "\t RA: %" PRIu64 " (normal)\n" + "\t RA: %" PRIu64 " (inconsistent)\n" + "\t RS: %" PRIu64 "\n", ifi_s->ifi_rainput, - ifi_s->ifi_rainconsistent); - printf("\tRS in: %llu\n", + ifi_s->ifi_rainconsistent, ifi_s->ifi_rsinput); printf("\n"); +#if 0 /* Not implemented yet */ printf("\tReceived RAs:\n"); +#endif } return (0); } -#ifdef ROUTEINFO static int action_show_rtinfo(struct rtinfo *rti) { @@ -648,7 +742,6 @@ action_show_rtinfo(struct rtinfo *rti) return (0); } -#endif static int action_show_prefix(struct prefix *pfx) @@ -726,17 +819,17 @@ action_show_rdnss(void *msg) { struct rdnss *rdn; struct rdnss_addr *rda; - u_int16_t *rdn_cnt; - u_int16_t *rda_cnt; + uint16_t *rdn_cnt; + uint16_t *rda_cnt; int i; int j; char *p; - u_int32_t ltime; + uint32_t ltime; char ntopbuf[INET6_ADDRSTRLEN]; char ssbuf[SSBUFLEN]; p = msg; - rdn_cnt = (u_int16_t *)p; + rdn_cnt = (uint16_t *)p; p += sizeof(*rdn_cnt); if (*rdn_cnt > 0) { @@ -745,7 +838,7 @@ action_show_rdnss(void *msg) ltime = rdn->rd_ltime; p += sizeof(*rdn); - rda_cnt = (u_int16_t *)p; + rda_cnt = (uint16_t *)p; p += sizeof(*rda_cnt); if (*rda_cnt > 0) for (j = 0; j < *rda_cnt; j++) { @@ -769,17 +862,17 @@ action_show_dnssl(void *msg) { struct dnssl *dns; struct dnssl_addr *dna; - u_int16_t *dns_cnt; - u_int16_t *dna_cnt; + uint16_t *dns_cnt; + uint16_t *dna_cnt; int i; int j; char *p; - u_int32_t ltime; + uint32_t ltime; char hbuf[NI_MAXHOST]; char ssbuf[SSBUFLEN]; p = msg; - dns_cnt = (u_int16_t *)p; + dns_cnt = (uint16_t *)p; p += sizeof(*dns_cnt); if (*dns_cnt > 0) { @@ -788,7 +881,7 @@ action_show_dnssl(void *msg) ltime = dns->dn_ltime; p += sizeof(*dns); - dna_cnt = (u_int16_t *)p; + dna_cnt = (uint16_t *)p; p += sizeof(*dna_cnt); if (*dna_cnt > 0) for (j = 0; j < *dna_cnt; j++) { Modified: head/usr.sbin/rtadvd/Makefile ============================================================================== --- head/usr.sbin/rtadvd/Makefile Sun Jul 17 18:51:51 2011 (r224143) +++ head/usr.sbin/rtadvd/Makefile Sun Jul 17 19:24:54 2011 (r224144) @@ -16,12 +16,13 @@ PROG= rtadvd MAN= rtadvd.conf.5 rtadvd.8 -SRCS= rtadvd.c rrenum.c advcap.c if.c config.c timer.c dump.c +SRCS= rtadvd.c rrenum.c advcap.c if.c config.c timer.c timer_subr.c \ + control.c control_server.c DPADD= ${LIBUTIL} LDADD= -lutil -CFLAGS+= -DHAVE_ARC4RANDOM -DHAVE_POLL_H -DROUTEINFO +CFLAGS+= -DHAVE_ARC4RANDOM WARNS?= 1 Modified: head/usr.sbin/rtadvd/config.c ============================================================================== --- head/usr.sbin/rtadvd/config.c Sun Jul 17 18:51:51 2011 (r224143) +++ head/usr.sbin/rtadvd/config.c Sun Jul 17 19:24:54 2011 (r224144) @@ -3,6 +3,7 @@ /* * Copyright (C) 1998 WIDE Project. + * Copyright (C) 2011 Hiroki Sato * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -52,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -130,48 +132,153 @@ dname_labelenc(char *dst, const char *sr var = def; \ } while (0) -#define ELM_MALLOC(p,error_action) \ - do { \ - p = malloc(sizeof(*p)); \ - if (p == NULL) { \ - syslog(LOG_ERR, "<%s> malloc failed: %s", \ - __func__, strerror(errno)); \ - error_action; \ - } \ - memset(p, 0, sizeof(*p)); \ - } while(0) +int +loadconfig_index(int idx) +{ + char ifname[IFNAMSIZ]; + + syslog(LOG_DEBUG, "<%s> enter", __func__); + + if (if_indextoname(idx, ifname) != NULL) + return (loadconfig_ifname(ifname)); + else + return (1); +} int -loadconfig(char *ifl_names[], const int ifl_len) +loadconfig_ifname(char *ifname) { - int i; - int idx; - int error; + struct ifinfo *ifi; + + syslog(LOG_DEBUG, "<%s> enter", __func__); + + update_ifinfo(&ifilist, UPDATE_IFINFO_ALL); + TAILQ_FOREACH(ifi, &ifilist, ifi_next) { + /* NULL means all IFs will be processed. */ + if (ifname != NULL && + strcmp(ifi->ifi_ifname, ifname) != 0) + continue; + + if (!ifi->ifi_persist) { + syslog(LOG_INFO, + "<%s> %s is not a target interface. " + "Ignored at this moment.", __func__, + ifi->ifi_ifname); + continue; - for (i = 0; i < ifl_len; i++) { - idx = if_nametoindex(ifl_names[i]); - if (idx == 0) { + } + if (ifi->ifi_ifindex == 0) { syslog(LOG_ERR, - "<%s> interface %s not found. " - "Ignored at this moment.", __func__, ifl_names[i]); + "<%s> %s not found. " + "Ignored at this moment.", __func__, + ifi->ifi_ifname); continue; } - syslog(LOG_INFO, - "<%s> loading config for %s.", __func__, ifl_names[i]); - error = getconfig(idx); - if (error) + if (getconfig(ifi) == NULL) { syslog(LOG_ERR, "<%s> invalid configuration for %s. " - "Ignored at this moment.", __func__, ifl_names[i]); + "Ignored at this moment.", __func__, + ifi->ifi_ifname); + continue; + } } + return (0); +} + +int +rm_ifinfo_index(int idx) +{ + struct ifinfo *ifi; + ifi = if_indextoifinfo(idx); + if (ifi == NULL) { + syslog(LOG_ERR, "<%s>: ifinfo not found (idx=%d)", + __func__, idx); + return (-1); + } + + return (rm_ifinfo(ifi)); +} + +int +rm_ifinfo(struct ifinfo *ifi) +{ + int error; + + syslog(LOG_DEBUG, "<%s> enter (%s).", __func__, ifi->ifi_ifname); + switch (ifi->ifi_state) { + case IFI_STATE_UNCONFIGURED: + return (0); + break; + default: + ifi->ifi_state = IFI_STATE_UNCONFIGURED; + syslog(LOG_DEBUG, + "<%s> ifname=%s marked as UNCONFIGURED.", + __func__, ifi->ifi_ifname); + + /* XXX: No MC leaving here becasue index is disappeared */ + + /* Inactivate timer */ + rtadvd_remove_timer(ifi->ifi_ra_timer); + ifi->ifi_ra_timer = NULL; + break; + } + + /* clean up ifi */ + if (!ifi->ifi_persist) { + TAILQ_REMOVE(&ifilist, ifi, ifi_next); + syslog(LOG_DEBUG, "<%s>: ifinfo (idx=%d) removed.", + __func__, ifi->ifi_ifindex); + free(ifi); + } else { + /* recreate an empty entry */ + update_persist_ifinfo(&ifilist, ifi->ifi_ifname); + syslog(LOG_DEBUG, "<%s>: ifname=%s is persistent.", + __func__, ifi->ifi_ifname); + } + + /* clean up rai if any */ + switch (ifi->ifi_state) { + case IFI_STATE_CONFIGURED: + if (ifi->ifi_rainfo != NULL) { + error = rm_rainfo(ifi->ifi_rainfo); + if (error) + return (error); + ifi->ifi_rainfo = NULL; + } + break; + case IFI_STATE_TRANSITIVE: + if (ifi->ifi_rainfo == ifi->ifi_rainfo_trans) { + if (ifi->ifi_rainfo != NULL) { + error = rm_rainfo(ifi->ifi_rainfo); + if (error) + return (error); + ifi->ifi_rainfo = NULL; + ifi->ifi_rainfo_trans = NULL; + } + } else { + if (ifi->ifi_rainfo != NULL) { + error = rm_rainfo(ifi->ifi_rainfo); + if (error) + return (error); + ifi->ifi_rainfo = NULL; + } + if (ifi->ifi_rainfo_trans != NULL) { + error = rm_rainfo(ifi->ifi_rainfo_trans); + if (error) + return (error); + ifi->ifi_rainfo_trans = NULL; + } + } + } + + syslog(LOG_DEBUG, "<%s> leave (%s).", __func__, ifi->ifi_ifname); return (0); } int -rmconfig(int idx) +rm_rainfo(struct rainfo *rai) { - struct rainfo *rai; struct prefix *pfx; struct soliciter *sol; struct rdnss *rdn; @@ -179,26 +286,16 @@ rmconfig(int idx) struct dnssl *dns; struct rtinfo *rti; - rai = if_indextorainfo(idx); - if (rai == NULL) { - syslog(LOG_ERR, "<%s>: rainfo not found (idx=%d)", - __func__, idx); - return (-1); - } + syslog(LOG_DEBUG, "<%s>: enter", __func__); TAILQ_REMOVE(&railist, rai, rai_next); - syslog(LOG_DEBUG, "<%s>: rainfo (idx=%d) removed.", - __func__, idx); - - /* Free all of allocated memories for this entry. */ - rtadvd_remove_timer(rai->rai_timer); + if (rai->rai_ifinfo != NULL) + syslog(LOG_DEBUG, "<%s>: rainfo (idx=%d) removed.", + __func__, rai->rai_ifinfo->ifi_ifindex); if (rai->rai_ra_data != NULL) free(rai->rai_ra_data); - if (rai->rai_sdl != NULL) - free(rai->rai_sdl); - while ((pfx = TAILQ_FIRST(&rai->rai_prefix)) != NULL) { TAILQ_REMOVE(&rai->rai_prefix, pfx, pfx_next); free(pfx); @@ -224,51 +321,51 @@ rmconfig(int idx) free(rti); } free(rai); - + syslog(LOG_DEBUG, "<%s>: leave", __func__); + return (0); } -int -getconfig(int idx) +struct ifinfo * +getconfig(struct ifinfo *ifi) { int stat, i; + int error; char tbuf[BUFSIZ]; struct rainfo *rai; struct rainfo *rai_old; - long val; + int32_t val; int64_t val64; char buf[BUFSIZ]; char *bp = buf; char *addr, *flagstr; - char intface[IFNAMSIZ]; - if (if_indextoname(idx, intface) == NULL) { - syslog(LOG_ERR, "<%s> invalid index number (%d)", - __func__, idx); - return (-1); - } + if (ifi == NULL) /* if does not exist */ + return (NULL); - TAILQ_FOREACH(rai_old, &railist, rai_next) - if (idx == rai_old->rai_ifindex) - break; + if (ifi->ifi_state == IFI_STATE_TRANSITIVE && + ifi->ifi_rainfo == NULL) { + syslog(LOG_INFO, "<%s> %s is shutting down. Skipped.", + __func__, ifi->ifi_ifname); + return (NULL); + } - if ((stat = agetent(tbuf, intface)) <= 0) { + if ((stat = agetent(tbuf, ifi->ifi_ifname)) <= 0) { memset(tbuf, 0, sizeof(tbuf)); syslog(LOG_INFO, "<%s> %s isn't defined in the configuration file" " or the configuration file doesn't exist." " Treat it as default", - __func__, intface); + __func__, ifi->ifi_ifname); } ELM_MALLOC(rai, exit(1)); TAILQ_INIT(&rai->rai_prefix); -#ifdef ROUTEINFO TAILQ_INIT(&rai->rai_route); -#endif TAILQ_INIT(&rai->rai_rdnss); TAILQ_INIT(&rai->rai_dnssl); TAILQ_INIT(&rai->rai_soliciter); + rai->rai_ifinfo = ifi; /* gather on-link prefixes from the network interfaces. */ if (agetflag("noifprefix")) @@ -282,25 +379,12 @@ getconfig(int idx) else rai->rai_advlinkopt = 1; if (rai->rai_advlinkopt) { - if ((rai->rai_sdl = if_nametosdl(intface)) == NULL) { + if (ifi->ifi_sdl.sdl_type == 0) { syslog(LOG_ERR, "<%s> can't get information of %s", - __func__, intface); + __func__, ifi->ifi_ifname); goto getconfig_free_rai; } - rai->rai_ifindex = rai->rai_sdl->sdl_index; - } else - rai->rai_ifindex = if_nametoindex(intface); - strncpy(rai->rai_ifname, intface, sizeof(rai->rai_ifname)); - syslog(LOG_DEBUG, - "<%s> ifindex = %d on %s", __func__, rai->rai_ifindex, - rai->rai_ifname); - - if ((rai->rai_phymtu = if_getmtu(intface)) == 0) { - rai->rai_phymtu = IPV6_MMTU; - syslog(LOG_WARNING, - "<%s> can't get interface mtu of %s. Treat as %d", - __func__, intface, IPV6_MMTU); } /* @@ -309,24 +393,24 @@ getconfig(int idx) MAYHAVE(val, "maxinterval", DEF_MAXRTRADVINTERVAL); if (val < MIN_MAXINTERVAL || val > MAX_MAXINTERVAL) { syslog(LOG_ERR, - "<%s> maxinterval (%ld) on %s is invalid " + "<%s> maxinterval (%" PRIu32 ") on %s is invalid " "(must be between %u and %u)", __func__, val, - intface, MIN_MAXINTERVAL, MAX_MAXINTERVAL); + ifi->ifi_ifname, MIN_MAXINTERVAL, MAX_MAXINTERVAL); goto getconfig_free_rai; } - rai->rai_maxinterval = (u_int)val; + rai->rai_maxinterval = (uint16_t)val; MAYHAVE(val, "mininterval", rai->rai_maxinterval/3); - if ((u_int)val < MIN_MININTERVAL || - (u_int)val > (rai->rai_maxinterval * 3) / 4) { + if ((uint16_t)val < MIN_MININTERVAL || + (uint16_t)val > (rai->rai_maxinterval * 3) / 4) { syslog(LOG_ERR, - "<%s> mininterval (%ld) on %s is invalid " + "<%s> mininterval (%" PRIu32 ") on %s is invalid " "(must be between %d and %d)", - __func__, val, intface, MIN_MININTERVAL, + __func__, val, ifi->ifi_ifname, MIN_MININTERVAL, (rai->rai_maxinterval * 3) / 4); goto getconfig_free_rai; } - rai->rai_mininterval = (u_int)val; + rai->rai_mininterval = (uint16_t)val; MAYHAVE(val, "chlim", DEF_ADVCURHOPLIMIT); rai->rai_hoplimit = val & 0xff; @@ -359,17 +443,17 @@ getconfig(int idx) rai->rai_rtpref = val & ND_RA_FLAG_RTPREF_MASK; if (rai->rai_rtpref == ND_RA_FLAG_RTPREF_RSV) { syslog(LOG_ERR, "<%s> invalid router preference (%02x) on %s", - __func__, rai->rai_rtpref, intface); + __func__, rai->rai_rtpref, ifi->ifi_ifname); goto getconfig_free_rai; } MAYHAVE(val, "rltime", rai->rai_maxinterval * 3); - if ((u_int)val && ((u_int)val < rai->rai_maxinterval || - (u_int)val > MAXROUTERLIFETIME)) { + if ((uint16_t)val && ((uint16_t)val < rai->rai_maxinterval || + (uint16_t)val > MAXROUTERLIFETIME)) { syslog(LOG_ERR, - "<%s> router lifetime (%ld) on %s is invalid " + "<%s> router lifetime (%" PRIu32 ") on %s is invalid " "(must be 0 or between %d and %d)", - __func__, val, intface, rai->rai_maxinterval, + __func__, val, ifi->ifi_ifname, rai->rai_maxinterval, MAXROUTERLIFETIME); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***