git: 3b0ee680507a - main - tcp: Prevent setting of ECN bits with setsockopt()

From: Richard Scheffenegger <rscheff_at_FreeBSD.org>
Date: Thu, 03 Feb 2022 19:11:23 UTC
The branch main has been updated by rscheff:

URL: https://cgit.FreeBSD.org/src/commit/?id=3b0ee680507ab4cfe4d493bc1487305666d9437c

commit 3b0ee680507ab4cfe4d493bc1487305666d9437c
Author:     Richard Scheffenegger <rscheff@FreeBSD.org>
AuthorDate: 2022-02-03 18:50:56 +0000
Commit:     Richard Scheffenegger <rscheff@FreeBSD.org>
CommitDate: 2022-02-03 19:06:42 +0000

    tcp: Prevent setting of ECN bits with setsockopt()
    
    setsockopt() grants full access to the deprecated
    TOS byte. For TCP, mask out the ECN codepoint, so that
    only the DSCP portion can be adjusted.
    
    Reviewed By: tuexen, hselasky, #manpages, #transport, debdrup
    Sponsored by:        NetApp, Inc.
    Differential Revision: https://reviews.freebsd.org/D34154
---
 share/man/man4/ip.4      | 11 +++++++----
 sys/netinet/ip.h         |  2 +-
 sys/netinet/tcp_usrreq.c |  3 +++
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/share/man/man4/ip.4 b/share/man/man4/ip.4
index 24b06846e66f..d1c3b34b51a6 100644
--- a/share/man/man4/ip.4
+++ b/share/man/man4/ip.4
@@ -90,10 +90,13 @@ setsockopt(s, IPPROTO_IP, IP_OPTIONS, NULL, 0);
 .Ed
 .Pp
 .Dv IP_TOS
-and
+may be used to set the differential service codepoint (DSCP) and the
+explicit congestion notfication (ECN) codepoint.
+Setting the ECN codepoint - the two least significant bits - on a
+socket using a transport protocol implementing ECN has no effect.
+.Pp
 .Dv IP_TTL
-may be used to set the type-of-service and time-to-live
-fields in the
+configures the time-to-live (TTL) field in the
 .Tn IP
 header for
 .Dv SOCK_STREAM , SOCK_DGRAM ,
@@ -102,7 +105,7 @@ and certain types of
 sockets.
 For example,
 .Bd -literal
-int tos = IPTOS_LOWDELAY;       /* see <netinet/ip.h> */
+int tos = IPTOS_DSCP_EF;       /* see <netinet/ip.h> */
 setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
 
 int ttl = 60;                   /* max = 255 */
diff --git a/sys/netinet/ip.h b/sys/netinet/ip.h
index 934bd812a495..81e46a778d2c 100644
--- a/sys/netinet/ip.h
+++ b/sys/netinet/ip.h
@@ -79,7 +79,7 @@ struct ip {
 #define	IPTOS_LOWDELAY		0x10
 #define	IPTOS_THROUGHPUT	0x08
 #define	IPTOS_RELIABILITY	0x04
-#define	IPTOS_MINCOST		0x02
+#define	IPTOS_MINCOST		IPTOS_DSCP_CS0
 
 /*
  * Definitions for IP precedence (also in ip_tos) (deprecated).
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index f2652811b86a..13e48eef459b 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -82,6 +82,7 @@ __FBSDID("$FreeBSD$");
 #include <netinet/in_pcb.h>
 #include <netinet/in_systm.h>
 #include <netinet/in_var.h>
+#include <netinet/ip.h>
 #include <netinet/ip_var.h>
 #ifdef INET6
 #include <netinet/ip6.h>
@@ -1759,6 +1760,8 @@ tcp_ctloutput_set(struct inpcb *inp, struct sockopt *sopt)
 		case IPPROTO_IP:
 			switch (sopt->sopt_name) {
 			case IP_TOS:
+				inp->inp_ip_tos &= ~IPTOS_ECN_MASK;
+				break;
 			case IP_TTL:
 				/* Notify tcp stacks that care (e.g. RACK). */
 				break;