diff options
Diffstat (limited to 'sys/netinet6/frag6.c')
-rw-r--r-- | sys/netinet6/frag6.c | 27 |
1 files changed, 13 insertions, 14 deletions
diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c index 7403e13..964f71f 100644 --- a/sys/netinet6/frag6.c +++ b/sys/netinet6/frag6.c @@ -259,10 +259,11 @@ frag6_input(mp, offp, proto) q6->ip6q_nxtp = (u_char *)nxtp; #endif q6->ip6q_ident = ip6f->ip6f_ident; - q6->ip6q_arrive = 0; /* Is it used anywhere? */ q6->ip6q_ttl = IPV6_FRAGTTL; q6->ip6q_src = ip6->ip6_src; q6->ip6q_dst = ip6->ip6_dst; + q6->ip6q_ecn = + (ntohl(ip6->ip6_flow) >> 20) & IPTOS_ECN_MASK; q6->ip6q_unfrglen = -1; /* The 1st fragment has not arrived. */ q6->ip6q_nfrag = 0; @@ -343,10 +344,6 @@ frag6_input(mp, offp, proto) if (ip6af == NULL) goto dropfrag; bzero(ip6af, sizeof(*ip6af)); - ip6af->ip6af_head = ip6->ip6_flow; - ip6af->ip6af_len = ip6->ip6_plen; - ip6af->ip6af_nxt = ip6->ip6_nxt; - ip6af->ip6af_hlim = ip6->ip6_hlim; ip6af->ip6af_mff = ip6f->ip6f_offlg & IP6F_MORE_FRAG; ip6af->ip6af_off = fragoff; ip6af->ip6af_frglen = frgpartlen; @@ -364,14 +361,14 @@ frag6_input(mp, offp, proto) * drop if CE and not-ECT are mixed for the same packet. */ ecn = (ntohl(ip6->ip6_flow) >> 20) & IPTOS_ECN_MASK; - ecn0 = (ntohl(q6->ip6q_down->ip6af_head) >> 20) & IPTOS_ECN_MASK; + ecn0 = q6->ip6q_ecn; if (ecn == IPTOS_ECN_CE) { if (ecn0 == IPTOS_ECN_NOTECT) { free(ip6af, M_FTABLE); goto dropfrag; } if (ecn0 != IPTOS_ECN_CE) - q6->ip6q_down->ip6af_head |= htonl(IPTOS_ECN_CE << 20); + q6->ip6q_ecn = IPTOS_ECN_CE; } if (ecn == IPTOS_ECN_NOTECT && ecn0 != IPTOS_ECN_NOTECT) { free(ip6af, M_FTABLE); @@ -428,6 +425,9 @@ frag6_input(mp, offp, proto) * existing fragments from a security point of view. * We don't know which fragment is the bad guy - here we trust * fragment that came in earlier, with no real reason. + * + * Note: due to changes after disabling this part, mbuf passed to + * m_adj() below now does not meet the requirement. */ if (af6->ip6af_up != (struct ip6asfrag *)q6) { i = af6->ip6af_up->ip6af_off + af6->ip6af_up->ip6af_frglen @@ -510,19 +510,18 @@ insert: free(ip6af, M_FTABLE); ip6 = mtod(m, struct ip6_hdr *); ip6->ip6_plen = htons((u_short)next + offset - sizeof(struct ip6_hdr)); - ip6->ip6_src = q6->ip6q_src; - ip6->ip6_dst = q6->ip6q_dst; + if (q6->ip6q_ecn == IPTOS_ECN_CE) + ip6->ip6_flow |= htonl(IPTOS_ECN_CE << 20); nxt = q6->ip6q_nxt; #ifdef notyet *q6->ip6q_nxtp = (u_char)(nxt & 0xff); #endif - /* - * Delete frag6 header with as a few cost as possible. - */ - if (offset < m->m_len) { + /* Delete frag6 header */ + if (m->m_len >= offset + sizeof(struct ip6_frag)) { + /* This is the only possible case with !PULLDOWN_TEST */ ovbcopy((caddr_t)ip6, (caddr_t)ip6 + sizeof(struct ip6_frag), - offset); + offset); m->m_data += sizeof(struct ip6_frag); m->m_len -= sizeof(struct ip6_frag); } else { |