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, 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 {
OpenPOWER on IntegriCloud