aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJerome Forissier <jerome.forissier@hp.com>2005-04-28 14:58:43 -0400
committerDavid S. Miller <davem@davemloft.net>2005-04-28 14:58:43 -0400
commit047a2428a14216a83980ed26b6a59b3ca40a1fb0 (patch)
tree9b4b4abb85b045fbf95700c1a9ca6e6ed7dfd60b
parent173372162ddbd414cc471c1a3a52ad7ea279aaf4 (diff)
[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>
-rw-r--r--include/net/sctp/sm.h42
-rw-r--r--net/sctp/sm_make_chunk.c19
-rw-r--r--net/sctp/sm_statefuns.c77
3 files changed, 86 insertions, 52 deletions
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 5576db56324d..f4fcee104707 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -407,32 +407,38 @@ sctp_vtag_verify(const struct sctp_chunk *chunk,
407 return 0; 407 return 0;
408} 408}
409 409
410/* Check VTAG of the packet matches the sender's own tag OR its peer's 410/* Check VTAG of the packet matches the sender's own tag and the T bit is
411 * tag and the T bit is set in the Chunk Flags. 411 * not set, OR its peer's tag and the T bit is set in the Chunk Flags.
412 */ 412 */
413static inline int 413static inline int
414sctp_vtag_verify_either(const struct sctp_chunk *chunk, 414sctp_vtag_verify_either(const struct sctp_chunk *chunk,
415 const struct sctp_association *asoc) 415 const struct sctp_association *asoc)
416{ 416{
417 /* RFC 2960 Section 8.5.1, sctpimpguide-06 Section 2.13.2 417 /* RFC 2960 Section 8.5.1, sctpimpguide Section 2.41
418 * 418 *
419 * B) The receiver of a ABORT shall accept the packet if the 419 * B) The receiver of a ABORT MUST accept the packet
420 * Verification Tag field of the packet matches its own tag OR it 420 * if the Verification Tag field of the packet matches its own tag
421 * is set to its peer's tag and the T bit is set in the Chunk 421 * and the T bit is not set
422 * Flags. Otherwise, the receiver MUST silently discard the packet 422 * OR
423 * and take no further action. 423 * it is set to its peer's tag and the T bit is set in the Chunk
424 * 424 * Flags.
425 * (C) The receiver of a SHUTDOWN COMPLETE shall accept the 425 * Otherwise, the receiver MUST silently discard the packet
426 * packet if the Verification Tag field of the packet 426 * and take no further action.
427 * matches its own tag OR it is set to its peer's tag and
428 * the T bit is set in the Chunk Flags. Otherwise, the
429 * receiver MUST silently discard the packet and take no
430 * further action....
431 * 427 *
428 * C) The receiver of a SHUTDOWN COMPLETE shall accept the packet
429 * if the Verification Tag field of the packet matches its own tag
430 * and the T bit is not set
431 * OR
432 * it is set to its peer's tag and the T bit is set in the Chunk
433 * Flags.
434 * Otherwise, the receiver MUST silently discard the packet
435 * and take no further action. An endpoint MUST ignore the
436 * SHUTDOWN COMPLETE if it is not in the SHUTDOWN-ACK-SENT state.
432 */ 437 */
433 if ((ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag) || 438 if ((!sctp_test_T_bit(chunk) &&
434 (sctp_test_T_bit(chunk) && (ntohl(chunk->sctp_hdr->vtag) 439 (ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag)) ||
435 == asoc->c.peer_vtag))) { 440 (sctp_test_T_bit(chunk) &&
441 (ntohl(chunk->sctp_hdr->vtag) == asoc->c.peer_vtag))) {
436 return 1; 442 return 1;
437 } 443 }
438 444
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(
710 struct sctp_chunk *retval; 710 struct sctp_chunk *retval;
711 __u8 flags = 0; 711 __u8 flags = 0;
712 712
713 /* Maybe set the T-bit if we have no association. */ 713 /* Set the T-bit if we have no association (vtag will be
714 * reflected)
715 */
714 flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T; 716 flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T;
715 717
716 retval = sctp_make_chunk(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags, 0); 718 retval = sctp_make_chunk(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags, 0);
@@ -732,7 +734,7 @@ struct sctp_chunk *sctp_make_shutdown_complete(
732} 734}
733 735
734/* Create an ABORT. Note that we set the T bit if we have no 736/* Create an ABORT. Note that we set the T bit if we have no
735 * association. 737 * association, except when responding to an INIT (sctpimpguide 2.41).
736 */ 738 */
737struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc, 739struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc,
738 const struct sctp_chunk *chunk, 740 const struct sctp_chunk *chunk,
@@ -741,8 +743,16 @@ struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc,
741 struct sctp_chunk *retval; 743 struct sctp_chunk *retval;
742 __u8 flags = 0; 744 __u8 flags = 0;
743 745
744 /* Maybe set the T-bit if we have no association. */ 746 /* Set the T-bit if we have no association and 'chunk' is not
745 flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T; 747 * an INIT (vtag will be reflected).
748 */
749 if (!asoc) {
750 if (chunk && chunk->chunk_hdr &&
751 chunk->chunk_hdr->type == SCTP_CID_INIT)
752 flags = 0;
753 else
754 flags = SCTP_CHUNK_FLAG_T;
755 }
746 756
747 retval = sctp_make_chunk(asoc, SCTP_CID_ABORT, flags, hint); 757 retval = sctp_make_chunk(asoc, SCTP_CID_ABORT, flags, hint);
748 758
@@ -2744,7 +2754,6 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
2744 2754
2745 hint = (nstreams + 1) * sizeof(__u32); 2755 hint = (nstreams + 1) * sizeof(__u32);
2746 2756
2747 /* Maybe set the T-bit if we have no association. */
2748 retval = sctp_make_chunk(asoc, SCTP_CID_FWD_TSN, 0, hint); 2757 retval = sctp_make_chunk(asoc, SCTP_CID_FWD_TSN, 0, hint);
2749 2758
2750 if (!retval) 2759 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,
126 * should stop the T2-shutdown timer and remove all knowledge of the 126 * should stop the T2-shutdown timer and remove all knowledge of the
127 * association (and thus the association enters the CLOSED state). 127 * association (and thus the association enters the CLOSED state).
128 * 128 *
129 * Verification Tag: 8.5.1(C) 129 * Verification Tag: 8.5.1(C), sctpimpguide 2.41.
130 * C) Rules for packet carrying SHUTDOWN COMPLETE: 130 * C) Rules for packet carrying SHUTDOWN COMPLETE:
131 * ... 131 * ...
132 * - The receiver of a SHUTDOWN COMPLETE shall accept the packet if the 132 * - The receiver of a SHUTDOWN COMPLETE shall accept the packet
133 * Verification Tag field of the packet matches its own tag OR it is 133 * if the Verification Tag field of the packet matches its own tag and
134 * set to its peer's tag and the T bit is set in the Chunk Flags. 134 * the T bit is not set
135 * Otherwise, the receiver MUST silently discard the packet and take 135 * OR
136 * no further action. An endpoint MUST ignore the SHUTDOWN COMPLETE if 136 * it is set to its peer's tag and the T bit is set in the Chunk
137 * it is not in the SHUTDOWN-ACK-SENT state. 137 * Flags.
138 * Otherwise, the receiver MUST silently discard the packet
139 * and take no further action. An endpoint MUST ignore the
140 * SHUTDOWN COMPLETE if it is not in the SHUTDOWN-ACK-SENT state.
138 * 141 *
139 * Inputs 142 * Inputs
140 * (endpoint, asoc, chunk) 143 * (endpoint, asoc, chunk)
@@ -2858,16 +2861,16 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep,
2858/* 2861/*
2859 * Generate an ABORT in response to a packet. 2862 * Generate an ABORT in response to a packet.
2860 * 2863 *
2861 * Section: 8.4 Handle "Out of the blue" Packets 2864 * Section: 8.4 Handle "Out of the blue" Packets, sctpimpguide 2.41
2862 * 2865 *
2863 * 8) The receiver should respond to the sender of the OOTB packet 2866 * 8) The receiver should respond to the sender of the OOTB packet with
2864 * with an ABORT. When sending the ABORT, the receiver of the 2867 * an ABORT. When sending the ABORT, the receiver of the OOTB packet
2865 * OOTB packet MUST fill in the Verification Tag field of the 2868 * MUST fill in the Verification Tag field of the outbound packet
2866 * outbound packet with the value found in the Verification Tag 2869 * with the value found in the Verification Tag field of the OOTB
2867 * field of the OOTB packet and set the T-bit in the Chunk Flags 2870 * packet and set the T-bit in the Chunk Flags to indicate that the
2868 * to indicate that no TCB was found. After sending this ABORT, 2871 * Verification Tag is reflected. After sending this ABORT, the
2869 * the receiver of the OOTB packet shall discard the OOTB packet 2872 * receiver of the OOTB packet shall discard the OOTB packet and take
2870 * and take no further action. 2873 * no further action.
2871 * 2874 *
2872 * Verification Tag: 2875 * Verification Tag:
2873 * 2876 *
@@ -2895,6 +2898,10 @@ sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
2895 return SCTP_DISPOSITION_NOMEM; 2898 return SCTP_DISPOSITION_NOMEM;
2896 } 2899 }
2897 2900
2901 /* Reflect vtag if T-Bit is set */
2902 if (sctp_test_T_bit(abort))
2903 packet->vtag = ntohl(chunk->sctp_hdr->vtag);
2904
2898 /* Set the skb to the belonging sock for accounting. */ 2905 /* Set the skb to the belonging sock for accounting. */
2899 abort->skb->sk = ep->base.sk; 2906 abort->skb->sk = ep->base.sk;
2900 2907
@@ -3026,22 +3033,24 @@ nomem:
3026} 3033}
3027 3034
3028/* 3035/*
3029 * RFC 2960, 8.4 - Handle "Out of the blue" Packets 3036 * RFC 2960, 8.4 - Handle "Out of the blue" Packets, sctpimpguide 2.41.
3037 *
3030 * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should 3038 * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should
3031 * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. 3039 * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE.
3032 * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB 3040 * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB
3033 * packet must fill in the Verification Tag field of the outbound 3041 * packet must fill in the Verification Tag field of the outbound
3034 * packet with the Verification Tag received in the SHUTDOWN ACK and 3042 * packet with the Verification Tag received in the SHUTDOWN ACK and
3035 * set the T-bit in the Chunk Flags to indicate that no TCB was 3043 * set the T-bit in the Chunk Flags to indicate that the Verification
3036 * found. Otherwise, 3044 * Tag is reflected.
3037 * 3045 *
3038 * 8) The receiver should respond to the sender of the OOTB packet with 3046 * 8) The receiver should respond to the sender of the OOTB packet with
3039 * an ABORT. When sending the ABORT, the receiver of the OOTB packet 3047 * an ABORT. When sending the ABORT, the receiver of the OOTB packet
3040 * MUST fill in the Verification Tag field of the outbound packet 3048 * MUST fill in the Verification Tag field of the outbound packet
3041 * with the value found in the Verification Tag field of the OOTB 3049 * with the value found in the Verification Tag field of the OOTB
3042 * packet and set the T-bit in the Chunk Flags to indicate that no 3050 * packet and set the T-bit in the Chunk Flags to indicate that the
3043 * TCB was found. After sending this ABORT, the receiver of the OOTB 3051 * Verification Tag is reflected. After sending this ABORT, the
3044 * packet shall discard the OOTB packet and take no further action. 3052 * receiver of the OOTB packet shall discard the OOTB packet and take
3053 * no further action.
3045 */ 3054 */
3046sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, 3055sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
3047 const struct sctp_association *asoc, 3056 const struct sctp_association *asoc,
@@ -3090,13 +3099,15 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
3090/* 3099/*
3091 * Handle an "Out of the blue" SHUTDOWN ACK. 3100 * Handle an "Out of the blue" SHUTDOWN ACK.
3092 * 3101 *
3093 * Section: 8.4 5) 3102 * Section: 8.4 5, sctpimpguide 2.41.
3103 *
3094 * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should 3104 * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should
3095 * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. 3105 * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE.
3096 * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB packet 3106 * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB
3097 * must fill in the Verification Tag field of the outbound packet with 3107 * packet must fill in the Verification Tag field of the outbound
3098 * the Verification Tag received in the SHUTDOWN ACK and set the 3108 * packet with the Verification Tag received in the SHUTDOWN ACK and
3099 * T-bit in the Chunk Flags to indicate that no TCB was found. 3109 * set the T-bit in the Chunk Flags to indicate that the Verification
3110 * Tag is reflected.
3100 * 3111 *
3101 * Inputs 3112 * Inputs
3102 * (endpoint, asoc, type, arg, commands) 3113 * (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 return SCTP_DISPOSITION_NOMEM; 3139 return SCTP_DISPOSITION_NOMEM;
3129 } 3140 }
3130 3141
3142 /* Reflect vtag if T-Bit is set */
3143 if (sctp_test_T_bit(shut))
3144 packet->vtag = ntohl(chunk->sctp_hdr->vtag);
3145
3131 /* Set the skb to the belonging sock for accounting. */ 3146 /* Set the skb to the belonging sock for accounting. */
3132 shut->skb->sk = ep->base.sk; 3147 shut->skb->sk = ep->base.sk;
3133 3148
@@ -3591,7 +3606,6 @@ sctp_disposition_t sctp_sf_discard_chunk(const struct sctp_endpoint *ep,
3591 * 3606 *
3592 * 2) If the OOTB packet contains an ABORT chunk, the receiver MUST 3607 * 2) If the OOTB packet contains an ABORT chunk, the receiver MUST
3593 * silently discard the OOTB packet and take no further action. 3608 * silently discard the OOTB packet and take no further action.
3594 * Otherwise,
3595 * 3609 *
3596 * Verification Tag: No verification necessary 3610 * Verification Tag: No verification necessary
3597 * 3611 *
@@ -4961,6 +4975,11 @@ static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
4961 sctp_ootb_pkt_free(packet); 4975 sctp_ootb_pkt_free(packet);
4962 return NULL; 4976 return NULL;
4963 } 4977 }
4978
4979 /* Reflect vtag if T-Bit is set */
4980 if (sctp_test_T_bit(abort))
4981 packet->vtag = ntohl(chunk->sctp_hdr->vtag);
4982
4964 /* Add specified error causes, i.e., payload, to the 4983 /* Add specified error causes, i.e., payload, to the
4965 * end of the chunk. 4984 * end of the chunk.
4966 */ 4985 */