diff options
| author | Jerome Forissier <jerome.forissier@hp.com> | 2005-04-28 14:58:43 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2005-04-28 14:58:43 -0400 |
| commit | 047a2428a14216a83980ed26b6a59b3ca40a1fb0 (patch) | |
| tree | 9b4b4abb85b045fbf95700c1a9ca6e6ed7dfd60b | |
| parent | 173372162ddbd414cc471c1a3a52ad7ea279aaf4 (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.h | 42 | ||||
| -rw-r--r-- | net/sctp/sm_make_chunk.c | 19 | ||||
| -rw-r--r-- | net/sctp/sm_statefuns.c | 77 |
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 | */ |
| 413 | static inline int | 413 | static inline int |
| 414 | sctp_vtag_verify_either(const struct sctp_chunk *chunk, | 414 | sctp_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 | */ |
| 737 | struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc, | 739 | struct 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 | */ |
| 3046 | sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, | 3055 | sctp_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 | */ |
