aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Tuexen <tuexen@FreeBSD.org>2023-06-21 20:54:33 +0000
committerMichael Tuexen <tuexen@FreeBSD.org>2023-06-21 20:54:33 +0000
commit02b885b09d1e90574162a1442b9ede06cef2b13a (patch)
treeb395e8e796e4a489ff4995b7f20e0618c8aeda8a
parent0fb0711dba76a32a2202d2f41d64aa1247b5e51d (diff)
downloadsrc-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.c10
-rw-r--r--sys/netinet/tcp_stacks/rack.c66
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) {
/*