git: 6026b45aabb3 - main - sctp: improve negotiation of zero checksum feature

From: Michael Tuexen <tuexen_at_FreeBSD.org>
Date: Wed, 15 Mar 2023 21:35:53 UTC
The branch main has been updated by tuexen:

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

commit 6026b45aabb3324934d076db53b48c50ce30a63d
Author:     Michael Tuexen <tuexen@FreeBSD.org>
AuthorDate: 2023-03-15 21:29:52 +0000
Commit:     Michael Tuexen <tuexen@FreeBSD.org>
CommitDate: 2023-03-15 21:29:52 +0000

    sctp: improve negotiation of zero checksum feature
    
    Enforce consistency between announcing 0-cksum support and actually
    using it in the association. The value from the inp when the
    INIT ACK is sent must be used, not the one from the inp when the
    cookie is received.
---
 sys/netinet/sctp_header.h | 3 ++-
 sys/netinet/sctp_input.c  | 2 ++
 sys/netinet/sctp_output.c | 5 +++++
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/sys/netinet/sctp_header.h b/sys/netinet/sctp_header.h
index 4d5b5bc9db0b..93dda17ae9b1 100644
--- a/sys/netinet/sctp_header.h
+++ b/sys/netinet/sctp_header.h
@@ -180,7 +180,7 @@ struct sctp_init {
 }         SCTP_PACKED;
 #define SCTP_IDENTIFICATION_SIZE 16
 #define SCTP_ADDRESS_SIZE 4
-#define SCTP_RESERVE_SPACE 6
+#define SCTP_RESERVE_SPACE 5
 /* state cookie header */
 struct sctp_state_cookie {	/* this is our definition... */
 	uint8_t identification[SCTP_IDENTIFICATION_SIZE];	/* id of who we are */
@@ -207,6 +207,7 @@ struct sctp_state_cookie {	/* this is our definition... */
 
 	uint8_t ipv4_scope;	/* IPv4 private addr scope */
 	uint8_t loopback_scope;	/* loopback scope information */
+	uint8_t zero_checksum;	/* copy of the inp value */
 	uint8_t reserved[SCTP_RESERVE_SPACE];	/* Align to 64 bits */
 	/*
 	 * at the end is tacked on the INIT chunk and the INIT-ACK chunk
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index dfc74e1e84f3..6299c5c7d827 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -1880,6 +1880,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
 			}
 			SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asconf_ack), aack);
 		}
+		asoc->zero_checksum = cookie->zero_checksum;
 
 		/* process the INIT-ACK info (my info) */
 		asoc->my_vtag = ntohl(initack_cp->init.initiate_tag);
@@ -2076,6 +2077,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
 		    SCTP_FROM_SCTP_INPUT + SCTP_LOC_18);
 		return (NULL);
 	}
+	asoc->zero_checksum = cookie->zero_checksum;
 	/* process the INIT-ACK info (my info) */
 	asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
 
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 97e89cb1396c..2ce05336482a 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -5804,6 +5804,11 @@ do_a_abort:
 #endif
 		}
 	}
+	if (asoc != NULL) {
+		stc.zero_checksum = asoc->zero_checksum > 0 ? 1 : 0;
+	} else {
+		stc.zero_checksum = inp->zero_checksum;
+	}
 	/* Now lets put the SCTP header in place */
 	initack = mtod(m, struct sctp_init_ack_chunk *);
 	/* Save it off for quick ref */