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); |
