From a805ffbcbce85872e71d825fd405a4a30e2ab4bc Mon Sep 17 00:00:00 2001 From: Cy Schubert Date: Tue, 16 Feb 2021 07:44:07 -0800 Subject: 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. --- 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 09b4c27a1cb4..c04015c2b41e 100644 --- a/sys/contrib/ipfilter/netinet/fil.c +++ b/sys/contrib/ipfilter/netinet/fil.c @@ -9338,6 +9338,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 8cb988e1fd17..7e976d88cc0f 100644 --- a/sys/contrib/ipfilter/netinet/ip_fil.h +++ b/sys/contrib/ipfilter/netinet/ip_fil.h @@ -1547,6 +1547,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; @@ -1653,6 +1654,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 bac73cee4e8b..072ab8bcd4e5 100644 --- a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c +++ b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c @@ -1487,3 +1487,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 33d190c61a0a..9ce6063eb7f3 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 } /* @@ -6141,10 +6147,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]; @@ -6180,8 +6184,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) { @@ -6189,7 +6192,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 6e49ef77b486..64beb1448858 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) \ @@ -132,6 +137,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 @@ -646,4 +652,3 @@ ipf_fbsd_sysctl_destroy(void) } return 0; } - -- cgit v1.2.3