diff options
Diffstat (limited to 'freebsd/sys/netpfil/pf/pf_norm.c')
-rw-r--r-- | freebsd/sys/netpfil/pf/pf_norm.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/freebsd/sys/netpfil/pf/pf_norm.c b/freebsd/sys/netpfil/pf/pf_norm.c index 61da5e4f..0f98c669 100644 --- a/freebsd/sys/netpfil/pf/pf_norm.c +++ b/freebsd/sys/netpfil/pf/pf_norm.c @@ -93,8 +93,10 @@ struct pf_fragment { TAILQ_ENTRY(pf_fragment) frag_next; uint32_t fr_timeout; uint16_t fr_maxlen; /* maximum length of single fragment */ + uint16_t fr_entries; /* Total number of pf_fragment entries */ TAILQ_HEAD(pf_fragq, pf_frent) fr_queue; }; +#define PF_MAX_FRENT_PER_FRAGMENT 64 struct pf_fragment_tag { uint16_t ft_hdrlen; /* header length of reassembled pkt */ @@ -111,17 +113,17 @@ MTX_SYSINIT(pf_frag_mtx, &pf_frag_mtx, "pf fragments", MTX_DEF); VNET_DEFINE(uma_zone_t, pf_state_scrub_z); /* XXX: shared with pfsync */ -static VNET_DEFINE(uma_zone_t, pf_frent_z); +VNET_DEFINE_STATIC(uma_zone_t, pf_frent_z); #define V_pf_frent_z VNET(pf_frent_z) -static VNET_DEFINE(uma_zone_t, pf_frag_z); +VNET_DEFINE_STATIC(uma_zone_t, pf_frag_z); #define V_pf_frag_z VNET(pf_frag_z) TAILQ_HEAD(pf_fragqueue, pf_fragment); TAILQ_HEAD(pf_cachequeue, pf_fragment); -static VNET_DEFINE(struct pf_fragqueue, pf_fragqueue); +VNET_DEFINE_STATIC(struct pf_fragqueue, pf_fragqueue); #define V_pf_fragqueue VNET(pf_fragqueue) RB_HEAD(pf_frag_tree, pf_fragment); -static VNET_DEFINE(struct pf_frag_tree, pf_frag_tree); +VNET_DEFINE_STATIC(struct pf_frag_tree, pf_frag_tree); #define V_pf_frag_tree VNET(pf_frag_tree) static int pf_frag_compare(struct pf_fragment *, struct pf_fragment *); @@ -386,6 +388,7 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct pf_frent *frent, *(struct pf_fragment_cmp *)frag = *key; frag->fr_timeout = time_uptime; frag->fr_maxlen = frent->fe_len; + frag->fr_entries = 0; TAILQ_INIT(&frag->fr_queue); RB_INSERT(pf_frag_tree, &V_pf_frag_tree, frag); @@ -397,6 +400,9 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct pf_frent *frent, return (frag); } + if (frag->fr_entries >= PF_MAX_FRENT_PER_FRAGMENT) + goto bad_fragment; + KASSERT(!TAILQ_EMPTY(&frag->fr_queue), ("!TAILQ_EMPTY()->fr_queue")); /* Remember maximum fragment len for refragmentation. */ @@ -469,6 +475,8 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct pf_frent *frent, else TAILQ_INSERT_AFTER(&frag->fr_queue, prev, frent, fr_next); + frag->fr_entries++; + return (frag); bad_fragment: |