diff options
Diffstat (limited to 'net/sctp/sm_sideeffect.c')
-rw-r--r-- | net/sctp/sm_sideeffect.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 4e4ca65cd320..d5ae450b6f02 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> |
@@ -475,7 +476,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc, | |||
475 | * used to provide an upper bound to this doubling operation. | 476 | * used to provide an upper bound to this doubling operation. |
476 | * | 477 | * |
477 | * Special Case: the first HB doesn't trigger exponential backoff. | 478 | * Special Case: the first HB doesn't trigger exponential backoff. |
478 | * The first unacknowleged HB triggers it. We do this with a flag | 479 | * The first unacknowledged HB triggers it. We do this with a flag |
479 | * that indicates that we have an outstanding HB. | 480 | * that indicates that we have an outstanding HB. |
480 | */ | 481 | */ |
481 | if (!is_hb || transport->hb_sent) { | 482 | if (!is_hb || transport->hb_sent) { |
@@ -961,6 +962,29 @@ static int sctp_cmd_send_msg(struct sctp_association *asoc, | |||
961 | } | 962 | } |
962 | 963 | ||
963 | 964 | ||
965 | /* Sent the next ASCONF packet currently stored in the association. | ||
966 | * This happens after the ASCONF_ACK was succeffully processed. | ||
967 | */ | ||
968 | static void sctp_cmd_send_asconf(struct sctp_association *asoc) | ||
969 | { | ||
970 | /* Send the next asconf chunk from the addip chunk | ||
971 | * queue. | ||
972 | */ | ||
973 | if (!list_empty(&asoc->addip_chunk_list)) { | ||
974 | struct list_head *entry = asoc->addip_chunk_list.next; | ||
975 | struct sctp_chunk *asconf = list_entry(entry, | ||
976 | struct sctp_chunk, list); | ||
977 | list_del_init(entry); | ||
978 | |||
979 | /* Hold the chunk until an ASCONF_ACK is received. */ | ||
980 | sctp_chunk_hold(asconf); | ||
981 | if (sctp_primitive_ASCONF(asoc, asconf)) | ||
982 | sctp_chunk_free(asconf); | ||
983 | else | ||
984 | asoc->addip_last_asconf = asconf; | ||
985 | } | ||
986 | } | ||
987 | |||
964 | 988 | ||
965 | /* These three macros allow us to pull the debugging code out of the | 989 | /* These three macros allow us to pull the debugging code out of the |
966 | * main flow of sctp_do_sm() to keep attention focused on the real | 990 | * main flow of sctp_do_sm() to keep attention focused on the real |
@@ -1616,6 +1640,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1616 | } | 1640 | } |
1617 | error = sctp_cmd_send_msg(asoc, cmd->obj.msg); | 1641 | error = sctp_cmd_send_msg(asoc, cmd->obj.msg); |
1618 | break; | 1642 | break; |
1643 | case SCTP_CMD_SEND_NEXT_ASCONF: | ||
1644 | sctp_cmd_send_asconf(asoc); | ||
1645 | break; | ||
1619 | default: | 1646 | default: |
1620 | printk(KERN_WARNING "Impossible command: %u, %p\n", | 1647 | printk(KERN_WARNING "Impossible command: %u, %p\n", |
1621 | cmd->verb, cmd->obj.ptr); | 1648 | cmd->verb, cmd->obj.ptr); |