svn commit: r236630 - projects/pf/head/sys/contrib/pf/net
Gleb Smirnoff
glebius at FreeBSD.org
Tue Jun 5 19:51:38 UTC 2012
Author: glebius
Date: Tue Jun 5 19:51:37 2012
New Revision: 236630
URL: http://svn.freebsd.org/changeset/base/236630
Log:
- Join "frag reassembly entry" and "frag cache entry" into one
union. Allocate union item from single zone, and assign the
frag limit to that zone.
- Allocate both kinds of fragments from one zone.
- Remove global counters, use uma_zone_get_cur() isntead.
Minor nits:
- M_ZERO instead of bzero()
- Reduce lock coverage in pf_normalize_ip().
Modified:
projects/pf/head/sys/contrib/pf/net/pf_norm.c
projects/pf/head/sys/contrib/pf/net/pfvar.h
Modified: projects/pf/head/sys/contrib/pf/net/pf_norm.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pf_norm.c Tue Jun 5 19:42:57 2012 (r236629)
+++ projects/pf/head/sys/contrib/pf/net/pf_norm.c Tue Jun 5 19:51:37 2012 (r236630)
@@ -70,15 +70,21 @@ __FBSDID("$FreeBSD$");
struct pf_frent {
LIST_ENTRY(pf_frent) fr_next;
- struct ip *fr_ip;
- struct mbuf *fr_m;
-};
-
-struct pf_frcache {
- LIST_ENTRY(pf_frcache) fr_next;
- uint16_t fr_off;
- uint16_t fr_end;
+ union {
+ struct {
+ struct ip *_fr_ip;
+ struct mbuf *_fr_m;
+ } _frag;
+ struct {
+ uint16_t _fr_off;
+ uint16_t _fr_end;
+ } _cache;
+ } _u;
};
+#define fr_ip _u._frag._fr_ip
+#define fr_m _u._frag._fr_m
+#define fr_off _u._cache._fr_off
+#define fr_end _u._cache._fr_end
struct pf_fragment {
RB_ENTRY(pf_fragment) fr_entry;
@@ -94,12 +100,7 @@ struct pf_fragment {
u_int16_t fr_id; /* fragment id for reassemble */
u_int16_t fr_max; /* fragment data max */
u_int32_t fr_timeout;
-#define fr_queue fr_u.fru_queue
-#define fr_cache fr_u.fru_cache
- union {
- LIST_HEAD(pf_fragq, pf_frent) fru_queue; /* buffering */
- LIST_HEAD(pf_cacheq, pf_frcache) fru_cache; /* non-buf */
- } fr_u;
+ LIST_HEAD(, pf_frent) fr_queue;
};
static struct mtx pf_frag_mtx;
@@ -113,14 +114,6 @@ static VNET_DEFINE(uma_zone_t, pf_frent_
#define V_pf_frent_z VNET(pf_frent_z)
static VNET_DEFINE(uma_zone_t, pf_frag_z);
#define V_pf_frag_z VNET(pf_frag_z)
-static VNET_DEFINE(uma_zone_t, pf_cache_z);
-#define V_pf_cache_z VNET(pf_cache_z)
-static VNET_DEFINE(uma_zone_t, pf_cent_z);
-#define V_pf_cent_z VNET(pf_cent_z)
-static VNET_DEFINE(int, pf_nfrents);
-#define V_pf_nfrents VNET(pf_nfrents)
-static VNET_DEFINE(int, pf_ncache);
-#define V_pf_ncache VNET(pf_ncache)
TAILQ_HEAD(pf_fragqueue, pf_fragment);
TAILQ_HEAD(pf_cachequeue, pf_fragment);
@@ -166,30 +159,17 @@ void
pf_normalize_init(void)
{
- V_pf_frent_z = uma_zcreate("pffrent", sizeof(struct pf_frent),
- NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
- /* XXXGL: two zones of struct pf_fragment */
- V_pf_frag_z = uma_zcreate("pffrag", sizeof(struct pf_fragment),
+ V_pf_frag_z = uma_zcreate("pf frags", sizeof(struct pf_fragment),
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
- V_pf_cache_z = uma_zcreate("pffrcache", sizeof(struct pf_fragment),
+ V_pf_frent_z = uma_zcreate("pf frag entries", sizeof(struct pf_frent),
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
- V_pf_cent_z = uma_zcreate("pffrcent", sizeof(struct pf_frcache),
- NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
- V_pf_state_scrub_z = uma_zcreate("pfstatescrub",
+ V_pf_state_scrub_z = uma_zcreate("pf state scrubs",
sizeof(struct pf_state_scrub), NULL, NULL, NULL, NULL,
UMA_ALIGN_PTR, 0);
- /*
- * XXX
- * No high water mark support(It's hint not hard limit).
- * uma_zone_set_max(pf_frag_z, PFFRAG_FRAG_HIWAT);
- */
- uma_zone_set_max(V_pf_frent_z, PFFRAG_FRENT_HIWAT);
- uma_zone_set_max(V_pf_cache_z, PFFRAG_FRCACHE_HIWAT);
- uma_zone_set_max(V_pf_cent_z, PFFRAG_FRCENT_HIWAT);
-
V_pf_limits[PF_LIMIT_FRAGS].zone = V_pf_frent_z;
V_pf_limits[PF_LIMIT_FRAGS].limit = PFFRAG_FRENT_HIWAT;
+ uma_zone_set_max(V_pf_frent_z, PFFRAG_FRENT_HIWAT);
mtx_init(&pf_frag_mtx, "pf fragments", NULL, MTX_DEF);
@@ -201,11 +181,9 @@ void
pf_normalize_cleanup(void)
{
+ uma_zdestroy(V_pf_state_scrub_z);
uma_zdestroy(V_pf_frent_z);
uma_zdestroy(V_pf_frag_z);
- uma_zdestroy(V_pf_cache_z);
- uma_zdestroy(V_pf_cent_z);
- uma_zdestroy(V_pf_state_scrub_z);
mtx_destroy(&pf_frag_mtx);
}
@@ -271,30 +249,22 @@ pf_purge_expired_fragments(void)
static void
pf_flush_fragments(void)
{
- struct pf_fragment *frag;
+ struct pf_fragment *frag, *cache;
int goal;
PF_FRAG_ASSERT();
- goal = V_pf_nfrents * 9 / 10;
- DPFPRINTF(("trying to free > %d frents\n",
- V_pf_nfrents - goal));
- while (goal < V_pf_nfrents) {
+ goal = uma_zone_get_cur(V_pf_frent_z) * 9 / 10;
+ DPFPRINTF(("trying to free %d frag entriess\n", goal));
+ while (goal < uma_zone_get_cur(V_pf_frent_z)) {
frag = TAILQ_LAST(&V_pf_fragqueue, pf_fragqueue);
- if (frag == NULL)
+ if (frag)
+ pf_free_fragment(frag);
+ cache = TAILQ_LAST(&V_pf_cachequeue, pf_cachequeue);
+ if (cache)
+ pf_free_fragment(cache);
+ if (frag == NULL && cache == NULL)
break;
- pf_free_fragment(frag);
- }
-
-
- goal = V_pf_ncache * 9 / 10;
- DPFPRINTF(("trying to free > %d cache entries\n",
- V_pf_ncache - goal));
- while (goal < V_pf_ncache) {
- frag = TAILQ_LAST(&V_pf_cachequeue, pf_cachequeue);
- if (frag == NULL)
- break;
- pf_free_fragment(frag);
}
}
@@ -304,7 +274,6 @@ static void
pf_free_fragment(struct pf_fragment *frag)
{
struct pf_frent *frent;
- struct pf_frcache *frcache;
PF_FRAG_ASSERT();
@@ -316,21 +285,19 @@ pf_free_fragment(struct pf_fragment *fra
m_freem(frent->fr_m);
uma_zfree(V_pf_frent_z, frent);
- V_pf_nfrents--;
}
} else {
- for (frcache = LIST_FIRST(&frag->fr_cache); frcache;
- frcache = LIST_FIRST(&frag->fr_cache)) {
- LIST_REMOVE(frcache, fr_next);
-
- KASSERT((LIST_EMPTY(&frag->fr_cache) ||
- LIST_FIRST(&frag->fr_cache)->fr_off >
- frcache->fr_end),
+ for (frent = LIST_FIRST(&frag->fr_queue); frent;
+ frent = LIST_FIRST(&frag->fr_queue)) {
+ LIST_REMOVE(frent, fr_next);
+
+ KASSERT((LIST_EMPTY(&frag->fr_queue) ||
+ LIST_FIRST(&frag->fr_queue)->fr_off >
+ frent->fr_end),
("! (LIST_EMPTY() || LIST_FIRST()->fr_off >"
- " frcache->fr_end): %s", __FUNCTION__));
+ " frent->fr_end): %s", __func__));
- uma_zfree(V_pf_cent_z, frcache);
- V_pf_ncache--;
+ uma_zfree(V_pf_frent_z, frent);
}
}
@@ -387,7 +354,7 @@ pf_remove_fragment(struct pf_fragment *f
} else {
RB_REMOVE(pf_frag_tree, &V_pf_cache_tree, frag);
TAILQ_REMOVE(&V_pf_cachequeue, frag, frag_next);
- uma_zfree(V_pf_cache_z, frag);
+ uma_zfree(V_pf_frag_z, frag);
}
}
@@ -495,7 +462,6 @@ pf_reassemble(struct mbuf **m0, struct p
m_freem(frea->fr_m);
LIST_REMOVE(frea, fr_next);
uma_zfree(V_pf_frent_z, frea);
- V_pf_nfrents--;
}
insert:
@@ -552,13 +518,11 @@ pf_reassemble(struct mbuf **m0, struct p
m->m_next = NULL;
m_cat(m, m2);
uma_zfree(V_pf_frent_z, frent);
- V_pf_nfrents--;
for (frent = next; frent != NULL; frent = next) {
next = LIST_NEXT(frent, fr_next);
m2 = frent->fr_m;
uma_zfree(V_pf_frent_z, frent);
- V_pf_nfrents--;
m->m_pkthdr.csum_flags &= m2->m_pkthdr.csum_flags;
m->m_pkthdr.csum_data += m2->m_pkthdr.csum_data;
m_cat(m, m2);
@@ -594,7 +558,6 @@ pf_reassemble(struct mbuf **m0, struct p
drop_fragment:
/* Oops - fail safe - drop packet */
uma_zfree(V_pf_frent_z, frent);
- V_pf_nfrents--;
m_freem(m);
return (NULL);
}
@@ -604,7 +567,7 @@ pf_fragcache(struct mbuf **m0, struct ip
int drop, int *nomem)
{
struct mbuf *m = *m0;
- struct pf_frcache *frp, *fra, *cur = NULL;
+ struct pf_frent *frp, *fra, *cur = NULL;
int ip_len = ntohs(h->ip_len) - (h->ip_hl << 2);
u_int16_t off = ntohs(h->ip_off) << 3;
u_int16_t max = ip_len + off;
@@ -616,22 +579,21 @@ pf_fragcache(struct mbuf **m0, struct ip
/* Create a new range queue for this packet */
if (*frag == NULL) {
- *frag = uma_zalloc(V_pf_cache_z, M_NOWAIT);
+ *frag = uma_zalloc(V_pf_frag_z, M_NOWAIT);
if (*frag == NULL) {
pf_flush_fragments();
- *frag = uma_zalloc(V_pf_cache_z, M_NOWAIT);
+ *frag = uma_zalloc(V_pf_frag_z, M_NOWAIT);
if (*frag == NULL)
goto no_mem;
}
/* Get an entry for the queue */
- cur = uma_zalloc(V_pf_cent_z, M_NOWAIT);
+ cur = uma_zalloc(V_pf_frent_z, M_NOWAIT);
if (cur == NULL) {
- uma_zfree(V_pf_cache_z, *frag);
+ uma_zfree(V_pf_frag_z, *frag);
*frag = NULL;
goto no_mem;
}
- V_pf_ncache++;
(*frag)->fr_flags = PFFRAG_NOBUFFER;
(*frag)->fr_max = 0;
@@ -643,8 +605,8 @@ pf_fragcache(struct mbuf **m0, struct ip
cur->fr_off = off;
cur->fr_end = max;
- LIST_INIT(&(*frag)->fr_cache);
- LIST_INSERT_HEAD(&(*frag)->fr_cache, cur, fr_next);
+ LIST_INIT(&(*frag)->fr_queue);
+ LIST_INSERT_HEAD(&(*frag)->fr_queue, cur, fr_next);
RB_INSERT(pf_frag_tree, &V_pf_cache_tree, *frag);
TAILQ_INSERT_HEAD(&V_pf_cachequeue, *frag, frag_next);
@@ -659,7 +621,7 @@ pf_fragcache(struct mbuf **m0, struct ip
* - off contains the real shifted offset.
*/
frp = NULL;
- LIST_FOREACH(fra, &(*frag)->fr_cache, fr_next) {
+ LIST_FOREACH(fra, &(*frag)->fr_queue, fr_next) {
if (fra->fr_off > off)
break;
frp = fra;
@@ -749,10 +711,9 @@ pf_fragcache(struct mbuf **m0, struct ip
h->ip_id, -precut, frp->fr_off, frp->fr_end, off,
max));
- cur = uma_zalloc(V_pf_cent_z, M_NOWAIT);
+ cur = uma_zalloc(V_pf_frent_z, M_NOWAIT);
if (cur == NULL)
goto no_mem;
- V_pf_ncache++;
cur->fr_off = off;
cur->fr_end = max;
@@ -804,10 +765,9 @@ pf_fragcache(struct mbuf **m0, struct ip
h->ip_id, -aftercut, off, max, fra->fr_off,
fra->fr_end));
- cur = uma_zalloc(V_pf_cent_z, M_NOWAIT);
+ cur = uma_zalloc(V_pf_frent_z, M_NOWAIT);
if (cur == NULL)
goto no_mem;
- V_pf_ncache++;
cur->fr_off = off;
cur->fr_end = max;
@@ -825,8 +785,7 @@ pf_fragcache(struct mbuf **m0, struct ip
max, fra->fr_off, fra->fr_end));
fra->fr_off = cur->fr_off;
LIST_REMOVE(cur, fr_next);
- uma_zfree(V_pf_cent_z, cur);
- V_pf_ncache--;
+ uma_zfree(V_pf_frent_z, cur);
cur = NULL;
} else if (frp && fra->fr_off <= frp->fr_end) {
@@ -839,8 +798,7 @@ pf_fragcache(struct mbuf **m0, struct ip
max, fra->fr_off, fra->fr_end));
fra->fr_off = frp->fr_off;
LIST_REMOVE(frp, fr_next);
- uma_zfree(V_pf_cent_z, frp);
- V_pf_ncache--;
+ uma_zfree(V_pf_frent_z, frp);
frp = NULL;
}
@@ -868,8 +826,8 @@ pf_fragcache(struct mbuf **m0, struct ip
/* Check if we are completely reassembled */
if (((*frag)->fr_flags & PFFRAG_SEENLAST) &&
- LIST_FIRST(&(*frag)->fr_cache)->fr_off == 0 &&
- LIST_FIRST(&(*frag)->fr_cache)->fr_end == (*frag)->fr_max) {
+ LIST_FIRST(&(*frag)->fr_queue)->fr_off == 0 &&
+ LIST_FIRST(&(*frag)->fr_queue)->fr_end == (*frag)->fr_max) {
/* Remove from fragment queue */
DPFPRINTF(("fragcache[%d]: done 0-%d\n", h->ip_id,
(*frag)->fr_max));
@@ -1021,22 +979,19 @@ pf_normalize_ip(struct mbuf **m0, int di
REASON_SET(reason, PFRES_MEMORY);
return (PF_DROP);
}
- V_pf_nfrents++;
frent->fr_ip = h;
frent->fr_m = m;
/* Might return a completely reassembled mbuf, or NULL */
DPFPRINTF(("reass frag %d @ %d-%d\n", h->ip_id, fragoff, max));
*m0 = m = pf_reassemble(m0, &frag, frent, mff);
+ PF_FRAG_UNLOCK();
- if (m == NULL) {
- PF_FRAG_UNLOCK();
+ if (m == NULL)
return (PF_DROP);
- }
/* use mtag from concatenated mbuf chain */
pd->pf_mtag = pf_find_mtag(m);
- PF_FRAG_UNLOCK();
#ifdef DIAGNOSTIC
if (pd->pf_mtag == NULL) {
printf("%s: pf_find_mtag returned NULL(1)\n", __func__);
@@ -1077,8 +1032,8 @@ pf_normalize_ip(struct mbuf **m0, int di
*m0 = m = pf_fragcache(m0, h, &frag, mff,
(r->rule_flag & PFRULE_FRAGDROP) ? 1 : 0, &nomem);
+ PF_FRAG_UNLOCK();
if (m == NULL) {
- PF_FRAG_UNLOCK();
if (nomem)
goto no_mem;
goto drop;
@@ -1086,7 +1041,6 @@ pf_normalize_ip(struct mbuf **m0, int di
/* use mtag from copied and trimmed mbuf chain */
pd->pf_mtag = pf_find_mtag(m);
- PF_FRAG_UNLOCK();
#ifdef DIAGNOSTIC
if (pd->pf_mtag == NULL) {
printf("%s: pf_find_mtag returned NULL(2)\n", __func__);
@@ -1466,10 +1420,9 @@ pf_normalize_tcp_init(struct mbuf *m, in
KASSERT((src->scrub == NULL),
("pf_normalize_tcp_init: src->scrub != NULL"));
- src->scrub = uma_zalloc(V_pf_state_scrub_z, M_NOWAIT);
+ src->scrub = uma_zalloc(V_pf_state_scrub_z, M_ZERO | M_NOWAIT);
if (src->scrub == NULL)
return (1);
- bzero(src->scrub, sizeof(*src->scrub));
switch (pd->af) {
#ifdef INET
Modified: projects/pf/head/sys/contrib/pf/net/pfvar.h
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pfvar.h Tue Jun 5 19:42:57 2012 (r236629)
+++ projects/pf/head/sys/contrib/pf/net/pfvar.h Tue Jun 5 19:51:37 2012 (r236630)
@@ -1408,12 +1408,7 @@ struct pf_divert {
};
#define PFFRAG_FRENT_HIWAT 5000 /* Number of fragment entries */
-#define PFFRAG_FRAG_HIWAT 1000 /* Number of fragmented packets */
-#define PFFRAG_FRCENT_HIWAT 50000 /* Number of fragment cache entries */
-#define PFFRAG_FRCACHE_HIWAT 10000 /* Number of fragment descriptors */
-
#define PFR_KENTRY_HIWAT 200000 /* Number of table entries */
-#define PFR_KENTRY_HIWAT_SMALL 100000 /* Number of table entries (tiny hosts) */
/*
* ioctl parameter structures
More information about the svn-src-projects
mailing list