diff options
Diffstat (limited to 'net/sctp/sm_sideeffect.c')
-rw-r--r-- | net/sctp/sm_sideeffect.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 4c5bed9af4e3..3b7230ef77c2 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -697,11 +697,15 @@ static void sctp_cmd_setup_t2(sctp_cmd_seq_t *cmds, | |||
697 | { | 697 | { |
698 | struct sctp_transport *t; | 698 | struct sctp_transport *t; |
699 | 699 | ||
700 | t = sctp_assoc_choose_alter_transport(asoc, | 700 | if (chunk->transport) |
701 | t = chunk->transport; | ||
702 | else { | ||
703 | t = sctp_assoc_choose_alter_transport(asoc, | ||
701 | asoc->shutdown_last_sent_to); | 704 | asoc->shutdown_last_sent_to); |
705 | chunk->transport = t; | ||
706 | } | ||
702 | asoc->shutdown_last_sent_to = t; | 707 | asoc->shutdown_last_sent_to = t; |
703 | asoc->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = t->rto; | 708 | asoc->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = t->rto; |
704 | chunk->transport = t; | ||
705 | } | 709 | } |
706 | 710 | ||
707 | /* Helper function to change the state of an association. */ | 711 | /* Helper function to change the state of an association. */ |
@@ -962,6 +966,29 @@ static int sctp_cmd_send_msg(struct sctp_association *asoc, | |||
962 | } | 966 | } |
963 | 967 | ||
964 | 968 | ||
969 | /* Sent the next ASCONF packet currently stored in the association. | ||
970 | * This happens after the ASCONF_ACK was succeffully processed. | ||
971 | */ | ||
972 | static void sctp_cmd_send_asconf(struct sctp_association *asoc) | ||
973 | { | ||
974 | /* Send the next asconf chunk from the addip chunk | ||
975 | * queue. | ||
976 | */ | ||
977 | if (!list_empty(&asoc->addip_chunk_list)) { | ||
978 | struct list_head *entry = asoc->addip_chunk_list.next; | ||
979 | struct sctp_chunk *asconf = list_entry(entry, | ||
980 | struct sctp_chunk, list); | ||
981 | list_del_init(entry); | ||
982 | |||
983 | /* Hold the chunk until an ASCONF_ACK is received. */ | ||
984 | sctp_chunk_hold(asconf); | ||
985 | if (sctp_primitive_ASCONF(asoc, asconf)) | ||
986 | sctp_chunk_free(asconf); | ||
987 | else | ||
988 | asoc->addip_last_asconf = asconf; | ||
989 | } | ||
990 | } | ||
991 | |||
965 | 992 | ||
966 | /* These three macros allow us to pull the debugging code out of the | 993 | /* 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 | 994 | * main flow of sctp_do_sm() to keep attention focused on the real |
@@ -1617,6 +1644,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1617 | } | 1644 | } |
1618 | error = sctp_cmd_send_msg(asoc, cmd->obj.msg); | 1645 | error = sctp_cmd_send_msg(asoc, cmd->obj.msg); |
1619 | break; | 1646 | break; |
1647 | case SCTP_CMD_SEND_NEXT_ASCONF: | ||
1648 | sctp_cmd_send_asconf(asoc); | ||
1649 | break; | ||
1620 | default: | 1650 | default: |
1621 | printk(KERN_WARNING "Impossible command: %u, %p\n", | 1651 | printk(KERN_WARNING "Impossible command: %u, %p\n", |
1622 | cmd->verb, cmd->obj.ptr); | 1652 | cmd->verb, cmd->obj.ptr); |