Backport from projects/pf r263908:

De-virtualize UMA zone pf_mtag_z and move to global initialization part.

The m_tag struct does not know about vnet context and the pf_mtag_free()
callback is called unaware of current vnet. This causes a panic.

MFC after:	1 week
This commit is contained in:
Martin Matuska 2014-04-20 09:17:48 +00:00
commit ecb47cf9c5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=264689
3 changed files with 28 additions and 12 deletions

View File

@ -1529,6 +1529,8 @@ VNET_DECLARE(struct pf_rulequeue, pf_unlinked_rules);
#define V_pf_unlinked_rules VNET(pf_unlinked_rules)
void pf_initialize(void);
void pf_mtag_initialize(void);
void pf_mtag_cleanup(void);
void pf_cleanup(void);
struct pf_mtag *pf_get_mtag(struct mbuf *);

View File

@ -187,8 +187,7 @@ struct mtx pf_unlnkdrules_mtx;
static VNET_DEFINE(uma_zone_t, pf_sources_z);
#define V_pf_sources_z VNET(pf_sources_z)
static VNET_DEFINE(uma_zone_t, pf_mtag_z);
#define V_pf_mtag_z VNET(pf_mtag_z)
uma_zone_t pf_mtag_z;
VNET_DEFINE(uma_zone_t, pf_state_z);
VNET_DEFINE(uma_zone_t, pf_state_key_z);
@ -283,7 +282,7 @@ static int pf_insert_src_node(struct pf_src_node **,
struct pf_rule *, struct pf_addr *, sa_family_t);
static u_int pf_purge_expired_states(u_int, int);
static void pf_purge_unlinked_rules(void);
static int pf_mtag_init(void *, int, int);
static int pf_mtag_uminit(void *, int, int);
static void pf_mtag_free(struct m_tag *);
#ifdef INET
static void pf_route(struct mbuf **, struct pf_rule *, int,
@ -726,7 +725,16 @@ pf_free_src_nodes(struct pf_src_node_list *head)
return (count);
}
/* Data storage structures initialization. */
void
pf_mtag_initialize()
{
pf_mtag_z = uma_zcreate("pf mtags", sizeof(struct m_tag) +
sizeof(struct pf_mtag), NULL, NULL, pf_mtag_uminit, NULL,
UMA_ALIGN_PTR, 0);
}
/* Per-vnet data storage structures initialization. */
void
pf_initialize()
{
@ -785,10 +793,6 @@ pf_initialize()
V_pf_altqs_active = &V_pf_altqs[0];
V_pf_altqs_inactive = &V_pf_altqs[1];
/* Mbuf tags */
V_pf_mtag_z = uma_zcreate("pf mtags", sizeof(struct m_tag) +
sizeof(struct pf_mtag), NULL, NULL, pf_mtag_init, NULL,
UMA_ALIGN_PTR, 0);
/* Send & overload+flush queues. */
STAILQ_INIT(&V_pf_sendqueue);
@ -803,6 +807,13 @@ pf_initialize()
mtx_init(&pf_unlnkdrules_mtx, "pf unlinked rules", NULL, MTX_DEF);
}
void
pf_mtag_cleanup()
{
uma_zdestroy(pf_mtag_z);
}
void
pf_cleanup()
{
@ -840,14 +851,13 @@ pf_cleanup()
mtx_destroy(&pf_overloadqueue_mtx);
mtx_destroy(&pf_unlnkdrules_mtx);
uma_zdestroy(V_pf_mtag_z);
uma_zdestroy(V_pf_sources_z);
uma_zdestroy(V_pf_state_z);
uma_zdestroy(V_pf_state_key_z);
}
static int
pf_mtag_init(void *mem, int size, int how)
pf_mtag_uminit(void *mem, int size, int how)
{
struct m_tag *t;
@ -864,7 +874,7 @@ static void
pf_mtag_free(struct m_tag *t)
{
uma_zfree(V_pf_mtag_z, t);
uma_zfree(pf_mtag_z, t);
}
struct pf_mtag *
@ -875,7 +885,7 @@ pf_get_mtag(struct mbuf *m)
if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) != NULL)
return ((struct pf_mtag *)(mtag + 1));
mtag = uma_zalloc(V_pf_mtag_z, M_NOWAIT);
mtag = uma_zalloc(pf_mtag_z, M_NOWAIT);
if (mtag == NULL)
return (NULL);
bzero(mtag + 1, sizeof(struct pf_mtag));

View File

@ -208,6 +208,8 @@ pfattach(void)
u_int32_t *my_timeout = V_pf_default_rule.timeout;
int error;
if (IS_DEFAULT_VNET(curvnet))
pf_mtag_initialize();
pf_initialize();
pfr_initialize();
pfi_initialize();
@ -3725,6 +3727,8 @@ pf_unload(void)
pfr_cleanup();
pf_osfp_flush();
pf_cleanup();
if (IS_DEFAULT_VNET(curvnet))
pf_mtag_cleanup();
PF_RULES_WUNLOCK();
destroy_dev(pf_dev);
rw_destroy(&pf_rules_lock);