diff options
Diffstat (limited to 'net/sctp/sm_sideeffect.c')
| -rw-r--r-- | net/sctp/sm_sideeffect.c | 27 | 
1 files changed, 27 insertions, 0 deletions
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 500886bda9b..d5ae450b6f0 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -51,6 +51,7 @@  #include <linux/types.h>  #include <linux/socket.h>  #include <linux/ip.h> +#include <linux/gfp.h>  #include <net/sock.h>  #include <net/sctp/sctp.h>  #include <net/sctp/sm.h> @@ -961,6 +962,29 @@ static int sctp_cmd_send_msg(struct sctp_association *asoc,  } +/* Sent the next ASCONF packet currently stored in the association. + * This happens after the ASCONF_ACK was succeffully processed. + */ +static void sctp_cmd_send_asconf(struct sctp_association *asoc) +{ +	/* Send the next asconf chunk from the addip chunk +	 * queue. +	 */ +	if (!list_empty(&asoc->addip_chunk_list)) { +		struct list_head *entry = asoc->addip_chunk_list.next; +		struct sctp_chunk *asconf = list_entry(entry, +						struct sctp_chunk, list); +		list_del_init(entry); + +		/* Hold the chunk until an ASCONF_ACK is received. */ +		sctp_chunk_hold(asconf); +		if (sctp_primitive_ASCONF(asoc, asconf)) +			sctp_chunk_free(asconf); +		else +			asoc->addip_last_asconf = asconf; +	} +} +  /* These three macros allow us to pull the debugging code out of the   * 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,  			}  			error = sctp_cmd_send_msg(asoc, cmd->obj.msg);  			break; +		case SCTP_CMD_SEND_NEXT_ASCONF: +			sctp_cmd_send_asconf(asoc); +			break;  		default:  			printk(KERN_WARNING "Impossible command: %u, %p\n",  			       cmd->verb, cmd->obj.ptr);  |