From owner-freebsd-pf@FreeBSD.ORG Tue Feb 11 08:30:18 2014 Return-Path: Delivered-To: freebsd-pf@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 7522A808; Tue, 11 Feb 2014 08:30:18 +0000 (UTC) Received: from mail.vx.sk (mail.vx.sk [176.9.45.25]) by mx1.freebsd.org (Postfix) with ESMTP id 125F11694; Tue, 11 Feb 2014 08:30:17 +0000 (UTC) Received: from mail.vx.sk (localhost [127.0.0.1]) by mail.vx.sk (Postfix) with ESMTP id 36DEFBCF4; Tue, 11 Feb 2014 09:30:11 +0100 (CET) X-Virus-Scanned: amavisd-new at mail.vx.sk Received: from mail.vx.sk by mail.vx.sk (amavisd-new, unix socket) with LMTP id UsUymfCUkl2K; Tue, 11 Feb 2014 09:30:10 +0100 (CET) Received: from [192.168.2.103] (dslb-094-223-160-133.pools.arcor-ip.net [94.223.160.133]) by mail.vx.sk (Postfix) with ESMTPSA id 74480BCEB; Tue, 11 Feb 2014 09:30:10 +0100 (CET) Message-ID: <52F9DF91.5080903@FreeBSD.org> Date: Tue, 11 Feb 2014 09:30:09 +0100 From: Martin Matuska User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0 MIME-Version: 1.0 To: freebsd-pf@FreeBSD.org Subject: CFR: VIMAGE + pf bugfix X-Enigmail-Version: 1.5.2 Content-Type: multipart/mixed; boundary="------------020103000302000908070302" Cc: Adrian Chadd , Marko Zec X-BeenThere: freebsd-pf@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "Technical discussion and general questions about packet filter \(pf\)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Feb 2014 08:30:18 -0000 This is a multi-part message in MIME format. --------------020103000302000908070302 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Hi, please review my attached patch. It fixes two panics and makes PF usable with VIMAGE (inside host system only). http://people.freebsd.org/~mm/patches/pf_mtag_taskq.patch The patch does the following: a) devirtualizes the UMA zone for pf_mtag b) adds vnet information to pf_overload_task Thank you, mm --------------020103000302000908070302 Content-Type: text/x-patch; name="pf_mtag_taskq.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="pf_mtag_taskq.patch" Index: sys/netpfil/pf/pf.c =================================================================== --- sys/netpfil/pf/pf.c (revision 261741) +++ sys/netpfil/pf/pf.c (working copy) @@ -172,7 +172,10 @@ struct pf_overload_entry { struct pf_rule *rule; }; -SLIST_HEAD(pf_overload_head, pf_overload_entry); +struct pf_overload_head { + SLIST_HEAD(, pf_overload_entry) head; + struct vnet *vnet; +}; static VNET_DEFINE(struct pf_overload_head, pf_overloadqueue); #define V_pf_overloadqueue VNET(pf_overloadqueue) static VNET_DEFINE(struct task, pf_overloadtask); @@ -187,8 +190,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); @@ -510,7 +512,7 @@ pf_src_connlimit(struct pf_state **state) pfoe->rule = (*state)->rule.ptr; pfoe->dir = (*state)->direction; PF_OVERLOADQ_LOCK(); - SLIST_INSERT_HEAD(&V_pf_overloadqueue, pfoe, next); + SLIST_INSERT_HEAD(&V_pf_overloadqueue.head, pfoe, next); PF_OVERLOADQ_UNLOCK(); taskqueue_enqueue(taskqueue_swi, &V_pf_overloadtask); @@ -527,11 +529,13 @@ pf_overload_task(void *c, int pending) PF_OVERLOADQ_LOCK(); queue = *(struct pf_overload_head *)c; - SLIST_INIT((struct pf_overload_head *)c); + SLIST_INIT(&((struct pf_overload_head *)c)->head); PF_OVERLOADQ_UNLOCK(); + CURVNET_SET(queue.vnet); + bzero(&p, sizeof(p)); - SLIST_FOREACH(pfoe, &queue, next) { + SLIST_FOREACH(pfoe, &queue.head, next) { V_pf_status.lcounters[LCNT_OVERLOAD_TABLE]++; if (V_pf_status.debug >= PF_DEBUG_MISC) { printf("%s: blocking address ", __func__); @@ -563,16 +567,18 @@ pf_overload_task(void *c, int pending) /* * Remove those entries, that don't need flushing. */ - SLIST_FOREACH_SAFE(pfoe, &queue, next, pfoe1) + SLIST_FOREACH_SAFE(pfoe, &queue.head, next, pfoe1) if (pfoe->rule->flush == 0) { - SLIST_REMOVE(&queue, pfoe, pf_overload_entry, next); + SLIST_REMOVE(&queue.head, pfoe, pf_overload_entry, next); free(pfoe, M_PFTEMP); } else V_pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++; /* If nothing to flush, return. */ - if (SLIST_EMPTY(&queue)) + if (SLIST_EMPTY(&queue.head)) { + CURVNET_RESTORE(); return; + } for (int i = 0; i <= V_pf_hashmask; i++) { struct pf_idhash *ih = &V_pf_idhash[i]; @@ -582,7 +588,7 @@ pf_overload_task(void *c, int pending) PF_HASHROW_LOCK(ih); LIST_FOREACH(s, &ih->states, entry) { sk = s->key[PF_SK_WIRE]; - SLIST_FOREACH(pfoe, &queue, next) + SLIST_FOREACH(pfoe, &queue.head, next) if (sk->af == pfoe->af && ((pfoe->rule->flush & PF_FLUSH_GLOBAL) || pfoe->rule == s->rule.ptr) && @@ -597,10 +603,12 @@ pf_overload_task(void *c, int pending) } PF_HASHROW_UNLOCK(ih); } - SLIST_FOREACH_SAFE(pfoe, &queue, next, pfoe1) + SLIST_FOREACH_SAFE(pfoe, &queue.head, next, pfoe1) free(pfoe, M_PFTEMP); if (V_pf_status.debug >= PF_DEBUG_MISC) printf("%s: %u states killed", __func__, killed); + + CURVNET_RESTORE(); } /* @@ -790,14 +798,16 @@ pf_initialize() 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); + if (IS_DEFAULT_VNET(curvnet)) + 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); - SLIST_INIT(&V_pf_overloadqueue); + SLIST_INIT(&V_pf_overloadqueue.head); TASK_INIT(&V_pf_overloadtask, 0, pf_overload_task, &V_pf_overloadqueue); + V_pf_overloadqueue.vnet = curvnet; mtx_init(&pf_sendqueue_mtx, "pf send queue", NULL, MTX_DEF); mtx_init(&pf_overloadqueue_mtx, "pf overload/flush queue", NULL, MTX_DEF); @@ -844,7 +854,8 @@ pf_cleanup() mtx_destroy(&pf_overloadqueue_mtx); mtx_destroy(&pf_unlnkdrules_mtx); - uma_zdestroy(V_pf_mtag_z); + if (IS_DEFAULT_VNET(curvnet)) + uma_zdestroy(pf_mtag_z); uma_zdestroy(V_pf_sources_z); uma_zdestroy(V_pf_state_z); uma_zdestroy(V_pf_state_key_z); @@ -868,7 +879,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 * @@ -879,7 +890,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)); @@ -1679,7 +1690,7 @@ pf_purge_unlinked_rules() * an already unlinked rule. */ PF_OVERLOADQ_LOCK(); - if (!SLIST_EMPTY(&V_pf_overloadqueue)) { + if (!SLIST_EMPTY(&V_pf_overloadqueue.head)) { PF_OVERLOADQ_UNLOCK(); return; } --------------020103000302000908070302--