Author: tuexen
Date: Sat Sep 12 17:08:51 2015
New Revision: 287717
URL: https://svnweb.freebsd.org/changeset/base/287717

Log:
  Cleanup the handling of error causes for ERROR chunks. This fixes
  an inconsistency of the padding handling. The final padding is
  now considered to be a chunk padding.
  
  MFC after:    1 week

Modified:
  head/sys/netinet/sctp.h
  head/sys/netinet/sctp_auth.c
  head/sys/netinet/sctp_header.h
  head/sys/netinet/sctp_indata.c
  head/sys/netinet/sctp_input.c

Modified: head/sys/netinet/sctp.h
==============================================================================
--- head/sys/netinet/sctp.h     Sat Sep 12 16:46:41 2015        (r287716)
+++ head/sys/netinet/sctp.h     Sat Sep 12 17:08:51 2015        (r287717)
@@ -388,33 +388,32 @@ struct sctp_error_cause {
 }                SCTP_PACKED;
 
 struct sctp_error_invalid_stream {
-       struct sctp_error_cause cause;  /* code=SCTP_ERROR_INVALID_STREAM */
+       struct sctp_error_cause cause;  /* code=SCTP_CAUSE_INVALID_STREAM */
        uint16_t stream_id;     /* stream id of the DATA in error */
        uint16_t reserved;
 }                         SCTP_PACKED;
 
 struct sctp_error_missing_param {
-       struct sctp_error_cause cause;  /* code=SCTP_ERROR_MISSING_PARAM */
+       struct sctp_error_cause cause;  /* code=SCTP_CAUSE_MISSING_PARAM */
        uint32_t num_missing_params;    /* number of missing parameters */
-       /* uint16_t param_type's follow */
+       uint16_t type[];
 }                        SCTP_PACKED;
 
 struct sctp_error_stale_cookie {
-       struct sctp_error_cause cause;  /* code=SCTP_ERROR_STALE_COOKIE */
+       struct sctp_error_cause cause;  /* code=SCTP_CAUSE_STALE_COOKIE */
        uint32_t stale_time;    /* time in usec of staleness */
 }                       SCTP_PACKED;
 
 struct sctp_error_out_of_resource {
-       struct sctp_error_cause cause;  /* code=SCTP_ERROR_OUT_OF_RESOURCES */
+       struct sctp_error_cause cause;  /* code=SCTP_CAUSE_OUT_OF_RESOURCES */
 }                          SCTP_PACKED;
 
 struct sctp_error_unresolv_addr {
-       struct sctp_error_cause cause;  /* code=SCTP_ERROR_UNRESOLVABLE_ADDR */
-
+       struct sctp_error_cause cause;  /* code=SCTP_CAUSE_UNRESOLVABLE_ADDR */
 }                        SCTP_PACKED;
 
 struct sctp_error_unrecognized_chunk {
-       struct sctp_error_cause cause;  /* code=SCTP_ERROR_UNRECOG_CHUNK */
+       struct sctp_error_cause cause;  /* code=SCTP_CAUSE_UNRECOG_CHUNK */
        struct sctp_chunkhdr ch;/* header from chunk in error */
 }                             SCTP_PACKED;
 
@@ -423,6 +422,11 @@ struct sctp_error_no_user_data {
        uint32_t tsn;           /* TSN of the empty data chunk */
 }                       SCTP_PACKED;
 
