Lines Matching +full:max +full:- +full:reason
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 1999-2000 Cisco, Inc.
4 * Copyright (c) 1999-2001 Motorola, Inc.
5 * Copyright (c) 2001-2003 International Business Machines Corp.
17 * lksctp developers <linux-sctp@vger.kernel.org>
46 peer->af_specific = sctp_get_af_specific(addr->sa.sa_family); in sctp_transport_init()
47 memcpy(&peer->ipaddr, addr, peer->af_specific->sockaddr_len); in sctp_transport_init()
48 memset(&peer->saddr, 0, sizeof(union sctp_addr)); in sctp_transport_init()
50 peer->sack_generation = 0; in sctp_transport_init()
58 peer->rto = msecs_to_jiffies(net->sctp.rto_initial); in sctp_transport_init()
60 peer->last_time_heard = 0; in sctp_transport_init()
61 peer->last_time_ecne_reduced = jiffies; in sctp_transport_init()
63 peer->param_flags = SPP_HB_DISABLE | in sctp_transport_init()
68 peer->pathmaxrxt = net->sctp.max_retrans_path; in sctp_transport_init()
69 peer->pf_retrans = net->sctp.pf_retrans; in sctp_transport_init()
71 INIT_LIST_HEAD(&peer->transmitted); in sctp_transport_init()
72 INIT_LIST_HEAD(&peer->send_ready); in sctp_transport_init()
73 INIT_LIST_HEAD(&peer->transports); in sctp_transport_init()
75 timer_setup(&peer->T3_rtx_timer, sctp_generate_t3_rtx_event, 0); in sctp_transport_init()
76 timer_setup(&peer->hb_timer, sctp_generate_heartbeat_event, 0); in sctp_transport_init()
77 timer_setup(&peer->reconf_timer, sctp_generate_reconf_event, 0); in sctp_transport_init()
78 timer_setup(&peer->proto_unreach_timer, in sctp_transport_init()
81 /* Initialize the 64-bit random nonce sent with heartbeat. */ in sctp_transport_init()
82 get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce)); in sctp_transport_init()
84 refcount_set(&peer->refcnt, 1); in sctp_transport_init()
120 if (del_timer(&transport->hb_timer)) in sctp_transport_free()
128 if (del_timer(&transport->T3_rtx_timer)) in sctp_transport_free()
131 if (del_timer(&transport->reconf_timer)) in sctp_transport_free()
135 if (del_timer(&transport->proto_unreach_timer)) in sctp_transport_free()
147 dst_release(transport->dst); in sctp_transport_destroy_rcu()
157 if (unlikely(refcount_read(&transport->refcnt))) { in sctp_transport_destroy()
162 sctp_packet_free(&transport->packet); in sctp_transport_destroy()
164 if (transport->asoc) in sctp_transport_destroy()
165 sctp_association_put(transport->asoc); in sctp_transport_destroy()
167 call_rcu(&transport->rcu, sctp_transport_destroy_rcu); in sctp_transport_destroy()
178 * retransmission), if the T3-rtx timer of that address is not running in sctp_transport_reset_t3_rtx()
183 if (!timer_pending(&transport->T3_rtx_timer)) in sctp_transport_reset_t3_rtx()
184 if (!mod_timer(&transport->T3_rtx_timer, in sctp_transport_reset_t3_rtx()
185 jiffies + transport->rto)) in sctp_transport_reset_t3_rtx()
195 if ((time_before(transport->hb_timer.expires, expires) || in sctp_transport_reset_hb_timer()
196 !timer_pending(&transport->hb_timer)) && in sctp_transport_reset_hb_timer()
197 !mod_timer(&transport->hb_timer, in sctp_transport_reset_hb_timer()
198 expires + prandom_u32_max(transport->rto))) in sctp_transport_reset_hb_timer()
204 if (!timer_pending(&transport->reconf_timer)) in sctp_transport_reset_reconf_timer()
205 if (!mod_timer(&transport->reconf_timer, in sctp_transport_reset_reconf_timer()
206 jiffies + transport->rto)) in sctp_transport_reset_reconf_timer()
217 transport->asoc = asoc; in sctp_transport_set_owner()
225 if (!transport->dst || transport->dst->obsolete) { in sctp_transport_pmtu()
227 transport->af_specific->get_dst(transport, &transport->saddr, in sctp_transport_pmtu()
228 &transport->fl, sk); in sctp_transport_pmtu()
231 if (transport->param_flags & SPP_PMTUD_DISABLE) { in sctp_transport_pmtu()
232 struct sctp_association *asoc = transport->asoc; in sctp_transport_pmtu()
234 if (!transport->pathmtu && asoc && asoc->pathmtu) in sctp_transport_pmtu()
235 transport->pathmtu = asoc->pathmtu; in sctp_transport_pmtu()
236 if (transport->pathmtu) in sctp_transport_pmtu()
240 if (transport->dst) in sctp_transport_pmtu()
241 transport->pathmtu = sctp_dst_mtu(transport->dst); in sctp_transport_pmtu()
243 transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; in sctp_transport_pmtu()
249 struct sock *sk = t->asoc->base.sk; in sctp_transport_update_pmtu()
261 struct sctp_pf *pf = sctp_get_pf_specific(dst->ops->family); in sctp_transport_update_pmtu()
264 pf->af->from_sk(&addr, sk); in sctp_transport_update_pmtu()
265 pf->to_sk_daddr(&t->ipaddr, sk); in sctp_transport_update_pmtu()
266 dst->ops->update_pmtu(dst, sk, NULL, pmtu, true); in sctp_transport_update_pmtu()
267 pf->to_sk_daddr(&addr, sk); in sctp_transport_update_pmtu()
273 t->af_specific->get_dst(t, &t->saddr, &t->fl, sk); in sctp_transport_update_pmtu()
274 dst = t->dst; in sctp_transport_update_pmtu()
278 /* Re-fetch, as under layers may have a higher minimum size */ in sctp_transport_update_pmtu()
280 change = t->pathmtu != pmtu; in sctp_transport_update_pmtu()
282 t->pathmtu = pmtu; in sctp_transport_update_pmtu()
293 struct sctp_association *asoc = transport->asoc; in sctp_transport_route()
294 struct sctp_af *af = transport->af_specific; in sctp_transport_route()
297 af->get_dst(transport, saddr, &transport->fl, sctp_opt2sk(opt)); in sctp_transport_route()
300 memcpy(&transport->saddr, saddr, sizeof(union sctp_addr)); in sctp_transport_route()
302 af->get_saddr(opt, transport, &transport->fl); in sctp_transport_route()
306 /* Initialize sk->sk_rcv_saddr, if the transport is the in sctp_transport_route()
309 if (transport->dst && asoc && in sctp_transport_route()
310 (!asoc->peer.primary_path || transport == asoc->peer.active_path)) in sctp_transport_route()
311 opt->pf->to_sk_saddr(&transport->saddr, asoc->base.sk); in sctp_transport_route()
317 return refcount_inc_not_zero(&transport->refcnt); in sctp_transport_hold()
325 if (refcount_dec_and_test(&transport->refcnt)) in sctp_transport_put()
332 if (unlikely(!tp->rto_pending)) in sctp_transport_update_rto()
336 if (tp->rttvar || tp->srtt) { in sctp_transport_update_rto()
337 struct net *net = tp->asoc->base.net; in sctp_transport_update_rto()
339 * RTTVAR <- (1 - RTO.Beta) * RTTVAR + RTO.Beta * |SRTT - R'| in sctp_transport_update_rto()
340 * SRTT <- (1 - RTO.Alpha) * SRTT + RTO.Alpha * R' in sctp_transport_update_rto()
349 tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta) in sctp_transport_update_rto()
350 + (((__u32)abs((__s64)tp->srtt - (__s64)rtt)) >> net->sctp.rto_beta); in sctp_transport_update_rto()
351 tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha) in sctp_transport_update_rto()
352 + (rtt >> net->sctp.rto_alpha); in sctp_transport_update_rto()
355 * SRTT <- R, RTTVAR <- R/2. in sctp_transport_update_rto()
357 tp->srtt = rtt; in sctp_transport_update_rto()
358 tp->rttvar = rtt >> 1; in sctp_transport_update_rto()
362 * adjust RTTVAR <- G, where G is the CLOCK GRANULARITY. in sctp_transport_update_rto()
364 if (tp->rttvar == 0) in sctp_transport_update_rto()
365 tp->rttvar = SCTP_CLOCK_GRANULARITY; in sctp_transport_update_rto()
367 /* 6.3.1 C3) After the computation, update RTO <- SRTT + 4 * RTTVAR. */ in sctp_transport_update_rto()
368 tp->rto = tp->srtt + (tp->rttvar << 2); in sctp_transport_update_rto()
373 if (tp->rto < tp->asoc->rto_min) in sctp_transport_update_rto()
374 tp->rto = tp->asoc->rto_min; in sctp_transport_update_rto()
377 * at least RTO.max seconds. in sctp_transport_update_rto()
379 if (tp->rto > tp->asoc->rto_max) in sctp_transport_update_rto()
380 tp->rto = tp->asoc->rto_max; in sctp_transport_update_rto()
382 sctp_max_rto(tp->asoc, tp); in sctp_transport_update_rto()
383 tp->rtt = rtt; in sctp_transport_update_rto()
388 tp->rto_pending = 0; in sctp_transport_update_rto()
391 __func__, tp, rtt, tp->srtt, tp->rttvar, tp->rto); in sctp_transport_update_rto()
400 struct sctp_association *asoc = transport->asoc; in sctp_transport_raise_cwnd()
403 cwnd = transport->cwnd; in sctp_transport_raise_cwnd()
404 flight_size = transport->flight_size; in sctp_transport_raise_cwnd()
407 if (asoc->fast_recovery && in sctp_transport_raise_cwnd()
408 TSN_lte(asoc->fast_recovery_exit, sack_ctsn)) in sctp_transport_raise_cwnd()
409 asoc->fast_recovery = 0; in sctp_transport_raise_cwnd()
411 ssthresh = transport->ssthresh; in sctp_transport_raise_cwnd()
412 pba = transport->partial_bytes_acked; in sctp_transport_raise_cwnd()
413 pmtu = transport->asoc->pathmtu; in sctp_transport_raise_cwnd()
418 * endpoint MUST use the slow-start algorithm to increase in sctp_transport_raise_cwnd()
428 * against the ACK-Splitting attack outlined in [SAVAGE99]. in sctp_transport_raise_cwnd()
430 if (asoc->fast_recovery) in sctp_transport_raise_cwnd()
470 * to (partial_bytes_acked - cwnd). Next, cwnd is in sctp_transport_raise_cwnd()
477 pba = pba - cwnd; in sctp_transport_raise_cwnd()
488 transport->cwnd = cwnd; in sctp_transport_raise_cwnd()
489 transport->partial_bytes_acked = pba; in sctp_transport_raise_cwnd()
496 enum sctp_lower_cwnd reason) in sctp_transport_lower_cwnd() argument
498 struct sctp_association *asoc = transport->asoc; in sctp_transport_lower_cwnd()
500 switch (reason) { in sctp_transport_lower_cwnd()
503 * When the T3-rtx timer expires on an address, SCTP should in sctp_transport_lower_cwnd()
505 * ssthresh = max(cwnd/2, 4*MTU) in sctp_transport_lower_cwnd()
509 transport->ssthresh = max(transport->cwnd/2, in sctp_transport_lower_cwnd()
510 4*asoc->pathmtu); in sctp_transport_lower_cwnd()
511 transport->cwnd = asoc->pathmtu; in sctp_transport_lower_cwnd()
513 /* T3-rtx also clears fast recovery */ in sctp_transport_lower_cwnd()
514 asoc->fast_recovery = 0; in sctp_transport_lower_cwnd()
526 * ssthresh = max(cwnd/2, 4*MTU) in sctp_transport_lower_cwnd()
530 if (asoc->fast_recovery) in sctp_transport_lower_cwnd()
534 asoc->fast_recovery = 1; in sctp_transport_lower_cwnd()
535 asoc->fast_recovery_exit = asoc->next_tsn - 1; in sctp_transport_lower_cwnd()
537 transport->ssthresh = max(transport->cwnd/2, in sctp_transport_lower_cwnd()
538 4*asoc->pathmtu); in sctp_transport_lower_cwnd()
539 transport->cwnd = transport->ssthresh; in sctp_transport_lower_cwnd()
544 * If the sender receives an ECN-Echo ACK packet in sctp_transport_lower_cwnd()
548 * congestion loss in non-ECN Capable TCP. That is, the TCP in sctp_transport_lower_cwnd()
553 * data (or more loosely more than once every round-trip time). in sctp_transport_lower_cwnd()
555 if (time_after(jiffies, transport->last_time_ecne_reduced + in sctp_transport_lower_cwnd()
556 transport->rtt)) { in sctp_transport_lower_cwnd()
557 transport->ssthresh = max(transport->cwnd/2, in sctp_transport_lower_cwnd()
558 4*asoc->pathmtu); in sctp_transport_lower_cwnd()
559 transport->cwnd = transport->ssthresh; in sctp_transport_lower_cwnd()
560 transport->last_time_ecne_reduced = jiffies; in sctp_transport_lower_cwnd()
568 * should be adjusted to max(cwnd/2, 4*MTU) per RTO. in sctp_transport_lower_cwnd()
573 transport->cwnd = max(transport->cwnd/2, in sctp_transport_lower_cwnd()
574 4*asoc->pathmtu); in sctp_transport_lower_cwnd()
576 transport->ssthresh = transport->cwnd; in sctp_transport_lower_cwnd()
580 transport->partial_bytes_acked = 0; in sctp_transport_lower_cwnd()
582 pr_debug("%s: transport:%p, reason:%d, cwnd:%d, ssthresh:%d\n", in sctp_transport_lower_cwnd()
583 __func__, transport, reason, transport->cwnd, in sctp_transport_lower_cwnd()
584 transport->ssthresh); in sctp_transport_lower_cwnd()
587 /* Apply Max.Burst limit to the congestion window:
588 * sctpimpguide-05 2.14.2
590 * transmit new DATA chunks, the protocol parameter Max.Burst MUST
593 * if ((flightsize+ Max.Burst * MTU) < cwnd)
594 * cwnd = flightsize + Max.Burst * MTU
599 struct sctp_association *asoc = t->asoc; in sctp_transport_burst_limited()
600 u32 old_cwnd = t->cwnd; in sctp_transport_burst_limited()
603 if (t->burst_limited || asoc->max_burst == 0) in sctp_transport_burst_limited()
606 max_burst_bytes = t->flight_size + (asoc->max_burst * asoc->pathmtu); in sctp_transport_burst_limited()
608 t->cwnd = max_burst_bytes; in sctp_transport_burst_limited()
609 t->burst_limited = old_cwnd; in sctp_transport_burst_limited()
618 if (t->burst_limited) { in sctp_transport_burst_reset()
619 t->cwnd = t->burst_limited; in sctp_transport_burst_reset()
620 t->burst_limited = 0; in sctp_transport_burst_reset()
627 /* RTO + timer slack +/- 50% of RTO */ in sctp_transport_timeout()
628 unsigned long timeout = trans->rto >> 1; in sctp_transport_timeout()
630 if (trans->state != SCTP_UNCONFIRMED && in sctp_transport_timeout()
631 trans->state != SCTP_PF) in sctp_transport_timeout()
632 timeout += trans->hbinterval; in sctp_transport_timeout()
640 struct sctp_association *asoc = t->asoc; in sctp_transport_reset()
647 t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380)); in sctp_transport_reset()
648 t->burst_limited = 0; in sctp_transport_reset()
649 t->ssthresh = asoc->peer.i.a_rwnd; in sctp_transport_reset()
650 t->rto = asoc->rto_initial; in sctp_transport_reset()
652 t->rtt = 0; in sctp_transport_reset()
653 t->srtt = 0; in sctp_transport_reset()
654 t->rttvar = 0; in sctp_transport_reset()
657 t->partial_bytes_acked = 0; in sctp_transport_reset()
658 t->flight_size = 0; in sctp_transport_reset()
659 t->error_count = 0; in sctp_transport_reset()
660 t->rto_pending = 0; in sctp_transport_reset()
661 t->hb_sent = 0; in sctp_transport_reset()
663 /* Initialize the state information for SFR-CACC */ in sctp_transport_reset()
664 t->cacc.changeover_active = 0; in sctp_transport_reset()
665 t->cacc.cycling_changeover = 0; in sctp_transport_reset()
666 t->cacc.next_tsn_at_change = 0; in sctp_transport_reset()
667 t->cacc.cacc_saw_newack = 0; in sctp_transport_reset()
674 if (del_timer(&t->T3_rtx_timer)) in sctp_transport_immediate_rtx()
677 sctp_retransmit(&t->asoc->outqueue, t, SCTP_RTXR_T3_RTX); in sctp_transport_immediate_rtx()
678 if (!timer_pending(&t->T3_rtx_timer)) { in sctp_transport_immediate_rtx()
679 if (!mod_timer(&t->T3_rtx_timer, jiffies + t->rto)) in sctp_transport_immediate_rtx()
687 dst_release(t->dst); in sctp_transport_dst_release()
688 t->dst = NULL; in sctp_transport_dst_release()
689 t->dst_pending_confirm = 0; in sctp_transport_dst_release()
695 t->dst_pending_confirm = 1; in sctp_transport_dst_confirm()