diff options
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 43 |
1 files changed, 19 insertions, 24 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index bf747094d26b..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, | |||
644 | 644 | ||
645 | list_for_each_entry(trans, | 645 | list_for_each_entry(trans, |
646 | &asoc->peer.transport_addr_list, transports) { | 646 | &asoc->peer.transport_addr_list, transports) { |
647 | /* Clear the source and route cache */ | ||
648 | sctp_transport_dst_release(trans); | ||
649 | trans->cwnd = min(4*asoc->pathmtu, max_t(__u32, | 647 | trans->cwnd = min(4*asoc->pathmtu, max_t(__u32, |
650 | 2*asoc->pathmtu, 4380)); | 648 | 2*asoc->pathmtu, 4380)); |
651 | trans->ssthresh = asoc->peer.i.a_rwnd; | 649 | trans->ssthresh = asoc->peer.i.a_rwnd; |
652 | trans->rto = asoc->rto_initial; | 650 | trans->rto = asoc->rto_initial; |
653 | sctp_max_rto(asoc, trans); | 651 | sctp_max_rto(asoc, trans); |
654 | trans->rtt = trans->srtt = trans->rttvar = 0; | 652 | trans->rtt = trans->srtt = trans->rttvar = 0; |
653 | /* Clear the source and route cache */ | ||
655 | sctp_transport_route(trans, NULL, | 654 | sctp_transport_route(trans, NULL, |
656 | sctp_sk(asoc->base.sk)); | 655 | sctp_sk(asoc->base.sk)); |
657 | } | 656 | } |
658 | } | 657 | } |
659 | retval = sctp_send_asconf(asoc, chunk); | 658 | retval = sctp_send_asconf(asoc, chunk); |
@@ -896,7 +895,6 @@ skip_mkasconf: | |||
896 | */ | 895 | */ |
897 | list_for_each_entry(transport, &asoc->peer.transport_addr_list, | 896 | list_for_each_entry(transport, &asoc->peer.transport_addr_list, |
898 | transports) { | 897 | transports) { |
899 | sctp_transport_dst_release(transport); | ||
900 | sctp_transport_route(transport, NULL, | 898 | sctp_transport_route(transport, NULL, |
901 | sctp_sk(asoc->base.sk)); | 899 | sctp_sk(asoc->base.sk)); |
902 | } | 900 | } |
@@ -1894,6 +1892,7 @@ static int sctp_sendmsg_to_asoc(struct sctp_association *asoc, | |||
1894 | struct sctp_sndrcvinfo *sinfo) | 1892 | struct sctp_sndrcvinfo *sinfo) |
1895 | { | 1893 | { |
1896 | struct sock *sk = asoc->base.sk; | 1894 | struct sock *sk = asoc->base.sk; |
1895 | struct sctp_sock *sp = sctp_sk(sk); | ||
1897 | struct net *net = sock_net(sk); | 1896 | struct net *net = sock_net(sk); |
1898 | struct sctp_datamsg *datamsg; | 1897 | struct sctp_datamsg *datamsg; |
1899 | bool wait_connect = false; | 1898 | bool wait_connect = false; |
@@ -1912,13 +1911,16 @@ static int sctp_sendmsg_to_asoc(struct sctp_association *asoc, | |||
1912 | goto err; | 1911 | goto err; |
1913 | } | 1912 | } |
1914 | 1913 | ||
1915 | if (sctp_sk(sk)->disable_fragments && msg_len > asoc->frag_point) { | 1914 | if (sp->disable_fragments && msg_len > asoc->frag_point) { |
1916 | err = -EMSGSIZE; | 1915 | err = -EMSGSIZE; |
1917 | goto err; | 1916 | goto err; |
1918 | } | 1917 | } |
1919 | 1918 | ||
1920 | if (asoc->pmtu_pending) | 1919 | if (asoc->pmtu_pending) { |
1921 | sctp_assoc_pending_pmtu(asoc); | 1920 | if (sp->param_flags & SPP_PMTUD_ENABLE) |
1921 | sctp_assoc_sync_pmtu(asoc); | ||
1922 | asoc->pmtu_pending = 0; | ||
1923 | } | ||
1922 | 1924 | ||
1923 | if (sctp_wspace(asoc) < msg_len) | 1925 | if (sctp_wspace(asoc) < msg_len) |
1924 | sctp_prsctp_prune(asoc, sinfo, msg_len - sctp_wspace(asoc)); | 1926 | sctp_prsctp_prune(asoc, sinfo, msg_len - sctp_wspace(asoc)); |
@@ -1935,7 +1937,7 @@ static int sctp_sendmsg_to_asoc(struct sctp_association *asoc, | |||
1935 | if (err) | 1937 | if (err) |
1936 | goto err; | 1938 | goto err; |
1937 | 1939 | ||
1938 | if (sctp_sk(sk)->strm_interleave) { | 1940 | if (sp->strm_interleave) { |
1939 | timeo = sock_sndtimeo(sk, 0); | 1941 | timeo = sock_sndtimeo(sk, 0); |
1940 | err = sctp_wait_for_connect(asoc, &timeo); | 1942 | err = sctp_wait_for_connect(asoc, &timeo); |
1941 | if (err) | 1943 | if (err) |
@@ -2538,7 +2540,7 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, | |||
2538 | trans->pathmtu = params->spp_pathmtu; | 2540 | trans->pathmtu = params->spp_pathmtu; |
2539 | sctp_assoc_sync_pmtu(asoc); | 2541 | sctp_assoc_sync_pmtu(asoc); |
2540 | } else if (asoc) { | 2542 | } else if (asoc) { |
2541 | asoc->pathmtu = params->spp_pathmtu; | 2543 | sctp_assoc_set_pmtu(asoc, params->spp_pathmtu); |
2542 | } else { | 2544 | } else { |
2543 | sp->pathmtu = params->spp_pathmtu; | 2545 | sp->pathmtu = params->spp_pathmtu; |
2544 | } | 2546 | } |
@@ -3208,7 +3210,6 @@ static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, unsign | |||
3208 | static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned int optlen) | 3210 | static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned int optlen) |
3209 | { | 3211 | { |
3210 | struct sctp_sock *sp = sctp_sk(sk); | 3212 | struct sctp_sock *sp = sctp_sk(sk); |
3211 | struct sctp_af *af = sp->pf->af; | ||
3212 | struct sctp_assoc_value params; | 3213 | struct sctp_assoc_value params; |
3213 | struct sctp_association *asoc; | 3214 | struct sctp_association *asoc; |
3214 | int val; | 3215 | int val; |
@@ -3230,30 +3231,24 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned | |||
3230 | return -EINVAL; | 3231 | return -EINVAL; |
3231 | } | 3232 | } |
3232 | 3233 | ||
3234 | asoc = sctp_id2assoc(sk, params.assoc_id); | ||
3235 | |||
3233 | if (val) { | 3236 | if (val) { |
3234 | int min_len, max_len; | 3237 | int min_len, max_len; |
3238 | __u16 datasize = asoc ? sctp_datachk_len(&asoc->stream) : | ||
3239 | sizeof(struct sctp_data_chunk); | ||
3235 | 3240 | ||
3236 | min_len = SCTP_DEFAULT_MINSEGMENT - af->net_header_len; | 3241 | min_len = sctp_mtu_payload(sp, SCTP_DEFAULT_MINSEGMENT, |
3237 | min_len -= af->ip_options_len(sk); | 3242 | datasize); |
3238 | min_len -= sizeof(struct sctphdr) + | 3243 | max_len = SCTP_MAX_CHUNK_LEN - datasize; |
3239 | sizeof(struct sctp_data_chunk); | ||
3240 | |||
3241 | max_len = SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_data_chunk); | ||
3242 | 3244 | ||
3243 | if (val < min_len || val > max_len) | 3245 | if (val < min_len || val > max_len) |
3244 | return -EINVAL; | 3246 | return -EINVAL; |
3245 | } | 3247 | } |
3246 | 3248 | ||
3247 | asoc = sctp_id2assoc(sk, params.assoc_id); | ||
3248 | if (asoc) { | 3249 | if (asoc) { |
3249 | if (val == 0) { | ||
3250 | val = asoc->pathmtu - af->net_header_len; | ||
3251 | val -= af->ip_options_len(sk); | ||
3252 | val -= sizeof(struct sctphdr) + | ||
3253 | sctp_datachk_len(&asoc->stream); | ||
3254 | } | ||
3255 | asoc->user_frag = val; | 3250 | asoc->user_frag = val; |
3256 | asoc->frag_point = sctp_frag_point(asoc, asoc->pathmtu); | 3251 | sctp_assoc_update_frag_point(asoc); |
3257 | } else { | 3252 | } else { |
3258 | if (params.assoc_id && sctp_style(sk, UDP)) | 3253 | if (params.assoc_id && sctp_style(sk, UDP)) |
3259 | return -EINVAL; | 3254 | return -EINVAL; |