diff options
Diffstat (limited to 'net/sctp/associola.c')
| -rw-r--r-- | net/sctp/associola.c | 16 | 
1 files changed, 12 insertions, 4 deletions
| diff --git a/net/sctp/associola.c b/net/sctp/associola.c index b1ef3bc301a5..b45ed1f96921 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -321,6 +321,9 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a  	asoc->default_timetolive = sp->default_timetolive;  	asoc->default_rcv_context = sp->default_rcv_context; +	/* SCTP_GET_ASSOC_STATS COUNTERS */ +	memset(&asoc->stats, 0, sizeof(struct sctp_priv_assoc_stats)); +  	/* AUTH related initializations */  	INIT_LIST_HEAD(&asoc->endpoint_shared_keys);  	err = sctp_auth_asoc_copy_shkeys(ep, asoc, gfp); @@ -445,7 +448,7 @@ void sctp_association_free(struct sctp_association *asoc)  	/* Release the transport structures. */  	list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {  		transport = list_entry(pos, struct sctp_transport, transports); -		list_del(pos); +		list_del_rcu(pos);  		sctp_transport_free(transport);  	} @@ -565,7 +568,7 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc,  		sctp_assoc_update_retran_path(asoc);  	/* Remove this peer from the list. */ -	list_del(&peer->transports); +	list_del_rcu(&peer->transports);  	/* Get the first transport of asoc. */  	pos = asoc->peer.transport_addr_list.next; @@ -760,12 +763,13 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,  	/* Set the transport's RTO.initial value */  	peer->rto = asoc->rto_initial; +	sctp_max_rto(asoc, peer);  	/* Set the peer's active state. */  	peer->state = peer_state;  	/* Attach the remote transport to our asoc.  */ -	list_add_tail(&peer->transports, &asoc->peer.transport_addr_list); +	list_add_tail_rcu(&peer->transports, &asoc->peer.transport_addr_list);  	asoc->peer.transport_count++;  	/* If we do not yet have a primary path, set one.  */ @@ -1152,8 +1156,12 @@ static void sctp_assoc_bh_rcv(struct work_struct *work)  		 */  		if (sctp_chunk_is_data(chunk))  			asoc->peer.last_data_from = chunk->transport; -		else +		else {  			SCTP_INC_STATS(net, SCTP_MIB_INCTRLCHUNKS); +			asoc->stats.ictrlchunks++; +			if (chunk->chunk_hdr->type == SCTP_CID_SACK) +				asoc->stats.isacks++; +		}  		if (chunk->transport)  			chunk->transport->last_time_heard = jiffies; |