netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net] tunnel: Propagate ECT(1) when decapsulating as recommended by RFC6040
@ 2020-04-27 14:11 Toke Høiland-Jørgensen
  2020-05-01  3:33 ` David Miller
  0 siblings, 1 reply; 2+ messages in thread
From: Toke Høiland-Jørgensen @ 2020-04-27 14:11 UTC (permalink / raw)
  To: davem
  Cc: Toke Høiland-Jørgensen, netdev, Bob Briscoe,
	Olivier Tilmans, Dave Taht, Stephen Hemminger

RFC 6040 recommends propagating an ECT(1) mark from an outer tunnel header
to the inner header if that inner header is already marked as ECT(0). When
RFC 6040 decapsulation was implemented, this case of propagation was not
added. This simply appears to be an oversight, so let's fix that.

Fixes: eccc1bb8d4b4 ("tunnel: drop packet if ECN present with not-ECT")
Reported-by: Bob Briscoe <ietf@bobbriscoe.net>
Reported-by: Olivier Tilmans <olivier.tilmans@nokia-bell-labs.com>
Cc: Dave Taht <dave.taht@gmail.com>
Cc: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
 include/net/inet_ecn.h | 57 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 55 insertions(+), 2 deletions(-)

diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h
index c8e2bebd8d93..0f0d1efe06dd 100644
--- a/include/net/inet_ecn.h
+++ b/include/net/inet_ecn.h
@@ -99,6 +99,20 @@ static inline int IP_ECN_set_ce(struct iphdr *iph)
 	return 1;
 }
 
+static inline int IP_ECN_set_ect1(struct iphdr *iph)
+{
+	u32 check = (__force u32)iph->check;
+
+	if ((iph->tos & INET_ECN_MASK) != INET_ECN_ECT_0)
+		return 0;
+
+	check += (__force u16)htons(0x100);
+
+	iph->check = (__force __sum16)(check + (check>=0xFFFF));
+	iph->tos ^= INET_ECN_MASK;
+	return 1;
+}
+
 static inline void IP_ECN_clear(struct iphdr *iph)
 {
 	iph->tos &= ~INET_ECN_MASK;
@@ -134,6 +148,22 @@ static inline int IP6_ECN_set_ce(struct sk_buff *skb, struct ipv6hdr *iph)
 	return 1;
 }
 
+static inline int IP6_ECN_set_ect1(struct sk_buff *skb, struct ipv6hdr *iph)
+{
+	__be32 from, to;
+
+	if ((ipv6_get_dsfield(iph) & INET_ECN_MASK) != INET_ECN_ECT_0)
+		return 0;
+
+	from = *(__be32 *)iph;
+	to = from ^ htonl(INET_ECN_MASK << 20);
+	*(__be32 *)iph = to;
+	if (skb->ip_summed == CHECKSUM_COMPLETE)
+		skb->csum = csum_add(csum_sub(skb->csum, (__force __wsum)from),
+				     (__force __wsum)to);
+	return 1;
+}
+
 static inline void ipv6_copy_dscp(unsigned int dscp, struct ipv6hdr *inner)
 {
 	dscp &= ~INET_ECN_MASK;
@@ -159,6 +189,25 @@ static inline int INET_ECN_set_ce(struct sk_buff *skb)
 	return 0;
 }
 
+static inline int INET_ECN_set_ect1(struct sk_buff *skb)
+{
+	switch (skb->protocol) {
+	case cpu_to_be16(ETH_P_IP):
+		if (skb_network_header(skb) + sizeof(struct iphdr) <=
+		    skb_tail_pointer(skb))
+			return IP_ECN_set_ect1(ip_hdr(skb));
+		break;
+
+	case cpu_to_be16(ETH_P_IPV6):
+		if (skb_network_header(skb) + sizeof(struct ipv6hdr) <=
+		    skb_tail_pointer(skb))
+			return IP6_ECN_set_ect1(skb, ipv6_hdr(skb));
+		break;
+	}
+
+	return 0;
+}
+
 /*
  * RFC 6040 4.2
  *  To decapsulate the inner header at the tunnel egress, a compliant
@@ -208,8 +257,12 @@ static inline int INET_ECN_decapsulate(struct sk_buff *skb,
 	int rc;
 
 	rc = __INET_ECN_decapsulate(outer, inner, &set_ce);
-	if (!rc && set_ce)
-		INET_ECN_set_ce(skb);
+	if (!rc) {
+		if (set_ce)
+			INET_ECN_set_ce(skb);
+		else if ((outer & INET_ECN_MASK) == INET_ECN_ECT_1)
+			INET_ECN_set_ect1(skb);
+	}
 
 	return rc;
 }
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH net] tunnel: Propagate ECT(1) when decapsulating as recommended by RFC6040
  2020-04-27 14:11 [PATCH net] tunnel: Propagate ECT(1) when decapsulating as recommended by RFC6040 Toke Høiland-Jørgensen
@ 2020-05-01  3:33 ` David Miller
  0 siblings, 0 replies; 2+ messages in thread
From: David Miller @ 2020-05-01  3:33 UTC (permalink / raw)
  To: toke; +Cc: netdev, ietf, olivier.tilmans, dave.taht, stephen

From: Toke Høiland-Jørgensen <toke@redhat.com>
Date: Mon, 27 Apr 2020 16:11:05 +0200

> RFC 6040 recommends propagating an ECT(1) mark from an outer tunnel header
> to the inner header if that inner header is already marked as ECT(0). When
> RFC 6040 decapsulation was implemented, this case of propagation was not
> added. This simply appears to be an oversight, so let's fix that.
> 
> Fixes: eccc1bb8d4b4 ("tunnel: drop packet if ECN present with not-ECT")
> Reported-by: Bob Briscoe <ietf@bobbriscoe.net>
> Reported-by: Olivier Tilmans <olivier.tilmans@nokia-bell-labs.com>
> Cc: Dave Taht <dave.taht@gmail.com>
> Cc: Stephen Hemminger <stephen@networkplumber.org>
> Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>

Applied and queued up for -stable, thanks.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-05-01  3:33 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-27 14:11 [PATCH net] tunnel: Propagate ECT(1) when decapsulating as recommended by RFC6040 Toke Høiland-Jørgensen
2020-05-01  3:33 ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).