Commit 047a2428 authored by Jerome Forissier's avatar Jerome Forissier Committed by David S. Miller

[SCTP] Implement Sec 2.41 of SCTP Implementers guide.

- Fixed sctp_vtag_verify_either() to comply with impguide 2.41 B) and C).
- Make sure vtag is reflected when T-bit is set in SHUTDOWN-COMPLETE sent
  due to an OOTB SHUTDOWN-ACK and in ABORT sent due to an OOTB packet.
- Do not set T-Bit in ABORT chunk in response to INIT.
- Fixed some comments to reflect the new meaning of the T-Bit.
Signed-off-by: default avatarJerome Forissier <jerome.forissier@hp.com>
Signed-off-by: default avatarSridhar Samudrala <sri@us.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 17337216
...@@ -407,32 +407,38 @@ sctp_vtag_verify(const struct sctp_chunk *chunk, ...@@ -407,32 +407,38 @@ sctp_vtag_verify(const struct sctp_chunk *chunk,
return 0; return 0;
} }
/* Check VTAG of the packet matches the sender's own tag OR its peer's /* Check VTAG of the packet matches the sender's own tag and the T bit is
* tag and the T bit is set in the Chunk Flags. * not set, OR its peer's tag and the T bit is set in the Chunk Flags.
*/ */
static inline int static inline int
sctp_vtag_verify_either(const struct sctp_chunk *chunk, sctp_vtag_verify_either(const struct sctp_chunk *chunk,
const struct sctp_association *asoc) 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 * B) The receiver of a ABORT MUST accept the packet
* Verification Tag field of the packet matches its own tag OR it * if the Verification Tag field of the packet matches its own tag
* is set to its peer's tag and the T bit is set in the Chunk * and the T bit is not set
* Flags. Otherwise, the receiver MUST silently discard the packet * OR
* and take no further action. * it is set to its peer's tag and the T bit is set in the Chunk
* * Flags.
* (C) The receiver of a SHUTDOWN COMPLETE shall accept the * Otherwise, the receiver MUST silently discard the packet
* packet if the Verification Tag field of the packet * and take no further action.
* 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
* 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) || if ((!sctp_test_T_bit(chunk) &&
(sctp_test_T_bit(chunk) && (ntohl(chunk->sctp_hdr->vtag) (ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag)) ||
== asoc->c.peer_vtag))) { (sctp_test_T_bit(chunk) &&
(ntohl(chunk->sctp_hdr->vtag) == asoc->c.peer_vtag))) {
return 1; return 1;
} }
......
...@@ -710,7 +710,9 @@ struct sctp_chunk *sctp_make_shutdown_complete( ...@@ -710,7 +710,9 @@ struct sctp_chunk *sctp_make_shutdown_complete(
struct sctp_chunk *retval; struct sctp_chunk *retval;
__u8 flags = 0; __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; flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T;
retval = sctp_make_chunk(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags, 0); retval = sctp_make_chunk(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags, 0);
...@@ -732,7 +734,7 @@ struct sctp_chunk *sctp_make_shutdown_complete( ...@@ -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 /* 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, struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc,
const struct sctp_chunk *chunk, const struct sctp_chunk *chunk,
...@@ -741,8 +743,16 @@ struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc, ...@@ -741,8 +743,16 @@ struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc,
struct sctp_chunk *retval; struct sctp_chunk *retval;
__u8 flags = 0; __u8 flags = 0;
/* Maybe set the T-bit if we have no association. */ /* Set the T-bit if we have no association and 'chunk' is not
flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T; * 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); 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, ...@@ -2744,7 +2754,6 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
hint = (nstreams + 1) * sizeof(__u32); 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); retval = sctp_make_chunk(asoc, SCTP_CID_FWD_TSN, 0, hint);
if (!retval) if (!retval)
......
...@@ -126,15 +126,18 @@ sctp_chunk_length_valid(struct sctp_chunk *chunk, ...@@ -126,15 +126,18 @@ sctp_chunk_length_valid(struct sctp_chunk *chunk,
* should stop the T2-shutdown timer and remove all knowledge of the * should stop the T2-shutdown timer and remove all knowledge of the
* association (and thus the association enters the CLOSED state). * 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: * C) Rules for packet carrying SHUTDOWN COMPLETE:
* ... * ...
* - The receiver of a SHUTDOWN COMPLETE shall accept the packet if the * - The receiver of a SHUTDOWN COMPLETE shall accept the packet
* Verification Tag field of the packet matches its own tag OR it is * if the Verification Tag field of the packet matches its own tag and
* set to its peer's tag and the T bit is set in the Chunk Flags. * the T bit is not set
* Otherwise, the receiver MUST silently discard the packet and take * OR
* no further action. An endpoint MUST ignore the SHUTDOWN COMPLETE if * it is set to its peer's tag and the T bit is set in the Chunk
* it is not in the SHUTDOWN-ACK-SENT state. * 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 * Inputs
* (endpoint, asoc, chunk) * (endpoint, asoc, chunk)
...@@ -2858,16 +2861,16 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep, ...@@ -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. * 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 * 8) The receiver should respond to the sender of the OOTB packet with
* with an ABORT. When sending the ABORT, the receiver of the * an ABORT. When sending the ABORT, the receiver of the OOTB packet
* OOTB packet MUST fill in the Verification Tag field of the * MUST fill in the Verification Tag field of the outbound packet
* outbound packet with the value found in the Verification Tag * with the value found in the Verification Tag field of the OOTB
* field of the OOTB packet and set the T-bit in the Chunk Flags * packet and set the T-bit in the Chunk Flags to indicate that the
* to indicate that no TCB was found. After sending this ABORT, * Verification Tag is reflected. After sending this ABORT, the
* the receiver of the OOTB packet shall discard the OOTB packet * receiver of the OOTB packet shall discard the OOTB packet and take
* and take no further action. * no further action.
* *
* Verification Tag: * Verification Tag:
* *
...@@ -2895,6 +2898,10 @@ sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep, ...@@ -2895,6 +2898,10 @@ sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
return SCTP_DISPOSITION_NOMEM; 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. */ /* Set the skb to the belonging sock for accounting. */
abort->skb->sk = ep->base.sk; abort->skb->sk = ep->base.sk;
...@@ -3026,22 +3033,24 @@ nomem: ...@@ -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 * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should
* respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE.
* When sending the SHUTDOWN COMPLETE, the receiver of the OOTB * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB
* packet must fill in the Verification Tag field of the outbound * packet must fill in the Verification Tag field of the outbound
* packet with the Verification Tag received in the SHUTDOWN ACK and * 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 * set the T-bit in the Chunk Flags to indicate that the Verification
* found. Otherwise, * Tag is reflected.
* *
* 8) The receiver should respond to the sender of the OOTB packet with * 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 * an ABORT. When sending the ABORT, the receiver of the OOTB packet
* MUST fill in the Verification Tag field of the outbound packet * MUST fill in the Verification Tag field of the outbound packet
* with the value found in the Verification Tag field of the OOTB * 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 * packet and set the T-bit in the Chunk Flags to indicate that the
* TCB was found. After sending this ABORT, the receiver of the OOTB * Verification Tag is reflected. After sending this ABORT, the
* packet shall discard the OOTB packet and take no further action. * 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, sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
const struct sctp_association *asoc, const struct sctp_association *asoc,
...@@ -3090,13 +3099,15 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, ...@@ -3090,13 +3099,15 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
/* /*
* Handle an "Out of the blue" SHUTDOWN ACK. * 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 * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should
* respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE.
* When sending the SHUTDOWN COMPLETE, the receiver of the OOTB packet * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB
* must fill in the Verification Tag field of the outbound packet with * packet must fill in the Verification Tag field of the outbound
* the Verification Tag received in the SHUTDOWN ACK and set the * packet with the Verification Tag received in the SHUTDOWN ACK and
* T-bit in the Chunk Flags to indicate that no TCB was found. * set the T-bit in the Chunk Flags to indicate that the Verification
* Tag is reflected.
* *
* Inputs * Inputs
* (endpoint, asoc, type, arg, commands) * (endpoint, asoc, type, arg, commands)
...@@ -3128,6 +3139,10 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep, ...@@ -3128,6 +3139,10 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
return SCTP_DISPOSITION_NOMEM; 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. */ /* Set the skb to the belonging sock for accounting. */
shut->skb->sk = ep->base.sk; shut->skb->sk = ep->base.sk;
...@@ -3591,7 +3606,6 @@ sctp_disposition_t sctp_sf_discard_chunk(const struct sctp_endpoint *ep, ...@@ -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 * 2) If the OOTB packet contains an ABORT chunk, the receiver MUST
* silently discard the OOTB packet and take no further action. * silently discard the OOTB packet and take no further action.
* Otherwise,
* *
* Verification Tag: No verification necessary * Verification Tag: No verification necessary
* *
...@@ -4961,6 +4975,11 @@ static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep, ...@@ -4961,6 +4975,11 @@ static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
sctp_ootb_pkt_free(packet); sctp_ootb_pkt_free(packet);
return NULL; 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 /* Add specified error causes, i.e., payload, to the
* end of the chunk. * end of the chunk.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment