Correctly detect the case where the last address is removed.

MFC after: 3 days
This commit is contained in:
Michael Tuexen 2015-06-14 22:14:00 +00:00
parent 4369c82dc6
commit 790a758db8

View File

@ -1328,6 +1328,7 @@ sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
{
uint32_t status;
int pending_delete_queued = 0;
int last;
/* see if peer supports ASCONF */
if (stcb->asoc.asconf_supported == 0) {
@ -1337,15 +1338,21 @@ sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
* if this is deleting the last address from the assoc, mark it as
* pending.
*/
if ((type == SCTP_DEL_IP_ADDRESS) && !stcb->asoc.asconf_del_pending &&
(sctp_local_addr_count(stcb) < 2)) {
/* set the pending delete info only */
stcb->asoc.asconf_del_pending = 1;
stcb->asoc.asconf_addr_del_pending = ifa;
atomic_add_int(&ifa->refcount, 1);
SCTPDBG(SCTP_DEBUG_ASCONF2,
"asconf_queue_add: mark delete last address pending\n");
return (-1);
if ((type == SCTP_DEL_IP_ADDRESS) && !stcb->asoc.asconf_del_pending) {
if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
last = (sctp_local_addr_count(stcb) == 0);
} else {
last = (sctp_local_addr_count(stcb) == 1);
}
if (last) {
/* set the pending delete info only */
stcb->asoc.asconf_del_pending = 1;
stcb->asoc.asconf_addr_del_pending = ifa;
atomic_add_int(&ifa->refcount, 1);
SCTPDBG(SCTP_DEBUG_ASCONF2,
"asconf_queue_add: mark delete last address pending\n");
return (-1);
}
}
/* queue an asconf parameter */
status = sctp_asconf_queue_mgmt(stcb, ifa, type);