+struct sctp_error_auth_invalid_hmac {
+       struct sctp_error_cause cause;  /* code=SCTP_CAUSE_UNSUPPORTED_HMACID */
+       uint16_t hmac_id;
+}                            SCTP_PACKED;
+
 /*
  * Main SCTP chunk types we place these here so natd and f/w's in user land
  * can find them.

Modified: head/sys/netinet/sctp_auth.c
==============================================================================
--- head/sys/netinet/sctp_auth.c        Sat Sep 12 16:46:41 2015        
(r287716)
+++ head/sys/netinet/sctp_auth.c        Sat Sep 12 17:08:51 2015        
(r287717)
@@ -1651,8 +1651,8 @@ sctp_handle_auth(struct sctp_tcb *stcb, 
 
        /* is the indicated HMAC supported? */
        if (!sctp_auth_is_supported_hmac(stcb->asoc.local_hmacs, hmac_id)) {
-               struct mbuf *m_err;
-               struct sctp_auth_invalid_hmac *err;
+               struct mbuf *op_err;
+               struct sctp_error_auth_invalid_hmac *cause;
 
                SCTP_STAT_INCR(sctps_recvivalhmacid);
                SCTPDBG(SCTP_DEBUG_AUTH1,
@@ -1662,20 +1662,19 @@ sctp_handle_auth(struct sctp_tcb *stcb, 
                 * report this in an Error Chunk: Unsupported HMAC
                 * Identifier
                 */
-               m_err = sctp_get_mbuf_for_msg(sizeof(*err), 0, M_NOWAIT,
-                   1, MT_HEADER);
-               if (m_err != NULL) {
+               op_err = sctp_get_mbuf_for_msg(sizeof(struct 
sctp_error_auth_invalid_hmac),
+                   0, M_NOWAIT, 1, MT_HEADER);
+               if (op_err != NULL) {
                        /* pre-reserve some space */
-                       SCTP_BUF_RESV_UF(m_err, sizeof(struct sctp_chunkhdr));
+                       SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
                        /* fill in the error */
-                       err = mtod(m_err, struct sctp_auth_invalid_hmac *);
-                       bzero(err, sizeof(*err));
-                       err->ph.param_type = 
htons(SCTP_CAUSE_UNSUPPORTED_HMACID);
-                       err->ph.param_length = htons(sizeof(*err));
-                       err->hmac_id = ntohs(hmac_id);
-                       SCTP_BUF_LEN(m_err) = sizeof(*err);
+                       cause = mtod(op_err, struct 
sctp_error_auth_invalid_hmac *);
+                       cause->cause.code = 
htons(SCTP_CAUSE_UNSUPPORTED_HMACID);
+                       cause->cause.length = htons(sizeof(struct 
sctp_error_auth_invalid_hmac));
+                       cause->hmac_id = ntohs(hmac_id);
+                       SCTP_BUF_LEN(op_err) = sizeof(struct 
sctp_error_auth_invalid_hmac);
                        /* queue it */
-                       sctp_queue_op_err(stcb, m_err);
+                       sctp_queue_op_err(stcb, op_err);
                }
                return (-1);
        }

Modified: head/sys/netinet/sctp_header.h
==============================================================================
--- head/sys/netinet/sctp_header.h      Sat Sep 12 16:46:41 2015        
(r287716)
+++ head/sys/netinet/sctp_header.h      Sat Sep 12 17:08:51 2015        
(r287717)
@@ -202,34 +202,6 @@ struct sctp_state_cookie { /* this is ou
         */
 }                 SCTP_PACKED;
 
-
-/* Used for NAT state error cause */
-struct sctp_missing_nat_state {
-       uint16_t cause;
-       uint16_t length;
-       uint8_t data[];
-}                      SCTP_PACKED;
-
-
-struct sctp_inv_mandatory_param {
-       uint16_t cause;
-       uint16_t length;
-       uint32_t num_param;
-       uint16_t param;
-       /*
-        * We include this to 0 it since only a missing cookie will cause
-        * this error.
-        */
-       uint16_t resv;
-}                        SCTP_PACKED;
-
-struct sctp_unresolv_addr {
-       uint16_t cause;
-       uint16_t length;
-       uint16_t addr_type;
-       uint16_t reserved;      /* Only one invalid addr type */
-}                  SCTP_PACKED;
-
 /* state cookie parameter */
 struct sctp_state_cookie_param {
        struct sctp_paramhdr ph;
@@ -370,28 +342,11 @@ struct sctp_shutdown_complete_chunk {
        struct sctp_chunkhdr ch;
 }                            SCTP_PACKED;
 
-/* Oper error holding a stale cookie */
-struct sctp_stale_cookie_msg {
-       struct sctp_paramhdr ph;/* really an error cause */
-       uint32_t time_usec;
-}                     SCTP_PACKED;
-
 struct sctp_adaptation_layer_indication {
        struct sctp_paramhdr ph;
        uint32_t indication;
 }                                SCTP_PACKED;
 
-struct sctp_cookie_while_shutting_down {
-       struct sctphdr sh;
-       struct sctp_chunkhdr ch;
-       struct sctp_paramhdr ph;/* really an error cause */
-}                               SCTP_PACKED;
-
-struct sctp_shutdown_complete_msg {
-       struct sctphdr sh;
-       struct sctp_shutdown_complete_chunk shut_cmp;
-}                          SCTP_PACKED;
-
 /*
  * draft-ietf-tsvwg-addip-sctp
  */
@@ -554,12 +509,6 @@ struct sctp_auth_chunk {
        uint8_t hmac[];
 }               SCTP_PACKED;
 
-struct sctp_auth_invalid_hmac {
-       struct sctp_paramhdr ph;
-       uint16_t hmac_id;
-       uint16_t padding;
-}                      SCTP_PACKED;
-
 /*
  * we pre-reserve enough room for a ECNE or CWR AND a SACK with no missing
  * pieces. If ENCE is missing we could have a couple of blocks. This way we

Modified: head/sys/netinet/sctp_indata.c
==============================================================================
--- head/sys/netinet/sctp_indata.c      Sat Sep 12 16:46:41 2015        
(r287716)
+++ head/sys/netinet/sctp_indata.c      Sat Sep 12 17:08:51 2015        
(r287717)
@@ -1426,30 +1426,25 @@ sctp_process_a_data_chunk(struct sctp_tc
        }
        strmno = ntohs(ch->dp.stream_id);
        if (strmno >= asoc->streamincnt) {
-               struct sctp_paramhdr *phdr;
-               struct mbuf *mb;
+               struct sctp_error_invalid_stream *cause;
 
-               mb = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) * 2),
+               op_err = sctp_get_mbuf_for_msg(sizeof(struct 
sctp_error_invalid_stream),
                    0, M_NOWAIT, 1, MT_DATA);
-               if (mb != NULL) {
+               if (op_err != NULL) {
                        /* add some space up front so prepend will work well */
-                       SCTP_BUF_RESV_UF(mb, sizeof(struct sctp_chunkhdr));
-                       phdr = mtod(mb, struct sctp_paramhdr *);
+                       SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
+                       cause = mtod(op_err, struct sctp_error_invalid_stream 
*);
                        /*
                         * Error causes are just param's and this one has
                         * two back to back phdr, one with the error type
                         * and size, the other with the streamid and a rsvd
                         */
-                       SCTP_BUF_LEN(mb) = (sizeof(struct sctp_paramhdr) * 2);
-                       phdr->param_type = htons(SCTP_CAUSE_INVALID_STREAM);
-                       phdr->param_length =
-                           htons(sizeof(struct sctp_paramhdr) * 2);
-                       phdr++;
-                       /* We insert the stream in the type field */
-                       phdr->param_type = ch->dp.stream_id;
-                       /* And set the length to 0 for the rsvd field */
-                       phdr->param_length = 0;
-                       sctp_queue_op_err(stcb, mb);
+                       SCTP_BUF_LEN(op_err) = sizeof(struct 
sctp_error_invalid_stream);
+                       cause->cause.code = htons(SCTP_CAUSE_INVALID_STREAM);
+                       cause->cause.length = htons(sizeof(struct 
sctp_error_invalid_stream));
+                       cause->stream_id = ch->dp.stream_id;
+                       cause->reserved = htons(0);
+                       sctp_queue_op_err(stcb, op_err);
                }
                SCTP_STAT_INCR(sctps_badsid);
                SCTP_TCB_LOCK_ASSERT(stcb);
@@ -2492,30 +2487,21 @@ sctp_process_data(struct mbuf **mm, int 
                                /* unknown chunk type, use bit rules */
                                if (ch->ch.chunk_type & 0x40) {
                                        /* Add a error report to the queue */
-                                       struct mbuf *merr;
-                                       struct sctp_paramhdr *phd;
+                                       struct mbuf *op_err;
+                                       struct sctp_gen_error_cause *cause;
 
-                                       merr = 
sctp_get_mbuf_for_msg(sizeof(*phd), 0, M_NOWAIT, 1, MT_DATA);
-                                       if (merr) {
-                                               phd = mtod(merr, struct 
sctp_paramhdr *);
-                                               /*
-                                                * We cheat and use param
-                                                * type since we did not
-                                                * bother to define a error
-                                                * cause struct. They are
-                                                * the same basic format
-                                                * with different names.
-                                                */
-                                               phd->param_type =
-                                                   
htons(SCTP_CAUSE_UNRECOG_CHUNK);
-                                               phd->param_length =
-                                                   htons(chk_length + 
sizeof(*phd));
-                                               SCTP_BUF_LEN(merr) = 
sizeof(*phd);
-                                               SCTP_BUF_NEXT(merr) = 
SCTP_M_COPYM(m, *offset, chk_length, M_NOWAIT);
-                                               if (SCTP_BUF_NEXT(merr)) {
-                                                       sctp_queue_op_err(stcb, 
merr);
+                                       op_err = 
sctp_get_mbuf_for_msg(sizeof(struct sctp_gen_error_cause),
+                                           0, M_NOWAIT, 1, MT_DATA);
+                                       if (op_err != NULL) {
+                                               cause = mtod(op_err, struct 
sctp_gen_error_cause *);
+                                               cause->code = 
htons(SCTP_CAUSE_UNRECOG_CHUNK);
+                                               cause->length = 
htons(chk_length + sizeof(struct sctp_gen_error_cause));
+                                               SCTP_BUF_LEN(op_err) = 
sizeof(struct sctp_gen_error_cause);
+                                               SCTP_BUF_NEXT(op_err) = 
SCTP_M_COPYM(m, *offset, chk_length, M_NOWAIT);
+                                               if (SCTP_BUF_NEXT(op_err) != 
NULL) {
+                                                       sctp_queue_op_err(stcb, 
op_err);
                                                } else {
-                                                       sctp_m_freem(merr);
+                                                       sctp_m_freem(op_err);
                                                }
                                        }
                                }

Modified: head/sys/netinet/sctp_input.c
==============================================================================
--- head/sys/netinet/sctp_input.c       Sat Sep 12 16:46:41 2015        
(r287716)
+++ head/sys/netinet/sctp_input.c       Sat Sep 12 17:08:51 2015        
(r287717)
@@ -530,25 +530,21 @@ sctp_process_init_ack(struct mbuf *m, in
                 * abandon the peer, its broke.
                 */
                if (retval == -3) {
+                       size_t len;
+
+                       len = sizeof(struct sctp_error_missing_param) + 
sizeof(uint16_t);
                        /* We abort with an error of missing mandatory param */
-                       op_err = sctp_generate_cause(SCTP_CAUSE_MISSING_PARAM, 
"");
-                       if (op_err) {
-                               /*
-                                * Expand beyond to include the mandatory
-                                * param cookie
-                                */
-                               struct sctp_inv_mandatory_param *mp;
+                       op_err = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, 
MT_DATA);
+                       if (op_err != NULL) {
+                               struct sctp_error_missing_param *cause;
 
-                               SCTP_BUF_LEN(op_err) =
-                                   sizeof(struct sctp_inv_mandatory_param);
-                               mp = mtod(op_err,
-                                   struct sctp_inv_mandatory_param *);
+                               SCTP_BUF_LEN(op_err) = len;
+                               cause = mtod(op_err, struct 
sctp_error_missing_param *);
                                /* Subtract the reserved param */
-                               mp->length =
-                                   htons(sizeof(struct 
sctp_inv_mandatory_param) - 2);
-                               mp->num_param = htonl(1);
-                               mp->param = htons(SCTP_STATE_COOKIE);
-                               mp->resv = 0;
+                               cause->cause.code = 
htons(SCTP_CAUSE_MISSING_PARAM);
+                               cause->cause.length = htons(len);
+                               cause->num_missing_params = htonl(1);
+                               cause->type[0] = htons(SCTP_STATE_COOKIE);
                        }
                        sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
                            src, dst, sh, op_err,
@@ -781,10 +777,10 @@ sctp_handle_abort(struct sctp_abort_chun
                 * Need to check the cause codes for our two magic nat
                 * aborts which don't kill the assoc necessarily.
                 */
-               struct sctp_missing_nat_state *natc;
+               struct sctp_gen_error_cause *cause;
 
-               natc = (struct sctp_missing_nat_state *)(abort + 1);
-               error = ntohs(natc->cause);
+               cause = (struct sctp_gen_error_cause *)(abort + 1);
+               error = ntohs(cause->code);
                if (error == SCTP_CAUSE_NAT_COLLIDING_STATE) {
                        SCTPDBG(SCTP_DEBUG_INPUT2, "Received Colliding state 
abort flags:%x\n",
                            abort->ch.chunk_flags);
@@ -2558,27 +2554,27 @@ sctp_handle_cookie_echo(struct mbuf *m, 
        if (timevalcmp(&now, &time_expires, >)) {
                /* cookie is stale! */
                struct mbuf *op_err;
-               struct sctp_stale_cookie_msg *scm;
+               struct sctp_error_stale_cookie *cause;
                uint32_t tim;
 
-               op_err = sctp_get_mbuf_for_msg(sizeof(struct 
sctp_stale_cookie_msg),
+               op_err = sctp_get_mbuf_for_msg(sizeof(struct 
sctp_error_stale_cookie),
                    0, M_NOWAIT, 1, MT_DATA);
                if (op_err == NULL) {
                        /* FOOBAR */
                        return (NULL);
                }
                /* Set the len */
-               SCTP_BUF_LEN(op_err) = sizeof(struct sctp_stale_cookie_msg);
-               scm = mtod(op_err, struct sctp_stale_cookie_msg *);
-               scm->ph.param_type = htons(SCTP_CAUSE_STALE_COOKIE);
-               scm->ph.param_length = htons((sizeof(struct sctp_paramhdr) +
+               SCTP_BUF_LEN(op_err) = sizeof(struct sctp_error_stale_cookie);
+               cause = mtod(op_err, struct sctp_error_stale_cookie *);
+               cause->cause.code = htons(SCTP_CAUSE_STALE_COOKIE);
+               cause->cause.length = htons((sizeof(struct sctp_paramhdr) +
                    (sizeof(uint32_t))));
                /* seconds to usec */
                tim = (now.tv_sec - time_expires.tv_sec) * 1000000;
                /* add in usec */
                if (tim == 0)
                        tim = now.tv_usec - cookie->time_entered.tv_usec;
-               scm->time_usec = htonl(tim);
+               cause->stale_time = htonl(tim);
                sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err,
                    mflowtype, mflowid, l_inp->fibnum,
                    vrf_id, port);
@@ -5581,35 +5577,27 @@ process_control_chunks:
        unknown_chunk:
                        /* it's an unknown chunk! */
                        if ((ch->chunk_type & 0x40) && (stcb != NULL)) {
-                               struct mbuf *mm;
-                               struct sctp_paramhdr *phd;
+                               struct sctp_gen_error_cause *cause;
                                int len;
 
-                               mm = sctp_get_mbuf_for_msg(sizeof(struct 
sctp_paramhdr),
+                               op_err = sctp_get_mbuf_for_msg(sizeof(struct 
sctp_gen_error_cause),
                                    0, M_NOWAIT, 1, MT_DATA);
-                               if (mm) {
+                               if (op_err != NULL) {
                                        len = min(SCTP_SIZE32(chk_length), 
(uint32_t) (length - *offset));
-                                       phd = mtod(mm, struct sctp_paramhdr *);
-                                       /*
-                                        * We cheat and use param type since
-                                        * we did not bother to define a
-                                        * error cause struct. They are the
-                                        * same basic format with different
-                                        * names.
-                                        */
-                                       phd->param_type = 
htons(SCTP_CAUSE_UNRECOG_CHUNK);
-                                       phd->param_length = htons(len + 
sizeof(*phd));
-                                       SCTP_BUF_LEN(mm) = sizeof(*phd);
-                                       SCTP_BUF_NEXT(mm) = SCTP_M_COPYM(m, 
*offset, len, M_NOWAIT);
-                                       if (SCTP_BUF_NEXT(mm)) {
+                                       cause = mtod(op_err, struct 
sctp_gen_error_cause *);
+                                       cause->code = 
htons(SCTP_CAUSE_UNRECOG_CHUNK);
+                                       cause->length = htons(len + 
sizeof(struct sctp_gen_error_cause));
+                                       SCTP_BUF_LEN(op_err) = sizeof(struct 
sctp_gen_error_cause);
+                                       SCTP_BUF_NEXT(op_err) = SCTP_M_COPYM(m, 
*offset, len, M_NOWAIT);
+                                       if (SCTP_BUF_NEXT(op_err) != NULL) {
 #ifdef SCTP_MBUF_LOGGING
                                                if 
(SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
                                                        
sctp_log_mbc(SCTP_BUF_NEXT(mm), SCTP_MBUF_ICOPY);
                                                }
 #endif
-                                               sctp_queue_op_err(stcb, mm);
+                                               sctp_queue_op_err(stcb, op_err);
                                        } else {
-                                               sctp_m_freem(mm);
+                                               sctp_m_freem(op_err);
                                        }
                                }
                        }
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to