git: 231bac4ccc43 - main - rtsol/rtsold: Add option to skip random delay

From: Colin Percival <cperciva_at_FreeBSD.org>
Date: Tue, 16 Nov 2021 18:27:37 UTC
The branch main has been updated by cperciva:

URL: https://cgit.FreeBSD.org/src/commit/?id=231bac4ccc431381d70c966a5bd5a95fbfc1f163

commit 231bac4ccc431381d70c966a5bd5a95fbfc1f163
Author:     Colin Percival <cperciva@FreeBSD.org>
AuthorDate: 2021-11-16 18:24:05 +0000
Commit:     Colin Percival <cperciva@FreeBSD.org>
CommitDate: 2021-11-16 18:27:28 +0000

    rtsol/rtsold: Add option to skip random delay
    
    In accordance with a SHOULD in RFC 4861, rtsol and rtsold wait a
    random time between zero and one (aka MAX_RTR_SOLICITATION_DELAY)
    seconds before sending a Router Solicitation, in order to avoid
    network congestion if many hosts come online at once.  (The
    question of how many hosts would be required to cause congestion
    by each sending a single packet on a Gbps+ network is left to the
    reader.)
    
    The new option -i disables this wait and instructs rtsol and rtsold
    to send the Router Solicitation immediately.
    
    Reviewed by:    bz, kp (earlier version)
    MFC after:      1 week
    Relnotes:       yes
    Sponsored by:   https://www.patreon.com/cperciva
    Differential Revision:  https://reviews.freebsd.org/D32956
---
 usr.sbin/rtsold/rtsold.8 | 16 +++++++++++-----
 usr.sbin/rtsold/rtsold.c | 13 ++++++++++---
 2 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/usr.sbin/rtsold/rtsold.8 b/usr.sbin/rtsold/rtsold.8
index 84e4d3013ef4..6b0e64ab0fac 100644
--- a/usr.sbin/rtsold/rtsold.8
+++ b/usr.sbin/rtsold/rtsold.8
@@ -29,7 +29,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd August 14, 2021
+.Dd November 12, 2021
 .Dt RTSOLD 8
 .Os
 .\"
@@ -39,27 +39,27 @@
 .\"
 .Sh SYNOPSIS
 .Nm
-.Op Fl dDfFmu1
+.Op Fl dDfFimu1
 .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 dDfFimu1
 .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 dDiu
 .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 dDiu
 .Op Fl M Ar script-name
 .Op Fl O Ar script-name
 .Op Fl R Ar script-name
@@ -194,6 +194,12 @@ The settings may be changed manually with
 .Xr sysctl 8
 and
 .Xr ifconfig 8 .
+.It Fl i
+Transmit Router Solicitation packets immediately, without waiting the
+normal random (between 0 and 1 second) delay.
+This option should not be used on networks where it might result in
+congestion due to many hosts simultaneously (re)connecting and
+sending such packets.
 .It Fl m
 Enable mobility support.
 If this option is specified,
diff --git a/usr.sbin/rtsold/rtsold.c b/usr.sbin/rtsold/rtsold.c
index 592321f59aca..f1ba3b07c879 100644
--- a/usr.sbin/rtsold/rtsold.c
+++ b/usr.sbin/rtsold/rtsold.c
@@ -99,6 +99,7 @@ cap_channel_t *capllflags, *capscript, *capsendmsg, *capsyslog;
 
 /* static variables and functions */
 static int mobile_node = 0;
+static int no_solicitation_delay = 0;
 
 static sig_atomic_t do_dump, do_exit;
 static struct pidfh *pfh;
@@ -125,11 +126,11 @@ main(int argc, char **argv)
 
 	progname = basename(argv[0]);
 	if (strcmp(progname, "rtsold") == 0) {
-		opts = "adDfFm1M:O:p:R:u";
+		opts = "adDfFim1M:O:p:R:u";
 		once = 0;
 		pidfilepath = NULL;
 	} else {
-		opts = "adDFM:O:R:u";
+		opts = "adDFiM:O:R:u";
 		fflag = 1;
 		once = 1;
 	}
@@ -151,6 +152,9 @@ main(int argc, char **argv)
 		case 'F':
 			Fflag = 1;
 			break;
+		case 'i':
+			no_solicitation_delay = 1;
+			break;
 		case 'm':
 			mobile_node = 1;
 			break;
@@ -717,7 +721,10 @@ rtsol_timer_update(struct ifinfo *ifi)
 			ifi->timer = tm_max;	/* stop timer(valid?) */
 		break;
 	case IFS_DELAY:
-		interval = arc4random_uniform(MAX_RTR_SOLICITATION_DELAY * MILLION);
+		if (no_solicitation_delay)
+			interval = 0;
+		else
+			interval = arc4random_uniform(MAX_RTR_SOLICITATION_DELAY * MILLION);
 		ifi->timer.tv_sec = interval / MILLION;
 		ifi->timer.tv_nsec = (interval % MILLION) * 1000;
 		break;