diff options
author | Michael Tuexen <tuexen@FreeBSD.org> | 2023-06-21 20:54:33 +0000 |
---|---|---|
committer | Michael Tuexen <tuexen@FreeBSD.org> | 2023-06-21 20:54:33 +0000 |
commit | 02b885b09d1e90574162a1442b9ede06cef2b13a (patch) | |
tree | b395e8e796e4a489ff4995b7f20e0618c8aeda8a | |
parent | 0fb0711dba76a32a2202d2f41d64aa1247b5e51d (diff) | |
download | src-02b885b09d1e90574162a1442b9ede06cef2b13a.tar.gz src-02b885b09d1e90574162a1442b9ede06cef2b13a.zip |
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
-rw-r--r-- | sys/netinet/tcp_stacks/bbr.c | 10 | ||||
-rw-r--r-- | 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) { /* |