git: 07738547c4c9 - stable/12 - ipfilter: Make LARGE_NAT a tunable.

From: Cy Schubert <cy_at_FreeBSD.org>
Date: Sun, 09 Jan 2022 00:45:13 UTC
The branch stable/12 has been updated by cy:

URL: https://cgit.FreeBSD.org/src/commit/?id=07738547c4c95f960bac02e2b335b61a3308dc71

commit 07738547c4c95f960bac02e2b335b61a3308dc71
Author:     Cy Schubert <cy@FreeBSD.org>
AuthorDate: 2021-02-16 15:44:07 +0000
Commit:     Cy Schubert <cy@FreeBSD.org>
CommitDate: 2022-01-08 07:01:55 +0000

    ipfilter: Make LARGE_NAT a tunable.
    
    LARGE_NAT is a C macro that increases
            NAT_SIZE from 127 to 2047,
            RDR_SIZE from 127 to 2047,
            HOSTMAP_SIZE from 2047 to 8191,
            NAT_TABLE_MAX from 30000 to 180000, and
            NAT_TABLE_SZ from 2047 to 16383.
    
    These values can be altered at runtime using the ipf -T command however
    some adminstrators of large firewalls rebuild the kernel to enable
    LARGE_NAT at boot. This revision adds the tunable net.inet.ipf.large_nat
    which allows an administrator to set this option at boot instead of build
    time. Setting the LARGE_NAT macro to 1 is unaffected allowing build-time
    users to continue using the old way.
    
    (cherry picked from commit a805ffbcbce85872e71d825fd405a4a30e2ab4bc)
---
 sys/contrib/ipfilter/netinet/fil.c            |  5 +++
 sys/contrib/ipfilter/netinet/ip_fil.h         |  2 +
 sys/contrib/ipfilter/netinet/ip_fil_freebsd.c |  7 ++++
 sys/contrib/ipfilter/netinet/ip_nat.c         | 28 +++++++------
 sys/contrib/ipfilter/netinet/ip_nat.h         | 60 +++++++++++++--------------
 sys/contrib/ipfilter/netinet/mlfk_ipl.c       |  7 +++-
 6 files changed, 65 insertions(+), 44 deletions(-)

diff --git a/sys/contrib/ipfilter/netinet/fil.c b/sys/contrib/ipfilter/netinet/fil.c
index 462c727af613..9addc0f4e00f 100644
--- a/sys/contrib/ipfilter/netinet/fil.c
+++ b/sys/contrib/ipfilter/netinet/fil.c
@@ -9330,6 +9330,11 @@ ipf_main_soft_create(arg)
 	softc->ipf_icmpminfragmtu = 68;
 	softc->ipf_flags = IPF_LOGGING;
 
+#ifdef LARGE_NAT
+	softc->ipf_large_nat = 1;
+#endif
+	ipf_fbsd_kenv_get(softc);
+
 	return softc;
 }
 
diff --git a/sys/contrib/ipfilter/netinet/ip_fil.h b/sys/contrib/ipfilter/netinet/ip_fil.h
index be8e023ac0ba..a01bd28e7270 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil.h
+++ b/sys/contrib/ipfilter/netinet/ip_fil.h
@@ -1551,6 +1551,7 @@ typedef struct ipf_main_softc_s {
 	u_int		ipf_icmptimeout;
 	u_int		ipf_icmpacktimeout;
 	u_int		ipf_iptimeout;
+	u_int		ipf_large_nat;
 	u_long		ipf_ticks;
 	u_long		ipf_userifqs;
 	u_long		ipf_rb_no_mem;
@@ -1657,6 +1658,7 @@ extern	int	ipf_pfil_hook(void);
 extern	int	ipf_pfil_unhook(void);
 extern	void	ipf_event_reg(void);
 extern	void	ipf_event_dereg(void);
+extern	void	ipf_fbsd_kenv_get(ipf_main_softc_t *);
 # endif
 
 # if defined(INSTANCES)
diff --git a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
index 176b380ca0a3..6f48a9c4ce97 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
+++ b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
@@ -1480,3 +1480,10 @@ ipf_pcksum6(m, ip6, off, len)
 #endif
 }
 #endif
