Hello -

Many operating systems out there are starting to enable TCP ECN by
default, most inbound-only.  Linux, FreeBSD, Apple MacOS and iOS.

This diff mimicks the FreeBSD diff found at
http://marc.info/?l=freebsd-commits-all&m=146369644516347&w=2

It modifies the net.inet.tcp.ecn from an off and on switch to a 
three-way setting: off, on, and inbound-only (0, 1, 2, respectively).

It also enables TCP ECN by default for inbound connections that request
it.

My home router has TCP ECN enabled. With 36 hours of uptime, netstat -s
shows:
        16165 ECN connections accepted
        1 ECE packet received
        6 ECE packets sent
        589 CWR packets received
        109 CWR packets sent

This diff is just to see if there is interest in such a change.  If
people seem to like the idea, perhaps I could update the diff to also:
        - Remove TCP_ECN kernel option and always compile in support?
        - Only allow 0, 1, or 2 via the sysctl net.inet.tcp.ecn knob.
        - Update pf.os

Thoughts?
 - David
 
Index: netinet/tcp_output.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_output.c,v
retrieving revision 1.118
diff -u -p -r1.118 tcp_output.c
--- netinet/tcp_output.c        19 Jul 2016 21:28:43 -0000      1.118
+++ netinet/tcp_output.c        8 Oct 2016 02:30:07 -0000
@@ -845,10 +845,12 @@ send:
                }
                if (!(tp->t_flags & TF_DISABLE_ECN)) {
                        /*
-                        * if this is a SYN seg, set ECE and CWR.
-                        * set only ECE for SYN-ACK if peer supports ECN.
+                        * If net.inet.tcp.ecn is set to 1 and this is a
+                        * SYN seg, set both ECE and CWR.
+                        * Set only ECE for SYN-ACK if peer supports ECN.
                         */
-                       if ((flags & (TH_SYN|TH_ACK)) == TH_SYN)
+                       if (tcp_do_ecn == 1 &&
+                           (flags & (TH_SYN|TH_ACK)) == TH_SYN)
                                flags |= (TH_ECE|TH_CWR);
                        else if ((tp->t_flags & TF_ECN_PERMIT) &&
                                 (flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK))
Index: netinet/tcp_subr.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_subr.c,v
retrieving revision 1.156
diff -u -p -r1.156 tcp_subr.c
--- netinet/tcp_subr.c  24 Sep 2016 14:51:37 -0000      1.156
+++ netinet/tcp_subr.c  8 Oct 2016 02:30:07 -0000
@@ -110,7 +110,7 @@ int tcp_do_sack = 1;        /* RFC 2018 selecti
 #endif
 int    tcp_ack_on_push = 0;    /* set to enable immediate ACK-on-PUSH */
 #ifdef TCP_ECN
-int    tcp_do_ecn = 0;         /* RFC3168 ECN enabled/disabled? */
+int    tcp_do_ecn = 2;         /* RFC3168 ECN enabled on inbound requests */
 #endif
 int    tcp_do_rfc3390 = 2;     /* Increase TCP's Initial Window to 10*mss */
 
Index: netinet/tcp_var.h
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_var.h,v
retrieving revision 1.116
diff -u -p -r1.116 tcp_var.h
--- netinet/tcp_var.h   4 Oct 2016 13:54:32 -0000       1.116
+++ netinet/tcp_var.h   8 Oct 2016 02:30:07 -0000
@@ -579,7 +579,7 @@ extern      int tcp_do_sack;        /* SACK enabled/
 extern struct pool sackhl_pool;
 extern int tcp_sackhole_limit; /* max entries for tcp sack queues */
 #endif
-extern int tcp_do_ecn;         /* RFC3168 ECN enabled/disabled? */
+extern int tcp_do_ecn;         /* RFC3168 ECN: 0:off 1:on 2:inbound-only */
 extern int tcp_do_rfc3390;     /* RFC3390 Increasing TCP's Initial Window */
 
 extern struct pool tcpqe_pool;

Reply via email to