mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-30 08:19:09 +00:00
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> MFC after: 3 weeks Differential Revision: https://reviews.freebsd.org/D14367
This commit is contained in:
parent
22ae8ae1f4
commit
bf56a3fe47
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=329950
@ -1467,6 +1467,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)
|
||||
|
@ -790,7 +790,7 @@ pf_initialize()
|
||||
if (pf_hashsize == 0 || !powerof2(pf_hashsize))
|
||||
pf_hashsize = PF_HASHSIZ;
|
||||
if (pf_srchashsize == 0 || !powerof2(pf_srchashsize))
|
||||
pf_srchashsize = PF_HASHSIZ / 4;
|
||||
pf_srchashsize = PF_SRCHASHSIZ;
|
||||
|
||||
V_pf_hashseed = arc4random();
|
||||
|
||||
@ -804,10 +804,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++) {
|
||||
@ -822,8 +837,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);
|
||||
|
Loading…
Reference in New Issue
Block a user