+
+void
+ipf_fbsd_kenv_get(ipf_main_softc_t *softc)
+{
+	TUNABLE_INT_FETCH("net.inet.ipf.large_nat",
+		&softc->ipf_large_nat);
+}
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c
index 028be649cccd..b0ac1a23c723 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.c
+++ b/sys/contrib/ipfilter/netinet/ip_nat.c
@@ -321,11 +321,19 @@ ipf_nat_soft_create(softc)
 
 	softn->ipf_nat_list_tail = &softn->ipf_nat_list;
 
-	softn->ipf_nat_table_max = NAT_TABLE_MAX;
-	softn->ipf_nat_table_sz = NAT_TABLE_SZ;
-	softn->ipf_nat_maprules_sz = NAT_SIZE;
-	softn->ipf_nat_rdrrules_sz = RDR_SIZE;
-	softn->ipf_nat_hostmap_sz = HOSTMAP_SIZE;
+	if (softc->ipf_large_nat) {
+	softn->ipf_nat_table_max = NAT_TABLE_MAX_LARGE;
+	softn->ipf_nat_table_sz = NAT_TABLE_SZ_LARGE;
+	softn->ipf_nat_maprules_sz = NAT_SIZE_LARGE;
+	softn->ipf_nat_rdrrules_sz = RDR_SIZE_LARGE;
+	softn->ipf_nat_hostmap_sz = HOSTMAP_SIZE_LARGE;
+	} else {
+	softn->ipf_nat_table_max = NAT_TABLE_MAX_NORMAL;
+	softn->ipf_nat_table_sz = NAT_TABLE_SZ_NORMAL;
+	softn->ipf_nat_maprules_sz = NAT_SIZE_NORMAL;
+	softn->ipf_nat_rdrrules_sz = RDR_SIZE_NORMAL;
+	softn->ipf_nat_hostmap_sz = HOSTMAP_SIZE_NORMAL;
+	}
 	softn->ipf_nat_doflush = 0;
 #ifdef  IPFILTER_LOG
 	softn->ipf_nat_logging = 1;
@@ -492,10 +500,8 @@ ipf_nat_soft_init(softc, arg)
 	for (i = 0, tq = softn->ipf_nat_tcptq; i < IPF_TCP_NSTATES; i++, tq++) {
 		if (tq->ifq_ttl < softn->ipf_nat_deficmpage)
 			tq->ifq_ttl = softn->ipf_nat_deficmpage;
-#ifdef LARGE_NAT
-		else if (tq->ifq_ttl > softn->ipf_nat_defage)
+		else if (tq->ifq_ttl > softn->ipf_nat_defage && softc->ipf_large_nat)
 			tq->ifq_ttl = softn->ipf_nat_defage;
-#endif
 	}
 
 	/*
@@ -6139,10 +6145,8 @@ ipf_nat_log(softc, softn, nat, action)
 	u_int action;
 {
 #ifdef	IPFILTER_LOG
-# ifndef LARGE_NAT
 	struct ipnat *np;
 	int rulen;
-# endif
 	struct natlog natl;
 	void *items[1];
 	size_t sizes[1];
@@ -6178,8 +6182,7 @@ ipf_nat_log(softc, softn, nat, action)
 	bcopy(nat->nat_ifnames[1], natl.nl_ifnames[1],
 	      sizeof(nat->nat_ifnames[1]));
 
-# ifndef LARGE_NAT
-	if (nat->nat_ptr != NULL) {
+	if (softc->ipf_large_nat && nat->nat_ptr != NULL) {
 		for (rulen = 0, np = softn->ipf_nat_list; np != NULL;
 		     np = np->in_next, rulen++)
 			if (np == nat->nat_ptr) {
@@ -6187,7 +6190,6 @@ ipf_nat_log(softc, softn, nat, action)
 				break;
 			}
 	}
-# endif
 	items[0] = &natl;
 	sizes[0] = sizeof(natl);
 	types[0] = 0;
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.h b/sys/contrib/ipfilter/netinet/ip_nat.h
index bcec72f21f8b..aac8c326aa05 100644
--- a/sys/contrib/ipfilter/netinet/ip_nat.h
+++ b/sys/contrib/ipfilter/netinet/ip_nat.h
@@ -34,44 +34,44 @@
 			 * appropriate sizes.  The figures below were used for
 			 * a setup with 1000-2000 networks to NAT.
 			 */
