summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2012-01-23 18:37:21 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2012-01-23 18:37:21 +0000
commitbb4a1aa885fbcdfc1215753a65eff08602291cf5 (patch)
treeacb8d2fd0f87ab733f468d76563809a3dde5c6ff
parent7f03c6135168029dc951e54895750e5651e1f96e (diff)
Do not keep state when dropping overlapping IPv6 fragments in pf
and IPv6 stack. ok sperreault@
-rw-r--r--sys/net/pf_norm.c35
-rw-r--r--sys/netinet6/frag6.c22
2 files changed, 18 insertions, 39 deletions
diff --git a/sys/net/pf_norm.c b/sys/net/pf_norm.c
index 345969c7a91..e0eb39fc449 100644
--- a/sys/net/pf_norm.c
+++ b/sys/net/pf_norm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_norm.c,v 1.150 2012/01/15 22:55:35 bluhm Exp $ */
+/* $OpenBSD: pf_norm.c,v 1.151 2012/01/23 18:37:20 bluhm Exp $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
@@ -326,15 +326,7 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct pf_frent *frent,
return (frag);
}
- if (TAILQ_EMPTY(&frag->fr_queue)) {
- /*
- * Overlapping IPv6 fragments have been detected. Do not
- * reassemble packet but also drop future fragments.
- * This will be done for this ident/src/dst combination
- * until fragment queue timeout.
- */
- goto drop_fragment;
- }
+ KASSERT(!TAILQ_EMPTY(&frag->fr_queue));
/* Remember maximum fragment len for refragmentation */
if (frent->fe_len > frag->fr_maxlen)
@@ -372,7 +364,7 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct pf_frent *frent,
u_int16_t precut;
if (frag->fr_af == AF_INET6)
- goto flush_fragentries;
+ goto free_fragment;
precut = prev->fe_off + prev->fe_len - frent->fe_off;
if (precut >= frent->fe_len) {
@@ -391,7 +383,7 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct pf_frent *frent,
u_int16_t aftercut;
if (frag->fr_af == AF_INET6)
- goto flush_fragentries;
+ goto free_fragment;
aftercut = frent->fe_off + frent->fe_len - after->fe_off;
if (aftercut < after->fe_len) {
@@ -419,22 +411,15 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct pf_frent *frent,
return (frag);
- flush_fragentries:
+ free_fragment:
/*
- * RFC5722: When reassembling an IPv6 datagram, if one or
- * more its constituent fragments is determined to be an
- * overlapping fragment, the entire datagram (and any constituent
- * fragments, including those not yet received) MUST be
- * silently discarded.
+ * RFC 5722, Errata 3089: When reassembling an IPv6 datagram, if one
+ * or more its constituent fragments is determined to be an overlapping
+ * fragment, the entire datagram (and any constituent fragments) MUST
+ * be silently discarded.
*/
DPFPRINTF(LOG_NOTICE, "flush overlapping fragments");
- while ((prev = TAILQ_FIRST(&frag->fr_queue)) != NULL) {
- TAILQ_REMOVE(&frag->fr_queue, prev, fr_next);
-
- m_freem(prev->fe_m);
- pool_put(&pf_frent_pl, prev);
- pf_nfrents--;
- }
+ pf_free_fragment(frag);
bad_fragment:
REASON_SET(reason, PFRES_FRAG);
drop_fragment:
diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c
index 779740399ed..18ef0b035ec 100644
--- a/sys/netinet6/frag6.c
+++ b/sys/netinet6/frag6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: frag6.c,v 1.40 2012/01/10 17:09:02 bluhm Exp $ */
+/* $OpenBSD: frag6.c,v 1.41 2012/01/23 18:37:20 bluhm Exp $ */
/* $KAME: frag6.c,v 1.40 2002/05/27 21:40:31 itojun Exp $ */
/*
@@ -285,14 +285,6 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
q6->ip6q_dst = ip6->ip6_dst;
q6->ip6q_unfrglen = -1; /* The 1st fragment has not arrived. */
q6->ip6q_nfrag = 0;
- } else if (LIST_EMPTY(&q6->ip6q_asfrag)) {
- /*
- * Overlapping fragments have been detected. Do not
- * reassemble packet but also drop future fragments.
- * This will be done for this ident/src/dst combination
- * until fragment queue timeout.
- */
- goto dropfrag;
}
/*
@@ -409,10 +401,10 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
break;
/*
- * RFC5722: When reassembling an IPv6 datagram, if one or more its
- * constituent fragments is determined to be an overlapping fragment,
- * the entire datagram (and any constituent fragments, including those
- * not yet received) MUST be silently discarded.
+ * RFC 5722, Errata 3089: When reassembling an IPv6 datagram, if one
+ * or more its constituent fragments is determined to be an overlapping
+ * fragment, the entire datagram (and any constituent fragments) MUST
+ * be silently discarded.
*/
if (paf6 != LIST_END(&q6->ip6q_asfrag)) {
i = (paf6->ip6af_off + paf6->ip6af_frglen) - ip6af->ip6af_off;
@@ -549,8 +541,10 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
free(af6, M_FTABLE);
}
ip6stat.ip6s_fragdropped += q6->ip6q_nfrag;
+ TAILQ_REMOVE(&frag6_queue, q6, ip6q_queue);
frag6_nfrags -= q6->ip6q_nfrag;
- q6->ip6q_nfrag = 0;
+ free(q6, M_FTABLE);
+ frag6_nfragpackets--;
dropfrag:
in6_ifstat_inc(dstifp, ifs6_reass_fail);