summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/ip_input.c')
-rw-r--r--sys/netinet/ip_input.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 02bd132..30a5b75 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1037,6 +1037,7 @@ ip_reass(struct mbuf *m, struct ipqhead *head, struct ipq *fp,
struct mbuf *t;
int hlen = ip->ip_hl << 2;
int i, next;
+ u_int8_t ecn, ecn0;
IPQ_LOCK_ASSERT();
@@ -1086,6 +1087,22 @@ ip_reass(struct mbuf *m, struct ipqhead *head, struct ipq *fp,
#define GETIP(m) ((struct ip*)((m)->m_pkthdr.header))
/*
+ * Handle ECN by comparing this segment with the first one;
+ * if CE is set, do not lose CE.
+ * drop if CE and not-ECT are mixed for the same packet.
+ */
+ ecn = ip->ip_tos & IPTOS_ECN_MASK;
+ ecn0 = GETIP(fp->ipq_frags)->ip_tos & IPTOS_ECN_MASK;
+ if (ecn == IPTOS_ECN_CE) {
+ if (ecn0 == IPTOS_ECN_NOTECT)
+ goto dropfrag;
+ if (ecn0 != IPTOS_ECN_CE)
+ GETIP(fp->ipq_frags)->ip_tos |= IPTOS_ECN_CE;
+ }
+ if (ecn == IPTOS_ECN_NOTECT && ecn0 != IPTOS_ECN_NOTECT)
+ goto dropfrag;
+
+ /*
* Find a segment which begins after this one does.
*/
for (p = NULL, q = fp->ipq_frags; q; p = q, q = q->m_nextpkt)
OpenPOWER on IntegriCloud