-#ifndef NAT_SIZE
-# ifdef LARGE_NAT
-#  define	NAT_SIZE	2047
-# else
-#  define	NAT_SIZE	127
-# endif
+#ifdef NAT_SIZE
+# define	NAT_SIZE_LARGE		NAT_SIZE
+# define	NAT_SIZE_NORMAL		NAT_SIZE
+#else
+# define	NAT_SIZE_LARGE		2047
+# define	NAT_SIZE_NORMAL		127
 #endif
-#ifndef RDR_SIZE
-# ifdef LARGE_NAT
-#  define	RDR_SIZE	2047
-# else
-#  define	RDR_SIZE	127
-# endif
+#ifdef RDR_SIZE
+# define	RDR_SIZE_LARGE		RDR_SIZE
+# define	RDR_SIZE_NORMAL		RDR_SIZE
+#else
+# define	RDR_SIZE_LARGE		2047
+# define	RDR_SIZE_NORMAL		127
 #endif
-#ifndef HOSTMAP_SIZE
-# ifdef LARGE_NAT
-#  define	HOSTMAP_SIZE	8191
-# else
-#  define	HOSTMAP_SIZE	2047
-# endif
+#ifdef HOSTMAP_SIZE
+# define	HOSTMAP_SIZE_LARGE	HOSTMAP_SIZE
+# define	HOSTMAP_SIZE_NORMAL	HOSTMAP_SIZE
+#else
+# define	HOSTMAP_SIZE_LARGE	8191
+# define	HOSTMAP_SIZE_NORMAL	2047
 #endif
-#ifndef NAT_TABLE_MAX
 /*
  * This is newly introduced and for the sake of "least surprise", the numbers
  * present aren't what we'd normally use for creating a proper hash table.
  */
-# ifdef	LARGE_NAT
-#  define	NAT_TABLE_MAX	180000
-# else
-#  define	NAT_TABLE_MAX	30000
-# endif
+#ifdef NAT_TABLE_MAX
+# define	NAT_TABLE_MAX_LARGE	NAT_TABLE_MAX
+# define	NAT_TABLE_MAX_NORMAL	NAT_TABLE_MAX
+#else
+# define	NAT_TABLE_MAX_LARGE	180000
+# define	NAT_TABLE_MAX_NORMAL	30000
 #endif
-#ifndef NAT_TABLE_SZ
-# ifdef LARGE_NAT
-#  define	NAT_TABLE_SZ	16383
-# else
-#  define	NAT_TABLE_SZ	2047
-# endif
+#ifdef NAT_TABLE_SZ
+# define	NAT_TABLE_SZ_LARGE	NAT_TABLE_SZ
+# define	NAT_TABLE_SZ_NORMAL	NAT_TABLE_SZ
+#else
+# define	NAT_TABLE_SZ_LARGE	16383
+# define	NAT_TABLE_SZ_NORMAL	2047
 #endif
 #ifndef	APR_LABELLEN
 #define	APR_LABELLEN	16
diff --git a/sys/contrib/ipfilter/netinet/mlfk_ipl.c b/sys/contrib/ipfilter/netinet/mlfk_ipl.c
index 0e5f6c6b968c..9f827d17fd70 100644
--- a/sys/contrib/ipfilter/netinet/mlfk_ipl.c
+++ b/sys/contrib/ipfilter/netinet/mlfk_ipl.c
@@ -80,6 +80,11 @@ static	int	ipfread(dev_t, struct uio *, int);
 static	int	ipfwrite(dev_t, struct uio *, int);
 #endif
 
+#ifdef LARGE_NAT
+#define IPF_LARGE_NAT	1
+#else
+#define IPF_LARGE_NAT	0
+#endif
 
 SYSCTL_DECL(_net_inet);
 #define SYSCTL_IPF(parent, nbr, name, access, ptr, val, descr) \
@@ -126,6 +131,7 @@ SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD,
 	   &VNET_NAME(ipfmain.ipf_running), 0, "IPF is running");
 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_chksrc), 0, "");
 SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &VNET_NAME(ipfmain.ipf_minttl), 0, "");
+SYSCTL_IPF(_net_inet_ipf, OID_AUTO, large_nat, CTLFLAG_RD, &VNET_NAME(ipfmain.ipf_large_nat), 0, "large_nat");
 
 #define CDEV_MAJOR 79
 #include <sys/poll.h>
@@ -662,4 +668,3 @@ ipf_fbsd_sysctl_destroy(void)
 	}
 	return 0;
 }
-