diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h index 5576db56324dd88ed87f6355a603464532dd0190..f4fcee104707ae7961605b632aba1bf620c25603 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h @@ -407,32 +407,38 @@ sctp_vtag_verify(const struct sctp_chunk *chunk, return 0; } -/* Check VTAG of the packet matches the sender's own tag OR its peer's - * tag and the T bit is set in the Chunk Flags. +/* Check VTAG of the packet matches the sender's own tag and the T bit is + * not set, OR its peer's tag and the T bit is set in the Chunk Flags. */ static inline int sctp_vtag_verify_either(const struct sctp_chunk *chunk, const struct sctp_association *asoc) { - /* RFC 2960 Section 8.5.1, sctpimpguide-06 Section 2.13.2 + /* RFC 2960 Section 8.5.1, sctpimpguide Section 2.41 * - * B) The receiver of a ABORT shall accept the packet if the - * Verification Tag field of the packet matches its own tag OR it - * is set to its peer's tag and the T bit is set in the Chunk - * Flags. Otherwise, the receiver MUST silently discard the packet - * and take no further action. - * - * (C) The receiver of a SHUTDOWN COMPLETE shall accept the - * packet if the Verification Tag field of the packet - * matches its own tag OR it is set to its peer's tag and - * the T bit is set in the Chunk Flags. Otherwise, the - * receiver MUST silently discard the packet and take no - * further action.... + * B) The receiver of a ABORT MUST accept the packet + * if the Verification Tag field of the packet matches its own tag + * and the T bit is not set + * OR + * it is set to its peer's tag and the T bit is set in the Chunk + * Flags. + * Otherwise, the receiver MUST silently discard the packet + * and take no further action. * + * C) The receiver of a SHUTDOWN COMPLETE shall accept the packet + * if the Verification Tag field of the packet matches its own tag + * and the T bit is not set + * OR + * it is set to its peer's tag and the T bit is set in the Chunk + * Flags. + * Otherwise, the receiver MUST silently discard the packet + * and take no further action. An endpoint MUST ignore the + * SHUTDOWN COMPLETE if it is not in the SHUTDOWN-ACK-SENT state. */ - if ((ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag) || - (sctp_test_T_bit(chunk) && (ntohl(chunk->sctp_hdr->vtag) - == asoc->c.peer_vtag))) { + if ((!sctp_test_T_bit(chunk) && + (ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag)) || + (sctp_test_T_bit(chunk) && + (ntohl(chunk->sctp_hdr->vtag) == asoc->c.peer_vtag))) { return 1; } diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 1db12cc18cf7fc4fd0b7209d3e5b03e192df2944..33ac8bf47b0e0d64b2ba9a75b136bc82eac1fa65 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -710,7 +710,9 @@ struct sctp_chunk *sctp_make_shutdown_complete( struct sctp_chunk *retval; __u8 flags = 0; - /* Maybe set the T-bit if we have no association. */ + /* Set the T-bit if we have no association (vtag will be + * reflected) + */ flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T; retval = sctp_make_chunk(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags, 0); @@ -732,7 +734,7 @@ struct sctp_chunk *sctp_make_shutdown_complete( } /* Create an ABORT. Note that we set the T bit if we have no - * association. + * association, except when responding to an INIT (sctpimpguide 2.41). */ struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc, const struct sctp_chunk *chunk, @@ -741,8 +743,16 @@ struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc, struct sctp_chunk *retval; __u8 flags = 0; - /* Maybe set the T-bit if we have no association. */ - flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T; + /* Set the T-bit if we have no association and 'chunk' is not + * an INIT (vtag will be reflected). + */ + if (!asoc) { + if (chunk && chunk->chunk_hdr && + chunk->chunk_hdr->type == SCTP_CID_INIT) + flags = 0; + else + flags = SCTP_CHUNK_FLAG_T; + } retval = sctp_make_chunk(asoc, SCTP_CID_ABORT, flags, hint); @@ -2744,7 +2754,6 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc, hint = (nstreams + 1) * sizeof(__u32); - /* Maybe set the T-bit if we have no association. */ retval = sctp_make_chunk(asoc, SCTP_CID_FWD_TSN, 0, hint); if (!retval) diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 278c56a2d0765086f540c66d64ff151eaba9a155..8e01b8f09ac28914573c81727d9e19ab55076652 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -126,15 +126,18 @@ sctp_chunk_length_valid(struct sctp_chunk *chunk, * should stop the T2-shutdown timer and remove all knowledge of the * association (and thus the association enters the CLOSED state). * - * Verification Tag: 8.5.1(C) + * Verification Tag: 8.5.1(C), sctpimpguide 2.41. * C) Rules for packet carrying SHUTDOWN COMPLETE: * ... - * - The receiver of a SHUTDOWN COMPLETE shall accept the packet if the - * Verification Tag field of the packet matches its own tag OR it is - * set to its peer's tag and the T bit is set in the Chunk Flags. - * Otherwise, the receiver MUST silently discard the packet and take - * no further action. An endpoint MUST ignore the SHUTDOWN COMPLETE if - * it is not in the SHUTDOWN-ACK-SENT state. + * - The receiver of a SHUTDOWN COMPLETE shall accept the packet + * if the Verification Tag field of the packet matches its own tag and + * the T bit is not set + * OR + * it is set to its peer's tag and the T bit is set in the Chunk + * Flags. + * Otherwise, the receiver MUST silently discard the packet + * and take no further action. An endpoint MUST ignore the + * SHUTDOWN COMPLETE if it is not in the SHUTDOWN-ACK-SENT state. * * Inputs * (endpoint, asoc, chunk) @@ -2858,16 +2861,16 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep, /* * Generate an ABORT in response to a packet. * - * Section: 8.4 Handle "Out of the blue" Packets + * Section: 8.4 Handle "Out of the blue" Packets, sctpimpguide 2.41 * - * 8) The receiver should respond to the sender of the OOTB packet - * with an ABORT. When sending the ABORT, the receiver of the - * OOTB packet MUST fill in the Verification Tag field of the - * outbound packet with the value found in the Verification Tag - * field of the OOTB packet and set the T-bit in the Chunk Flags - * to indicate that no TCB was found. After sending this ABORT, - * the receiver of the OOTB packet shall discard the OOTB packet - * and take no further action. + * 8) The receiver should respond to the sender of the OOTB packet with + * an ABORT. When sending the ABORT, the receiver of the OOTB packet + * MUST fill in the Verification Tag field of the outbound packet + * with the value found in the Verification Tag field of the OOTB + * packet and set the T-bit in the Chunk Flags to indicate that the + * Verification Tag is reflected. After sending this ABORT, the + * receiver of the OOTB packet shall discard the OOTB packet and take + * no further action. * * Verification Tag: * @@ -2895,6 +2898,10 @@ sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep, return SCTP_DISPOSITION_NOMEM; } + /* Reflect vtag if T-Bit is set */ + if (sctp_test_T_bit(abort)) + packet->vtag = ntohl(chunk->sctp_hdr->vtag); + /* Set the skb to the belonging sock for accounting. */ abort->skb->sk = ep->base.sk; @@ -3026,22 +3033,24 @@ sctp_disposition_t sctp_sf_do_9_2_final(const struct sctp_endpoint *ep, } /* - * RFC 2960, 8.4 - Handle "Out of the blue" Packets + * RFC 2960, 8.4 - Handle "Out of the blue" Packets, sctpimpguide 2.41. + * * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB * packet must fill in the Verification Tag field of the outbound * packet with the Verification Tag received in the SHUTDOWN ACK and - * set the T-bit in the Chunk Flags to indicate that no TCB was - * found. Otherwise, + * set the T-bit in the Chunk Flags to indicate that the Verification + * Tag is reflected. * * 8) The receiver should respond to the sender of the OOTB packet with * an ABORT. When sending the ABORT, the receiver of the OOTB packet * MUST fill in the Verification Tag field of the outbound packet * with the value found in the Verification Tag field of the OOTB - * packet and set the T-bit in the Chunk Flags to indicate that no - * TCB was found. After sending this ABORT, the receiver of the OOTB - * packet shall discard the OOTB packet and take no further action. + * packet and set the T-bit in the Chunk Flags to indicate that the + * Verification Tag is reflected. After sending this ABORT, the + * receiver of the OOTB packet shall discard the OOTB packet and take + * no further action. */ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, const struct sctp_association *asoc, @@ -3090,13 +3099,15 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, /* * Handle an "Out of the blue" SHUTDOWN ACK. * - * Section: 8.4 5) + * Section: 8.4 5, sctpimpguide 2.41. + * * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should - * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. - * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB packet - * must fill in the Verification Tag field of the outbound packet with - * the Verification Tag received in the SHUTDOWN ACK and set the - * T-bit in the Chunk Flags to indicate that no TCB was found. + * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. + * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB + * packet must fill in the Verification Tag field of the outbound + * packet with the Verification Tag received in the SHUTDOWN ACK and + * set the T-bit in the Chunk Flags to indicate that the Verification + * Tag is reflected. * * Inputs * (endpoint, asoc, type, arg, commands) @@ -3128,6 +3139,10 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep, return SCTP_DISPOSITION_NOMEM; } + /* Reflect vtag if T-Bit is set */ + if (sctp_test_T_bit(shut)) + packet->vtag = ntohl(chunk->sctp_hdr->vtag); + /* Set the skb to the belonging sock for accounting. */ shut->skb->sk = ep->base.sk; @@ -3591,7 +3606,6 @@ sctp_disposition_t sctp_sf_discard_chunk(const struct sctp_endpoint *ep, * * 2) If the OOTB packet contains an ABORT chunk, the receiver MUST * silently discard the OOTB packet and take no further action. - * Otherwise, * * Verification Tag: No verification necessary * @@ -4961,6 +4975,11 @@ static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep, sctp_ootb_pkt_free(packet); return NULL; } + + /* Reflect vtag if T-Bit is set */ + if (sctp_test_T_bit(abort)) + packet->vtag = ntohl(chunk->sctp_hdr->vtag); + /* Add specified error causes, i.e., payload, to the * end of the chunk. */