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.
This commit is contained in:
Cy Schubert 2021-02-16 07:44:07 -08:00
parent e2ad10e847
commit a805ffbcbc
6 changed files with 65 additions and 44 deletions

View File

@ -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;
}

View File

@ -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)

View File

@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -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 <sys/poll.h>
@ -646,4 +652,3 @@ ipf_fbsd_sysctl_destroy(void)
}
return 0;
}