aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/sm_sideeffect.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/sm_sideeffect.c')
-rw-r--r--net/sctp/sm_sideeffect.c71
1 files changed, 67 insertions, 4 deletions
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index efa516b47e81..eb1f42f45fdd 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -51,6 +51,7 @@
51#include <linux/types.h> 51#include <linux/types.h>
52#include <linux/socket.h> 52#include <linux/socket.h>
53#include <linux/ip.h> 53#include <linux/ip.h>
54#include <linux/gfp.h>
54#include <net/sock.h> 55#include <net/sock.h>
55#include <net/sctp/sctp.h> 56#include <net/sctp/sctp.h>
56#include <net/sctp/sm.h> 57#include <net/sctp/sm.h>
@@ -217,8 +218,7 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force,
217 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, 218 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
218 SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); 219 SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
219 } else { 220 } else {
220 if (asoc->a_rwnd > asoc->rwnd) 221 asoc->a_rwnd = asoc->rwnd;
221 asoc->a_rwnd = asoc->rwnd;
222 sack = sctp_make_sack(asoc); 222 sack = sctp_make_sack(asoc);
223 if (!sack) 223 if (!sack)
224 goto nomem; 224 goto nomem;
@@ -397,6 +397,41 @@ out_unlock:
397 sctp_transport_put(transport); 397 sctp_transport_put(transport);
398} 398}
399 399
400/* Handle the timeout of the ICMP protocol unreachable timer. Trigger
401 * the correct state machine transition that will close the association.
402 */
403void sctp_generate_proto_unreach_event(unsigned long data)
404{
405 struct sctp_transport *transport = (struct sctp_transport *) data;
406 struct sctp_association *asoc = transport->asoc;
407
408 sctp_bh_lock_sock(asoc->base.sk);
409 if (sock_owned_by_user(asoc->base.sk)) {
410 SCTP_DEBUG_PRINTK("%s:Sock is busy.\n", __func__);
411
412 /* Try again later. */
413 if (!mod_timer(&transport->proto_unreach_timer,
414 jiffies + (HZ/20)))
415 sctp_association_hold(asoc);
416 goto out_unlock;
417 }
418
419 /* Is this structure just waiting around for us to actually
420 * get destroyed?
421 */
422 if (asoc->base.dead)
423 goto out_unlock;
424
425 sctp_do_sm(SCTP_EVENT_T_OTHER,
426 SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
427 asoc->state, asoc->ep, asoc, transport, GFP_ATOMIC);
428
429out_unlock:
430 sctp_bh_unlock_sock(asoc->base.sk);
431 sctp_association_put(asoc);
432}
433
434
400/* Inject a SACK Timeout event into the state machine. */ 435/* Inject a SACK Timeout event into the state machine. */
401static void sctp_generate_sack_event(unsigned long data) 436static void sctp_generate_sack_event(unsigned long data)
402{ 437{
@@ -476,7 +511,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
476 * used to provide an upper bound to this doubling operation. 511 * used to provide an upper bound to this doubling operation.
477 * 512 *
478 * Special Case: the first HB doesn't trigger exponential backoff. 513 * Special Case: the first HB doesn't trigger exponential backoff.
479 * The first unacknowleged HB triggers it. We do this with a flag 514 * The first unacknowledged HB triggers it. We do this with a flag
480 * that indicates that we have an outstanding HB. 515 * that indicates that we have an outstanding HB.
481 */ 516 */
482 if (!is_hb || transport->hb_sent) { 517 if (!is_hb || transport->hb_sent) {
@@ -718,7 +753,7 @@ static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds,
718 753
719 if (sctp_style(sk, TCP)) { 754 if (sctp_style(sk, TCP)) {
720 /* Change the sk->sk_state of a TCP-style socket that has 755 /* Change the sk->sk_state of a TCP-style socket that has
721 * sucessfully completed a connect() call. 756 * successfully completed a connect() call.
722 */ 757 */
723 if (sctp_state(asoc, ESTABLISHED) && sctp_sstate(sk, CLOSED)) 758 if (sctp_state(asoc, ESTABLISHED) && sctp_sstate(sk, CLOSED))
724 sk->sk_state = SCTP_SS_ESTABLISHED; 759 sk->sk_state = SCTP_SS_ESTABLISHED;
@@ -962,6 +997,29 @@ static int sctp_cmd_send_msg(struct sctp_association *asoc,
962} 997}
963 998
964 999
1000/* Sent the next ASCONF packet currently stored in the association.
1001 * This happens after the ASCONF_ACK was succeffully processed.
1002 */
1003static void sctp_cmd_send_asconf(struct sctp_association *asoc)
1004{
1005 /* Send the next asconf chunk from the addip chunk
1006 * queue.
1007 */
1008 if (!list_empty(&asoc->addip_chunk_list)) {
1009 struct list_head *entry = asoc->addip_chunk_list.next;
1010 struct sctp_chunk *asconf = list_entry(entry,
1011 struct sctp_chunk, list);
1012 list_del_init(entry);
1013
1014 /* Hold the chunk until an ASCONF_ACK is received. */
1015 sctp_chunk_hold(asconf);
1016 if (sctp_primitive_ASCONF(asoc, asconf))
1017 sctp_chunk_free(asconf);
1018 else
1019 asoc->addip_last_asconf = asconf;
1020 }
1021}
1022
965 1023
966/* These three macros allow us to pull the debugging code out of the 1024/* These three macros allow us to pull the debugging code out of the
967 * main flow of sctp_do_sm() to keep attention focused on the real 1025 * main flow of sctp_do_sm() to keep attention focused on the real
@@ -1417,6 +1475,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1417 asoc->init_last_sent_to = t; 1475 asoc->init_last_sent_to = t;
1418 chunk->transport = t; 1476 chunk->transport = t;
1419 t->init_sent_count++; 1477 t->init_sent_count++;
1478 /* Set the new transport as primary */
1479 sctp_assoc_set_primary(asoc, t);
1420 break; 1480 break;
1421 1481
1422 case SCTP_CMD_INIT_RESTART: 1482 case SCTP_CMD_INIT_RESTART:
@@ -1615,6 +1675,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1615 } 1675 }
1616 error = sctp_cmd_send_msg(asoc, cmd->obj.msg); 1676 error = sctp_cmd_send_msg(asoc, cmd->obj.msg);
1617 break; 1677 break;
1678 case SCTP_CMD_SEND_NEXT_ASCONF:
1679 sctp_cmd_send_asconf(asoc);
1680 break;
1618 default: 1681 default:
1619 printk(KERN_WARNING "Impossible command: %u, %p\n", 1682 printk(KERN_WARNING "Impossible command: %u, %p\n",
1620 cmd->verb, cmd->obj.ptr); 1683 cmd->verb, cmd->obj.ptr);