The branch main has been updated by tuexen:

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

commit 644cffe67f61ad5b36b60d621d1c630ff2a50412
Author:     Michael Tuexen <[email protected]>
AuthorDate: 2024-02-24 18:16:36 +0000
Commit:     Michael Tuexen <[email protected]>
CommitDate: 2024-02-24 18:16:36 +0000

    sctp: improve sending of packets containing an INIT ACK chunk
    
    If the peer announced support of zero checksums, do so when sending
    packets containing an INIT ACK chunk.
    
    MFC after:      1 week
---
 sys/netinet/sctp_input.c  |  2 +-
 sys/netinet/sctp_output.c | 36 ++++++++++++++++++++++++++++++++----
 sys/netinet/sctp_output.h |  4 +++-
 3 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 6937f8a2a43f..a55ef5ac1eab 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -406,7 +406,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int 
offset,
        op_err = sctp_arethere_unrecognized_parameters(m,
            (offset + sizeof(struct sctp_init_chunk)),
            &abort_flag, (struct sctp_chunkhdr *)cp,
-           &nat_friendly, &cookie_found);
+           &nat_friendly, &cookie_found, NULL);
        if (abort_flag) {
                /* Send an abort and notify peer */
                sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index c988a8426fe8..a8facff6b917 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -4918,7 +4918,8 @@ sctp_arethere_unrecognized_parameters(struct mbuf 
*in_initpkt,
     int param_offset, int *abort_processing,
     struct sctp_chunkhdr *cp,
     int *nat_friendly,
-    int *cookie_found)
+    int *cookie_found,
+    uint32_t *edmid)
 {
        /*
         * Given a mbuf containing an INIT or INIT-ACK with the param_offset
@@ -4934,8 +4935,8 @@ sctp_arethere_unrecognized_parameters(struct mbuf 
*in_initpkt,
         * hoped that this routine may be reused in the future by new
         * features.
         */
+       struct sctp_zero_checksum_acceptable zero_chksum, *zero_chksum_p;
        struct sctp_paramhdr *phdr, params;
-
        struct mbuf *mat, *m_tmp, *op_err, *op_err_last;
        int at, limit, pad_needed;
        uint16_t ptype, plen, padded_size;
@@ -4944,6 +4945,9 @@ sctp_arethere_unrecognized_parameters(struct mbuf 
*in_initpkt,
        if (cookie_found != NULL) {
                *cookie_found = 0;
        }
+       if (edmid != NULL) {
+               *edmid = SCTP_EDMID_NONE;
+       }
        mat = in_initpkt;
        limit = ntohs(cp->chunk_length) - sizeof(struct sctp_init_chunk);
        at = param_offset;
@@ -4999,6 +5003,22 @@ sctp_arethere_unrecognized_parameters(struct mbuf 
*in_initpkt,
                        }
                        at += padded_size;
                        break;
+               case SCTP_ZERO_CHECKSUM_ACCEPTABLE:
+                       if (padded_size != sizeof(struct 
sctp_zero_checksum_acceptable)) {
+                               SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - 
error checksum acceptable %d\n", plen);
+                               goto invalid_size;
+                       }
+                       if (edmid != NULL) {
+                               phdr = sctp_get_next_param(mat, at,
+                                   (struct sctp_paramhdr *)&zero_chksum,
+                                   sizeof(struct 
sctp_zero_checksum_acceptable));
+                               if (phdr != NULL) {
+                                       zero_chksum_p = (struct 
sctp_zero_checksum_acceptable *)phdr;
+                                       *edmid = ntohl(zero_chksum_p->edmid);
+                               }
+                       }
+                       at += padded_size;
+                       break;
                case SCTP_RANDOM:
                        if (padded_size > (sizeof(struct sctp_auth_random) + 
SCTP_RANDOM_MAX_SIZE)) {
                                SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - 
error random %d\n", plen);
@@ -5513,7 +5533,9 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct 
sctp_tcb *stcb,
        int nat_friendly = 0;
        int error;
        struct socket *so;
+       uint32_t edmid;
        uint16_t num_ext, chunk_len, padding_len, parameter_len;
+       bool use_zero_crc;
 
        if (stcb) {
                asoc = &stcb->asoc;
@@ -5554,7 +5576,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct 
sctp_tcb *stcb,
            (offset + sizeof(struct sctp_init_chunk)),
            &abort_flag,
            (struct sctp_chunkhdr *)init_chk,
-           &nat_friendly, NULL);
+           &nat_friendly, NULL, &edmid);
        if (abort_flag) {
 do_a_abort:
                if (op_err == NULL) {
@@ -6155,12 +6177,18 @@ do_a_abort:
                over_addr = NULL;
        }
 
+       if (asoc != NULL) {
+               use_zero_crc = (asoc->rcv_edmid != SCTP_EDMID_NONE) && 
(asoc->rcv_edmid == edmid);
+       } else {
+               use_zero_crc = (inp->rcv_edmid != SCTP_EDMID_NONE) && 
(inp->rcv_edmid == edmid);
+       }
+
        if ((error = sctp_lowlevel_chunk_output(inp, NULL, NULL, to, m, 0, 
NULL, 0, 0,
            0, 0,
            inp->sctp_lport, sh->src_port, init_chk->init.initiate_tag,
            port, over_addr,
            mflowtype, mflowid,
-           false,              /* XXXMT: Improve this! */
+           use_zero_crc,
            SCTP_SO_NOT_LOCKED))) {
                SCTPDBG(SCTP_DEBUG_OUTPUT4, "Gak send error %d\n", error);
                if (error == ENOBUFS) {
diff --git a/sys/netinet/sctp_output.h b/sys/netinet/sctp_output.h
index 1a1d17221b02..88c12367346a 100644
--- a/sys/netinet/sctp_output.h
+++ b/sys/netinet/sctp_output.h
@@ -80,7 +80,9 @@ sctp_send_initiate_ack(struct sctp_inpcb *, struct sctp_tcb *,
 
 struct mbuf *
 sctp_arethere_unrecognized_parameters(struct mbuf *, int, int *,
-    struct sctp_chunkhdr *, int *, int *);
+    struct sctp_chunkhdr *, int *, int *,
+    uint32_t *);
+
 void sctp_queue_op_err(struct sctp_tcb *, struct mbuf *);
 
 int

Reply via email to