summaryrefslogtreecommitdiffstats
path: root/sys/netpfil
diff options
context:
space:
mode:
authormm <mm@FreeBSD.org>2014-04-27 09:05:34 +0000
committermm <mm@FreeBSD.org>2014-04-27 09:05:34 +0000
commit5b89692b00a51ee27c4f004b3c954b0b123bf551 (patch)
tree4057c670b23905e051d5000aca915b4be3d33852 /sys/netpfil
parent1e4589b921fdaa1b1d2fc6b6ed016f1e0a01cb8f (diff)
downloadFreeBSD-src-5b89692b00a51ee27c4f004b3c954b0b123bf551.zip
FreeBSD-src-5b89692b00a51ee27c4f004b3c954b0b123bf551.tar.gz
MFC r264689:
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. PR: kern/182964
Diffstat (limited to 'sys/netpfil')
-rw-r--r--sys/netpfil/pf/pf.c34
-rw-r--r--sys/netpfil/pf/pf_ioctl.c4
2 files changed, 26 insertions, 12 deletions
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index c6840fd..980db13 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -186,8 +186,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);
@@ -282,7 +281,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,
@@ -727,7 +726,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()
{
@@ -786,10 +794,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);
@@ -805,6 +809,13 @@ pf_initialize()
}
void
+pf_mtag_cleanup()
+{
+
+ uma_zdestroy(pf_mtag_z);
+}
+
+void
pf_cleanup()
{
struct pf_keyhash *kh;
@@ -841,14 +852,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;
@@ -865,7 +875,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 *
@@ -876,7 +886,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));
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index aa42040..ef44806 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -204,6 +204,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();
@@ -3721,6 +3723,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);
OpenPOWER on IntegriCloud