[SCTP] Implement Sec 2.41 of SCTP Implementers guide.
authorJerome Forissier <jerome.forissier@hp.com>
Thu, 28 Apr 2005 18:58:43 +0000 (11:58 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 28 Apr 2005 18:58:43 +0000 (11:58 -0700)
- 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>
include/net/sctp/sm.h
net/sctp/sm_make_chunk.c
net/sctp/sm_statefuns.c

index 5576db5..f4fcee1 100644 (file)
@@ -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;
        }
 
index 1db12cc..33ac8bf 100644 (file)
@@ -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)
index 278c56a..8e01b8f 100644 (file)
@@ -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.
                 */