aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/sm_statefuns.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/sm_statefuns.c')
-rw-r--r--net/sctp/sm_statefuns.c37
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
2955discard_noforce: 2961discard_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;
2960consume: 2966consume:
@@ -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));