diff --git a/sys/netinet/ip_ecn.c b/sys/netinet/ip_ecn.c --- a/sys/netinet/ip_ecn.c +++ b/sys/netinet/ip_ecn.c @@ -60,7 +60,6 @@ * Outer Hdr at Inner Hdr at * Encapsulator Decapsulator * Header fields: -------------------- ------------ - * DS Field copied from inner hdr no change * ECN Field constructed by (I) constructed by (E) * * ECN_ALLOWED (normal mode): @@ -118,11 +117,12 @@ KASSERT(outer != NULL && inner != NULL, "NULL pointer passed to ip_ecn_ingress"); - *outer = *inner; switch (mode) { case ECN_COMPLETE: case ECN_ALLOWED: /* normal mode: always copy the ECN field. */ + *outer &= ~IPTOS_ECN_MASK; + *outer |= (*inner & IPTOS_ECN_MASK); break; case ECN_FORBIDDEN: @@ -131,6 +131,7 @@ break; case ECN_NOCARE: + *outer = *inner; break; } } @@ -205,9 +206,9 @@ KASSERT(outer != NULL && inner != NULL, "NULL pointer passed to ip6_ecn_ingress"); - inner8 = (ntohl(*inner) >> IPV6_FLOWLABEL_LEN) & 0xff; + inner8 = (ntohl(*inner) >> IPV6_FLOWLABEL_LEN) & 0x03; ip_ecn_ingress(mode, &outer8, &inner8); - *outer &= ~htonl(0xff << IPV6_FLOWLABEL_LEN); + *outer &= ~htonl(0x03 << IPV6_FLOWLABEL_LEN); *outer |= htonl((u_int32_t)outer8 << IPV6_FLOWLABEL_LEN); } @@ -220,14 +221,14 @@ KASSERT(outer != NULL && inner != NULL, "NULL pointer passed to ip6_ecn_egress"); - outer8 = (ntohl(*outer) >> IPV6_FLOWLABEL_LEN) & 0xff; - inner8 = oinner8 = (ntohl(*inner) >> IPV6_FLOWLABEL_LEN) & 0xff; + outer8 = (ntohl(*outer) >> IPV6_FLOWLABEL_LEN) & 0x03; + inner8 = oinner8 = (ntohl(*inner) >> IPV6_FLOWLABEL_LEN) & 0x03; ret = ip_ecn_egress(mode, &outer8, &inner8); if (ret == ECN_DROP) return (ECN_DROP); if (inner8 != oinner8) { - *inner &= ~htonl(0xff << IPV6_FLOWLABEL_LEN); + *inner &= ~htonl(0x03 << IPV6_FLOWLABEL_LEN); *inner |= htonl((u_int32_t)inner8 << IPV6_FLOWLABEL_LEN); } return (ret);