git: d66540e829ec - main - tcp: improve sending of TTL/hoplimit and DSCP

From: Michael Tuexen <tuexen_at_FreeBSD.org>
Date: Mon, 05 Jun 2023 21:01:20 UTC
The branch main has been updated by tuexen:

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

commit d66540e829ec22b9654cf4b9119bed9326f89fad
Author:     Michael Tuexen <tuexen@FreeBSD.org>
AuthorDate: 2023-06-05 16:43:06 +0000
Commit:     Michael Tuexen <tuexen@FreeBSD.org>
CommitDate: 2023-06-05 16:43:06 +0000

    tcp: improve sending of TTL/hoplimit and DSCP
    
    Ensure that a user specified value of TTL/hoplimit and DSCP is
    used when sending packets.
    
    Reviewed by:            cc, rscheff
    MFC after:              1 week
    Sponsored by:           Netflix, Inc.
    Differential Revision:  https://reviews.freebsd.org/D40423
---
 sys/netinet/tcp_stacks/rack.c | 27 ++-------------------------
 sys/netinet/tcp_subr.c        | 13 ++++++++++---
 2 files changed, 12 insertions(+), 28 deletions(-)

diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c
index affd135bb453..c9b5b937cc46 100644
--- a/sys/netinet/tcp_stacks/rack.c
+++ b/sys/netinet/tcp_stacks/rack.c
@@ -18826,7 +18826,7 @@ rack_fast_rsm_output(struct tcpcb *tp, struct tcp_rack *rack, struct rack_sendma
 	}
 #ifdef INET6
 	if (rack->r_is_v6) {
-		error = ip6_output(m, NULL,
+		error = ip6_output(m, inp->in6p_outputopts,
 				   &inp->inp_route6,
 				   ip_sendflag, NULL, NULL, inp);
 	}
@@ -19338,7 +19338,7 @@ again:
 		lgb = NULL;
 #ifdef INET6
 	if (rack->r_is_v6) {
-		error = ip6_output(m, NULL,
+		error = ip6_output(m, inp->in6p_outputopts,
 				   &inp->inp_route6,
 				   0, NULL, NULL, inp);
 	}
@@ -21792,11 +21792,7 @@ send:
 		TCP_PROBE5(send, NULL, tp, ip6, tp, th);
 		/* TODO: IPv6 IP6TOS_ECT bit on */
 		error = ip6_output(m,
-#if defined(IPSEC) || defined(IPSEC_SUPPORT)
 				   inp->in6p_outputopts,
-#else
-				   NULL,
-#endif
 				   &inp->inp_route6,
 				   ((rsm || sack_rxmit) ? IP_NO_SND_TAG_RL : 0),
 				   NULL, NULL, inp);
@@ -23448,10 +23444,6 @@ static int
 rack_set_sockopt(struct tcpcb *tp, struct sockopt *sopt)
 {
 	struct inpcb *inp = tptoinpcb(tp);
-#ifdef INET6
-	struct ip6_hdr *ip6;
-	int32_t mask, tclass;
-#endif
 #ifdef INET
 	struct ip *ip;
 #endif
@@ -23465,9 +23457,6 @@ rack_set_sockopt(struct tcpcb *tp, struct sockopt *sopt)
 		INP_WUNLOCK(inp);
 		return (EINVAL);
 	}
-#ifdef INET6
-	ip6 = (struct ip6_hdr *)rack->r_ctl.fsb.tcp_ip_hdr;
-#endif
 #ifdef INET
 	ip = (struct ip *)rack->r_ctl.fsb.tcp_ip_hdr;
 #endif
@@ -23480,18 +23469,6 @@ rack_set_sockopt(struct tcpcb *tp, struct sockopt *sopt)
 		case IPV6_USE_MIN_MTU:
 			tcp6_use_min_mtu(tp);
 			break;
-		case IPV6_TCLASS:
-			/*
-			 * The DSCP codepoint has changed, update the fsb
-			 * by overwriting any previous traffic class.
-			 */
-			if (inp->in6p_outputopts) {
-				mask = 0xfc;
-				tclass = inp->in6p_outputopts->ip6po_tclass;
-				ip6->ip6_flow &= htonl((~mask) << 20);
-				ip6->ip6_flow |= htonl((tclass & mask) << 20);
-			}
-			break;
 		}
 		INP_WUNLOCK(inp);
 		return (0);
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index fe065fd08737..47eb2d80efd6 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -2049,9 +2049,15 @@ tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m,
 			ulen = tlen - sizeof(struct ip);
 			uh->uh_ulen = htons(ulen);
 		}
-		ip->ip_tos = ect;
 		ip->ip_len = htons(tlen);
-		ip->ip_ttl = V_ip_defttl;
+		if (inp != NULL) {
+			ip->ip_tos = inp->inp_ip_tos & ~IPTOS_ECN_MASK;
+			ip->ip_ttl = inp->inp_ip_ttl;
+		} else {
+			ip->ip_tos = 0;
+			ip->ip_ttl = V_ip_defttl;
+		}
+		ip->ip_tos |= ect;
 		if (port) {
 			ip->ip_p = IPPROTO_UDP;
 		} else {
@@ -2195,7 +2201,8 @@ tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m,
 #ifdef INET6
 	if (isipv6) {
 		TCP_PROBE5(send, NULL, tp, ip6, tp, nth);
-		output_ret = ip6_output(m, NULL, NULL, 0, NULL, NULL, inp);
+		output_ret = ip6_output(m, inp ? inp->in6p_outputopts : NULL,
+		    NULL, 0, NULL, NULL, inp);
 	}
 #endif /* INET6 */
 #if defined(INET) && defined(INET6)