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 *);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to