diff options
Diffstat (limited to 'net/sctp/sm_statefuns.c')
| -rw-r--r-- | net/sctp/sm_statefuns.c | 41 | 
1 files changed, 26 insertions, 15 deletions
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index c8fae1983dd..1ef9de9bbae 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -384,6 +384,11 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,  	if (!new_asoc)  		goto nomem; +	if (sctp_assoc_set_bind_addr_from_ep(new_asoc, +					     sctp_scope(sctp_source(chunk)), +					     GFP_ATOMIC) < 0) +		goto nomem_init; +  	/* The call, sctp_process_init(), can fail on memory allocation.  */  	if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,  			       sctp_source(chunk), @@ -401,9 +406,6 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,  		len = ntohs(err_chunk->chunk_hdr->length) -  			sizeof(sctp_chunkhdr_t); -	if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0) -		goto nomem_init; -  	repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);  	if (!repl)  		goto nomem_init; @@ -994,14 +996,15 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep,  				sctp_sf_heartbeat(ep, asoc, type, arg,  						  commands))  			return SCTP_DISPOSITION_NOMEM; +  		/* Set transport error counter and association error counter  		 * when sending heartbeat.  		 */ -		sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_IDLE, -				SCTP_TRANSPORT(transport));  		sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_HB_SENT,  				SCTP_TRANSPORT(transport));  	} +	sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_IDLE, +			SCTP_TRANSPORT(transport));  	sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMER_UPDATE,  			SCTP_TRANSPORT(transport)); @@ -1452,6 +1455,10 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(  	if (!new_asoc)  		goto nomem; +	if (sctp_assoc_set_bind_addr_from_ep(new_asoc, +				sctp_scope(sctp_source(chunk)), GFP_ATOMIC) < 0) +		goto nomem; +  	/* In the outbound INIT ACK the endpoint MUST copy its current  	 * Verification Tag and Peers Verification tag into a reserved  	 * place (local tie-tag and per tie-tag) within the state cookie. @@ -1488,9 +1495,6 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(  			sizeof(sctp_chunkhdr_t);  	} -	if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0) -		goto nomem; -  	repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);  	if (!repl)  		goto nomem; @@ -1717,7 +1721,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,  		err = sctp_make_op_error(asoc, chunk,  					 SCTP_ERROR_COOKIE_IN_SHUTDOWN, -					 NULL, 0); +					 NULL, 0, 0);  		if (err)  			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,  					SCTP_CHUNK(err)); @@ -2865,6 +2869,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,  					sctp_cmd_seq_t *commands)  {  	struct sctp_chunk *chunk = arg; +	sctp_arg_t force = SCTP_NOFORCE();  	int error;  	if (!sctp_vtag_verify(chunk, asoc)) { @@ -2898,6 +2903,9 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,  		BUG();  	} +	if (chunk->chunk_hdr->flags & SCTP_DATA_SACK_IMM) +		force = SCTP_FORCE(); +  	if (asoc->autoclose) {  		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,  				SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); @@ -2926,7 +2934,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,  	 * more aggressive than the following algorithms allow.  	 */  	if (chunk->end_of_packet) -		sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE()); +		sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, force);  	return SCTP_DISPOSITION_CONSUME; @@ -2951,7 +2959,7 @@ discard_force:  discard_noforce:  	if (chunk->end_of_packet) -		sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE()); +		sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, force);  	return SCTP_DISPOSITION_DISCARD;  consume: @@ -3970,7 +3978,7 @@ sctp_disposition_t sctp_sf_eat_auth(const struct sctp_endpoint *ep,  			err_chunk = sctp_make_op_error(asoc, chunk,  							SCTP_ERROR_UNSUP_HMAC,  							&auth_hdr->hmac_id, -							sizeof(__u16)); +							sizeof(__u16), 0);  			if (err_chunk) {  				sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,  						SCTP_CHUNK(err_chunk)); @@ -4062,7 +4070,8 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep,  		hdr = unk_chunk->chunk_hdr;  		err_chunk = sctp_make_op_error(asoc, unk_chunk,  					       SCTP_ERROR_UNKNOWN_CHUNK, hdr, -					       WORD_ROUND(ntohs(hdr->length))); +					       WORD_ROUND(ntohs(hdr->length)), +					       0);  		if (err_chunk) {  			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,  					SCTP_CHUNK(err_chunk)); @@ -4081,7 +4090,8 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep,  		hdr = unk_chunk->chunk_hdr;  		err_chunk = sctp_make_op_error(asoc, unk_chunk,  					       SCTP_ERROR_UNKNOWN_CHUNK, hdr, -					       WORD_ROUND(ntohs(hdr->length))); +					       WORD_ROUND(ntohs(hdr->length)), +					       0);  		if (err_chunk) {  			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,  					SCTP_CHUNK(err_chunk)); @@ -6045,7 +6055,8 @@ static int sctp_eat_data(const struct sctp_association *asoc,  		err = sctp_make_op_error(asoc, chunk, SCTP_ERROR_INV_STRM,  					 &data_hdr->stream, -					 sizeof(data_hdr->stream)); +					 sizeof(data_hdr->stream), +					 sizeof(u16));  		if (err)  			sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,  					SCTP_CHUNK(err));  |