Implement behavior suggested by RFC5722: drop the fragment queue
entirely if the system receives a duplicate fragment
Details
- Reviewers
bz
Send a fragmented packet to the system, then send one of the fragments
once again. One can use frag6 tests from the OpenBSD regression suite.
Diff Detail
- Lint
Lint Skipped - Unit
Tests Skipped
Event Timeline
I have added the wrong revision to the review!
This is the correct one, I couldn't edit the patch itself :-(
- a/sys/netinet6/frag6.c
+++ b/sys/netinet6/frag6.c
@@ -63,7 +63,7 @@ static void frag6_enq(struct ip6asfrag *, struct ip6asfrag *);
static void frag6_deq(struct ip6asfrag *);
static void frag6_insque(struct ip6q *, struct ip6q *);
static void frag6_remque(struct ip6q *);
-static void frag6_freef(struct ip6q *);
+static void frag6_freef(struct ip6q *, int);
static struct mtx ip6qlock;
/*
@@ -459,6 +459,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
i, ip6_sprintf(ip6buf, &q6->ip6q_src));
#endif
free(ip6af, M_FTABLE);
+ frag6_freef(q6, 0);
goto dropfrag; } }
@@ -471,6 +472,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
i, ip6_sprintf(ip6buf, &q6->ip6q_src));
#endif
free(ip6af, M_FTABLE);
+ frag6_freef(q6, 0);
goto dropfrag; } }
@@ -603,7 +605,7 @@ insert:
- associated datagrams. */ void
-frag6_freef(struct ip6q *q6)
+frag6_freef(struct ip6q *q6, int sendicmp)
{
struct ip6asfrag *af6, *down6;
@@ -620,7 +622,7 @@ frag6_freef(struct ip6q *q6)
- Return ICMP time exceeded error for the 1st fragment.
- Just free other fragments. */
- if (af6->ip6af_off == 0) {
+ if (af6->ip6af_off == 0 && sendicmp == 1) {
struct ip6_hdr *ip6; /* adjust pointer */
@@ -719,7 +721,7 @@ frag6_slowtimo(void)
if (q6->ip6q_prev->ip6q_ttl == 0) { IP6STAT_INC(ip6s_fragtimeout); /* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
- frag6_freef(q6->ip6q_prev);
+ frag6_freef(q6->ip6q_prev, 1);
} } /*
@@ -731,7 +733,7 @@ frag6_slowtimo(void)
V_ip6q.ip6q_prev) { IP6STAT_INC(ip6s_fragoverflow); /* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
- frag6_freef(V_ip6q.ip6q_prev);
+ frag6_freef(V_ip6q.ip6q_prev, 1);
} CURVNET_RESTORE(); }
@@ -757,7 +759,7 @@ frag6_drain(void)
while (V_ip6q.ip6q_next != &V_ip6q) { IP6STAT_INC(ip6s_fragdropped); /* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
- frag6_freef(V_ip6q.ip6q_next);
+ frag6_freef(V_ip6q.ip6q_next, 1);
} CURVNET_RESTORE(); }
I somehow would expect a comment to be updated somewhere referencing RFC5722?
Appart from that no objections though I have only skimmed through and not properly reviewed this.