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.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 4c5bed9af4e3..eb1f42f45fdd 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -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{
@@ -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
@@ -1617,6 +1675,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1617 } 1675 }
1618 error = sctp_cmd_send_msg(asoc, cmd->obj.msg); 1676 error = sctp_cmd_send_msg(asoc, cmd->obj.msg);
1619 break; 1677 break;
1678 case SCTP_CMD_SEND_NEXT_ASCONF:
1679 sctp_cmd_send_asconf(asoc);
1680 break;
1620 default: 1681 default:
1621 printk(KERN_WARNING "Impossible command: %u, %p\n", 1682 printk(KERN_WARNING "Impossible command: %u, %p\n",
1622 cmd->verb, cmd->obj.ptr); 1683 cmd->verb, cmd->obj.ptr);