diff options
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/sm_sideeffect.c | 29 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 35 |
2 files changed, 27 insertions, 37 deletions
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 1d143bc3f73d..4aa03588f87b 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -1112,32 +1112,6 @@ static void sctp_cmd_send_msg(struct sctp_association *asoc, | |||
1112 | } | 1112 | } |
1113 | 1113 | ||
1114 | 1114 | ||
1115 | /* Sent the next ASCONF packet currently stored in the association. | ||
1116 | * This happens after the ASCONF_ACK was succeffully processed. | ||
1117 | */ | ||
1118 | static void sctp_cmd_send_asconf(struct sctp_association *asoc) | ||
1119 | { | ||
1120 | struct net *net = sock_net(asoc->base.sk); | ||
1121 | |||
1122 | /* Send the next asconf chunk from the addip chunk | ||
1123 | * queue. | ||
1124 | */ | ||
1125 | if (!list_empty(&asoc->addip_chunk_list)) { | ||
1126 | struct list_head *entry = asoc->addip_chunk_list.next; | ||
1127 | struct sctp_chunk *asconf = list_entry(entry, | ||
1128 | struct sctp_chunk, list); | ||
1129 | list_del_init(entry); | ||
1130 | |||
1131 | /* Hold the chunk until an ASCONF_ACK is received. */ | ||
1132 | sctp_chunk_hold(asconf); | ||
1133 | if (sctp_primitive_ASCONF(net, asoc, asconf)) | ||
1134 | sctp_chunk_free(asconf); | ||
1135 | else | ||
1136 | asoc->addip_last_asconf = asconf; | ||
1137 | } | ||
1138 | } | ||
1139 | |||
1140 | |||
1141 | /* These three macros allow us to pull the debugging code out of the | 1115 | /* These three macros allow us to pull the debugging code out of the |
1142 | * main flow of sctp_do_sm() to keep attention focused on the real | 1116 | * main flow of sctp_do_sm() to keep attention focused on the real |
1143 | * functionality there. | 1117 | * functionality there. |
@@ -1783,9 +1757,6 @@ static int sctp_cmd_interpreter(enum sctp_event_type event_type, | |||
1783 | } | 1757 | } |
1784 | sctp_cmd_send_msg(asoc, cmd->obj.msg, gfp); | 1758 | sctp_cmd_send_msg(asoc, cmd->obj.msg, gfp); |
1785 | break; | 1759 | break; |
1786 | case SCTP_CMD_SEND_NEXT_ASCONF: | ||
1787 | sctp_cmd_send_asconf(asoc); | ||
1788 | break; | ||
1789 | case SCTP_CMD_PURGE_ASCONF_QUEUE: | 1760 | case SCTP_CMD_PURGE_ASCONF_QUEUE: |
1790 | sctp_asconf_queue_teardown(asoc); | 1761 | sctp_asconf_queue_teardown(asoc); |
1791 | break; | 1762 | break; |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 7dfc34b28f4f..e3f4abe6134e 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -3824,6 +3824,29 @@ enum sctp_disposition sctp_sf_do_asconf(struct net *net, | |||
3824 | return SCTP_DISPOSITION_CONSUME; | 3824 | return SCTP_DISPOSITION_CONSUME; |
3825 | } | 3825 | } |
3826 | 3826 | ||
3827 | static enum sctp_disposition sctp_send_next_asconf( | ||
3828 | struct net *net, | ||
3829 | const struct sctp_endpoint *ep, | ||
3830 | struct sctp_association *asoc, | ||
3831 | const union sctp_subtype type, | ||
3832 | struct sctp_cmd_seq *commands) | ||
3833 | { | ||
3834 | struct sctp_chunk *asconf; | ||
3835 | struct list_head *entry; | ||
3836 | |||
3837 | if (list_empty(&asoc->addip_chunk_list)) | ||
3838 | return SCTP_DISPOSITION_CONSUME; | ||
3839 | |||
3840 | entry = asoc->addip_chunk_list.next; | ||
3841 | asconf = list_entry(entry, struct sctp_chunk, list); | ||
3842 | |||
3843 | list_del_init(entry); | ||
3844 | sctp_chunk_hold(asconf); | ||
3845 | asoc->addip_last_asconf = asconf; | ||
3846 | |||
3847 | return sctp_sf_do_prm_asconf(net, ep, asoc, type, asconf, commands); | ||
3848 | } | ||
3849 | |||
3827 | /* | 3850 | /* |
3828 | * ADDIP Section 4.3 General rules for address manipulation | 3851 | * ADDIP Section 4.3 General rules for address manipulation |
3829 | * When building TLV parameters for the ASCONF Chunk that will add or | 3852 | * When building TLV parameters for the ASCONF Chunk that will add or |
@@ -3915,14 +3938,10 @@ enum sctp_disposition sctp_sf_do_asconf_ack(struct net *net, | |||
3915 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); | 3938 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); |
3916 | 3939 | ||
3917 | if (!sctp_process_asconf_ack((struct sctp_association *)asoc, | 3940 | if (!sctp_process_asconf_ack((struct sctp_association *)asoc, |
3918 | asconf_ack)) { | 3941 | asconf_ack)) |
3919 | /* Successfully processed ASCONF_ACK. We can | 3942 | return sctp_send_next_asconf(net, ep, |
3920 | * release the next asconf if we have one. | 3943 | (struct sctp_association *)asoc, |
3921 | */ | 3944 | type, commands); |
3922 | sctp_add_cmd_sf(commands, SCTP_CMD_SEND_NEXT_ASCONF, | ||
3923 | SCTP_NULL()); | ||
3924 | return SCTP_DISPOSITION_CONSUME; | ||
3925 | } | ||
3926 | 3945 | ||
3927 | abort = sctp_make_abort(asoc, asconf_ack, | 3946 | abort = sctp_make_abort(asoc, asconf_ack, |
3928 | sizeof(struct sctp_errhdr)); | 3947 | sizeof(struct sctp_errhdr)); |