Author: mm
Date: Sun Apr 20 09:17:48 2014
New Revision: 264689
URL: http://svnweb.freebsd.org/changeset/base/264689

Log:
  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

Modified:
  head/sys/net/pfvar.h
  head/sys/netpfil/pf/pf.c
  head/sys/netpfil/pf/pf_ioctl.c
Directory Properties:
  head/   (props changed)
  head/sys/   (props changed)

Modified: head/sys/net/pfvar.h
==============================================================================
--- head/sys/net/pfvar.h        Sun Apr 20 06:46:04 2014        (r264688)
+++ head/sys/net/pfvar.h        Sun Apr 20 09:17:48 2014        (r264689)
@@ -1529,6 +1529,8 @@ VNET_DECLARE(struct pf_rulequeue, pf_unl
 #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 *);

Modified: head/sys/netpfil/pf/pf.c
==============================================================================
--- head/sys/netpfil/pf/pf.c    Sun Apr 20 06:46:04 2014        (r264688)
+++ head/sys/netpfil/pf/pf.c    Sun Apr 20 09:17:48 2014        (r264689)
@@ -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 p
                            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_lis
        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);
@@ -804,6 +808,13 @@ pf_initialize()
 }
 
 void
+pf_mtag_cleanup()
+{
+
+       uma_zdestroy(pf_mtag_z);
+}
+
+void
 pf_cleanup()
 {
        struct pf_keyhash       *kh;
@@ -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));

Modified: head/sys/netpfil/pf/pf_ioctl.c
==============================================================================
--- head/sys/netpfil/pf/pf_ioctl.c      Sun Apr 20 06:46:04 2014        
(r264688)
+++ head/sys/netpfil/pf/pf_ioctl.c      Sun Apr 20 09:17:48 2014        
(r264689)
@@ -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);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to