diff options
Diffstat (limited to 'net/sctp/socket.c')
| -rw-r--r-- | net/sctp/socket.c | 47 | 
1 files changed, 20 insertions, 27 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index ae7e7c606f72..d20f7addee19 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -644,16 +644,15 @@ static int sctp_send_asconf_add_ip(struct sock		*sk,  			list_for_each_entry(trans,  			    &asoc->peer.transport_addr_list, transports) { -				/* Clear the source and route cache */ -				sctp_transport_dst_release(trans);  				trans->cwnd = min(4*asoc->pathmtu, max_t(__u32,  				    2*asoc->pathmtu, 4380));  				trans->ssthresh = asoc->peer.i.a_rwnd;  				trans->rto = asoc->rto_initial;  				sctp_max_rto(asoc, trans);  				trans->rtt = trans->srtt = trans->rttvar = 0; +				/* Clear the source and route cache */  				sctp_transport_route(trans, NULL, -				    sctp_sk(asoc->base.sk)); +						     sctp_sk(asoc->base.sk));  			}  		}  		retval = sctp_send_asconf(asoc, chunk); @@ -896,7 +895,6 @@ skip_mkasconf:  		 */  		list_for_each_entry(transport, &asoc->peer.transport_addr_list,  					transports) { -			sctp_transport_dst_release(transport);  			sctp_transport_route(transport, NULL,  					     sctp_sk(asoc->base.sk));  		} @@ -1894,6 +1892,7 @@ static int sctp_sendmsg_to_asoc(struct sctp_association *asoc,  				struct sctp_sndrcvinfo *sinfo)  {  	struct sock *sk = asoc->base.sk; +	struct sctp_sock *sp = sctp_sk(sk);  	struct net *net = sock_net(sk);  	struct sctp_datamsg *datamsg;  	bool wait_connect = false; @@ -1912,13 +1911,16 @@ static int sctp_sendmsg_to_asoc(struct sctp_association *asoc,  			goto err;  	} -	if (sctp_sk(sk)->disable_fragments && msg_len > asoc->frag_point) { +	if (sp->disable_fragments && msg_len > asoc->frag_point) {  		err = -EMSGSIZE;  		goto err;  	} -	if (asoc->pmtu_pending) -		sctp_assoc_pending_pmtu(asoc); +	if (asoc->pmtu_pending) { +		if (sp->param_flags & SPP_PMTUD_ENABLE) +			sctp_assoc_sync_pmtu(asoc); +		asoc->pmtu_pending = 0; +	}  	if (sctp_wspace(asoc) < msg_len)  		sctp_prsctp_prune(asoc, sinfo, msg_len - sctp_wspace(asoc)); @@ -1935,7 +1937,7 @@ static int sctp_sendmsg_to_asoc(struct sctp_association *asoc,  		if (err)  			goto err; -		if (sctp_sk(sk)->strm_interleave) { +		if (sp->strm_interleave) {  			timeo = sock_sndtimeo(sk, 0);  			err = sctp_wait_for_connect(asoc, &timeo);  			if (err) @@ -2538,7 +2540,7 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,  			trans->pathmtu = params->spp_pathmtu;  			sctp_assoc_sync_pmtu(asoc);  		} else if (asoc) { -			asoc->pathmtu = params->spp_pathmtu; +			sctp_assoc_set_pmtu(asoc, params->spp_pathmtu);  		} else {  			sp->pathmtu = params->spp_pathmtu;  		} @@ -3208,7 +3210,6 @@ static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, unsign  static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned int optlen)  {  	struct sctp_sock *sp = sctp_sk(sk); -	struct sctp_af *af = sp->pf->af;  	struct sctp_assoc_value params;  	struct sctp_association *asoc;  	int val; @@ -3230,30 +3231,24 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned  		return -EINVAL;  	} +	asoc = sctp_id2assoc(sk, params.assoc_id); +  	if (val) {  		int min_len, max_len; +		__u16 datasize = asoc ? sctp_datachk_len(&asoc->stream) : +				 sizeof(struct sctp_data_chunk); -		min_len = SCTP_DEFAULT_MINSEGMENT - af->net_header_len; -		min_len -= af->ip_options_len(sk); -		min_len -= sizeof(struct sctphdr) + -			   sizeof(struct sctp_data_chunk); - -		max_len = SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_data_chunk); +		min_len = sctp_mtu_payload(sp, SCTP_DEFAULT_MINSEGMENT, +					   datasize); +		max_len = SCTP_MAX_CHUNK_LEN - datasize;  		if (val < min_len || val > max_len)  			return -EINVAL;  	} -	asoc = sctp_id2assoc(sk, params.assoc_id);  	if (asoc) { -		if (val == 0) { -			val = asoc->pathmtu - af->net_header_len; -			val -= af->ip_options_len(sk); -			val -= sizeof(struct sctphdr) + -			       sctp_datachk_len(&asoc->stream); -		}  		asoc->user_frag = val; -		asoc->frag_point = sctp_frag_point(asoc, asoc->pathmtu); +		sctp_assoc_update_frag_point(asoc);  	} else {  		if (params.assoc_id && sctp_style(sk, UDP))  			return -EINVAL; @@ -7722,14 +7717,12 @@ out:   * here, again, by modeling the current TCP/UDP code.  We don't have   * a good way to test with it yet.   */ -__poll_t sctp_poll(struct file *file, struct socket *sock, poll_table *wait) +__poll_t sctp_poll_mask(struct socket *sock, __poll_t events)  {  	struct sock *sk = sock->sk;  	struct sctp_sock *sp = sctp_sk(sk);  	__poll_t mask; -	poll_wait(file, sk_sleep(sk), wait); -  	sock_rps_record_flow(sk);  	/* A TCP-style listening socket becomes readable when the accept queue  | 
