|
@@ -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));
|
|
|
}
|
|
@@ -1895,6 +1893,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;
|
|
@@ -1913,13 +1912,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));
|
|
@@ -1936,7 +1938,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)
|
|
@@ -2539,7 +2541,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;
|
|
|
}
|
|
@@ -3209,7 +3211,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;
|
|
@@ -3231,30 +3232,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;
|