diff --git a/usr.sbin/rtsold/rtsol.c b/usr.sbin/rtsold/rtsol.c --- a/usr.sbin/rtsold/rtsol.c +++ b/usr.sbin/rtsold/rtsol.c @@ -81,6 +81,7 @@ #define _ARGS_MANAGED managedconf_script, ifi->ifname, rasender #define _ARGS_OTHER otherconf_script, ifi->ifname, rasender +#define _ARGS_ALWAYS alwaysconf_script, ifi->ifname, rasender #define _ARGS_RESADD resolvconf_script, "-a", rsid #define _ARGS_RESDEL resolvconf_script, "-d", rsid @@ -327,6 +328,17 @@ if (!ifi->managedconfig) CALL_SCRIPT(OTHER, NULL); } + + /* + * "Always" script. + */ + if (!ifi->alwaysconfig) { + const char *rasender = inet_ntop(AF_INET6, &from.sin6_addr, + ntopbuf, sizeof(ntopbuf)); + ifi->alwaysconfig = 1; + CALL_SCRIPT(ALWAYS, NULL); + } + clock_gettime(CLOCK_MONOTONIC_FAST, &now); newent_rai = 0; rai = find_rainfo(ifi, &from); diff --git a/usr.sbin/rtsold/rtsold.h b/usr.sbin/rtsold/rtsold.h --- a/usr.sbin/rtsold/rtsold.h +++ b/usr.sbin/rtsold/rtsold.h @@ -75,6 +75,7 @@ * configuration */ int otherconfig; /* need a separate protocol for the "other" * configuration */ + int alwaysconfig; /* Have we called the 'always' script? */ int state; int probes; int dadcount; @@ -160,6 +161,7 @@ extern int uflag; extern const char *managedconf_script; extern const char *otherconf_script; +extern const char *alwaysconf_script; extern const char *resolvconf_script; extern struct cap_channel *capllflags, *capscript, *capsendmsg, *capsyslog; diff --git a/usr.sbin/rtsold/rtsold.8 b/usr.sbin/rtsold/rtsold.8 --- a/usr.sbin/rtsold/rtsold.8 +++ b/usr.sbin/rtsold/rtsold.8 @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 15, 2021 +.Dd May 2, 2023 .Dt RTSOLD 8 .Os .\" @@ -42,6 +42,7 @@ .Op Fl dDfFimu1 .Op Fl M Ar script-name .Op Fl O Ar script-name +.Op Fl A Ar script-name .Op Fl p Ar pidfile .Op Fl R Ar script-name .Ar interface ... @@ -49,6 +50,7 @@ .Op Fl dDfFimu1 .Op Fl M Ar script-name .Op Fl O Ar script-name +.Op Fl A Ar script-name .Op Fl p Ar pidfile .Op Fl R Ar script-name .Fl a @@ -56,12 +58,14 @@ .Op Fl dDiu .Op Fl M Ar script-name .Op Fl O Ar script-name +.Op Fl A Ar script-name .Op Fl R Ar script-name .Ar interface ... .Nm rtsol .Op Fl dDiu .Op Fl M Ar script-name .Op Fl O Ar script-name +.Op Fl A Ar script-name .Op Fl R Ar script-name .Fl a .\" @@ -250,6 +254,18 @@ 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 A Ar script-name +Specifies a supplement script file to always be called for the router +advertisement. +.Nm +will invoke +.Ar script-name +with a first argument of the receiving interface name +and a second argument of the sending router address. +.Ar script-name +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 Writes the process ID of .Nm diff --git a/usr.sbin/rtsold/rtsold.c b/usr.sbin/rtsold/rtsold.c --- a/usr.sbin/rtsold/rtsold.c +++ b/usr.sbin/rtsold/rtsold.c @@ -82,6 +82,7 @@ const char *managedconf_script; const char *otherconf_script; +const char *alwaysconf_script; const char *resolvconf_script = "/sbin/resolvconf"; cap_channel_t *capllflags, *capscript, *capsendmsg, *capsyslog; @@ -126,11 +127,11 @@ progname = basename(argv[0]); if (strcmp(progname, "rtsold") == 0) { - opts = "adDfFim1M:O:p:R:u"; + opts = "adDfFim1M:O:A:p:R:u"; once = 0; pidfilepath = NULL; } else { - opts = "adDFiM:O:R:u"; + opts = "adDFiM:O:A:R:u"; fflag = 1; once = 1; } @@ -167,6 +168,9 @@ case 'O': otherconf_script = optarg; break; + case 'A': + alwaysconf_script = optarg; + break; case 'p': pidfilepath = optarg; break; @@ -204,6 +208,9 @@ if (otherconf_script != NULL && *otherconf_script != '/') errx(1, "configuration script (%s) must be an absolute path", otherconf_script); + if (alwaysconf_script != NULL && *alwaysconf_script != '/') + errx(1, "configuration script (%s) must be an absolute path", + alwaysconf_script); if (*resolvconf_script != '/') errx(1, "configuration script (%s) must be an absolute path", resolvconf_script); @@ -336,7 +343,8 @@ { #ifdef WITH_CASPER const char *const scripts[] = - { resolvconf_script, managedconf_script, otherconf_script }; + { resolvconf_script, managedconf_script, otherconf_script, + alwaysconf_script }; cap_channel_t *capcasper; nvlist_t *limits; @@ -616,6 +624,7 @@ if (probe) { ifi->managedconfig = 0; ifi->otherconfig = 0; + ifi->alwaysconfig = 0; } if (probe && mobile_node) { error = cap_probe_defrouters(capsendmsg, @@ -786,13 +795,17 @@ if (strcmp(progname, "rtsold") == 0) { fprintf(stderr, "usage: rtsold [-dDfFm1] [-O script-name] " + "[-M script-name ] [-A script-name ] " "[-p pidfile] [-R script-name] interface ...\n"); fprintf(stderr, "usage: rtsold [-dDfFm1] [-O script-name] " + "[-M script-name ] [-A script-name ] " "[-p pidfile] [-R script-name] -a\n"); } else { fprintf(stderr, "usage: rtsol [-dDF] [-O script-name] " + "[-M script-name ] [-A script-name ] " "[-p pidfile] [-R script-name] interface ...\n"); fprintf(stderr, "usage: rtsol [-dDF] [-O script-name] " + "[-M script-name ] [-A script-name ] " "[-p pidfile] [-R script-name] -a\n"); } exit(1);