svn commit: r331117 - in stable/10/sys: net netpfil/pf
Kristof Provost
kp at FreeBSD.org
Sun Mar 18 11:26:08 UTC 2018
Author: kp
Date: Sun Mar 18 11:26:07 2018
New Revision: 331117
URL: https://svnweb.freebsd.org/changeset/base/331117
Log:
MFC r329950:
pf: Cope with overly large net.pf.states_hashsize
If the user configures a states_hashsize or source_nodes_hashsize value we may
not have enough memory to allocate this. This used to lock up pf, because these
allocations used M_WAITOK.
Cope with this by attempting the allocation with M_NOWAIT and falling back to
the default sizes (with M_WAITOK) if these fail.
PR: 209475
Submitted by: Fehmi Noyan Isi <fnoyanisi AT yahoo.com>
Modified:
stable/10/sys/net/pfvar.h
stable/10/sys/netpfil/pf/pf.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/net/pfvar.h
==============================================================================
--- stable/10/sys/net/pfvar.h Sun Mar 18 11:25:39 2018 (r331116)
+++ stable/10/sys/net/pfvar.h Sun Mar 18 11:26:07 2018 (r331117)
@@ -1458,6 +1458,7 @@ struct pf_idhash {
extern u_long pf_hashmask;
extern u_long pf_srchashmask;
#define PF_HASHSIZ (32768)
+#define PF_SRCHASHSIZ (PF_HASHSIZ/4)
VNET_DECLARE(struct pf_keyhash *, pf_keyhash);
VNET_DECLARE(struct pf_idhash *, pf_idhash);
#define V_pf_keyhash VNET(pf_keyhash)
Modified: stable/10/sys/netpfil/pf/pf.c
==============================================================================
--- stable/10/sys/netpfil/pf/pf.c Sun Mar 18 11:25:39 2018 (r331116)
+++ stable/10/sys/netpfil/pf/pf.c Sun Mar 18 11:26:07 2018 (r331117)
@@ -781,7 +781,7 @@ pf_initialize()
pf_hashsize = PF_HASHSIZ;
TUNABLE_ULONG_FETCH("net.pf.source_nodes_hashsize", &pf_srchashsize);
if (pf_srchashsize == 0 || !powerof2(pf_srchashsize))
- pf_srchashsize = PF_HASHSIZ / 4;
+ pf_srchashsize = PF_SRCHASHSIZ;
V_pf_hashseed = arc4random();
@@ -795,10 +795,25 @@ pf_initialize()
V_pf_state_key_z = uma_zcreate("pf state keys",
sizeof(struct pf_state_key), pf_state_key_ctor, NULL, NULL, NULL,
UMA_ALIGN_PTR, 0);
- V_pf_keyhash = malloc(pf_hashsize * sizeof(struct pf_keyhash),
- M_PFHASH, M_WAITOK | M_ZERO);
- V_pf_idhash = malloc(pf_hashsize * sizeof(struct pf_idhash),
- M_PFHASH, M_WAITOK | M_ZERO);
+
+ V_pf_keyhash = mallocarray(pf_hashsize, sizeof(struct pf_keyhash),
+ M_PFHASH, M_NOWAIT | M_ZERO);
+ V_pf_idhash = mallocarray(pf_hashsize, sizeof(struct pf_idhash),
+ M_PFHASH, M_NOWAIT | M_ZERO);
+ if (V_pf_keyhash == NULL || V_pf_idhash == NULL) {
+ printf("pf: Unable to allocate memory for "
+ "state_hashsize %lu.\n", pf_hashsize);
+
+ free(V_pf_keyhash, M_PFHASH);
+ free(V_pf_idhash, M_PFHASH);
+
+ pf_hashsize = PF_HASHSIZ;
+ V_pf_keyhash = mallocarray(pf_hashsize,
+ sizeof(struct pf_keyhash), M_PFHASH, M_WAITOK | M_ZERO);
+ V_pf_idhash = mallocarray(pf_hashsize,
+ sizeof(struct pf_idhash), M_PFHASH, M_WAITOK | M_ZERO);
+ }
+
pf_hashmask = pf_hashsize - 1;
for (i = 0, kh = V_pf_keyhash, ih = V_pf_idhash; i <= pf_hashmask;
i++, kh++, ih++) {
@@ -813,8 +828,18 @@ pf_initialize()
V_pf_limits[PF_LIMIT_SRC_NODES].zone = V_pf_sources_z;
uma_zone_set_max(V_pf_sources_z, PFSNODE_HIWAT);
uma_zone_set_warning(V_pf_sources_z, "PF source nodes limit reached");
- V_pf_srchash = malloc(pf_srchashsize * sizeof(struct pf_srchash),
- M_PFHASH, M_WAITOK|M_ZERO);
+
+ V_pf_srchash = mallocarray(pf_srchashsize,
+ sizeof(struct pf_srchash), M_PFHASH, M_NOWAIT | M_ZERO);
+ if (V_pf_srchash == NULL) {
+ printf("pf: Unable to allocate memory for "
+ "source_hashsize %lu.\n", pf_srchashsize);
+
+ pf_srchashsize = PF_SRCHASHSIZ;
+ V_pf_srchash = mallocarray(pf_srchashsize,
+ sizeof(struct pf_srchash), M_PFHASH, M_WAITOK | M_ZERO);
+ }
+
pf_srchashmask = pf_srchashsize - 1;
for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask; i++, sh++)
mtx_init(&sh->lock, "pf_srchash", NULL, MTX_DEF);
More information about the svn-src-all
mailing list