git: 7531c434a593 - main - ipfilter/ippool: Dump a copy of ippool in ippool.conf format

From: Cy Schubert <cy_at_FreeBSD.org>
Date: Thu, 22 Sep 2022 22:39:25 UTC
The branch main has been updated by cy:

URL: https://cgit.FreeBSD.org/src/commit/?id=7531c434a593b2f369d69c85551e7ad1ebb7499a

commit 7531c434a593b2f369d69c85551e7ad1ebb7499a
Author:     Cy Schubert <cy@FreeBSD.org>
AuthorDate: 2022-09-21 15:33:11 +0000
Commit:     Cy Schubert <cy@FreeBSD.org>
CommitDate: 2022-09-22 22:38:11 +0000

    ipfilter/ippool: Dump a copy of ippool in ippool.conf format
    
    Add an ippool(8) option to dump a copy of the inm-memory ippool tables
    in an ippool(5) format so that it can be reloaded using ippool -f.
    
    MFC after:      2 weeks
---
 sbin/ipf/ippool/ippool.8         |  6 +++++-
 sbin/ipf/ippool/ippool.c         |  5 ++++-
 sbin/ipf/libipf/printpool_live.c | 12 ++++++++++--
 sbin/ipf/libipf/printpooldata.c  | 10 ++++++++--
 4 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/sbin/ipf/ippool/ippool.8 b/sbin/ipf/ippool/ippool.8
index bcc8f3cbd71d..358ece5a26ff 100644
--- a/sbin/ipf/ippool/ippool.8
+++ b/sbin/ipf/ippool/ippool.8
@@ -18,7 +18,7 @@ ippool \- user interface to the IPFilter pools
 -F [-dv] [-o <role>] [-t <type>]
 .br
 .B ippool
--l [-dv] [-m <name>] [-t <type>] [-o <role>] [-M <core>] [-N <namelist>]
+-l [-dDv] [-m <name>] [-t <type>] [-o <role>] [-M <core>] [-N <namelist>]
 .br
 .B ippool
 -r [-dnv] [-m <name>] [-o <role>] [-t <type>] -i <ipaddr>[/<netmask>]
@@ -121,6 +121,10 @@ as a number of seconds.
 When parsing a configuration file, rather than load new pool data into the
 kernel, unload it.
 .TP
+.B -D
+When used in conjuction with -l, dump the ippool configuration to stdout in
+a format that can be subsequently used as input into ippool -f.
+.TP
 .SH FILES
 .br
 /dev/iplookup
diff --git a/sbin/ipf/ippool/ippool.c b/sbin/ipf/ippool/ippool.c
index 3e8918e1fcfa..384146d729c9 100644
--- a/sbin/ipf/ippool/ippool.c
+++ b/sbin/ipf/ippool/ippool.c
@@ -670,12 +670,15 @@ poollist(int argc, char *argv[])
 	poolname = NULL;
 	role = IPL_LOGALL;
 
-	while ((c = getopt(argc, argv, "dm:M:N:o:t:v")) != -1)
+	while ((c = getopt(argc, argv, "dDm:M:N:o:t:v")) != -1)
 		switch (c)
 		{
 		case 'd' :
 			opts |= OPT_DEBUG;
 			break;
+		case 'D' :
+			opts |= OPT_SAVEOUT;
+			break;
 		case 'm' :
 			poolname = optarg;
 			break;
diff --git a/sbin/ipf/libipf/printpool_live.c b/sbin/ipf/libipf/printpool_live.c
index 324deb629d0b..c1d770b4ef77 100644
--- a/sbin/ipf/libipf/printpool_live.c
+++ b/sbin/ipf/libipf/printpool_live.c
@@ -26,7 +26,9 @@ printpool_live(ip_pool_t *pool, int fd, char *name, int opts,
 
 	if ((pool->ipo_flags & IPOOL_DELETE) != 0)
 		PRINTF("# ");
-	if ((opts & OPT_DEBUG) == 0)
+	if (opts & OPT_SAVEOUT)
+		PRINTF("{\n");
+	else if ((opts & OPT_DEBUG) == 0)
 		PRINTF("\t{");
 
 	obj.ipfo_rev = IPFILTER_VERSION;
@@ -48,9 +50,13 @@ printpool_live(ip_pool_t *pool, int fd, char *name, int opts,
 		while (!last && (ioctl(fd, SIOCLOOKUPITER, &obj) == 0)) {
 			if (entry.ipn_next == NULL)
 				last = 1;
+			if (opts & OPT_SAVEOUT)
+				PRINTF("\t");
 			(void) printpoolnode(&entry, opts, fields);
 			if ((opts & OPT_DEBUG) == 0)
 				putchar(';');
+			if (opts & OPT_SAVEOUT)
+				PRINTF("\n");
 			printed++;
 		}
 	}
@@ -58,7 +64,9 @@ printpool_live(ip_pool_t *pool, int fd, char *name, int opts,
 	if (printed == 0)
 		putchar(';');
 
-	if ((opts & OPT_DEBUG) == 0)
+	if (opts & OPT_SAVEOUT)
+		PRINTF("};\n");
+	else if ((opts & OPT_DEBUG) == 0)
 		PRINTF(" };\n");
 
 	(void) ioctl(fd,SIOCIPFDELTOK, &iter.ili_key);
diff --git a/sbin/ipf/libipf/printpooldata.c b/sbin/ipf/libipf/printpooldata.c
index ce754f9a89bb..bd5af316eb19 100644
--- a/sbin/ipf/libipf/printpooldata.c
+++ b/sbin/ipf/libipf/printpooldata.c
@@ -12,7 +12,9 @@ void
 printpooldata(ip_pool_t *pool, int opts)
 {
 
-	if ((opts & OPT_DEBUG) == 0) {
+	if (opts & OPT_SAVEOUT) {
+		PRINTF("pool ");
+	} else if ((opts & OPT_DEBUG) == 0) {
 		if ((pool->ipo_flags & IPOOL_ANON) != 0)
 			PRINTF("# 'anonymous' tree %s\n", pool->ipo_name);
 		if ((pool->ipo_flags & IPOOL_DELETE) != 0)
@@ -32,7 +34,11 @@ printpooldata(ip_pool_t *pool, int opts)
 
 	printunit(pool->ipo_unit);
 
-	if ((opts & OPT_DEBUG) == 0) {
+	if ((opts & OPT_SAVEOUT)) {
+		PRINTF("/tree (%s \"\%s\";)\n",
+			(!*pool->ipo_name || ISDIGIT(*pool->ipo_name)) ? \
+			"number" : "name", pool->ipo_name);
+	} else if ((opts & OPT_DEBUG) == 0) {
 		PRINTF(" type=tree %s=%s\n",
 			(!*pool->ipo_name || ISDIGIT(*pool->ipo_name)) ? \
 			"number" : "name", pool->ipo_name);