rtsol(d): add script for "M bit"

While we do support the "O bit" running a script (usually to start a
dhcpv6 client) we have no options for setups which set the "M bit" for,
e.g., static address assignment as in EC2.

Duplicate most of the "O bit" logic to also start a script for the
"M bit" with the one difference: if the "M bit" is set we will not
start the script for the "O bit" as well (per RFC 4861, Section 4.2).

Reviewed by:	hrs, markj
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D26099
This commit is contained in:
Bjoern A. Zeeb 2020-08-25 16:09:23 +00:00
parent ae750d5cdf
commit 60e7f66931
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=364771
5 changed files with 69 additions and 11 deletions

View file

@ -84,6 +84,8 @@ rtsold_dump(FILE *fp)
}
fprintf(fp, " interface status: %s\n",
ifi->active > 0 ? "active" : "inactive");
fprintf(fp, " managed config: %s\n",
ifi->managedconfig ? "on" : "off");
fprintf(fp, " other config: %s\n",
ifi->otherconfig ? "on" : "off");
fprintf(fp, " rtsold status: %s\n", ifstatstr[ifi->state]);

View file

@ -79,6 +79,7 @@ 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_MANAGED managedconf_script, ifi->ifname
#define _ARGS_OTHER otherconf_script, ifi->ifname
#define _ARGS_RESADD resolvconf_script, "-a", rsid
#define _ARGS_RESDEL resolvconf_script, "-d", rsid
@ -290,19 +291,37 @@ rtsol_input(int sock)
nd_ra = (struct nd_router_advert *)icp;
/*
* Process the "M bit."
* If the value of ManagedConfigFlag changes from FALSE to TRUE, the
* host should invoke the stateful autoconfiguration protocol,
* requesting information.
* [RFC 4861 Section 4.2]
* XXX ??? [draft-ietf-v6ops-dhcpv6-slaac-problem-07]
*/
if (((nd_ra->nd_ra_flags_reserved) & ND_RA_FLAG_MANAGED) &&
!ifi->managedconfig) {
warnmsg(LOG_DEBUG, __func__,
"ManagedConfigFlag on %s is turned on", ifi->ifname);
ifi->managedconfig = 1;
CALL_SCRIPT(MANAGED, NULL);
}
/*
* Process the "O bit."
* If the value of OtherConfigFlag changes from FALSE to TRUE, the
* host should invoke the stateful autoconfiguration protocol,
* requesting information.
* [RFC 2462 Section 5.5.3]
* requesting information unless the "M bit" was set as well in
* which case the "O bit" is redundant.
* [RFC 4861 Section 4.2]
*/
if (((nd_ra->nd_ra_flags_reserved) & ND_RA_FLAG_OTHER) &&
!ifi->otherconfig) {
warnmsg(LOG_DEBUG, __func__,
"OtherConfigFlag on %s is turned on", ifi->ifname);
ifi->otherconfig = 1;
CALL_SCRIPT(OTHER, NULL);
if (!ifi->managedconfig)
CALL_SCRIPT(OTHER, NULL);
}
clock_gettime(CLOCK_MONOTONIC_FAST, &now);
newent_rai = 0;

View file

@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd June 14, 2011
.Dd August 19, 2020
.Dt RTSOLD 8
.Os
.\"
@ -40,23 +40,27 @@
.Sh SYNOPSIS
.Nm
.Op Fl dDfFmu1
.Op Fl M Ar script-name
.Op Fl O Ar script-name
.Op Fl p Ar pidfile
.Op Fl R Ar script-name
.Ar interface ...
.Nm
.Op Fl dDfFmu1
.Op Fl M Ar script-name
.Op Fl O Ar script-name
.Op Fl p Ar pidfile
.Op Fl R Ar script-name
.Fl a
.Nm rtsol
.Op Fl dDu
.Op Fl M Ar script-name
.Op Fl O Ar script-name
.Op Fl R Ar script-name
.Ar interface ...
.Nm rtsol
.Op Fl dDu
.Op Fl M Ar script-name
.Op Fl O Ar script-name
.Op Fl R Ar script-name
.Fl a
@ -208,6 +212,20 @@ Transmit Router Solicitation packets until at least one valid Router
Advertisement packet has arrived on each
.Ar interface ,
then exit.
.It Fl M Ar script-name
Specifies a supplement script file to handle the Managed Configuration
flag of the router advertisement.
When the flag changes from FALSE to TRUE,
.Nm
will invoke
.Ar script-name
with a single argument of the receiving interface name,
expecting the script will then start a protocol for the managed
configuration.
.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 O Ar script-name
Specifies a supplement script file to handle the Other Configuration
flag of the router advertisement.
@ -218,6 +236,8 @@ will invoke
with a single argument of the receiving interface name,
expecting the script will then start a protocol for the other
configuration.
The script will not be run if the Managed Configuration flag in the
router advertisement is also TRUE.
.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

