The branch main has been updated by glebius:

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

commit de156263a598a0277b7bbc13ef8bdc6f4541b604
Author:     Gleb Smirnoff <[email protected]>
AuthorDate: 2021-10-26 03:40:12 +0000
Commit:     Gleb Smirnoff <[email protected]>
CommitDate: 2021-10-27 15:21:59 +0000

    Several IP level socket options may affect TCP.
    
    After handling them in IP level ctloutput, pass them down to TCP
    ctloutput.
    
    We already have a hack to handle IPV6_USE_MIN_MTU. Leave it in place
    for now, but comment out how it should be handled.
    
    For IPv4 we are interested in IP_TOS and IP_TTL.
    
    Reviewed by:            rrs
    Differential Revision:  https://reviews.freebsd.org/D32655
---
 sys/netinet/tcp_usrreq.c | 75 ++++++++++++++++++++++++++++++++++--------------
 1 file changed, 54 insertions(+), 21 deletions(-)

diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 0fca9b88e6f3..b6e345bd454c 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -1739,20 +1739,44 @@ tcp_ctloutput_set(struct inpcb *inp, struct sockopt 
*sopt)
 
        if (sopt->sopt_level != IPPROTO_TCP) {
 #ifdef INET6
-               if (inp->inp_vflag & INP_IPV6PROTO) {
+               if (inp->inp_vflag & INP_IPV6PROTO)
                        error = ip6_ctloutput(inp->inp_socket, sopt);
-                       /*
-                        * In case of the IPV6_USE_MIN_MTU socket option,
-                        * the INC_IPV6MINMTU flag to announce a corresponding
-                        * MSS during the initial handshake.
-                        * If the TCP connection is not in the front states,
-                        * just reduce the MSS being used.
-                        * This avoids the sending of TCP segments which will
-                        * be fragmented at the IPv6 layer.
-                        */
-                       if ((error == 0) &&
-                           (sopt->sopt_level == IPPROTO_IPV6) &&
-                           (sopt->sopt_name == IPV6_USE_MIN_MTU)) {
+#endif
+#if defined(INET6) && defined(INET)
+               else
+#endif
+#ifdef INET
+                       error = ip_ctloutput(inp->inp_socket, sopt);
+#endif
+               /*
+                * When an IP-level socket option affects TCP, pass control
+                * down to stack tfb_tcp_ctloutput, otherwise return what
+                * IP level returned.
+                */
+               switch (sopt->sopt_level) {
+#ifdef INET6
+               case IPPROTO_IPV6:
+                       if ((inp->inp_vflag & INP_IPV6PROTO) == 0)
+                               return (error);
+                       switch (sopt->sopt_name) {
+                       case IPV6_TCLASS:
+                               /* Notify tcp stacks that care (e.g. RACK). */
+                               break;
+                       case IPV6_USE_MIN_MTU:
+                               /*
+                                * XXXGL: this handling should belong to
+                                * stack specific tfb_tcp_ctloutput, we
+                                * should just break here.
+                                *
+                                * In case of the IPV6_USE_MIN_MTU socket
+                                * option, the INC_IPV6MINMTU flag to announce
+                                * a corresponding MSS during the initial
+                                * handshake.  If the TCP connection is not in
+                                * the front states, just reduce the MSS being
+                                * used.  This avoids the sending of TCP
+                                * segments which will be fragmented at the
+                                * IPv6 layer.
+                                */
                                INP_WLOCK(inp);
                                if ((inp->inp_flags &
                                    (INP_TIMEWAIT | INP_DROPPED))) {
@@ -1775,18 +1799,27 @@ tcp_ctloutput_set(struct inpcb *inp, struct sockopt 
*sopt)
                                        }
                                }
                                INP_WUNLOCK(inp);
+                               /* FALLTHROUGH */
+                       default:
+                               return (error);
                        }
-               }
-#endif /* INET6 */
-#if defined(INET6) && defined(INET)
-               else
+                       break;
 #endif
 #ifdef INET
-               {
-                       error = ip_ctloutput(inp->inp_socket, sopt);
-               }
+               case IPPROTO_IP:
+                       switch (sopt->sopt_name) {
+                       case IP_TOS:
+                       case IP_TTL:
+                               /* Notify tcp stacks that care (e.g. RACK). */
+                               break;
+                       default:
+                               return (error);
+                       }
+                       break;
 #endif
-               return (error);
+               default:
+                       return (error);
+               }
        } else if (sopt->sopt_name == TCP_FUNCTION_BLK) {
                /*
                 * Protect the TCP option TCP_FUNCTION_BLK so

Reply via email to