git: 04a3ca71ead6 - main - netcat: Add a flag to enable the use of SO_REUSEPORT_LB

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Fri, 24 Jan 2025 16:48:28 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=04a3ca71ead61b4ced23a791d3a5e2633ca1ef72

commit 04a3ca71ead61b4ced23a791d3a5e2633ca1ef72
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-01-24 16:37:43 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-01-24 16:37:43 +0000

    netcat: Add a flag to enable the use of SO_REUSEPORT_LB
    
    This is handy for testing purposes.  Hide it behind a long option so
    that it doesn't conflict with upstream, like we do with several other
    flags.
    
    Reviewed by:    imp, glebius, delphij
    MFC after:      2 weeks
    Sponsored by:   Klara, Inc.
    Sponsored by:   Stormshield
    Differential Revision:  https://reviews.freebsd.org/D48543
---
 contrib/netcat/nc.1     | 9 ++++++++-
 contrib/netcat/netcat.c | 9 ++++++++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/contrib/netcat/nc.1 b/contrib/netcat/nc.1
index 2e34cdc586c3..5801c6fa00e3 100644
--- a/contrib/netcat/nc.1
+++ b/contrib/netcat/nc.1
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 17, 2023
+.Dd January 20, 2025
 .Dt NC 1
 .Os
 .Sh NAME
@@ -40,6 +40,7 @@
 .Op Fl e Ar IPsec_policy
 .Op Fl I Ar length
 .Op Fl i Ar interval
+.Op Fl -lb
 .Op Fl -no-tcpopt
 .Op Fl -sctp
 .Op Fl -crlf
@@ -175,6 +176,12 @@ options.
 Additionally, any timeouts specified with the
 .Fl w
 option are ignored.
+.It Fl -lb
+When using
+.Fl l ,
+put the socket in load-balancing mode.
+In this mode, multiple sockets can bind to the same address and port,
+and incoming connections are distributed among them.
 .It Fl M
 Collect per-connection TCP statistics using the
 .Xr stats 3
diff --git a/contrib/netcat/netcat.c b/contrib/netcat/netcat.c
index 279489a45e92..7035fdf68961 100644
--- a/contrib/netcat/netcat.c
+++ b/contrib/netcat/netcat.c
@@ -89,6 +89,7 @@ int	Fflag;					/* fdpass sock to stdout */
 unsigned int iflag;				/* Interval Flag */
 int	kflag;					/* More than one connect */
 int	lflag;					/* Bind to local port */
+int	FreeBSD_lb;				/* Use SO_REUSEPORT_LB */
 int	FreeBSD_Mflag;				/* Measure using stats(3) */
 int	Nflag;					/* shutdown() network socket */
 int	nflag;					/* Don't do name look up */
@@ -168,6 +169,7 @@ main(int argc, char *argv[])
 	char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE];
 	struct option longopts[] = {
 		{ "crlf",	no_argument,	&FreeBSD_crlf,	1 },
+		{ "lb",		no_argument,	&FreeBSD_lb, 1 },
 		{ "no-tcpopt",	no_argument,	&FreeBSD_Oflag,	1 },
 		{ "sctp",	no_argument,	&FreeBSD_sctp,	1 },
 		{ "tun",	required_argument,	NULL,	FREEBSD_TUN },
@@ -371,6 +373,8 @@ main(int argc, char *argv[])
 		errx(1, "cannot use -z and -l");
 	if (!lflag && kflag)
 		errx(1, "must use -l with -k");
+	if (!lflag && FreeBSD_lb)
+		errx(1, "must use -l with --lb");
 	if (FreeBSD_sctp) {
 		if (uflag)
 			errx(1, "cannot use -u and --sctp");
@@ -800,6 +804,8 @@ local_listen(char *host, char *port, struct addrinfo hints)
 
 	res0 = res;
 	do {
+		int opt;
+
 		if ((s = socket(res0->ai_family, res0->ai_socktype,
 		    res0->ai_protocol)) < 0)
 			continue;
@@ -808,7 +814,8 @@ local_listen(char *host, char *port, struct addrinfo hints)
 		    &rtableid, sizeof(rtableid)) == -1))
 			err(1, "setsockopt SO_SETFIB");
 
-		ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
+		opt = FreeBSD_lb != 0 ? SO_REUSEPORT_LB : SO_REUSEPORT;
+		ret = setsockopt(s, SOL_SOCKET, opt, &x, sizeof(x));
 		if (ret == -1)
 			err(1, NULL);