diff options
author | Frank Filz <ffilz@us.ibm.com> | 2005-12-22 14:36:46 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-01-03 16:11:11 -0500 |
commit | 52ccb8e90c0ace233b8b740f2fc5de0dbd706b27 (patch) | |
tree | d2c06dd7b26e70c8dccf31971508005fdc82cbb2 /net/sctp | |
parent | fd9662555cc35f8bf9242cd7bba8b44ae168a68b (diff) |
[SCTP]: Update SCTP_PEER_ADDR_PARAMS socket option to the latest api draft.
This patch adds support to set/get heartbeat interval, maximum number of
retransmissions, pathmtu, sackdelay time for a particular transport/
association/socket as per the latest SCTP sockets api draft11.
Signed-off-by: Frank Filz <ffilz@us.ibm.com>
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/associola.c | 81 | ||||
-rw-r--r-- | net/sctp/input.c | 36 | ||||
-rw-r--r-- | net/sctp/output.c | 17 | ||||
-rw-r--r-- | net/sctp/sm_sideeffect.c | 26 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 20 | ||||
-rw-r--r-- | net/sctp/socket.c | 511 | ||||
-rw-r--r-- | net/sctp/transport.c | 32 |
7 files changed, 523 insertions, 200 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index dec68a604773..9d05e13e92f6 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -110,7 +110,6 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
110 | asoc->cookie_life.tv_sec = sp->assocparams.sasoc_cookie_life / 1000; | 110 | asoc->cookie_life.tv_sec = sp->assocparams.sasoc_cookie_life / 1000; |
111 | asoc->cookie_life.tv_usec = (sp->assocparams.sasoc_cookie_life % 1000) | 111 | asoc->cookie_life.tv_usec = (sp->assocparams.sasoc_cookie_life % 1000) |
112 | * 1000; | 112 | * 1000; |
113 | asoc->pmtu = 0; | ||
114 | asoc->frag_point = 0; | 113 | asoc->frag_point = 0; |
115 | 114 | ||
116 | /* Set the association max_retrans and RTO values from the | 115 | /* Set the association max_retrans and RTO values from the |
@@ -123,6 +122,25 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
123 | 122 | ||
124 | asoc->overall_error_count = 0; | 123 | asoc->overall_error_count = 0; |
125 | 124 | ||
125 | /* Initialize the association's heartbeat interval based on the | ||
126 | * sock configured value. | ||
127 | */ | ||
128 | asoc->hbinterval = msecs_to_jiffies(sp->hbinterval); | ||
129 | |||
130 | /* Initialize path max retrans value. */ | ||
131 | asoc->pathmaxrxt = sp->pathmaxrxt; | ||
132 | |||
133 | /* Initialize default path MTU. */ | ||
134 | asoc->pathmtu = sp->pathmtu; | ||
135 | |||
136 | /* Set association default SACK delay */ | ||
137 | asoc->sackdelay = msecs_to_jiffies(sp->sackdelay); | ||
138 | |||
139 | /* Set the association default flags controlling | ||
140 | * Heartbeat, SACK delay, and Path MTU Discovery. | ||
141 | */ | ||
142 | asoc->param_flags = sp->param_flags; | ||
143 | |||
126 | /* Initialize the maximum mumber of new data packets that can be sent | 144 | /* Initialize the maximum mumber of new data packets that can be sent |
127 | * in a burst. | 145 | * in a burst. |
128 | */ | 146 | */ |
@@ -144,8 +162,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
144 | = 5 * asoc->rto_max; | 162 | = 5 * asoc->rto_max; |
145 | 163 | ||
146 | asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; | 164 | asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; |
147 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = | 165 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay; |
148 | SCTP_DEFAULT_TIMEOUT_SACK; | ||
149 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = | 166 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = |
150 | sp->autoclose * HZ; | 167 | sp->autoclose * HZ; |
151 | 168 | ||
@@ -540,23 +557,46 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, | |||
540 | 557 | ||
541 | sctp_transport_set_owner(peer, asoc); | 558 | sctp_transport_set_owner(peer, asoc); |
542 | 559 | ||
560 | /* Initialize the peer's heartbeat interval based on the | ||
561 | * association configured value. | ||
562 | */ | ||
563 | peer->hbinterval = asoc->hbinterval; | ||
564 | |||
565 | /* Set the path max_retrans. */ | ||
566 | peer->pathmaxrxt = asoc->pathmaxrxt; | ||
567 | |||
568 | /* Initialize the peer's SACK delay timeout based on the | ||
569 | * association configured value. | ||
570 | */ | ||
571 | peer->sackdelay = asoc->sackdelay; | ||
572 | |||
573 | /* Enable/disable heartbeat, SACK delay, and path MTU discovery | ||
574 | * based on association setting. | ||
575 | */ | ||
576 | peer->param_flags = asoc->param_flags; | ||
577 | |||
543 | /* Initialize the pmtu of the transport. */ | 578 | /* Initialize the pmtu of the transport. */ |
544 | sctp_transport_pmtu(peer); | 579 | if (peer->param_flags & SPP_PMTUD_ENABLE) |
580 | sctp_transport_pmtu(peer); | ||
581 | else if (asoc->pathmtu) | ||
582 | peer->pathmtu = asoc->pathmtu; | ||
583 | else | ||
584 | peer->pathmtu = SCTP_DEFAULT_MAXSEGMENT; | ||
545 | 585 | ||
546 | /* If this is the first transport addr on this association, | 586 | /* If this is the first transport addr on this association, |
547 | * initialize the association PMTU to the peer's PMTU. | 587 | * initialize the association PMTU to the peer's PMTU. |
548 | * If not and the current association PMTU is higher than the new | 588 | * If not and the current association PMTU is higher than the new |
549 | * peer's PMTU, reset the association PMTU to the new peer's PMTU. | 589 | * peer's PMTU, reset the association PMTU to the new peer's PMTU. |
550 | */ | 590 | */ |
551 | if (asoc->pmtu) | 591 | if (asoc->pathmtu) |
552 | asoc->pmtu = min_t(int, peer->pmtu, asoc->pmtu); | 592 | asoc->pathmtu = min_t(int, peer->pathmtu, asoc->pathmtu); |
553 | else | 593 | else |
554 | asoc->pmtu = peer->pmtu; | 594 | asoc->pathmtu = peer->pathmtu; |
555 | 595 | ||
556 | SCTP_DEBUG_PRINTK("sctp_assoc_add_peer:association %p PMTU set to " | 596 | SCTP_DEBUG_PRINTK("sctp_assoc_add_peer:association %p PMTU set to " |
557 | "%d\n", asoc, asoc->pmtu); | 597 | "%d\n", asoc, asoc->pathmtu); |
558 | 598 | ||
559 | asoc->frag_point = sctp_frag_point(sp, asoc->pmtu); | 599 | asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu); |
560 | 600 | ||
561 | /* The asoc->peer.port might not be meaningful yet, but | 601 | /* The asoc->peer.port might not be meaningful yet, but |
562 | * initialize the packet structure anyway. | 602 | * initialize the packet structure anyway. |
@@ -574,7 +614,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, | |||
574 | * (for example, implementations MAY use the size of the | 614 | * (for example, implementations MAY use the size of the |
575 | * receiver advertised window). | 615 | * receiver advertised window). |
576 | */ | 616 | */ |
577 | peer->cwnd = min(4*asoc->pmtu, max_t(__u32, 2*asoc->pmtu, 4380)); | 617 | peer->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380)); |
578 | 618 | ||
579 | /* At this point, we may not have the receiver's advertised window, | 619 | /* At this point, we may not have the receiver's advertised window, |
580 | * so initialize ssthresh to the default value and it will be set | 620 | * so initialize ssthresh to the default value and it will be set |
@@ -585,17 +625,6 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, | |||
585 | peer->partial_bytes_acked = 0; | 625 | peer->partial_bytes_acked = 0; |
586 | peer->flight_size = 0; | 626 | peer->flight_size = 0; |
587 | 627 | ||
588 | /* By default, enable heartbeat for peer address. */ | ||
589 | peer->hb_allowed = 1; | ||
590 | |||
591 | /* Initialize the peer's heartbeat interval based on the | ||
592 | * sock configured value. | ||
593 | */ | ||
594 | peer->hb_interval = msecs_to_jiffies(sp->paddrparam.spp_hbinterval); | ||
595 | |||
596 | /* Set the path max_retrans. */ | ||
597 | peer->max_retrans = sp->paddrparam.spp_pathmaxrxt; | ||
598 | |||
599 | /* Set the transport's RTO.initial value */ | 628 | /* Set the transport's RTO.initial value */ |
600 | peer->rto = asoc->rto_initial; | 629 | peer->rto = asoc->rto_initial; |
601 | 630 | ||
@@ -1155,18 +1184,18 @@ void sctp_assoc_sync_pmtu(struct sctp_association *asoc) | |||
1155 | /* Get the lowest pmtu of all the transports. */ | 1184 | /* Get the lowest pmtu of all the transports. */ |
1156 | list_for_each(pos, &asoc->peer.transport_addr_list) { | 1185 | list_for_each(pos, &asoc->peer.transport_addr_list) { |
1157 | t = list_entry(pos, struct sctp_transport, transports); | 1186 | t = list_entry(pos, struct sctp_transport, transports); |
1158 | if (!pmtu || (t->pmtu < pmtu)) | 1187 | if (!pmtu || (t->pathmtu < pmtu)) |
1159 | pmtu = t->pmtu; | 1188 | pmtu = t->pathmtu; |
1160 | } | 1189 | } |
1161 | 1190 | ||
1162 | if (pmtu) { | 1191 | if (pmtu) { |
1163 | struct sctp_sock *sp = sctp_sk(asoc->base.sk); | 1192 | struct sctp_sock *sp = sctp_sk(asoc->base.sk); |
1164 | asoc->pmtu = pmtu; | 1193 | asoc->pathmtu = pmtu; |
1165 | asoc->frag_point = sctp_frag_point(sp, pmtu); | 1194 | asoc->frag_point = sctp_frag_point(sp, pmtu); |
1166 | } | 1195 | } |
1167 | 1196 | ||
1168 | SCTP_DEBUG_PRINTK("%s: asoc:%p, pmtu:%d, frag_point:%d\n", | 1197 | SCTP_DEBUG_PRINTK("%s: asoc:%p, pmtu:%d, frag_point:%d\n", |
1169 | __FUNCTION__, asoc, asoc->pmtu, asoc->frag_point); | 1198 | __FUNCTION__, asoc, asoc->pathmtu, asoc->frag_point); |
1170 | } | 1199 | } |
1171 | 1200 | ||
1172 | /* Should we send a SACK to update our peer? */ | 1201 | /* Should we send a SACK to update our peer? */ |
@@ -1179,7 +1208,7 @@ static inline int sctp_peer_needs_update(struct sctp_association *asoc) | |||
1179 | case SCTP_STATE_SHUTDOWN_SENT: | 1208 | case SCTP_STATE_SHUTDOWN_SENT: |
1180 | if ((asoc->rwnd > asoc->a_rwnd) && | 1209 | if ((asoc->rwnd > asoc->a_rwnd) && |
1181 | ((asoc->rwnd - asoc->a_rwnd) >= | 1210 | ((asoc->rwnd - asoc->a_rwnd) >= |
1182 | min_t(__u32, (asoc->base.sk->sk_rcvbuf >> 1), asoc->pmtu))) | 1211 | min_t(__u32, (asoc->base.sk->sk_rcvbuf >> 1), asoc->pathmtu))) |
1183 | return 1; | 1212 | return 1; |
1184 | break; | 1213 | break; |
1185 | default: | 1214 | default: |
diff --git a/net/sctp/input.c b/net/sctp/input.c index b24ff2c1aef5..238f1bffa684 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -305,18 +305,36 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) | |||
305 | void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, | 305 | void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, |
306 | struct sctp_transport *t, __u32 pmtu) | 306 | struct sctp_transport *t, __u32 pmtu) |
307 | { | 307 | { |
308 | if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) { | 308 | if (sock_owned_by_user(sk) || !t || (t->pathmtu == pmtu)) |
309 | printk(KERN_WARNING "%s: Reported pmtu %d too low, " | 309 | return; |
310 | "using default minimum of %d\n", __FUNCTION__, pmtu, | ||
311 | SCTP_DEFAULT_MINSEGMENT); | ||
312 | pmtu = SCTP_DEFAULT_MINSEGMENT; | ||
313 | } | ||
314 | 310 | ||
315 | if (!sock_owned_by_user(sk) && t && (t->pmtu != pmtu)) { | 311 | if (t->param_flags & SPP_PMTUD_ENABLE) { |
316 | t->pmtu = pmtu; | 312 | if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) { |
313 | printk(KERN_WARNING "%s: Reported pmtu %d too low, " | ||
314 | "using default minimum of %d\n", | ||
315 | __FUNCTION__, pmtu, | ||
316 | SCTP_DEFAULT_MINSEGMENT); | ||
317 | /* Use default minimum segment size and disable | ||
318 | * pmtu discovery on this transport. | ||
319 | */ | ||
320 | t->pathmtu = SCTP_DEFAULT_MINSEGMENT; | ||
321 | t->param_flags = (t->param_flags & ~SPP_HB) | | ||
322 | SPP_PMTUD_DISABLE; | ||
323 | } else { | ||
324 | t->pathmtu = pmtu; | ||
325 | } | ||
326 | |||
327 | /* Update association pmtu. */ | ||
317 | sctp_assoc_sync_pmtu(asoc); | 328 | sctp_assoc_sync_pmtu(asoc); |
318 | sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD); | ||
319 | } | 329 | } |
330 | |||
331 | /* Retransmit with the new pmtu setting. | ||
332 | * Normally, if PMTU discovery is disabled, an ICMP Fragmentation | ||
333 | * Needed will never be sent, but if a message was sent before | ||
334 | * PMTU discovery was disabled that was larger than the PMTU, it | ||
335 | * would not be fragmented, so it must be re-transmitted fragmented. | ||
336 | */ | ||
337 | sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD); | ||
320 | } | 338 | } |
321 | 339 | ||
322 | /* | 340 | /* |
diff --git a/net/sctp/output.c b/net/sctp/output.c index 931371633464..a40991ef72c9 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -234,8 +234,8 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet, | |||
234 | goto finish; | 234 | goto finish; |
235 | 235 | ||
236 | pmtu = ((packet->transport->asoc) ? | 236 | pmtu = ((packet->transport->asoc) ? |
237 | (packet->transport->asoc->pmtu) : | 237 | (packet->transport->asoc->pathmtu) : |
238 | (packet->transport->pmtu)); | 238 | (packet->transport->pathmtu)); |
239 | 239 | ||
240 | too_big = (psize + chunk_len > pmtu); | 240 | too_big = (psize + chunk_len > pmtu); |
241 | 241 | ||
@@ -482,7 +482,9 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
482 | if (!dst || (dst->obsolete > 1)) { | 482 | if (!dst || (dst->obsolete > 1)) { |
483 | dst_release(dst); | 483 | dst_release(dst); |
484 | sctp_transport_route(tp, NULL, sctp_sk(sk)); | 484 | sctp_transport_route(tp, NULL, sctp_sk(sk)); |
485 | sctp_assoc_sync_pmtu(asoc); | 485 | if (asoc->param_flags & SPP_PMTUD_ENABLE) { |
486 | sctp_assoc_sync_pmtu(asoc); | ||
487 | } | ||
486 | } | 488 | } |
487 | 489 | ||
488 | nskb->dst = dst_clone(tp->dst); | 490 | nskb->dst = dst_clone(tp->dst); |
@@ -492,7 +494,10 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
492 | SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n", | 494 | SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n", |
493 | nskb->len); | 495 | nskb->len); |
494 | 496 | ||
495 | (*tp->af_specific->sctp_xmit)(nskb, tp, packet->ipfragok); | 497 | if (tp->param_flags & SPP_PMTUD_ENABLE) |
498 | (*tp->af_specific->sctp_xmit)(nskb, tp, packet->ipfragok); | ||
499 | else | ||
500 | (*tp->af_specific->sctp_xmit)(nskb, tp, 1); | ||
496 | 501 | ||
497 | out: | 502 | out: |
498 | packet->size = packet->overhead; | 503 | packet->size = packet->overhead; |
@@ -577,7 +582,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet, | |||
577 | * if ((flightsize + Max.Burst * MTU) < cwnd) | 582 | * if ((flightsize + Max.Burst * MTU) < cwnd) |
578 | * cwnd = flightsize + Max.Burst * MTU | 583 | * cwnd = flightsize + Max.Burst * MTU |
579 | */ | 584 | */ |
580 | max_burst_bytes = asoc->max_burst * asoc->pmtu; | 585 | max_burst_bytes = asoc->max_burst * asoc->pathmtu; |
581 | if ((transport->flight_size + max_burst_bytes) < transport->cwnd) { | 586 | if ((transport->flight_size + max_burst_bytes) < transport->cwnd) { |
582 | transport->cwnd = transport->flight_size + max_burst_bytes; | 587 | transport->cwnd = transport->flight_size + max_burst_bytes; |
583 | SCTP_DEBUG_PRINTK("%s: cwnd limited by max_burst: " | 588 | SCTP_DEBUG_PRINTK("%s: cwnd limited by max_burst: " |
@@ -622,7 +627,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet, | |||
622 | * data will fit or delay in hopes of bundling a full | 627 | * data will fit or delay in hopes of bundling a full |
623 | * sized packet. | 628 | * sized packet. |
624 | */ | 629 | */ |
625 | if (len < asoc->pmtu - packet->overhead) { | 630 | if (len < asoc->pathmtu - packet->overhead) { |
626 | retval = SCTP_XMIT_NAGLE_DELAY; | 631 | retval = SCTP_XMIT_NAGLE_DELAY; |
627 | goto finish; | 632 | goto finish; |
628 | } | 633 | } |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 823947170a33..2d7d8a5db2ac 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -157,9 +157,12 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force, | |||
157 | { | 157 | { |
158 | __u32 ctsn, max_tsn_seen; | 158 | __u32 ctsn, max_tsn_seen; |
159 | struct sctp_chunk *sack; | 159 | struct sctp_chunk *sack; |
160 | struct sctp_transport *trans = asoc->peer.last_data_from; | ||
160 | int error = 0; | 161 | int error = 0; |
161 | 162 | ||
162 | if (force) | 163 | if (force || |
164 | (!trans && (asoc->param_flags & SPP_SACKDELAY_DISABLE)) || | ||
165 | (trans && (trans->param_flags & SPP_SACKDELAY_DISABLE))) | ||
163 | asoc->peer.sack_needed = 1; | 166 | asoc->peer.sack_needed = 1; |
164 | 167 | ||
165 | ctsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map); | 168 | ctsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map); |
@@ -189,7 +192,22 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force, | |||
189 | if (!asoc->peer.sack_needed) { | 192 | if (!asoc->peer.sack_needed) { |
190 | /* We will need a SACK for the next packet. */ | 193 | /* We will need a SACK for the next packet. */ |
191 | asoc->peer.sack_needed = 1; | 194 | asoc->peer.sack_needed = 1; |
192 | goto out; | 195 | |
196 | /* Set the SACK delay timeout based on the | ||
197 | * SACK delay for the last transport | ||
198 | * data was received from, or the default | ||
199 | * for the association. | ||
200 | */ | ||
201 | if (trans) | ||
202 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = | ||
203 | trans->sackdelay; | ||
204 | else | ||
205 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = | ||
206 | asoc->sackdelay; | ||
207 | |||
208 | /* Restart the SACK timer. */ | ||
209 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | ||
210 | SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); | ||
193 | } else { | 211 | } else { |
194 | if (asoc->a_rwnd > asoc->rwnd) | 212 | if (asoc->a_rwnd > asoc->rwnd) |
195 | asoc->a_rwnd = asoc->rwnd; | 213 | asoc->a_rwnd = asoc->rwnd; |
@@ -205,7 +223,7 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force, | |||
205 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 223 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
206 | SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); | 224 | SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); |
207 | } | 225 | } |
208 | out: | 226 | |
209 | return error; | 227 | return error; |
210 | nomem: | 228 | nomem: |
211 | error = -ENOMEM; | 229 | error = -ENOMEM; |
@@ -415,7 +433,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc, | |||
415 | asoc->overall_error_count++; | 433 | asoc->overall_error_count++; |
416 | 434 | ||
417 | if (transport->state != SCTP_INACTIVE && | 435 | if (transport->state != SCTP_INACTIVE && |
418 | (transport->error_count++ >= transport->max_retrans)) { | 436 | (transport->error_count++ >= transport->pathmaxrxt)) { |
419 | SCTP_DEBUG_PRINTK_IPADDR("transport_strike:association %p", | 437 | SCTP_DEBUG_PRINTK_IPADDR("transport_strike:association %p", |
420 | " transport IP: port:%d failed.\n", | 438 | " transport IP: port:%d failed.\n", |
421 | asoc, | 439 | asoc, |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 475bfb4972d9..557a7d90b92a 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -900,7 +900,7 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep, | |||
900 | * HEARTBEAT is sent (see Section 8.3). | 900 | * HEARTBEAT is sent (see Section 8.3). |
901 | */ | 901 | */ |
902 | 902 | ||
903 | if (transport->hb_allowed) { | 903 | if (transport->param_flags & SPP_HB_ENABLE) { |
904 | if (SCTP_DISPOSITION_NOMEM == | 904 | if (SCTP_DISPOSITION_NOMEM == |
905 | sctp_sf_heartbeat(ep, asoc, type, arg, | 905 | sctp_sf_heartbeat(ep, asoc, type, arg, |
906 | commands)) | 906 | commands)) |
@@ -1051,7 +1051,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep, | |||
1051 | return SCTP_DISPOSITION_DISCARD; | 1051 | return SCTP_DISPOSITION_DISCARD; |
1052 | } | 1052 | } |
1053 | 1053 | ||
1054 | max_interval = link->hb_interval + link->rto; | 1054 | max_interval = link->hbinterval + link->rto; |
1055 | 1055 | ||
1056 | /* Check if the timestamp looks valid. */ | 1056 | /* Check if the timestamp looks valid. */ |
1057 | if (time_after(hbinfo->sent_at, jiffies) || | 1057 | if (time_after(hbinfo->sent_at, jiffies) || |
@@ -2691,14 +2691,9 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep, | |||
2691 | * document allow. However, an SCTP transmitter MUST NOT be | 2691 | * document allow. However, an SCTP transmitter MUST NOT be |
2692 | * more aggressive than the following algorithms allow. | 2692 | * more aggressive than the following algorithms allow. |
2693 | */ | 2693 | */ |
2694 | if (chunk->end_of_packet) { | 2694 | if (chunk->end_of_packet) |
2695 | sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE()); | 2695 | sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE()); |
2696 | 2696 | ||
2697 | /* Start the SACK timer. */ | ||
2698 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | ||
2699 | SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); | ||
2700 | } | ||
2701 | |||
2702 | return SCTP_DISPOSITION_CONSUME; | 2697 | return SCTP_DISPOSITION_CONSUME; |
2703 | 2698 | ||
2704 | discard_force: | 2699 | discard_force: |
@@ -2721,13 +2716,9 @@ discard_force: | |||
2721 | return SCTP_DISPOSITION_DISCARD; | 2716 | return SCTP_DISPOSITION_DISCARD; |
2722 | 2717 | ||
2723 | discard_noforce: | 2718 | discard_noforce: |
2724 | if (chunk->end_of_packet) { | 2719 | if (chunk->end_of_packet) |
2725 | sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE()); | 2720 | sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE()); |
2726 | 2721 | ||
2727 | /* Start the SACK timer. */ | ||
2728 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | ||
2729 | SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); | ||
2730 | } | ||
2731 | return SCTP_DISPOSITION_DISCARD; | 2722 | return SCTP_DISPOSITION_DISCARD; |
2732 | consume: | 2723 | consume: |
2733 | return SCTP_DISPOSITION_CONSUME; | 2724 | return SCTP_DISPOSITION_CONSUME; |
@@ -3442,9 +3433,6 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(const struct sctp_endpoint *ep, | |||
3442 | * send another. | 3433 | * send another. |
3443 | */ | 3434 | */ |
3444 | sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE()); | 3435 | sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE()); |
3445 | /* Start the SACK timer. */ | ||
3446 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | ||
3447 | SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); | ||
3448 | 3436 | ||
3449 | return SCTP_DISPOSITION_CONSUME; | 3437 | return SCTP_DISPOSITION_CONSUME; |
3450 | 3438 | ||
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 9df888e932c5..adb5ee62c2a6 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -1941,106 +1941,275 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, | |||
1941 | * address's parameters: | 1941 | * address's parameters: |
1942 | * | 1942 | * |
1943 | * struct sctp_paddrparams { | 1943 | * struct sctp_paddrparams { |
1944 | * sctp_assoc_t spp_assoc_id; | 1944 | * sctp_assoc_t spp_assoc_id; |
1945 | * struct sockaddr_storage spp_address; | 1945 | * struct sockaddr_storage spp_address; |
1946 | * uint32_t spp_hbinterval; | 1946 | * uint32_t spp_hbinterval; |
1947 | * uint16_t spp_pathmaxrxt; | 1947 | * uint16_t spp_pathmaxrxt; |
1948 | * }; | 1948 | * uint32_t spp_pathmtu; |
1949 | * | 1949 | * uint32_t spp_sackdelay; |
1950 | * spp_assoc_id - (UDP style socket) This is filled in the application, | 1950 | * uint32_t spp_flags; |
1951 | * and identifies the association for this query. | 1951 | * }; |
1952 | * | ||
1953 | * spp_assoc_id - (one-to-many style socket) This is filled in the | ||
1954 | * application, and identifies the association for | ||
1955 | * this query. | ||
1952 | * spp_address - This specifies which address is of interest. | 1956 | * spp_address - This specifies which address is of interest. |
1953 | * spp_hbinterval - This contains the value of the heartbeat interval, | 1957 | * spp_hbinterval - This contains the value of the heartbeat interval, |
1954 | * in milliseconds. A value of 0, when modifying the | 1958 | * in milliseconds. If a value of zero |
1955 | * parameter, specifies that the heartbeat on this | 1959 | * is present in this field then no changes are to |
1956 | * address should be disabled. A value of UINT32_MAX | 1960 | * be made to this parameter. |
1957 | * (4294967295), when modifying the parameter, | ||
1958 | * specifies that a heartbeat should be sent | ||
1959 | * immediately to the peer address, and the current | ||
1960 | * interval should remain unchanged. | ||
1961 | * spp_pathmaxrxt - This contains the maximum number of | 1961 | * spp_pathmaxrxt - This contains the maximum number of |
1962 | * retransmissions before this address shall be | 1962 | * retransmissions before this address shall be |
1963 | * considered unreachable. | 1963 | * considered unreachable. If a value of zero |
1964 | * is present in this field then no changes are to | ||
1965 | * be made to this parameter. | ||
1966 | * spp_pathmtu - When Path MTU discovery is disabled the value | ||
1967 | * specified here will be the "fixed" path mtu. | ||
1968 | * Note that if the spp_address field is empty | ||
1969 | * then all associations on this address will | ||
1970 | * have this fixed path mtu set upon them. | ||
1971 | * | ||
1972 | * spp_sackdelay - When delayed sack is enabled, this value specifies | ||
1973 | * the number of milliseconds that sacks will be delayed | ||
1974 | * for. This value will apply to all addresses of an | ||
1975 | * association if the spp_address field is empty. Note | ||
1976 | * also, that if delayed sack is enabled and this | ||
1977 | * value is set to 0, no change is made to the last | ||
1978 | * recorded delayed sack timer value. | ||
1979 | * | ||
1980 | * spp_flags - These flags are used to control various features | ||
1981 | * on an association. The flag field may contain | ||
1982 | * zero or more of the following options. | ||
1983 | * | ||
1984 | * SPP_HB_ENABLE - Enable heartbeats on the | ||
1985 | * specified address. Note that if the address | ||
1986 | * field is empty all addresses for the association | ||
1987 | * have heartbeats enabled upon them. | ||
1988 | * | ||
1989 | * SPP_HB_DISABLE - Disable heartbeats on the | ||
1990 | * speicifed address. Note that if the address | ||
1991 | * field is empty all addresses for the association | ||
1992 | * will have their heartbeats disabled. Note also | ||
1993 | * that SPP_HB_ENABLE and SPP_HB_DISABLE are | ||
1994 | * mutually exclusive, only one of these two should | ||
1995 | * be specified. Enabling both fields will have | ||
1996 | * undetermined results. | ||
1997 | * | ||
1998 | * SPP_HB_DEMAND - Request a user initiated heartbeat | ||
1999 | * to be made immediately. | ||
2000 | * | ||
2001 | * SPP_PMTUD_ENABLE - This field will enable PMTU | ||
2002 | * discovery upon the specified address. Note that | ||
2003 | * if the address feild is empty then all addresses | ||
2004 | * on the association are effected. | ||
2005 | * | ||
2006 | * SPP_PMTUD_DISABLE - This field will disable PMTU | ||
2007 | * discovery upon the specified address. Note that | ||
2008 | * if the address feild is empty then all addresses | ||
2009 | * on the association are effected. Not also that | ||
2010 | * SPP_PMTUD_ENABLE and SPP_PMTUD_DISABLE are mutually | ||
2011 | * exclusive. Enabling both will have undetermined | ||
2012 | * results. | ||
2013 | * | ||
2014 | * SPP_SACKDELAY_ENABLE - Setting this flag turns | ||
2015 | * on delayed sack. The time specified in spp_sackdelay | ||
2016 | * is used to specify the sack delay for this address. Note | ||
2017 | * that if spp_address is empty then all addresses will | ||
2018 | * enable delayed sack and take on the sack delay | ||
2019 | * value specified in spp_sackdelay. | ||
2020 | * SPP_SACKDELAY_DISABLE - Setting this flag turns | ||
2021 | * off delayed sack. If the spp_address field is blank then | ||
2022 | * delayed sack is disabled for the entire association. Note | ||
2023 | * also that this field is mutually exclusive to | ||
2024 | * SPP_SACKDELAY_ENABLE, setting both will have undefined | ||
2025 | * results. | ||
1964 | */ | 2026 | */ |
2027 | int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, | ||
2028 | struct sctp_transport *trans, | ||
2029 | struct sctp_association *asoc, | ||
2030 | struct sctp_sock *sp, | ||
2031 | int hb_change, | ||
2032 | int pmtud_change, | ||
2033 | int sackdelay_change) | ||
2034 | { | ||
2035 | int error; | ||
2036 | |||
2037 | if (params->spp_flags & SPP_HB_DEMAND && trans) { | ||
2038 | error = sctp_primitive_REQUESTHEARTBEAT (trans->asoc, trans); | ||
2039 | if (error) | ||
2040 | return error; | ||
2041 | } | ||
2042 | |||
2043 | if (params->spp_hbinterval) { | ||
2044 | if (trans) { | ||
2045 | trans->hbinterval = msecs_to_jiffies(params->spp_hbinterval); | ||
2046 | } else if (asoc) { | ||
2047 | asoc->hbinterval = msecs_to_jiffies(params->spp_hbinterval); | ||
2048 | } else { | ||
2049 | sp->hbinterval = params->spp_hbinterval; | ||
2050 | } | ||
2051 | } | ||
2052 | |||
2053 | if (hb_change) { | ||
2054 | if (trans) { | ||
2055 | trans->param_flags = | ||
2056 | (trans->param_flags & ~SPP_HB) | hb_change; | ||
2057 | } else if (asoc) { | ||
2058 | asoc->param_flags = | ||
2059 | (asoc->param_flags & ~SPP_HB) | hb_change; | ||
2060 | } else { | ||
2061 | sp->param_flags = | ||
2062 | (sp->param_flags & ~SPP_HB) | hb_change; | ||
2063 | } | ||
2064 | } | ||
2065 | |||
2066 | if (params->spp_pathmtu) { | ||
2067 | if (trans) { | ||
2068 | trans->pathmtu = params->spp_pathmtu; | ||
2069 | sctp_assoc_sync_pmtu(asoc); | ||
2070 | } else if (asoc) { | ||
2071 | asoc->pathmtu = params->spp_pathmtu; | ||
2072 | sctp_frag_point(sp, params->spp_pathmtu); | ||
2073 | } else { | ||
2074 | sp->pathmtu = params->spp_pathmtu; | ||
2075 | } | ||
2076 | } | ||
2077 | |||
2078 | if (pmtud_change) { | ||
2079 | if (trans) { | ||
2080 | int update = (trans->param_flags & SPP_PMTUD_DISABLE) && | ||
2081 | (params->spp_flags & SPP_PMTUD_ENABLE); | ||
2082 | trans->param_flags = | ||
2083 | (trans->param_flags & ~SPP_PMTUD) | pmtud_change; | ||
2084 | if (update) { | ||
2085 | sctp_transport_pmtu(trans); | ||
2086 | sctp_assoc_sync_pmtu(asoc); | ||
2087 | } | ||
2088 | } else if (asoc) { | ||
2089 | asoc->param_flags = | ||
2090 | (asoc->param_flags & ~SPP_PMTUD) | pmtud_change; | ||
2091 | } else { | ||
2092 | sp->param_flags = | ||
2093 | (sp->param_flags & ~SPP_PMTUD) | pmtud_change; | ||
2094 | } | ||
2095 | } | ||
2096 | |||
2097 | if (params->spp_sackdelay) { | ||
2098 | if (trans) { | ||
2099 | trans->sackdelay = | ||
2100 | msecs_to_jiffies(params->spp_sackdelay); | ||
2101 | } else if (asoc) { | ||
2102 | asoc->sackdelay = | ||
2103 | msecs_to_jiffies(params->spp_sackdelay); | ||
2104 | } else { | ||
2105 | sp->sackdelay = params->spp_sackdelay; | ||
2106 | } | ||
2107 | } | ||
2108 | |||
2109 | if (sackdelay_change) { | ||
2110 | if (trans) { | ||
2111 | trans->param_flags = | ||
2112 | (trans->param_flags & ~SPP_SACKDELAY) | | ||
2113 | sackdelay_change; | ||
2114 | } else if (asoc) { | ||
2115 | asoc->param_flags = | ||
2116 | (asoc->param_flags & ~SPP_SACKDELAY) | | ||
2117 | sackdelay_change; | ||
2118 | } else { | ||
2119 | sp->param_flags = | ||
2120 | (sp->param_flags & ~SPP_SACKDELAY) | | ||
2121 | sackdelay_change; | ||
2122 | } | ||
2123 | } | ||
2124 | |||
2125 | if (params->spp_pathmaxrxt) { | ||
2126 | if (trans) { | ||
2127 | trans->pathmaxrxt = params->spp_pathmaxrxt; | ||
2128 | } else if (asoc) { | ||
2129 | asoc->pathmaxrxt = params->spp_pathmaxrxt; | ||
2130 | } else { | ||
2131 | sp->pathmaxrxt = params->spp_pathmaxrxt; | ||
2132 | } | ||
2133 | } | ||
2134 | |||
2135 | return 0; | ||
2136 | } | ||
2137 | |||
1965 | static int sctp_setsockopt_peer_addr_params(struct sock *sk, | 2138 | static int sctp_setsockopt_peer_addr_params(struct sock *sk, |
1966 | char __user *optval, int optlen) | 2139 | char __user *optval, int optlen) |
1967 | { | 2140 | { |
1968 | struct sctp_paddrparams params; | 2141 | struct sctp_paddrparams params; |
1969 | struct sctp_transport *trans; | 2142 | struct sctp_transport *trans = NULL; |
2143 | struct sctp_association *asoc = NULL; | ||
2144 | struct sctp_sock *sp = sctp_sk(sk); | ||
1970 | int error; | 2145 | int error; |
2146 | int hb_change, pmtud_change, sackdelay_change; | ||
1971 | 2147 | ||
1972 | if (optlen != sizeof(struct sctp_paddrparams)) | 2148 | if (optlen != sizeof(struct sctp_paddrparams)) |
1973 | return -EINVAL; | 2149 | return - EINVAL; |
2150 | |||
1974 | if (copy_from_user(¶ms, optval, optlen)) | 2151 | if (copy_from_user(¶ms, optval, optlen)) |
1975 | return -EFAULT; | 2152 | return -EFAULT; |
1976 | 2153 | ||
1977 | /* | 2154 | /* Validate flags and value parameters. */ |
1978 | * API 7. Socket Options (setting the default value for the endpoint) | 2155 | hb_change = params.spp_flags & SPP_HB; |
1979 | * All options that support specific settings on an association by | 2156 | pmtud_change = params.spp_flags & SPP_PMTUD; |
1980 | * filling in either an association id variable or a sockaddr_storage | 2157 | sackdelay_change = params.spp_flags & SPP_SACKDELAY; |
1981 | * SHOULD also support setting of the same value for the entire endpoint | 2158 | |
1982 | * (i.e. future associations). To accomplish this the following logic is | 2159 | if (hb_change == SPP_HB || |
1983 | * used when setting one of these options: | 2160 | pmtud_change == SPP_PMTUD || |
1984 | 2161 | sackdelay_change == SPP_SACKDELAY || | |
1985 | * c) If neither the sockaddr_storage or association identification is | 2162 | params.spp_sackdelay > 500 || |
1986 | * set i.e. the sockaddr_storage is set to all 0's (INADDR_ANY) and | 2163 | (params.spp_pathmtu |
1987 | * the association identification is 0, the settings are a default | 2164 | && params.spp_pathmtu < SCTP_DEFAULT_MINSEGMENT)) |
1988 | * and to be applied to the endpoint (all future associations). | 2165 | return -EINVAL; |
1989 | */ | ||
1990 | 2166 | ||
1991 | /* update default value for endpoint (all future associations) */ | 2167 | /* If an address other than INADDR_ANY is specified, and |
1992 | if (!params.spp_assoc_id && | 2168 | * no transport is found, then the request is invalid. |
1993 | sctp_is_any(( union sctp_addr *)¶ms.spp_address)) { | 2169 | */ |
1994 | /* Manual heartbeat on an endpoint is invalid. */ | 2170 | if (!sctp_is_any(( union sctp_addr *)¶ms.spp_address)) { |
1995 | if (0xffffffff == params.spp_hbinterval) | 2171 | trans = sctp_addr_id2transport(sk, ¶ms.spp_address, |
2172 | params.spp_assoc_id); | ||
2173 | if (!trans) | ||
1996 | return -EINVAL; | 2174 | return -EINVAL; |
1997 | else if (params.spp_hbinterval) | ||
1998 | sctp_sk(sk)->paddrparam.spp_hbinterval = | ||
1999 | params.spp_hbinterval; | ||
2000 | if (params.spp_pathmaxrxt) | ||
2001 | sctp_sk(sk)->paddrparam.spp_pathmaxrxt = | ||
2002 | params.spp_pathmaxrxt; | ||
2003 | return 0; | ||
2004 | } | 2175 | } |
2005 | 2176 | ||
2006 | trans = sctp_addr_id2transport(sk, ¶ms.spp_address, | 2177 | /* Get association, if assoc_id != 0 and the socket is a one |
2007 | params.spp_assoc_id); | 2178 | * to many style socket, and an association was not found, then |
2008 | if (!trans) | 2179 | * the id was invalid. |
2180 | */ | ||
2181 | asoc = sctp_id2assoc(sk, params.spp_assoc_id); | ||
2182 | if (!asoc && params.spp_assoc_id && sctp_style(sk, UDP)) | ||
2009 | return -EINVAL; | 2183 | return -EINVAL; |
2010 | 2184 | ||
2011 | /* Applications can enable or disable heartbeats for any peer address | 2185 | /* Heartbeat demand can only be sent on a transport or |
2012 | * of an association, modify an address's heartbeat interval, force a | 2186 | * association, but not a socket. |
2013 | * heartbeat to be sent immediately, and adjust the address's maximum | ||
2014 | * number of retransmissions sent before an address is considered | ||
2015 | * unreachable. | ||
2016 | * | ||
2017 | * The value of the heartbeat interval, in milliseconds. A value of | ||
2018 | * UINT32_MAX (4294967295), when modifying the parameter, specifies | ||
2019 | * that a heartbeat should be sent immediately to the peer address, | ||
2020 | * and the current interval should remain unchanged. | ||
2021 | */ | ||
2022 | if (0xffffffff == params.spp_hbinterval) { | ||
2023 | error = sctp_primitive_REQUESTHEARTBEAT (trans->asoc, trans); | ||
2024 | if (error) | ||
2025 | return error; | ||
2026 | } else { | ||
2027 | /* The value of the heartbeat interval, in milliseconds. A value of 0, | ||
2028 | * when modifying the parameter, specifies that the heartbeat on this | ||
2029 | * address should be disabled. | ||
2030 | */ | 2187 | */ |
2031 | if (params.spp_hbinterval) { | 2188 | if (params.spp_flags & SPP_HB_DEMAND && !trans && !asoc) |
2032 | trans->hb_allowed = 1; | 2189 | return -EINVAL; |
2033 | trans->hb_interval = | 2190 | |
2034 | msecs_to_jiffies(params.spp_hbinterval); | 2191 | /* Process parameters. */ |
2035 | } else | 2192 | error = sctp_apply_peer_addr_params(¶ms, trans, asoc, sp, |
2036 | trans->hb_allowed = 0; | 2193 | hb_change, pmtud_change, |
2037 | } | 2194 | sackdelay_change); |
2038 | 2195 | ||
2039 | /* spp_pathmaxrxt contains the maximum number of retransmissions | 2196 | if (error) |
2040 | * before this address shall be considered unreachable. | 2197 | return error; |
2198 | |||
2199 | /* If changes are for association, also apply parameters to each | ||
2200 | * transport. | ||
2041 | */ | 2201 | */ |
2042 | if (params.spp_pathmaxrxt) | 2202 | if (!trans && asoc) { |
2043 | trans->max_retrans = params.spp_pathmaxrxt; | 2203 | struct list_head *pos; |
2204 | |||
2205 | list_for_each(pos, &asoc->peer.transport_addr_list) { | ||
2206 | trans = list_entry(pos, struct sctp_transport, | ||
2207 | transports); | ||
2208 | sctp_apply_peer_addr_params(¶ms, trans, asoc, sp, | ||
2209 | hb_change, pmtud_change, | ||
2210 | sackdelay_change); | ||
2211 | } | ||
2212 | } | ||
2044 | 2213 | ||
2045 | return 0; | 2214 | return 0; |
2046 | } | 2215 | } |
@@ -2334,7 +2503,7 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optl | |||
2334 | /* Update the frag_point of the existing associations. */ | 2503 | /* Update the frag_point of the existing associations. */ |
2335 | list_for_each(pos, &(sp->ep->asocs)) { | 2504 | list_for_each(pos, &(sp->ep->asocs)) { |
2336 | asoc = list_entry(pos, struct sctp_association, asocs); | 2505 | asoc = list_entry(pos, struct sctp_association, asocs); |
2337 | asoc->frag_point = sctp_frag_point(sp, asoc->pmtu); | 2506 | asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu); |
2338 | } | 2507 | } |
2339 | 2508 | ||
2340 | return 0; | 2509 | return 0; |
@@ -2715,8 +2884,13 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
2715 | /* Default Peer Address Parameters. These defaults can | 2884 | /* Default Peer Address Parameters. These defaults can |
2716 | * be modified via SCTP_PEER_ADDR_PARAMS | 2885 | * be modified via SCTP_PEER_ADDR_PARAMS |
2717 | */ | 2886 | */ |
2718 | sp->paddrparam.spp_hbinterval = jiffies_to_msecs(sctp_hb_interval); | 2887 | sp->hbinterval = jiffies_to_msecs(sctp_hb_interval); |
2719 | sp->paddrparam.spp_pathmaxrxt = sctp_max_retrans_path; | 2888 | sp->pathmaxrxt = sctp_max_retrans_path; |
2889 | sp->pathmtu = 0; // allow default discovery | ||
2890 | sp->sackdelay = sctp_sack_timeout; | ||
2891 | sp->param_flags = SPP_HB_ENABLE | | ||
2892 | SPP_PMTUD_ENABLE | | ||
2893 | SPP_SACKDELAY_ENABLE; | ||
2720 | 2894 | ||
2721 | /* If enabled no SCTP message fragmentation will be performed. | 2895 | /* If enabled no SCTP message fragmentation will be performed. |
2722 | * Configure through SCTP_DISABLE_FRAGMENTS socket option. | 2896 | * Configure through SCTP_DISABLE_FRAGMENTS socket option. |
@@ -2865,7 +3039,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len, | |||
2865 | status.sstat_primary.spinfo_cwnd = transport->cwnd; | 3039 | status.sstat_primary.spinfo_cwnd = transport->cwnd; |
2866 | status.sstat_primary.spinfo_srtt = transport->srtt; | 3040 | status.sstat_primary.spinfo_srtt = transport->srtt; |
2867 | status.sstat_primary.spinfo_rto = jiffies_to_msecs(transport->rto); | 3041 | status.sstat_primary.spinfo_rto = jiffies_to_msecs(transport->rto); |
2868 | status.sstat_primary.spinfo_mtu = transport->pmtu; | 3042 | status.sstat_primary.spinfo_mtu = transport->pathmtu; |
2869 | 3043 | ||
2870 | if (status.sstat_primary.spinfo_state == SCTP_UNKNOWN) | 3044 | if (status.sstat_primary.spinfo_state == SCTP_UNKNOWN) |
2871 | status.sstat_primary.spinfo_state = SCTP_ACTIVE; | 3045 | status.sstat_primary.spinfo_state = SCTP_ACTIVE; |
@@ -2924,7 +3098,7 @@ static int sctp_getsockopt_peer_addr_info(struct sock *sk, int len, | |||
2924 | pinfo.spinfo_cwnd = transport->cwnd; | 3098 | pinfo.spinfo_cwnd = transport->cwnd; |
2925 | pinfo.spinfo_srtt = transport->srtt; | 3099 | pinfo.spinfo_srtt = transport->srtt; |
2926 | pinfo.spinfo_rto = jiffies_to_msecs(transport->rto); | 3100 | pinfo.spinfo_rto = jiffies_to_msecs(transport->rto); |
2927 | pinfo.spinfo_mtu = transport->pmtu; | 3101 | pinfo.spinfo_mtu = transport->pathmtu; |
2928 | 3102 | ||
2929 | if (pinfo.spinfo_state == SCTP_UNKNOWN) | 3103 | if (pinfo.spinfo_state == SCTP_UNKNOWN) |
2930 | pinfo.spinfo_state = SCTP_ACTIVE; | 3104 | pinfo.spinfo_state = SCTP_ACTIVE; |
@@ -3086,69 +3260,154 @@ out: | |||
3086 | * address's parameters: | 3260 | * address's parameters: |
3087 | * | 3261 | * |
3088 | * struct sctp_paddrparams { | 3262 | * struct sctp_paddrparams { |
3089 | * sctp_assoc_t spp_assoc_id; | 3263 | * sctp_assoc_t spp_assoc_id; |
3090 | * struct sockaddr_storage spp_address; | 3264 | * struct sockaddr_storage spp_address; |
3091 | * uint32_t spp_hbinterval; | 3265 | * uint32_t spp_hbinterval; |
3092 | * uint16_t spp_pathmaxrxt; | 3266 | * uint16_t spp_pathmaxrxt; |
3093 | * }; | 3267 | * uint32_t spp_pathmtu; |
3094 | * | 3268 | * uint32_t spp_sackdelay; |
3095 | * spp_assoc_id - (UDP style socket) This is filled in the application, | 3269 | * uint32_t spp_flags; |
3096 | * and identifies the association for this query. | 3270 | * }; |
3271 | * | ||
3272 | * spp_assoc_id - (one-to-many style socket) This is filled in the | ||
3273 | * application, and identifies the association for | ||
3274 | * this query. | ||
3097 | * spp_address - This specifies which address is of interest. | 3275 | * spp_address - This specifies which address is of interest. |
3098 | * spp_hbinterval - This contains the value of the heartbeat interval, | 3276 | * spp_hbinterval - This contains the value of the heartbeat interval, |
3099 | * in milliseconds. A value of 0, when modifying the | 3277 | * in milliseconds. If a value of zero |
3100 | * parameter, specifies that the heartbeat on this | 3278 | * is present in this field then no changes are to |
3101 | * address should be disabled. A value of UINT32_MAX | 3279 | * be made to this parameter. |
3102 | * (4294967295), when modifying the parameter, | ||
3103 | * specifies that a heartbeat should be sent | ||
3104 | * immediately to the peer address, and the current | ||
3105 | * interval should remain unchanged. | ||
3106 | * spp_pathmaxrxt - This contains the maximum number of | 3280 | * spp_pathmaxrxt - This contains the maximum number of |
3107 | * retransmissions before this address shall be | 3281 | * retransmissions before this address shall be |
3108 | * considered unreachable. | 3282 | * considered unreachable. If a value of zero |
3283 | * is present in this field then no changes are to | ||
3284 | * be made to this parameter. | ||
3285 | * spp_pathmtu - When Path MTU discovery is disabled the value | ||
3286 | * specified here will be the "fixed" path mtu. | ||
3287 | * Note that if the spp_address field is empty | ||
3288 | * then all associations on this address will | ||
3289 | * have this fixed path mtu set upon them. | ||
3290 | * | ||
3291 | * spp_sackdelay - When delayed sack is enabled, this value specifies | ||
3292 | * the number of milliseconds that sacks will be delayed | ||
3293 | * for. This value will apply to all addresses of an | ||
3294 | * association if the spp_address field is empty. Note | ||
3295 | * also, that if delayed sack is enabled and this | ||
3296 | * value is set to 0, no change is made to the last | ||
3297 | * recorded delayed sack timer value. | ||
3298 | * | ||
3299 | * spp_flags - These flags are used to control various features | ||
3300 | * on an association. The flag field may contain | ||
3301 | * zero or more of the following options. | ||
3302 | * | ||
3303 | * SPP_HB_ENABLE - Enable heartbeats on the | ||
3304 | * specified address. Note that if the address | ||
3305 | * field is empty all addresses for the association | ||
3306 | * have heartbeats enabled upon them. | ||
3307 | * | ||
3308 | * SPP_HB_DISABLE - Disable heartbeats on the | ||
3309 | * speicifed address. Note that if the address | ||
3310 | * field is empty all addresses for the association | ||
3311 | * will have their heartbeats disabled. Note also | ||
3312 | * that SPP_HB_ENABLE and SPP_HB_DISABLE are | ||
3313 | * mutually exclusive, only one of these two should | ||
3314 | * be specified. Enabling both fields will have | ||
3315 | * undetermined results. | ||
3316 | * | ||
3317 | * SPP_HB_DEMAND - Request a user initiated heartbeat | ||
3318 | * to be made immediately. | ||
3319 | * | ||
3320 | * SPP_PMTUD_ENABLE - This field will enable PMTU | ||
3321 | * discovery upon the specified address. Note that | ||
3322 | * if the address feild is empty then all addresses | ||
3323 | * on the association are effected. | ||
3324 | * | ||
3325 | * SPP_PMTUD_DISABLE - This field will disable PMTU | ||
3326 | * discovery upon the specified address. Note that | ||
3327 | * if the address feild is empty then all addresses | ||
3328 | * on the association are effected. Not also that | ||
3329 | * SPP_PMTUD_ENABLE and SPP_PMTUD_DISABLE are mutually | ||
3330 | * exclusive. Enabling both will have undetermined | ||
3331 | * results. | ||
3332 | * | ||
3333 | * SPP_SACKDELAY_ENABLE - Setting this flag turns | ||
3334 | * on delayed sack. The time specified in spp_sackdelay | ||
3335 | * is used to specify the sack delay for this address. Note | ||
3336 | * that if spp_address is empty then all addresses will | ||
3337 | * enable delayed sack and take on the sack delay | ||
3338 | * value specified in spp_sackdelay. | ||
3339 | * SPP_SACKDELAY_DISABLE - Setting this flag turns | ||
3340 | * off delayed sack. If the spp_address field is blank then | ||
3341 | * delayed sack is disabled for the entire association. Note | ||
3342 | * also that this field is mutually exclusive to | ||
3343 | * SPP_SACKDELAY_ENABLE, setting both will have undefined | ||
3344 | * results. | ||
3109 | */ | 3345 | */ |
3110 | static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len, | 3346 | static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len, |
3111 | char __user *optval, int __user *optlen) | 3347 | char __user *optval, int __user *optlen) |
3112 | { | 3348 | { |
3113 | struct sctp_paddrparams params; | 3349 | struct sctp_paddrparams params; |
3114 | struct sctp_transport *trans; | 3350 | struct sctp_transport *trans = NULL; |
3351 | struct sctp_association *asoc = NULL; | ||
3352 | struct sctp_sock *sp = sctp_sk(sk); | ||
3115 | 3353 | ||
3116 | if (len != sizeof(struct sctp_paddrparams)) | 3354 | if (len != sizeof(struct sctp_paddrparams)) |
3117 | return -EINVAL; | 3355 | return -EINVAL; |
3356 | |||
3118 | if (copy_from_user(¶ms, optval, len)) | 3357 | if (copy_from_user(¶ms, optval, len)) |
3119 | return -EFAULT; | 3358 | return -EFAULT; |
3120 | 3359 | ||
3121 | /* If no association id is specified retrieve the default value | 3360 | /* If an address other than INADDR_ANY is specified, and |
3122 | * for the endpoint that will be used for all future associations | 3361 | * no transport is found, then the request is invalid. |
3123 | */ | 3362 | */ |
3124 | if (!params.spp_assoc_id && | 3363 | if (!sctp_is_any(( union sctp_addr *)¶ms.spp_address)) { |
3125 | sctp_is_any(( union sctp_addr *)¶ms.spp_address)) { | 3364 | trans = sctp_addr_id2transport(sk, ¶ms.spp_address, |
3126 | params.spp_hbinterval = sctp_sk(sk)->paddrparam.spp_hbinterval; | 3365 | params.spp_assoc_id); |
3127 | params.spp_pathmaxrxt = sctp_sk(sk)->paddrparam.spp_pathmaxrxt; | 3366 | if (!trans) { |
3128 | 3367 | SCTP_DEBUG_PRINTK("Failed no transport\n"); | |
3129 | goto done; | 3368 | return -EINVAL; |
3369 | } | ||
3130 | } | 3370 | } |
3131 | 3371 | ||
3132 | trans = sctp_addr_id2transport(sk, ¶ms.spp_address, | 3372 | /* Get association, if assoc_id != 0 and the socket is a one |
3133 | params.spp_assoc_id); | 3373 | * to many style socket, and an association was not found, then |
3134 | if (!trans) | 3374 | * the id was invalid. |
3135 | return -EINVAL; | ||
3136 | |||
3137 | /* The value of the heartbeat interval, in milliseconds. A value of 0, | ||
3138 | * when modifying the parameter, specifies that the heartbeat on this | ||
3139 | * address should be disabled. | ||
3140 | */ | 3375 | */ |
3141 | if (!trans->hb_allowed) | 3376 | asoc = sctp_id2assoc(sk, params.spp_assoc_id); |
3142 | params.spp_hbinterval = 0; | 3377 | if (!asoc && params.spp_assoc_id && sctp_style(sk, UDP)) { |
3143 | else | 3378 | SCTP_DEBUG_PRINTK("Failed no association\n"); |
3144 | params.spp_hbinterval = jiffies_to_msecs(trans->hb_interval); | 3379 | return -EINVAL; |
3380 | } | ||
3145 | 3381 | ||
3146 | /* spp_pathmaxrxt contains the maximum number of retransmissions | 3382 | if (trans) { |
3147 | * before this address shall be considered unreachable. | 3383 | /* Fetch transport values. */ |
3148 | */ | 3384 | params.spp_hbinterval = jiffies_to_msecs(trans->hbinterval); |
3149 | params.spp_pathmaxrxt = trans->max_retrans; | 3385 | params.spp_pathmtu = trans->pathmtu; |
3386 | params.spp_pathmaxrxt = trans->pathmaxrxt; | ||
3387 | params.spp_sackdelay = jiffies_to_msecs(trans->sackdelay); | ||
3388 | |||
3389 | /*draft-11 doesn't say what to return in spp_flags*/ | ||
3390 | params.spp_flags = trans->param_flags; | ||
3391 | } else if (asoc) { | ||
3392 | /* Fetch association values. */ | ||
3393 | params.spp_hbinterval = jiffies_to_msecs(asoc->hbinterval); | ||
3394 | params.spp_pathmtu = asoc->pathmtu; | ||
3395 | params.spp_pathmaxrxt = asoc->pathmaxrxt; | ||
3396 | params.spp_sackdelay = jiffies_to_msecs(asoc->sackdelay); | ||
3397 | |||
3398 | /*draft-11 doesn't say what to return in spp_flags*/ | ||
3399 | params.spp_flags = asoc->param_flags; | ||
3400 | } else { | ||
3401 | /* Fetch socket values. */ | ||
3402 | params.spp_hbinterval = sp->hbinterval; | ||
3403 | params.spp_pathmtu = sp->pathmtu; | ||
3404 | params.spp_sackdelay = sp->sackdelay; | ||
3405 | params.spp_pathmaxrxt = sp->pathmaxrxt; | ||
3406 | |||
3407 | /*draft-11 doesn't say what to return in spp_flags*/ | ||
3408 | params.spp_flags = sp->param_flags; | ||
3409 | } | ||
3150 | 3410 | ||
3151 | done: | ||
3152 | if (copy_to_user(optval, ¶ms, len)) | 3411 | if (copy_to_user(optval, ¶ms, len)) |
3153 | return -EFAULT; | 3412 | return -EFAULT; |
3154 | 3413 | ||
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 268ddaf2dc0f..68d73e2dd155 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -86,10 +86,13 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, | |||
86 | peer->init_sent_count = 0; | 86 | peer->init_sent_count = 0; |
87 | 87 | ||
88 | peer->state = SCTP_ACTIVE; | 88 | peer->state = SCTP_ACTIVE; |
89 | peer->hb_allowed = 0; | 89 | peer->param_flags = SPP_HB_DISABLE | |
90 | SPP_PMTUD_ENABLE | | ||
91 | SPP_SACKDELAY_ENABLE; | ||
92 | peer->hbinterval = 0; | ||
90 | 93 | ||
91 | /* Initialize the default path max_retrans. */ | 94 | /* Initialize the default path max_retrans. */ |
92 | peer->max_retrans = sctp_max_retrans_path; | 95 | peer->pathmaxrxt = sctp_max_retrans_path; |
93 | peer->error_count = 0; | 96 | peer->error_count = 0; |
94 | 97 | ||
95 | INIT_LIST_HEAD(&peer->transmitted); | 98 | INIT_LIST_HEAD(&peer->transmitted); |
@@ -229,10 +232,10 @@ void sctp_transport_pmtu(struct sctp_transport *transport) | |||
229 | dst = transport->af_specific->get_dst(NULL, &transport->ipaddr, NULL); | 232 | dst = transport->af_specific->get_dst(NULL, &transport->ipaddr, NULL); |
230 | 233 | ||
231 | if (dst) { | 234 | if (dst) { |
232 | transport->pmtu = dst_mtu(dst); | 235 | transport->pathmtu = dst_mtu(dst); |
233 | dst_release(dst); | 236 | dst_release(dst); |
234 | } else | 237 | } else |
235 | transport->pmtu = SCTP_DEFAULT_MAXSEGMENT; | 238 | transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; |
236 | } | 239 | } |
237 | 240 | ||
238 | /* Caches the dst entry and source address for a transport's destination | 241 | /* Caches the dst entry and source address for a transport's destination |
@@ -254,8 +257,11 @@ void sctp_transport_route(struct sctp_transport *transport, | |||
254 | af->get_saddr(asoc, dst, daddr, &transport->saddr); | 257 | af->get_saddr(asoc, dst, daddr, &transport->saddr); |
255 | 258 | ||
256 | transport->dst = dst; | 259 | transport->dst = dst; |
260 | if ((transport->param_flags & SPP_PMTUD_DISABLE) && transport->pathmtu) { | ||
261 | return; | ||
262 | } | ||
257 | if (dst) { | 263 | if (dst) { |
258 | transport->pmtu = dst_mtu(dst); | 264 | transport->pathmtu = dst_mtu(dst); |
259 | 265 | ||
260 | /* Initialize sk->sk_rcv_saddr, if the transport is the | 266 | /* Initialize sk->sk_rcv_saddr, if the transport is the |
261 | * association's active path for getsockname(). | 267 | * association's active path for getsockname(). |
@@ -264,7 +270,7 @@ void sctp_transport_route(struct sctp_transport *transport, | |||
264 | opt->pf->af->to_sk_saddr(&transport->saddr, | 270 | opt->pf->af->to_sk_saddr(&transport->saddr, |
265 | asoc->base.sk); | 271 | asoc->base.sk); |
266 | } else | 272 | } else |
267 | transport->pmtu = SCTP_DEFAULT_MAXSEGMENT; | 273 | transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; |
268 | } | 274 | } |
269 | 275 | ||
270 | /* Hold a reference to a transport. */ | 276 | /* Hold a reference to a transport. */ |
@@ -369,7 +375,7 @@ void sctp_transport_raise_cwnd(struct sctp_transport *transport, | |||
369 | 375 | ||
370 | ssthresh = transport->ssthresh; | 376 | ssthresh = transport->ssthresh; |
371 | pba = transport->partial_bytes_acked; | 377 | pba = transport->partial_bytes_acked; |
372 | pmtu = transport->asoc->pmtu; | 378 | pmtu = transport->asoc->pathmtu; |
373 | 379 | ||
374 | if (cwnd <= ssthresh) { | 380 | if (cwnd <= ssthresh) { |
375 | /* RFC 2960 7.2.1, sctpimpguide-05 2.14.2 When cwnd is less | 381 | /* RFC 2960 7.2.1, sctpimpguide-05 2.14.2 When cwnd is less |
@@ -441,8 +447,8 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, | |||
441 | * partial_bytes_acked = 0 | 447 | * partial_bytes_acked = 0 |
442 | */ | 448 | */ |
443 | transport->ssthresh = max(transport->cwnd/2, | 449 | transport->ssthresh = max(transport->cwnd/2, |
444 | 4*transport->asoc->pmtu); | 450 | 4*transport->asoc->pathmtu); |
445 | transport->cwnd = transport->asoc->pmtu; | 451 | transport->cwnd = transport->asoc->pathmtu; |
446 | break; | 452 | break; |
447 | 453 | ||
448 | case SCTP_LOWER_CWND_FAST_RTX: | 454 | case SCTP_LOWER_CWND_FAST_RTX: |
@@ -459,7 +465,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, | |||
459 | * partial_bytes_acked = 0 | 465 | * partial_bytes_acked = 0 |
460 | */ | 466 | */ |
461 | transport->ssthresh = max(transport->cwnd/2, | 467 | transport->ssthresh = max(transport->cwnd/2, |
462 | 4*transport->asoc->pmtu); | 468 | 4*transport->asoc->pathmtu); |
463 | transport->cwnd = transport->ssthresh; | 469 | transport->cwnd = transport->ssthresh; |
464 | break; | 470 | break; |
465 | 471 | ||
@@ -479,7 +485,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, | |||
479 | if ((jiffies - transport->last_time_ecne_reduced) > | 485 | if ((jiffies - transport->last_time_ecne_reduced) > |
480 | transport->rtt) { | 486 | transport->rtt) { |
481 | transport->ssthresh = max(transport->cwnd/2, | 487 | transport->ssthresh = max(transport->cwnd/2, |
482 | 4*transport->asoc->pmtu); | 488 | 4*transport->asoc->pathmtu); |
483 | transport->cwnd = transport->ssthresh; | 489 | transport->cwnd = transport->ssthresh; |
484 | transport->last_time_ecne_reduced = jiffies; | 490 | transport->last_time_ecne_reduced = jiffies; |
485 | } | 491 | } |
@@ -496,7 +502,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, | |||
496 | */ | 502 | */ |
497 | if ((jiffies - transport->last_time_used) > transport->rto) | 503 | if ((jiffies - transport->last_time_used) > transport->rto) |
498 | transport->cwnd = max(transport->cwnd/2, | 504 | transport->cwnd = max(transport->cwnd/2, |
499 | 4*transport->asoc->pmtu); | 505 | 4*transport->asoc->pathmtu); |
500 | break; | 506 | break; |
501 | }; | 507 | }; |
502 | 508 | ||
@@ -511,7 +517,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, | |||
511 | unsigned long sctp_transport_timeout(struct sctp_transport *t) | 517 | unsigned long sctp_transport_timeout(struct sctp_transport *t) |
512 | { | 518 | { |
513 | unsigned long timeout; | 519 | unsigned long timeout; |
514 | timeout = t->hb_interval + t->rto + sctp_jitter(t->rto); | 520 | timeout = t->hbinterval + t->rto + sctp_jitter(t->rto); |
515 | timeout += jiffies; | 521 | timeout += jiffies; |
516 | return timeout; | 522 | return timeout; |
517 | } | 523 | } |