Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+24 −18
Original line number Diff line number Diff line
@@ -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
	 * 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 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;
	}

+14 −5
Original line number Diff line number Diff line
@@ -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)
+48 −29
Original line number Diff line number Diff line
@@ -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.
 *    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.
		 */