git: 7a49fc843975 - stable/13 - sctp: use the correct traffic class when sending SCTP/IPv6 packets

From: Michael Tuexen <tuexen_at_FreeBSD.org>
Date: Fri, 10 Dec 2021 10:40:35 UTC
The branch stable/13 has been updated by tuexen:

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

commit 7a49fc843975cecb87ed36a33a85efdf12912089
Author:     Michael Tuexen <tuexen@FreeBSD.org>
AuthorDate: 2021-12-03 20:28:47 +0000
Commit:     Michael Tuexen <tuexen@FreeBSD.org>
CommitDate: 2021-12-10 10:39:44 +0000

    sctp: use the correct traffic class when sending SCTP/IPv6 packets
    
    When sending packets the stcb was used to access the inp and then
    access the endpoint specific IPv6 level options. This fails when
    there exists an inp, but no stcb yet. This is the case for sending
    an INIT-ACK in response to an INIT when no association already
    exists. Fix this by just providing the inp instead of the stcb.
    
    PR:             260120
    MFC after:      1 week
    
    (cherry picked from commit f32357be53d07622603049f9855be2d66ca6dc2b)
---
 sys/netinet/sctp_os_bsd.h | 42 ++++++++++++++++++++++--------------------
 sys/netinet/sctp_output.c |  4 ++--
 2 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h
index 12a666b8eead..39c0a8cb5c2a 100644
--- a/sys/netinet/sctp_os_bsd.h
+++ b/sys/netinet/sctp_os_bsd.h
@@ -411,28 +411,30 @@ typedef struct route sctp_route_t;
 /*
  * IP output routines
  */
-#define SCTP_IP_OUTPUT(result, o_pak, ro, stcb, vrf_id) \
-{ \
-	int o_flgs = IP_RAWOUTPUT; \
-	struct sctp_tcb *local_stcb = stcb; \
-	if (local_stcb && \
-	    local_stcb->sctp_ep && \
-	    local_stcb->sctp_ep->sctp_socket) \
-		o_flgs |= local_stcb->sctp_ep->sctp_socket->so_options & SO_DONTROUTE; \
-	m_clrprotoflags(o_pak); \
-	result = ip_output(o_pak, NULL, ro, o_flgs, 0, NULL); \
+#define SCTP_IP_OUTPUT(result, o_pak, ro, _inp, vrf_id)                      \
+{                                                                            \
+	struct sctp_inpcb *local_inp = _inp;                                 \
+	int o_flgs = IP_RAWOUTPUT;                                           \
+	                                                                     \
+	m_clrprotoflags(o_pak);                                              \
+	if ((local_inp != NULL) && (local_inp->sctp_socket != NULL)) {       \
+		o_flgs |= local_inp->sctp_socket->so_options & SO_DONTROUTE; \
+	}                                                                    \
+	result = ip_output(o_pak, NULL, ro, o_flgs, 0, NULL);                \
 }
 
-#define SCTP_IP6_OUTPUT(result, o_pak, ro, ifp, stcb, vrf_id) \
-{ \
-	struct sctp_tcb *local_stcb = stcb; \
-	m_clrprotoflags(o_pak); \
-	if (local_stcb && local_stcb->sctp_ep) \
-		result = ip6_output(o_pak, \
-				    ((struct inpcb *)(local_stcb->sctp_ep))->in6p_outputopts, \
-				    (ro), 0, 0, ifp, NULL); \
-	else \
-		result = ip6_output(o_pak, NULL, (ro), 0, 0, ifp, NULL); \
+#define SCTP_IP6_OUTPUT(result, o_pak, ro, ifp, _inp, vrf_id)                \
+{                                                                            \
+	struct sctp_inpcb *local_inp = _inp;                                 \
+	                                                                     \
+	m_clrprotoflags(o_pak);                                              \
+	if (local_inp != NULL) {                                             \
+		result = ip6_output(o_pak,                                   \
+		                    local_inp->ip_inp.inp.in6p_outputopts,   \
+		                    (ro), 0, 0, ifp, NULL);                  \
+	} else {                                                             \
+		result = ip6_output(o_pak, NULL, (ro), 0, 0, ifp, NULL);     \
+	}                                                                    \
 }
 
 struct mbuf *
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 5953cf724c89..277a6625aa12 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -4220,7 +4220,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
 #endif
 			/* send it out.  table id is taken from stcb */
 			SCTP_PROBE5(send, NULL, stcb, ip, stcb, sctphdr);
-			SCTP_IP_OUTPUT(ret, o_pak, ro, stcb, vrf_id);
+			SCTP_IP_OUTPUT(ret, o_pak, ro, inp, vrf_id);
 			if (port) {
 				UDPSTAT_INC(udps_opackets);
 			}
@@ -4544,7 +4544,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
 				sctp_packet_log(o_pak);
 #endif
 			SCTP_PROBE5(send, NULL, stcb, ip6h, stcb, sctphdr);
-			SCTP_IP6_OUTPUT(ret, o_pak, (struct route_in6 *)ro, &ifp, stcb, vrf_id);
+			SCTP_IP6_OUTPUT(ret, o_pak, (struct route_in6 *)ro, &ifp, inp, vrf_id);
 			if (net) {
 				/* for link local this must be done */
 				sin6->sin6_scope_id = prev_scope;