summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorKenjiro Cho <kjc@cvs.openbsd.org>2002-05-17 07:16:27 +0000
committerKenjiro Cho <kjc@cvs.openbsd.org>2002-05-17 07:16:27 +0000
commit66237872139a844457e646fc63357f62a6b17281 (patch)
tree4ec0fe9d9bd211abe67fc15c495afbdab0b2a360 /sys
parent8d2468c02e807c605250387bf25a15d60fc8be73 (diff)
sync with KAME.
update ECN in ALTQ from RFC2481 to RFC3168.
Diffstat (limited to 'sys')
-rw-r--r--sys/altq/altq_blue.c84
-rw-r--r--sys/altq/altq_red.c85
2 files changed, 77 insertions, 92 deletions
diff --git a/sys/altq/altq_blue.c b/sys/altq/altq_blue.c
index 263ba50b0af..2b9964853f8 100644
--- a/sys/altq/altq_blue.c
+++ b/sys/altq/altq_blue.c
@@ -1,8 +1,8 @@
-/* $OpenBSD: altq_blue.c,v 1.4 2002/03/14 03:15:50 millert Exp $ */
-/* $KAME: altq_blue.c,v 1.7 2000/12/14 08:12:45 thorpej Exp $ */
+/* $OpenBSD: altq_blue.c,v 1.5 2002/05/17 07:16:26 kjc Exp $ */
+/* $KAME: altq_blue.c,v 1.9 2002/04/03 05:38:50 kjc Exp $ */
/*
- * Copyright (C) 1997-2000
+ * Copyright (C) 1997-2002
* Sony Computer Science Laboratories Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -536,46 +536,32 @@ mark_ecn(m, pktattr, flags)
case AF_INET:
if (flags & BLUEF_ECN4) {
struct ip *ip = (struct ip *)pktattr->pattr_hdr;
+ u_int8_t otos;
+ int sum;
if (ip->ip_v != 4)
return (0); /* version mismatch! */
- if (ip->ip_tos & IPTOS_ECT) {
- /* ECN-capable, mark ECN bit. */
- if ((ip->ip_tos & IPTOS_CE) == 0) {
-#if (IPTOS_CE == 0x01)
- u_short sum;
-
- ip->ip_tos |= IPTOS_CE;
- /*
- * optimized version when IPTOS_CE
- * is 0x01.
- * HC' = HC -1 when HC > 0
- * = 0xfffe when HC = 0
- */
- sum = ntohs(ip->ip_sum);
- if (sum == 0)
- sum = 0xfffe;
- else
- sum -= 1;
- ip->ip_sum = htons(sum);
-#else /* IPTOS_CE != 0x01 */
- long sum;
-
- ip->ip_tos |= IPTOS_CE;
- /*
- * update checksum (from RFC1624)
- * HC' = ~(~HC + ~m + m')
- */
- sum = ~ntohs(ip->ip_sum) & 0xffff;
- sum += 0xffff + IPTOS_CE;
- sum = (sum >> 16) + (sum & 0xffff);
- sum += (sum >> 16); /* add carry */
-
- ip->ip_sum = htons(~sum & 0xffff);
-#endif /* IPTOS_CE != 0x01 */
- }
- return (1);
- }
+ if ((ip->ip_tos & IPTOS_ECN_MASK) == IPTOS_ECN_NOTECT)
+ return (0); /* not-ECT */
+ if ((ip->ip_tos & IPTOS_ECN_MASK) == IPTOS_ECN_CE)
+ return (1); /* already marked */
+
+ /*
+ * ecn-capable but not marked,
+ * mark CE and update checksum
+ */
+ otos = ip->ip_tos;
+ ip->ip_tos |= IPTOS_ECN_CE;
+ /*
+ * update checksum (from RFC1624)
+ * HC' = ~(~HC + ~m + m')
+ */
+ sum = ~ntohs(ip->ip_sum) & 0xffff;
+ sum += (~otos & 0xffff) + ip->ip_tos;
+ sum = (sum >> 16) + (sum & 0xffff);
+ sum += (sum >> 16); /* add carry */
+ ip->ip_sum = htons(~sum & 0xffff);
+ return (1);
}
break;
#ifdef INET6
@@ -587,12 +573,18 @@ mark_ecn(m, pktattr, flags)
flowlabel = ntohl(ip6->ip6_flow);
if ((flowlabel >> 28) != 6)
return (0); /* version mismatch! */
- if (flowlabel & (IPTOS_ECT << 20)) {
- /* ECN-capable, mark ECN bit. */
- flowlabel |= (IPTOS_CE << 20);
- ip6->ip6_flow = htonl(flowlabel);
- return (1);
- }
+ if ((flowlabel & (IPTOS_ECN_MASK << 20)) ==
+ (IPTOS_ECN_NOTECT << 20))
+ return (0); /* not-ECT */
+ if ((flowlabel & (IPTOS_ECN_MASK << 20)) ==
+ (IPTOS_ECN_CE << 20))
+ return (1); /* already marked */
+ /*
+ * ecn-capable but not marked, mark CE
+ */
+ flowlabel |= (IPTOS_ECN_CE << 20);
+ ip6->ip6_flow = htonl(flowlabel);
+ return (1);
}
break;
#endif /* INET6 */
diff --git a/sys/altq/altq_red.c b/sys/altq/altq_red.c
index 70d7ec18097..b2d91f3ac7f 100644
--- a/sys/altq/altq_red.c
+++ b/sys/altq/altq_red.c
@@ -1,8 +1,8 @@
-/* $OpenBSD: altq_red.c,v 1.3 2002/03/14 01:26:26 millert Exp $ */
-/* $KAME: altq_red.c,v 1.8 2000/12/14 08:12:46 thorpej Exp $ */
+/* $OpenBSD: altq_red.c,v 1.4 2002/05/17 07:16:26 kjc Exp $ */
+/* $KAME: altq_red.c,v 1.10 2002/04/03 05:38:51 kjc Exp $ */
/*
- * Copyright (C) 1997-2000
+ * Copyright (C) 1997-2002
* Sony Computer Science Laboratories Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -837,46 +837,33 @@ mark_ecn(m, pktattr, flags)
case AF_INET:
if (flags & REDF_ECN4) {
struct ip *ip = (struct ip *)pktattr->pattr_hdr;
+ u_int8_t otos;
+ int sum;
if (ip->ip_v != 4)
return (0); /* version mismatch! */
- if (ip->ip_tos & IPTOS_ECT) {
- /* ECN-capable, mark ECN bit. */
- if ((ip->ip_tos & IPTOS_CE) == 0) {
-#if (IPTOS_CE == 0x01)
- u_short sum;
-
- ip->ip_tos |= IPTOS_CE;
- /*
- * optimized version when IPTOS_CE
- * is 0x01.
- * HC' = HC -1 when HC > 0
- * = 0xfffe when HC = 0
- */
- sum = ntohs(ip->ip_sum);
- if (sum == 0)
- sum = 0xfffe;
- else
- sum -= 1;
- ip->ip_sum = htons(sum);
-#else /* IPTOS_CE != 0x01 */
- long sum;
-
- ip->ip_tos |= IPTOS_CE;
- /*
- * update checksum (from RFC1624)
- * HC' = ~(~HC + ~m + m')
- */
- sum = ~ntohs(ip->ip_sum) & 0xffff;
- sum += 0xffff + IPTOS_CE;
- sum = (sum >> 16) + (sum & 0xffff);
- sum += (sum >> 16); /* add carry */
-
- ip->ip_sum = htons(~sum & 0xffff);
-#endif /* IPTOS_CE != 0x01 */
- }
- return (1);
- }
+
+ if ((ip->ip_tos & IPTOS_ECN_MASK) == IPTOS_ECN_NOTECT)
+ return (0); /* not-ECT */
+ if ((ip->ip_tos & IPTOS_ECN_MASK) == IPTOS_ECN_CE)
+ return (1); /* already marked */
+
+ /*
+ * ecn-capable but not marked,
+ * mark CE and update checksum
+ */
+ otos = ip->ip_tos;
+ ip->ip_tos |= IPTOS_ECN_CE;
+ /*
+ * update checksum (from RFC1624)
+ * HC' = ~(~HC + ~m + m')
+ */
+ sum = ~ntohs(ip->ip_sum) & 0xffff;
+ sum += (~otos & 0xffff) + ip->ip_tos;
+ sum = (sum >> 16) + (sum & 0xffff);
+ sum += (sum >> 16); /* add carry */
+ ip->ip_sum = htons(~sum & 0xffff);
+ return (1);
}
break;
#ifdef INET6
@@ -888,12 +875,18 @@ mark_ecn(m, pktattr, flags)
flowlabel = ntohl(ip6->ip6_flow);
if ((flowlabel >> 28) != 6)
return (0); /* version mismatch! */
- if (flowlabel & (IPTOS_ECT << 20)) {
- /* ECN-capable, mark ECN bit. */
- flowlabel |= (IPTOS_CE << 20);
- ip6->ip6_flow = htonl(flowlabel);
- return (1);
- }
+ if ((flowlabel & (IPTOS_ECN_MASK << 20)) ==
+ (IPTOS_ECN_NOTECT << 20))
+ return (0); /* not-ECT */
+ if ((flowlabel & (IPTOS_ECN_MASK << 20)) ==
+ (IPTOS_ECN_CE << 20))
+ return (1); /* already marked */
+ /*
+ * ecn-capable but not marked, mark CE
+ */
+ flowlabel |= (IPTOS_ECN_CE << 20);
+ ip6->ip6_flow = htonl(flowlabel);
+ return (1);
}
break;
#endif /* INET6 */