diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/sctp/sm_make_chunk.c | 19 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 77 |
2 files changed, 62 insertions, 34 deletions
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 1db12cc18cf7..33ac8bf47b0e 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 278c56a2d076..8e01b8f09ac2 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 @@ nomem: } /* - * 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. */ |