Index: sys/netinet6/frag6.c =================================================================== --- sys/netinet6/frag6.c +++ sys/netinet6/frag6.c @@ -63,7 +63,7 @@ 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; /* @@ -159,7 +159,7 @@ int fragoff, frgpartlen; /* must be larger than u_int16_t */ struct ifnet *dstifp; u_int8_t ecn, ecn0; -#if 0 +#if 1 char ip6buf[INET6_ADDRSTRLEN]; #endif @@ -453,24 +453,26 @@ i = af6->ip6af_up->ip6af_off + af6->ip6af_up->ip6af_frglen - ip6af->ip6af_off; if (i > 0) { -#if 0 /* suppress the noisy log */ +#if 1 /* suppress the noisy log */ log(LOG_ERR, "%d bytes of a fragment from %s " "overlaps the previous fragment\n", i, ip6_sprintf(ip6buf, &q6->ip6q_src)); #endif free(ip6af, M_FTABLE); + frag6_freef(q6, 0); goto dropfrag; } } if (af6 != (struct ip6asfrag *)q6) { i = (ip6af->ip6af_off + ip6af->ip6af_frglen) - af6->ip6af_off; if (i > 0) { -#if 0 /* suppress the noisy log */ +#if 1 /* suppress the noisy log */ log(LOG_ERR, "%d bytes of a fragment from %s " "overlaps the succeeding fragment", i, ip6_sprintf(ip6buf, &q6->ip6q_src)); #endif free(ip6af, M_FTABLE); + frag6_freef(q6, 0); goto dropfrag; } } @@ -603,7 +605,7 @@ * associated datagrams. */ void -frag6_freef(struct ip6q *q6) +frag6_freef(struct ip6q *q6, int sendicmp) { struct ip6asfrag *af6, *down6; @@ -620,7 +622,7 @@ * 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 @@ 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 @@ 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 @@ 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(); }