View file

@ -80,6 +80,7 @@ int aflag = 0;
int dflag = 0;
int uflag = 0;
const char *managedconf_script;
const char *otherconf_script;
const char *resolvconf_script = "/sbin/resolvconf";
@ -124,11 +125,11 @@ main(int argc, char **argv)
progname = basename(argv[0]);
if (strcmp(progname, "rtsold") == 0) {
opts = "adDfFm1O:p:R:u";
opts = "adDfFm1M:O:p:R:u";
once = 0;
pidfilepath = NULL;
} else {
opts = "adDFO:R:u";
opts = "adDFM:O:R:u";
fflag = 1;
once = 1;
}
@ -156,6 +157,9 @@ main(int argc, char **argv)
case '1':
once = 1;
break;
case 'M':
managedconf_script = optarg;
break;
case 'O':
otherconf_script = optarg;
break;
@ -190,6 +194,9 @@ main(int argc, char **argv)
else
log_upto = LOG_NOTICE;
if (managedconf_script != NULL && *managedconf_script != '/')
errx(1, "configuration script (%s) must be an absolute path",
managedconf_script);
if (otherconf_script != NULL && *otherconf_script != '/')
errx(1, "configuration script (%s) must be an absolute path",
otherconf_script);
@ -324,9 +331,11 @@ static int
init_capabilities(void)
{
#ifdef WITH_CASPER
const char *const scripts[2] = { resolvconf_script, otherconf_script };
const char *const scripts[] =
{ resolvconf_script, managedconf_script, otherconf_script };
cap_channel_t *capcasper;
nvlist_t *limits;
int count;
capcasper = cap_init();
if (capcasper == NULL)
@ -339,9 +348,12 @@ init_capabilities(void)
capscript = cap_service_open(capcasper, "rtsold.script");
if (capscript == NULL)
return (-1);
count = 0;
for (size_t i = 0; i < nitems(scripts); i++)
if (scripts[i] != NULL)
count++;
limits = nvlist_create(0);
nvlist_add_string_array(limits, "scripts", scripts,
otherconf_script != NULL ? 2 : 1);
nvlist_add_string_array(limits, "scripts", scripts, count);
if (cap_limit_set(capscript, limits) != 0)
return (-1);
@ -597,10 +609,12 @@ rtsol_check_timer(void)
/*
* If we need a probe, clear the previous
* status wrt the "other" configuration.
* status wrt the "managed/other" configuration.
*/
if (probe)
if (probe) {
ifi->managedconfig = 0;
ifi->otherconfig = 0;
}
if (probe && mobile_node) {
error = cap_probe_defrouters(capsendmsg,
ifi);

View file

@ -71,6 +71,8 @@ struct ifinfo {
int probeinterval; /* interval of probe timer (if necessary) */
int probetimer; /* rest of probe timer */
int mediareqok; /* whether the IF supports SIOCGIFMEDIA */
int managedconfig; /* need a separate protocol for the "managed"
* configuration */
int otherconfig; /* need a separate protocol for the "other"
* configuration */
int state;
@ -156,6 +158,7 @@ extern int dflag;
extern int aflag;
extern int Fflag;
extern int uflag;
extern const char *managedconf_script;
extern const char *otherconf_script;
extern const char *resolvconf_script;
extern struct cap_channel *capllflags, *capscript, *capsendmsg, *capsyslog;