The branch main has been updated by tuexen:

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

commit 02b885b09d1e90574162a1442b9ede06cef2b13a
Author:     Michael Tuexen <[email protected]>
AuthorDate: 2023-06-21 20:54:33 +0000
Commit:     Michael Tuexen <[email protected]>
CommitDate: 2023-06-21 20:54:33 +0000

    tcp: fix TCP MD5 computation for the BBR and RACK stack
    
    PR:                     253096
    Reviewed by:            cc, rscheff
    MFC after:              3 days
    Sponsored by:           Netflix, Inc.
    Differential Revision:  https://reviews.freebsd.org/D40597
---
 sys/netinet/tcp_stacks/bbr.c  | 10 +++----
 sys/netinet/tcp_stacks/rack.c | 66 ++++++++++++++++++++++++++++++++++++-------
 2 files changed, 61 insertions(+), 15 deletions(-)

diff --git a/sys/netinet/tcp_stacks/bbr.c b/sys/netinet/tcp_stacks/bbr.c
index d9952ba6bd14..1bc20de9e503 100644
--- a/sys/netinet/tcp_stacks/bbr.c
+++ b/sys/netinet/tcp_stacks/bbr.c
@@ -13377,6 +13377,11 @@ send:
         * the pointer in case of a stack switch.
         */
        tp->snd_up = tp->snd_una;
+       /*
+        * Put TCP length in extended header, and then checksum extended
+        * header and data.
+        */
+       m->m_pkthdr.len = hdrlen + len; /* in6_cksum() need this */
 
 #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
        if (to.to_flags & TOF_SIGNATURE) {
@@ -13396,11 +13401,6 @@ send:
        }
 #endif
 
-       /*
-        * Put TCP length in extended header, and then checksum extended
-        * header and data.
-        */
-       m->m_pkthdr.len = hdrlen + len; /* in6_cksum() need this */
 #ifdef INET6
        if (isipv6) {
                /*
diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c
index c4d4923fb592..59dd113c03d5 100644
--- a/sys/netinet/tcp_stacks/rack.c
+++ b/sys/netinet/tcp_stacks/rack.c
@@ -18747,6 +18747,11 @@ rack_fast_rsm_output(struct tcpcb *tp, struct tcp_rack 
*rack, struct rack_sendma
                to.to_tsecr = tp->ts_recent;
                to.to_flags = TOF_TS;
        }
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
+       /* TCP-MD5 (RFC2385). */
+       if (tp->t_flags & TF_SIGNATURE)
+               to.to_flags |= TOF_SIGNATURE;
+#endif
        optlen = tcp_addoptions(&to, opt);
        hdrlen += optlen;
        udp = rack->r_ctl.fsb.udp;
@@ -18906,6 +18911,24 @@ rack_fast_rsm_output(struct tcpcb *tp, struct tcp_rack 
*rack, struct rack_sendma
        }
        tcp_set_flags(th, flags);
        m->m_pkthdr.len = hdrlen + len; /* in6_cksum() need this */
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
+       if (to.to_flags & TOF_SIGNATURE) {
+               /*
+                * Calculate MD5 signature and put it into the place
+                * determined before.
+                * NOTE: since TCP options buffer doesn't point into
+                * mbuf's data, calculate offset and use it.
+                */
+               if (!TCPMD5_ENABLED() || TCPMD5_OUTPUT(m, th,
+                                                      (u_char *)(th + 1) + 
(to.to_signature - opt)) != 0) {
+                       /*
+                        * Do not send segment if the calculation of MD5
+                        * digest has failed.
+                        */
+                       goto failed;
+               }
+       }
+#endif
 #ifdef INET6
        if (rack->r_is_v6) {
                if (tp->t_port) {
@@ -19312,6 +19335,11 @@ rack_fast_output(struct tcpcb *tp, struct tcp_rack 
*rack, uint64_t ts_val,
                to.to_tsecr = tp->ts_recent;
                to.to_flags = TOF_TS;
        }
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
+       /* TCP-MD5 (RFC2385). */
+       if (tp->t_flags & TF_SIGNATURE)
+               to.to_flags |= TOF_SIGNATURE;
+#endif
        optlen = tcp_addoptions(&to, opt);
        hdrlen += optlen;
        udp = rack->r_ctl.fsb.udp;
@@ -19451,6 +19479,24 @@ again:
        }
        tcp_set_flags(th, flags);
        m->m_pkthdr.len = hdrlen + len; /* in6_cksum() need this */
+#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
+       if (to.to_flags & TOF_SIGNATURE) {
+               /*
+                * Calculate MD5 signature and put it into the place
+                * determined before.
+                * NOTE: since TCP options buffer doesn't point into
+                * mbuf's data, calculate offset and use it.
+                */
+               if (!TCPMD5_ENABLED() || TCPMD5_OUTPUT(m, th,
+                                                      (u_char *)(th + 1) + 
(to.to_signature - opt)) != 0) {
+                       /*
+                        * Do not send segment if the calculation of MD5
+                        * digest has failed.
+                        */
+                       goto failed;
+               }
+       }
+#endif
 #ifdef INET6
        if (rack->r_is_v6) {
                if (tp->t_port) {
@@ -21337,7 +21383,7 @@ send:
                /* TCP-MD5 (RFC2385). */
                if (tp->t_flags & TF_SIGNATURE)
                        to.to_flags |= TOF_SIGNATURE;
-#endif                         /* TCP_SIGNATURE */
+#endif
 
                /* Processing the options. */
                hdrlen += optlen = tcp_addoptions(&to, opt);
@@ -21831,6 +21877,15 @@ send:
                if (udp)
                        udp = (struct udphdr *)(cpto + ((uint8_t 
*)rack->r_ctl.fsb.udp - rack->r_ctl.fsb.tcp_ip_hdr));
        }
+       if (optlen) {
+               bcopy(opt, th + 1, optlen);
+               th->th_off = (sizeof(struct tcphdr) + optlen) >> 2;
+       }
+       /*
+        * Put TCP length in extended header, and then checksum extended
+        * header and data.
+        */
+       m->m_pkthdr.len = hdrlen + len; /* in6_cksum() need this */
 #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
        if (to.to_flags & TOF_SIGNATURE) {
                /*
@@ -21849,15 +21904,6 @@ send:
                }
        }
 #endif
-       if (optlen) {
-               bcopy(opt, th + 1, optlen);
-               th->th_off = (sizeof(struct tcphdr) + optlen) >> 2;
-       }
-       /*
-        * Put TCP length in extended header, and then checksum extended
-        * header and data.
-        */
-       m->m_pkthdr.len = hdrlen + len; /* in6_cksum() need this */
 #ifdef INET6
        if (isipv6) {
                /*

Reply via email to