From owner-svn-src-all@FreeBSD.ORG Mon Sep 12 23:55:23 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 89CEE1065673; Mon, 12 Sep 2011 23:55:23 +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 78FCD8FC15; Mon, 12 Sep 2011 23:55:23 +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 p8CNtNr9047886; Mon, 12 Sep 2011 23:55:23 GMT (envelope-from hrs@svn.freebsd.org) Received: (from hrs@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p8CNtNUw047881; Mon, 12 Sep 2011 23:55:23 GMT (envelope-from hrs@svn.freebsd.org) Message-Id: <201109122355.p8CNtNUw047881@svn.freebsd.org> From: Hiroki Sato Date: Mon, 12 Sep 2011 23:55:23 +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: r225520 - head/usr.sbin/rtsold X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 12 Sep 2011 23:55:23 -0000 Author: hrs Date: Mon Sep 12 23:55:23 2011 New Revision: 225520 URL: http://svn.freebsd.org/changeset/base/225520 Log: - Add ":origin" label to the interface id for resolvconf(8). (r223149) - Add -u option to enable adding :[RA-source-address] to the interface id. (r223149) - s/INET6_ADDRSTRLEN/sizeof(ntopbuf)/ (r223149) - Fix a bug that can prevent -D from being overridden by -d. (r223149) - /-P pidfile/-p pidfile/ for consistency with rtadvd(8). (r223149) - Fix -F flag handling to support receiving RAs even when ip6.forwarding=1. (r225150) Approved by: re (kib) Modified: head/usr.sbin/rtsold/rtsol.c head/usr.sbin/rtsold/rtsold.8 head/usr.sbin/rtsold/rtsold.c head/usr.sbin/rtsold/rtsold.h Directory Properties: head/usr.sbin/rtsold/ (props changed) Modified: head/usr.sbin/rtsold/rtsol.c ============================================================================== --- head/usr.sbin/rtsold/rtsol.c Mon Sep 12 23:52:55 2011 (r225519) +++ head/usr.sbin/rtsold/rtsol.c Mon Sep 12 23:55:23 2011 (r225520) @@ -73,6 +73,7 @@ static struct sockaddr_in6 from; static int rcvcmsglen; int rssock; +static char rsid[IFNAMSIZ + 1 + sizeof(DNSINFO_ORIGIN_LABEL) + 1 + NI_MAXHOST]; struct ifinfo_head_t ifinfo_head = TAILQ_HEAD_INITIALIZER(ifinfo_head); @@ -82,14 +83,18 @@ static const struct sockaddr_in6 sin6_al .sin6_addr = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT, }; -static void call_script(const int, const char *const *, void *); +static void call_script(const int, const char *const *, + struct script_msg_head_t *); static size_t dname_labeldec(char *, size_t, const char *); static int safefile(const char *); static struct ra_opt *find_raopt(struct rainfo *, int, void *, size_t); +static int ra_opt_rdnss_dispatch(struct ifinfo *, struct rainfo *, + struct script_msg_head_t *, struct script_msg_head_t *); +static char *make_rsid(const char *, const char *, struct rainfo *); #define _ARGS_OTHER otherconf_script, ifi->ifname -#define _ARGS_RESADD resolvconf_script, "-a", ifi->ifname -#define _ARGS_RESDEL resolvconf_script, "-d", ifi->ifname +#define _ARGS_RESADD resolvconf_script, "-a", rsid +#define _ARGS_RESDEL resolvconf_script, "-d", rsid #define CALL_SCRIPT(name, sm_head) \ do { \ @@ -306,7 +311,7 @@ rtsol_input(int s) warnmsg(LOG_ERR, __func__, "invalid icmp type(%d) from %s on %s", icp->icmp6_type, inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, - INET6_ADDRSTRLEN), + sizeof(ntopbuf)), if_indextoname(pi->ipi6_ifindex, ifnamebuf)); return; } @@ -315,7 +320,7 @@ rtsol_input(int s) warnmsg(LOG_INFO, __func__, "invalid icmp code(%d) from %s on %s", icp->icmp6_code, inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, - INET6_ADDRSTRLEN), + sizeof(ntopbuf)), if_indextoname(pi->ipi6_ifindex, ifnamebuf)); return; } @@ -325,7 +330,7 @@ rtsol_input(int s) "invalid RA with hop limit(%d) from %s on %s", *hlimp, inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, - INET6_ADDRSTRLEN), + sizeof(ntopbuf)), if_indextoname(pi->ipi6_ifindex, ifnamebuf)); return; } @@ -334,7 +339,7 @@ rtsol_input(int s) warnmsg(LOG_INFO, __func__, "invalid RA with non link-local source from %s on %s", inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, - INET6_ADDRSTRLEN), + sizeof(ntopbuf)), if_indextoname(pi->ipi6_ifindex, ifnamebuf)); return; } @@ -345,14 +350,14 @@ rtsol_input(int s) warnmsg(LOG_INFO, __func__, "received RA from %s on an unexpected IF(%s)", inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, - INET6_ADDRSTRLEN), + sizeof(ntopbuf)), if_indextoname(pi->ipi6_ifindex, ifnamebuf)); return; } warnmsg(LOG_DEBUG, __func__, "received RA from %s on %s, state is %d", - inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, INET6_ADDRSTRLEN), + inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, sizeof(ntopbuf)), ifi->ifname, ifi->state); nd_ra = (struct nd_router_advert *)icp; @@ -378,6 +383,8 @@ rtsol_input(int s) ELM_MALLOC(rai, exit(1)); rai->rai_ifinfo = ifi; TAILQ_INIT(&rai->rai_ra_opt); + rai->rai_saddr.sin6_family = AF_INET6; + rai->rai_saddr.sin6_len = sizeof(rai->rai_saddr); memcpy(&rai->rai_saddr.sin6_addr, &from.sin6_addr, sizeof(rai->rai_saddr.sin6_addr)); newent_rai = 1; @@ -406,19 +413,19 @@ rtsol_input(int s) "too short RDNSS option" "in RA from %s was ignored.", inet_ntop(AF_INET6, &from.sin6_addr, - ntopbuf, INET6_ADDRSTRLEN)); + ntopbuf, sizeof(ntopbuf))); break; } addr = (struct in6_addr *)(raoptp + sizeof(*rdnss)); while ((char *)addr < (char *)RA_OPT_NEXT_HDR(raoptp)) { if (inet_ntop(AF_INET6, addr, ntopbuf, - INET6_ADDRSTRLEN) == NULL) { + sizeof(ntopbuf)) == NULL) { warnmsg(LOG_INFO, __func__, "an invalid address in RDNSS option" " in RA from %s was ignored.", inet_ntop(AF_INET6, &from.sin6_addr, - ntopbuf, INET6_ADDRSTRLEN)); + ntopbuf, sizeof(ntopbuf))); addr++; continue; } @@ -482,7 +489,7 @@ rtsol_input(int s) "too short DNSSL option" "in RA from %s was ignored.", inet_ntop(AF_INET6, &from.sin6_addr, - ntopbuf, INET6_ADDRSTRLEN)); + ntopbuf, sizeof(ntopbuf))); break; } @@ -568,10 +575,11 @@ ra_opt_handler(struct ifinfo *ifi) struct rainfo *rai; struct script_msg *smp1, *smp2, *smp3; struct timeval now; - TAILQ_HEAD(, script_msg) sm_rdnss_head = - TAILQ_HEAD_INITIALIZER(sm_rdnss_head); - TAILQ_HEAD(, script_msg) sm_dnssl_head = - TAILQ_HEAD_INITIALIZER(sm_dnssl_head); + struct script_msg_head_t sm_rdnss_head = + TAILQ_HEAD_INITIALIZER(sm_rdnss_head); + struct script_msg_head_t sm_dnssl_head = + TAILQ_HEAD_INITIALIZER(sm_dnssl_head); + int dcount, dlen; dcount = 0; @@ -658,17 +666,69 @@ free2: free1: free(smp1); } + /* Call the script for each information source. */ + if (uflag) + ra_opt_rdnss_dispatch(ifi, rai, &sm_rdnss_head, + &sm_dnssl_head); + } + /* Call the script for each interface. */ + if (!uflag) + ra_opt_rdnss_dispatch(ifi, NULL, &sm_rdnss_head, + &sm_dnssl_head); + return (0); +} + +char * +make_rsid(const char *ifname, const char *origin, struct rainfo *rai) +{ + char hbuf[NI_MAXHOST]; + + if (rai == NULL) + sprintf(rsid, "%s:%s", ifname, origin); + else { + if (!IN6_IS_ADDR_LINKLOCAL(&rai->rai_saddr.sin6_addr)) + return (NULL); + if (getnameinfo((struct sockaddr *)&rai->rai_saddr, + rai->rai_saddr.sin6_len, hbuf, sizeof(hbuf), NULL, 0, + NI_NUMERICHOST) != 0) + return (NULL); + sprintf(rsid, "%s:%s:[%s]", ifname, origin, hbuf); } + warnmsg(LOG_DEBUG, __func__, "rsid = [%s]", rsid); + return (rsid); +} + +int +ra_opt_rdnss_dispatch(struct ifinfo *ifi, + struct rainfo *rai, + struct script_msg_head_t *sm_rdnss_head, + struct script_msg_head_t *sm_dnssl_head) +{ + const char *r; + struct script_msg *smp1; + int error; + + error = 0; /* Add \n for DNSSL list. */ - if (!TAILQ_EMPTY(&sm_dnssl_head)) { - ELM_MALLOC(smp1, goto ra_opt_handler_freeit); + if (!TAILQ_EMPTY(sm_dnssl_head)) { + ELM_MALLOC(smp1, goto ra_opt_rdnss_freeit); smp1->sm_msg = resstr_nl; - TAILQ_INSERT_TAIL(&sm_dnssl_head, smp1, sm_next); + TAILQ_INSERT_TAIL(sm_dnssl_head, smp1, sm_next); } - TAILQ_CONCAT(&sm_rdnss_head, &sm_dnssl_head, sm_next); + TAILQ_CONCAT(sm_rdnss_head, sm_dnssl_head, sm_next); - if (!TAILQ_EMPTY(&sm_rdnss_head)) - CALL_SCRIPT(RESADD, &sm_rdnss_head); + if (rai != NULL && uflag) + r = make_rsid(ifi->ifname, DNSINFO_ORIGIN_LABEL, rai); + else + r = make_rsid(ifi->ifname, DNSINFO_ORIGIN_LABEL, NULL); + if (r == NULL) { + warnmsg(LOG_ERR, __func__, "make_rsid() failed. " + "Script was not invoked."); + error = 1; + goto ra_opt_rdnss_freeit; + } + if (!TAILQ_EMPTY(sm_rdnss_head)) + CALL_SCRIPT(RESADD, sm_rdnss_head); else if (ifi->ifi_rdnss == IFI_DNSOPT_STATE_RECEIVED || ifi->ifi_dnssl == IFI_DNSOPT_STATE_RECEIVED) { CALL_SCRIPT(RESDEL, NULL); @@ -676,21 +736,21 @@ free1: ifi->ifi_dnssl = IFI_DNSOPT_STATE_NOINFO; } -ra_opt_handler_freeit: +ra_opt_rdnss_freeit: /* Clear script message queue. */ - if (!TAILQ_EMPTY(&sm_rdnss_head)) { - while ((smp1 = TAILQ_FIRST(&sm_rdnss_head)) != NULL) { - TAILQ_REMOVE(&sm_rdnss_head, smp1, sm_next); + if (!TAILQ_EMPTY(sm_rdnss_head)) { + while ((smp1 = TAILQ_FIRST(sm_rdnss_head)) != NULL) { + TAILQ_REMOVE(sm_rdnss_head, smp1, sm_next); free(smp1); } } - if (!TAILQ_EMPTY(&sm_dnssl_head)) { - while ((smp1 = TAILQ_FIRST(&sm_dnssl_head)) != NULL) { - TAILQ_REMOVE(&sm_dnssl_head, smp1, sm_next); + if (!TAILQ_EMPTY(sm_dnssl_head)) { + while ((smp1 = TAILQ_FIRST(sm_dnssl_head)) != NULL) { + TAILQ_REMOVE(sm_dnssl_head, smp1, sm_next); free(smp1); } } - return (0); + return (error); } static struct ra_opt * @@ -709,19 +769,18 @@ find_raopt(struct rainfo *rai, int type, } static void -call_script(const int argc, const char *const argv[], void *head) +call_script(const int argc, const char *const argv[], + struct script_msg_head_t *sm_head) { const char *scriptpath; int fd[2]; int error; pid_t pid, wpid; - TAILQ_HEAD(, script_msg) *sm_head; if ((scriptpath = argv[0]) == NULL) return; fd[0] = fd[1] = -1; - sm_head = head; if (sm_head != NULL && !TAILQ_EMPTY(sm_head)) { error = pipe(fd); if (error) { Modified: head/usr.sbin/rtsold/rtsold.8 ============================================================================== --- head/usr.sbin/rtsold/rtsold.8 Mon Sep 12 23:52:55 2011 (r225519) +++ head/usr.sbin/rtsold/rtsold.8 Mon Sep 12 23:55:23 2011 (r225520) @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 28, 2011 +.Dd June 14, 2011 .Dt RTSOLD 8 .Os .\" @@ -39,24 +39,24 @@ .\" .Sh SYNOPSIS .Nm -.Op Fl dDfFm1 +.Op Fl dDfFmu1 .Op Fl O Ar script-name -.Op Fl P Ar pidfile +.Op Fl p Ar pidfile .Op Fl R Ar script-name .Ar interface ... .Nm -.Op Fl dDfFm1 +.Op Fl dDfFmu1 .Op Fl O Ar script-name -.Op Fl P Ar pidfile +.Op Fl p Ar pidfile .Op Fl R Ar script-name .Fl a .Nm rtsol -.Op Fl dD +.Op Fl dDu .Op Fl O Ar script-name .Op Fl R Ar script-name .Ar interface ... .Nm rtsol -.Op Fl dD +.Op Fl dDu .Op Fl O Ar script-name .Op Fl R Ar script-name .Fl a @@ -227,7 +227,7 @@ configuration. must be the absolute path from root to the script file, be a regular file, and be created by the same owner who runs .Nm . -.It Fl P Ar pidfile +.It Fl p Ar pidfile Writes the process ID of .Nm to @@ -245,6 +245,18 @@ standard input of this script. The .Xr resolvconf 8 script is used by default. +.It Fl u +Specifies whether adding the source address of Router Advertisement +messages to the interface name in an argument of the RDNSS and DNSSL +script. +.Pp +If +.Fl u +is specified, the interface name in the script argument will be +.Ql ifname:slaac:[RA-source-address] . +.Pp +If not, it will be +.Ql ifname:slaac . .El .Sh FILES .Bl -tag -width /var/run/rtsold.dump -compact Modified: head/usr.sbin/rtsold/rtsold.c ============================================================================== --- head/usr.sbin/rtsold/rtsold.c Mon Sep 12 23:52:55 2011 (r225519) +++ head/usr.sbin/rtsold/rtsold.c Mon Sep 12 23:55:23 2011 (r225520) @@ -75,6 +75,7 @@ static int fflag = 0; int Fflag = 0; /* force setting sysctl parameters */ int aflag = 0; int dflag = 0; +int uflag = 0; const char *otherconf_script; const char *resolvconf_script = "/sbin/resolvconf"; @@ -129,10 +130,10 @@ main(int argc, char **argv) #ifndef SMALL /* rtsold */ - opts = "adDfFm1O:P:R:"; + opts = "adDfFm1O:p:R:u"; #else /* rtsol */ - opts = "adDFO:P:R:"; + opts = "adDFO:R:u"; fflag = 1; once = 1; #endif @@ -144,10 +145,10 @@ main(int argc, char **argv) aflag = 1; break; case 'd': - dflag = 1; + dflag += 1; break; case 'D': - dflag = 2; + dflag += 2; break; case 'f': fflag = 1; @@ -164,12 +165,15 @@ main(int argc, char **argv) case 'O': otherconf_script = optarg; break; - case 'P': + case 'p': pidfilename = optarg; break; case 'R': resolvconf_script = optarg; break; + case 'u': + uflag = 1; + break; default: usage(); exit(1); @@ -184,8 +188,13 @@ main(int argc, char **argv) } /* set log level */ - if (dflag == 0) + if (dflag > 1) + log_upto = LOG_DEBUG; + else if (dflag > 0) + log_upto = LOG_INFO; + else log_upto = LOG_NOTICE; + if (!fflag) { char *ident; @@ -216,6 +225,7 @@ main(int argc, char **argv) srandom((u_long)time(NULL)); #endif +#if (__FreeBSD_version < 900000) if (Fflag) { setinet6sysctl(IPV6CTL_FORWARDING, 0); } else { @@ -223,6 +233,7 @@ main(int argc, char **argv) if (getinet6sysctl(IPV6CTL_FORWARDING)) warnx("kernel is configured as a router, not a host"); } +#endif #ifndef SMALL /* initialization to dump internal status to a file */ @@ -402,6 +413,32 @@ ifconfig(char *ifname) return (-1); } + if (Fflag) { + struct in6_ndireq nd; + int s; + + if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { + warnmsg(LOG_ERR, __func__, "socket() failed."); + return (-1); + } + memset(&nd, 0, sizeof(nd)); + strlcpy(nd.ifname, ifname, sizeof(nd.ifname)); + if (ioctl(s, SIOCGIFINFO_IN6, (caddr_t)&nd) < 0) { + warnmsg(LOG_ERR, __func__, + "cannot get accept_rtadv flag"); + close(s); + return (-1); + } + nd.ndi.flags |= ND6_IFF_ACCEPT_RTADV; + if (ioctl(s, SIOCSIFINFO_IN6, (caddr_t)&nd) < 0) { + warnmsg(LOG_ERR, __func__, + "cannot set accept_rtadv flag"); + close(s); + return (-1); + } + close(s); + } + if ((ifi = malloc(sizeof(*ifi))) == NULL) { warnmsg(LOG_ERR, __func__, "memory allocation failed"); free(sdl); Modified: head/usr.sbin/rtsold/rtsold.h ============================================================================== --- head/usr.sbin/rtsold/rtsold.h Mon Sep 12 23:52:55 2011 (r225519) +++ head/usr.sbin/rtsold/rtsold.h Mon Sep 12 23:55:23 2011 (r225520) @@ -37,6 +37,8 @@ struct script_msg { char *sm_msg; }; +TAILQ_HEAD(script_msg_head_t, script_msg); + struct ra_opt { TAILQ_ENTRY(ra_opt) rao_next; @@ -60,7 +62,7 @@ struct ifinfo { TAILQ_ENTRY(ifinfo) ifi_next; /* pointer to the next interface */ struct sockaddr_dl *sdl; /* link-layer address */ - char ifname[IF_NAMESIZE]; /* interface name */ + char ifname[IFNAMSIZ]; /* interface name */ u_int32_t linkid; /* link ID of this interface */ int active; /* interface status */ int probeinterval; /* interval of probe timer (if necessary) */ @@ -96,6 +98,7 @@ struct ifinfo { /* Interface list */ extern TAILQ_HEAD(ifinfo_head_t, ifinfo) ifinfo_head; +#define DNSINFO_ORIGIN_LABEL "slaac" /* * RFC 3542 API deprecates IPV6_PKTINFO in favor of * IPV6_RECVPKTINFO @@ -126,6 +129,7 @@ extern struct timeval tm_max; extern int dflag; extern int aflag; extern int Fflag; +extern int uflag; extern const char *otherconf_script; extern const char *resolvconf_script; extern int ifconfig(char *);