aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/transport.c')
-rw-r--r--net/sctp/transport.c67
1 files changed, 25 insertions, 42 deletions
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index be4d63d5a5cc..132046cb82fc 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -64,9 +64,6 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
64 /* Copy in the address. */ 64 /* Copy in the address. */
65 peer->ipaddr = *addr; 65 peer->ipaddr = *addr;
66 peer->af_specific = sctp_get_af_specific(addr->sa.sa_family); 66 peer->af_specific = sctp_get_af_specific(addr->sa.sa_family);
67 peer->asoc = NULL;
68
69 peer->dst = NULL;
70 memset(&peer->saddr, 0, sizeof(union sctp_addr)); 67 memset(&peer->saddr, 0, sizeof(union sctp_addr));
71 68
72 /* From 6.3.1 RTO Calculation: 69 /* From 6.3.1 RTO Calculation:
@@ -76,52 +73,32 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
76 * parameter 'RTO.Initial'. 73 * parameter 'RTO.Initial'.
77 */ 74 */
78 peer->rto = msecs_to_jiffies(sctp_rto_initial); 75 peer->rto = msecs_to_jiffies(sctp_rto_initial);
79 peer->rtt = 0;
80 peer->rttvar = 0;
81 peer->srtt = 0;
82 peer->rto_pending = 0;
83 peer->hb_sent = 0;
84 peer->fast_recovery = 0;
85 76
86 peer->last_time_heard = jiffies; 77 peer->last_time_heard = jiffies;
87 peer->last_time_ecne_reduced = jiffies; 78 peer->last_time_ecne_reduced = jiffies;
88 79
89 peer->init_sent_count = 0;
90
91 peer->param_flags = SPP_HB_DISABLE | 80 peer->param_flags = SPP_HB_DISABLE |
92 SPP_PMTUD_ENABLE | 81 SPP_PMTUD_ENABLE |
93 SPP_SACKDELAY_ENABLE; 82 SPP_SACKDELAY_ENABLE;
94 peer->hbinterval = 0;
95 83
96 /* Initialize the default path max_retrans. */ 84 /* Initialize the default path max_retrans. */
97 peer->pathmaxrxt = sctp_max_retrans_path; 85 peer->pathmaxrxt = sctp_max_retrans_path;
98 peer->error_count = 0;
99 86
100 INIT_LIST_HEAD(&peer->transmitted); 87 INIT_LIST_HEAD(&peer->transmitted);
101 INIT_LIST_HEAD(&peer->send_ready); 88 INIT_LIST_HEAD(&peer->send_ready);
102 INIT_LIST_HEAD(&peer->transports); 89 INIT_LIST_HEAD(&peer->transports);
103 90
104 peer->T3_rtx_timer.expires = 0;
105 peer->hb_timer.expires = 0;
106
107 setup_timer(&peer->T3_rtx_timer, sctp_generate_t3_rtx_event, 91 setup_timer(&peer->T3_rtx_timer, sctp_generate_t3_rtx_event,
108 (unsigned long)peer); 92 (unsigned long)peer);
109 setup_timer(&peer->hb_timer, sctp_generate_heartbeat_event, 93 setup_timer(&peer->hb_timer, sctp_generate_heartbeat_event,
110 (unsigned long)peer); 94 (unsigned long)peer);
95 setup_timer(&peer->proto_unreach_timer,
96 sctp_generate_proto_unreach_event, (unsigned long)peer);
111 97
112 /* Initialize the 64-bit random nonce sent with heartbeat. */ 98 /* Initialize the 64-bit random nonce sent with heartbeat. */
113 get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce)); 99 get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce));
114 100
115 atomic_set(&peer->refcnt, 1); 101 atomic_set(&peer->refcnt, 1);
116 peer->dead = 0;
117
118 peer->malloced = 0;
119
120 /* Initialize the state information for SFR-CACC */
121 peer->cacc.changeover_active = 0;
122 peer->cacc.cycling_changeover = 0;
123 peer->cacc.next_tsn_at_change = 0;
124 peer->cacc.cacc_saw_newack = 0;
125 102
126 return peer; 103 return peer;
127} 104}
@@ -171,6 +148,10 @@ void sctp_transport_free(struct sctp_transport *transport)
171 del_timer(&transport->T3_rtx_timer)) 148 del_timer(&transport->T3_rtx_timer))
172 sctp_transport_put(transport); 149 sctp_transport_put(transport);
173 150
151 /* Delete the ICMP proto unreachable timer if it's active. */
152 if (timer_pending(&transport->proto_unreach_timer) &&
153 del_timer(&transport->proto_unreach_timer))
154 sctp_association_put(transport->asoc);
174 155
175 sctp_transport_put(transport); 156 sctp_transport_put(transport);
176} 157}
@@ -195,7 +176,7 @@ static void sctp_transport_destroy(struct sctp_transport *transport)
195/* Start T3_rtx timer if it is not already running and update the heartbeat 176/* Start T3_rtx timer if it is not already running and update the heartbeat
196 * timer. This routine is called every time a DATA chunk is sent. 177 * timer. This routine is called every time a DATA chunk is sent.
197 */ 178 */
198void sctp_transport_reset_timers(struct sctp_transport *transport, int force) 179void sctp_transport_reset_timers(struct sctp_transport *transport)
199{ 180{
200 /* RFC 2960 6.3.2 Retransmission Timer Rules 181 /* RFC 2960 6.3.2 Retransmission Timer Rules
201 * 182 *
@@ -205,7 +186,7 @@ void sctp_transport_reset_timers(struct sctp_transport *transport, int force)
205 * address. 186 * address.
206 */ 187 */
207 188
208 if (force || !timer_pending(&transport->T3_rtx_timer)) 189 if (!timer_pending(&transport->T3_rtx_timer))
209 if (!mod_timer(&transport->T3_rtx_timer, 190 if (!mod_timer(&transport->T3_rtx_timer,
210 jiffies + transport->rto)) 191 jiffies + transport->rto))
211 sctp_transport_hold(transport); 192 sctp_transport_hold(transport);
@@ -403,15 +384,16 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
403void sctp_transport_raise_cwnd(struct sctp_transport *transport, 384void sctp_transport_raise_cwnd(struct sctp_transport *transport,
404 __u32 sack_ctsn, __u32 bytes_acked) 385 __u32 sack_ctsn, __u32 bytes_acked)
405{ 386{
387 struct sctp_association *asoc = transport->asoc;
406 __u32 cwnd, ssthresh, flight_size, pba, pmtu; 388 __u32 cwnd, ssthresh, flight_size, pba, pmtu;
407 389
408 cwnd = transport->cwnd; 390 cwnd = transport->cwnd;
409 flight_size = transport->flight_size; 391 flight_size = transport->flight_size;
410 392
411 /* See if we need to exit Fast Recovery first */ 393 /* See if we need to exit Fast Recovery first */
412 if (transport->fast_recovery && 394 if (asoc->fast_recovery &&
413 TSN_lte(transport->fast_recovery_exit, sack_ctsn)) 395 TSN_lte(asoc->fast_recovery_exit, sack_ctsn))
414 transport->fast_recovery = 0; 396 asoc->fast_recovery = 0;
415 397
416 /* The appropriate cwnd increase algorithm is performed if, and only 398 /* The appropriate cwnd increase algorithm is performed if, and only
417 * if the cumulative TSN whould advanced and the congestion window is 399 * if the cumulative TSN whould advanced and the congestion window is
@@ -440,7 +422,7 @@ void sctp_transport_raise_cwnd(struct sctp_transport *transport,
440 * 2) the destination's path MTU. This upper bound protects 422 * 2) the destination's path MTU. This upper bound protects
441 * against the ACK-Splitting attack outlined in [SAVAGE99]. 423 * against the ACK-Splitting attack outlined in [SAVAGE99].
442 */ 424 */
443 if (transport->fast_recovery) 425 if (asoc->fast_recovery)
444 return; 426 return;
445 427
446 if (bytes_acked > pmtu) 428 if (bytes_acked > pmtu)
@@ -491,6 +473,8 @@ void sctp_transport_raise_cwnd(struct sctp_transport *transport,
491void sctp_transport_lower_cwnd(struct sctp_transport *transport, 473void sctp_transport_lower_cwnd(struct sctp_transport *transport,
492 sctp_lower_cwnd_t reason) 474 sctp_lower_cwnd_t reason)
493{ 475{
476 struct sctp_association *asoc = transport->asoc;
477
494 switch (reason) { 478 switch (reason) {
495 case SCTP_LOWER_CWND_T3_RTX: 479 case SCTP_LOWER_CWND_T3_RTX:
496 /* RFC 2960 Section 7.2.3, sctpimpguide 480 /* RFC 2960 Section 7.2.3, sctpimpguide
@@ -501,11 +485,11 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
501 * partial_bytes_acked = 0 485 * partial_bytes_acked = 0
502 */ 486 */
503 transport->ssthresh = max(transport->cwnd/2, 487 transport->ssthresh = max(transport->cwnd/2,
504 4*transport->asoc->pathmtu); 488 4*asoc->pathmtu);
505 transport->cwnd = transport->asoc->pathmtu; 489 transport->cwnd = asoc->pathmtu;
506 490
507 /* T3-rtx also clears fast recovery on the transport */ 491 /* T3-rtx also clears fast recovery */
508 transport->fast_recovery = 0; 492 asoc->fast_recovery = 0;
509 break; 493 break;
510 494
511 case SCTP_LOWER_CWND_FAST_RTX: 495 case SCTP_LOWER_CWND_FAST_RTX:
@@ -521,15 +505,15 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
521 * cwnd = ssthresh 505 * cwnd = ssthresh
522 * partial_bytes_acked = 0 506 * partial_bytes_acked = 0
523 */ 507 */
524 if (transport->fast_recovery) 508 if (asoc->fast_recovery)
525 return; 509 return;
526 510
527 /* Mark Fast recovery */ 511 /* Mark Fast recovery */
528 transport->fast_recovery = 1; 512 asoc->fast_recovery = 1;
529 transport->fast_recovery_exit = transport->asoc->next_tsn - 1; 513 asoc->fast_recovery_exit = asoc->next_tsn - 1;
530 514
531 transport->ssthresh = max(transport->cwnd/2, 515 transport->ssthresh = max(transport->cwnd/2,
532 4*transport->asoc->pathmtu); 516 4*asoc->pathmtu);
533 transport->cwnd = transport->ssthresh; 517 transport->cwnd = transport->ssthresh;
534 break; 518 break;
535 519
@@ -549,7 +533,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
549 if (time_after(jiffies, transport->last_time_ecne_reduced + 533 if (time_after(jiffies, transport->last_time_ecne_reduced +
550 transport->rtt)) { 534 transport->rtt)) {
551 transport->ssthresh = max(transport->cwnd/2, 535 transport->ssthresh = max(transport->cwnd/2,
552 4*transport->asoc->pathmtu); 536 4*asoc->pathmtu);
553 transport->cwnd = transport->ssthresh; 537 transport->cwnd = transport->ssthresh;
554 transport->last_time_ecne_reduced = jiffies; 538 transport->last_time_ecne_reduced = jiffies;
555 } 539 }
@@ -565,7 +549,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
565 * interval. 549 * interval.
566 */ 550 */
567 transport->cwnd = max(transport->cwnd/2, 551 transport->cwnd = max(transport->cwnd/2,
568 4*transport->asoc->pathmtu); 552 4*asoc->pathmtu);
569 break; 553 break;
570 } 554 }
571 555
@@ -650,7 +634,6 @@ void sctp_transport_reset(struct sctp_transport *t)
650 t->error_count = 0; 634 t->error_count = 0;
651 t->rto_pending = 0; 635 t->rto_pending = 0;
652 t->hb_sent = 0; 636 t->hb_sent = 0;
653 t->fast_recovery = 0;
654 637
655 /* Initialize the state information for SFR-CACC */ 638 /* Initialize the state information for SFR-CACC */
656 t->cacc.changeover_active = 0; 639 t->cacc.changeover_active = 0;