diff options
Diffstat (limited to 'net/sctp/sm_statefuns.c')
-rw-r--r-- | net/sctp/sm_statefuns.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index d4df45022ffa..24b2cd555637 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <linux/ipv6.h> | 56 | #include <linux/ipv6.h> |
57 | #include <linux/net.h> | 57 | #include <linux/net.h> |
58 | #include <linux/inet.h> | 58 | #include <linux/inet.h> |
59 | #include <linux/slab.h> | ||
59 | #include <net/sock.h> | 60 | #include <net/sock.h> |
60 | #include <net/inet_ecn.h> | 61 | #include <net/inet_ecn.h> |
61 | #include <linux/skbuff.h> | 62 | #include <linux/skbuff.h> |
@@ -996,14 +997,15 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep, | |||
996 | sctp_sf_heartbeat(ep, asoc, type, arg, | 997 | sctp_sf_heartbeat(ep, asoc, type, arg, |
997 | commands)) | 998 | commands)) |
998 | return SCTP_DISPOSITION_NOMEM; | 999 | return SCTP_DISPOSITION_NOMEM; |
1000 | |||
999 | /* Set transport error counter and association error counter | 1001 | /* Set transport error counter and association error counter |
1000 | * when sending heartbeat. | 1002 | * when sending heartbeat. |
1001 | */ | 1003 | */ |
1002 | sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_IDLE, | ||
1003 | SCTP_TRANSPORT(transport)); | ||
1004 | sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_HB_SENT, | 1004 | sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_HB_SENT, |
1005 | SCTP_TRANSPORT(transport)); | 1005 | SCTP_TRANSPORT(transport)); |
1006 | } | 1006 | } |
1007 | sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_IDLE, | ||
1008 | SCTP_TRANSPORT(transport)); | ||
1007 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMER_UPDATE, | 1009 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMER_UPDATE, |
1008 | SCTP_TRANSPORT(transport)); | 1010 | SCTP_TRANSPORT(transport)); |
1009 | 1011 | ||
@@ -1720,7 +1722,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep, | |||
1720 | 1722 | ||
1721 | err = sctp_make_op_error(asoc, chunk, | 1723 | err = sctp_make_op_error(asoc, chunk, |
1722 | SCTP_ERROR_COOKIE_IN_SHUTDOWN, | 1724 | SCTP_ERROR_COOKIE_IN_SHUTDOWN, |
1723 | NULL, 0); | 1725 | NULL, 0, 0); |
1724 | if (err) | 1726 | if (err) |
1725 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, | 1727 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, |
1726 | SCTP_CHUNK(err)); | 1728 | SCTP_CHUNK(err)); |
@@ -2868,6 +2870,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep, | |||
2868 | sctp_cmd_seq_t *commands) | 2870 | sctp_cmd_seq_t *commands) |
2869 | { | 2871 | { |
2870 | struct sctp_chunk *chunk = arg; | 2872 | struct sctp_chunk *chunk = arg; |
2873 | sctp_arg_t force = SCTP_NOFORCE(); | ||
2871 | int error; | 2874 | int error; |
2872 | 2875 | ||
2873 | if (!sctp_vtag_verify(chunk, asoc)) { | 2876 | if (!sctp_vtag_verify(chunk, asoc)) { |
@@ -2901,6 +2904,9 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep, | |||
2901 | BUG(); | 2904 | BUG(); |
2902 | } | 2905 | } |
2903 | 2906 | ||
2907 | if (chunk->chunk_hdr->flags & SCTP_DATA_SACK_IMM) | ||
2908 | force = SCTP_FORCE(); | ||
2909 | |||
2904 | if (asoc->autoclose) { | 2910 | if (asoc->autoclose) { |
2905 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | 2911 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
2906 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 2912 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
@@ -2929,7 +2935,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep, | |||
2929 | * more aggressive than the following algorithms allow. | 2935 | * more aggressive than the following algorithms allow. |
2930 | */ | 2936 | */ |
2931 | if (chunk->end_of_packet) | 2937 | if (chunk->end_of_packet) |
2932 | sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE()); | 2938 | sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, force); |
2933 | 2939 | ||
2934 | return SCTP_DISPOSITION_CONSUME; | 2940 | return SCTP_DISPOSITION_CONSUME; |
2935 | 2941 | ||
@@ -2954,7 +2960,7 @@ discard_force: | |||
2954 | 2960 | ||
2955 | discard_noforce: | 2961 | discard_noforce: |
2956 | if (chunk->end_of_packet) | 2962 | if (chunk->end_of_packet) |
2957 | sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE()); | 2963 | sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, force); |
2958 | 2964 | ||
2959 | return SCTP_DISPOSITION_DISCARD; | 2965 | return SCTP_DISPOSITION_DISCARD; |
2960 | consume: | 2966 | consume: |
@@ -3572,7 +3578,7 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep, | |||
3572 | * To do this properly, we'll set the destination address of the chunk | 3578 | * To do this properly, we'll set the destination address of the chunk |
3573 | * and at the transmit time, will try look up the transport to use. | 3579 | * and at the transmit time, will try look up the transport to use. |
3574 | * Since ASCONFs may be bundled, the correct transport may not be | 3580 | * Since ASCONFs may be bundled, the correct transport may not be |
3575 | * created untill we process the entire packet, thus this workaround. | 3581 | * created until we process the entire packet, thus this workaround. |
3576 | */ | 3582 | */ |
3577 | asconf_ack->dest = chunk->source; | 3583 | asconf_ack->dest = chunk->source; |
3578 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(asconf_ack)); | 3584 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(asconf_ack)); |
@@ -3670,8 +3676,14 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep, | |||
3670 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); | 3676 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); |
3671 | 3677 | ||
3672 | if (!sctp_process_asconf_ack((struct sctp_association *)asoc, | 3678 | if (!sctp_process_asconf_ack((struct sctp_association *)asoc, |
3673 | asconf_ack)) | 3679 | asconf_ack)) { |
3680 | /* Successfully processed ASCONF_ACK. We can | ||
3681 | * release the next asconf if we have one. | ||
3682 | */ | ||
3683 | sctp_add_cmd_sf(commands, SCTP_CMD_SEND_NEXT_ASCONF, | ||
3684 | SCTP_NULL()); | ||
3674 | return SCTP_DISPOSITION_CONSUME; | 3685 | return SCTP_DISPOSITION_CONSUME; |
3686 | } | ||
3675 | 3687 | ||
3676 | abort = sctp_make_abort(asoc, asconf_ack, | 3688 | abort = sctp_make_abort(asoc, asconf_ack, |
3677 | sizeof(sctp_errhdr_t)); | 3689 | sizeof(sctp_errhdr_t)); |
@@ -3973,7 +3985,7 @@ sctp_disposition_t sctp_sf_eat_auth(const struct sctp_endpoint *ep, | |||
3973 | err_chunk = sctp_make_op_error(asoc, chunk, | 3985 | err_chunk = sctp_make_op_error(asoc, chunk, |
3974 | SCTP_ERROR_UNSUP_HMAC, | 3986 | SCTP_ERROR_UNSUP_HMAC, |
3975 | &auth_hdr->hmac_id, | 3987 | &auth_hdr->hmac_id, |
3976 | sizeof(__u16)); | 3988 | sizeof(__u16), 0); |
3977 | if (err_chunk) { | 3989 | if (err_chunk) { |
3978 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, | 3990 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, |
3979 | SCTP_CHUNK(err_chunk)); | 3991 | SCTP_CHUNK(err_chunk)); |
@@ -4065,7 +4077,8 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep, | |||
4065 | hdr = unk_chunk->chunk_hdr; | 4077 | hdr = unk_chunk->chunk_hdr; |
4066 | err_chunk = sctp_make_op_error(asoc, unk_chunk, | 4078 | err_chunk = sctp_make_op_error(asoc, unk_chunk, |
4067 | SCTP_ERROR_UNKNOWN_CHUNK, hdr, | 4079 | SCTP_ERROR_UNKNOWN_CHUNK, hdr, |
4068 | WORD_ROUND(ntohs(hdr->length))); | 4080 | WORD_ROUND(ntohs(hdr->length)), |
4081 | 0); | ||
4069 | if (err_chunk) { | 4082 | if (err_chunk) { |
4070 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, | 4083 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, |
4071 | SCTP_CHUNK(err_chunk)); | 4084 | SCTP_CHUNK(err_chunk)); |
@@ -4084,7 +4097,8 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep, | |||
4084 | hdr = unk_chunk->chunk_hdr; | 4097 | hdr = unk_chunk->chunk_hdr; |
4085 | err_chunk = sctp_make_op_error(asoc, unk_chunk, | 4098 | err_chunk = sctp_make_op_error(asoc, unk_chunk, |
4086 | SCTP_ERROR_UNKNOWN_CHUNK, hdr, | 4099 | SCTP_ERROR_UNKNOWN_CHUNK, hdr, |
4087 | WORD_ROUND(ntohs(hdr->length))); | 4100 | WORD_ROUND(ntohs(hdr->length)), |
4101 | 0); | ||
4088 | if (err_chunk) { | 4102 | if (err_chunk) { |
4089 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, | 4103 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, |
4090 | SCTP_CHUNK(err_chunk)); | 4104 | SCTP_CHUNK(err_chunk)); |
@@ -6048,7 +6062,8 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
6048 | 6062 | ||
6049 | err = sctp_make_op_error(asoc, chunk, SCTP_ERROR_INV_STRM, | 6063 | err = sctp_make_op_error(asoc, chunk, SCTP_ERROR_INV_STRM, |
6050 | &data_hdr->stream, | 6064 | &data_hdr->stream, |
6051 | sizeof(data_hdr->stream)); | 6065 | sizeof(data_hdr->stream), |
6066 | sizeof(u16)); | ||
6052 | if (err) | 6067 | if (err) |
6053 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, | 6068 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, |
6054 | SCTP_CHUNK(err)); | 6069 | SCTP_CHUNK(err)); |