summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet6/frag6.c27
-rw-r--r--sys/netinet6/ip6_var.h14
2 files changed, 16 insertions, 25 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 {
diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h
index 91b444b..8aafe93 100644
--- a/sys/netinet6/ip6_var.h
+++ b/sys/netinet6/ip6_var.h
@@ -69,16 +69,13 @@
* being reassembled is attached to one of these structures.
*/
struct ip6q {
- u_int32_t ip6q_head;
- u_int16_t ip6q_len;
- u_int8_t ip6q_nxt; /* ip6f_nxt in first fragment */
- u_int8_t ip6q_hlim;
struct ip6asfrag *ip6q_down;
struct ip6asfrag *ip6q_up;
u_int32_t ip6q_ident;
- u_int8_t ip6q_arrive;
+ u_int8_t ip6q_nxt;
+ u_int8_t ip6q_ecn;
u_int8_t ip6q_ttl;
- struct in6_addr ip6q_src, ip6q_dst;
+ struct in6_addr ip6q_src, ip6q_dst;
struct ip6q *ip6q_next;
struct ip6q *ip6q_prev;
int ip6q_unfrglen; /* len of unfragmentable part */
@@ -89,11 +86,6 @@ struct ip6q {
};
struct ip6asfrag {
- u_int32_t ip6af_head;
- u_int16_t ip6af_len;
- u_int8_t ip6af_nxt;
- u_int8_t ip6af_hlim;
- /* must not override the above members during reassembling */
struct ip6asfrag *ip6af_down;
struct ip6asfrag *ip6af_up;
struct mbuf *ip6af_m;
OpenPOWER on IntegriCloud