summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/frag6.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet6/frag6.c')
-rw-r--r--sys/netinet6/frag6.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c
index ea4e6ca..dbf9279 100644
--- a/sys/netinet6/frag6.c
+++ b/sys/netinet6/frag6.c
@@ -1,5 +1,5 @@
/* $FreeBSD$ */
-/* $KAME: frag6.c,v 1.24 2000/03/25 07:23:41 sumikawa Exp $ */
+/* $KAME: frag6.c,v 1.31 2001/05/17 13:45:34 jinmei Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -66,6 +66,7 @@ static void frag6_insque __P((struct ip6q *, struct ip6q *));
static void frag6_remque __P((struct ip6q *));
static void frag6_freef __P((struct ip6q *));
+/* XXX we eventually need splreass6, or some real semaphore */
int frag6_doing_reass;
u_int frag6_nfragpackets;
struct ip6q ip6q; /* ip6 reassemble queue */
@@ -206,6 +207,8 @@ frag6_input(mp, offp, proto)
/* offset now points to data portion */
offset += sizeof(struct ip6_frag);
+ frag6_doing_reass = 1;
+
for (q6 = ip6q.ip6q_next; q6 != &ip6q; q6 = q6->ip6q_next)
if (ip6f->ip6f_ident == q6->ip6q_ident &&
IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, &q6->ip6q_src) &&
@@ -217,7 +220,6 @@ frag6_input(mp, offp, proto)
* the first fragment to arrive, create a reassembly queue.
*/
first_frag = 1;
- frag6_nfragpackets++;
/*
* Enforce upper bound on number of fragmented packets
@@ -225,11 +227,11 @@ frag6_input(mp, offp, proto)
* If maxfrag is 0, never accept fragments.
* If maxfrag is -1, accept all fragments without limitation.
*/
- if (frag6_nfragpackets >= (u_int)ip6_maxfragpackets) {
- ip6stat.ip6s_fragoverflow++;
- in6_ifstat_inc(dstifp, ifs6_reass_fail);
- frag6_freef(ip6q.ip6q_prev);
- }
+ if (ip6_maxfragpackets < 0)
+ ;
+ else if (frag6_nfragpackets >= (u_int)ip6_maxfragpackets)
+ goto dropfrag;
+ frag6_nfragpackets++;
q6 = (struct ip6q *)malloc(sizeof(struct ip6q), M_FTABLE,
M_DONTWAIT);
if (q6 == NULL)
@@ -274,6 +276,7 @@ frag6_input(mp, offp, proto)
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
offset - sizeof(struct ip6_frag) +
offsetof(struct ip6_frag, ip6f_offlg));
+ frag6_doing_reass = 0;
return(IPPROTO_DONE);
}
}
@@ -281,6 +284,7 @@ frag6_input(mp, offp, proto)
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
offset - sizeof(struct ip6_frag) +
offsetof(struct ip6_frag, ip6f_offlg));
+ frag6_doing_reass = 0;
return(IPPROTO_DONE);
}
/*
@@ -531,6 +535,7 @@ insert:
in6_ifstat_inc(dstifp, ifs6_reass_fail);
ip6stat.ip6s_fragdropped++;
m_freem(m);
+ frag6_doing_reass = 0;
return IPPROTO_DONE;
}
@@ -620,7 +625,7 @@ frag6_remque(p6)
}
/*
- * IP timer processing;
+ * IPv6 reassembling timer processing;
* if a timer expires on a reassembly
* queue, discard it.
*/
@@ -629,9 +634,6 @@ frag6_slowtimo()
{
struct ip6q *q6;
int s = splnet();
-#if 0
- extern struct route_in6 ip6_forward_rt;
-#endif
frag6_doing_reass = 1;
q6 = ip6q.ip6q_next;
@@ -650,7 +652,8 @@ frag6_slowtimo()
* (due to the limit being lowered), drain off
* enough to get down to the new limit.
*/
- while (frag6_nfragpackets > (u_int)ip6_maxfragpackets) {
+ while (frag6_nfragpackets > (u_int)ip6_maxfragpackets &&
+ ip6q.ip6q_prev) {
ip6stat.ip6s_fragoverflow++;
/* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
frag6_freef(ip6q.ip6q_prev);
OpenPOWER on IntegriCloud