[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: Jerome Forissier <jerome.forissier@hp.com> Signed-off-by: Sridhar Samudrala <sri@us.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
173372162d
commit
047a2428a1
@@ -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(
|
|||||||
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(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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,
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
* 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,
|
|||||||
/*
|
/*
|
||||||
* 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,
|
|||||||
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:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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,
|
|||||||
/*
|
/*
|
||||||
* 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,
|
|||||||
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,
|
|||||||
*
|
*
|
||||||
* 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,
|
|||||||
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.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user