| 4394 | } |
| 4395 | |
| 4396 | void |
| 4397 | sctp_remove_net(struct sctp_tcb *stcb, struct sctp_nets *net) |
| 4398 | { |
| 4399 | struct sctp_inpcb *inp; |
| 4400 | struct sctp_association *asoc; |
| 4401 | |
| 4402 | inp = stcb->sctp_ep; |
| 4403 | asoc = &stcb->asoc; |
| 4404 | asoc->numnets--; |
| 4405 | TAILQ_REMOVE(&asoc->nets, net, sctp_next); |
| 4406 | if (net == asoc->primary_destination) { |
| 4407 | /* Reset primary */ |
| 4408 | struct sctp_nets *lnet; |
| 4409 | |
| 4410 | lnet = TAILQ_FIRST(&asoc->nets); |
| 4411 | /* |
| 4412 | * Mobility adaptation Ideally, if deleted destination is |
| 4413 | * the primary, it becomes a fast retransmission trigger by |
| 4414 | * the subsequent SET PRIMARY. (by micchie) |
| 4415 | */ |
| 4416 | if (sctp_is_mobility_feature_on(stcb->sctp_ep, |
| 4417 | SCTP_MOBILITY_BASE) || |
| 4418 | sctp_is_mobility_feature_on(stcb->sctp_ep, |
| 4419 | SCTP_MOBILITY_FASTHANDOFF)) { |
| 4420 | SCTPDBG(SCTP_DEBUG_ASCONF1, "remove_net: primary dst is deleting\n"); |
| 4421 | if (asoc->deleted_primary != NULL) { |
| 4422 | SCTPDBG(SCTP_DEBUG_ASCONF1, "remove_net: deleted primary may be already stored\n"); |
| 4423 | goto out; |
| 4424 | } |
| 4425 | asoc->deleted_primary = net; |
| 4426 | atomic_add_int(&net->ref_count, 1); |
| 4427 | memset(&net->lastsa, 0, sizeof(net->lastsa)); |
| 4428 | memset(&net->lastsv, 0, sizeof(net->lastsv)); |
| 4429 | sctp_mobility_feature_on(stcb->sctp_ep, |
| 4430 | SCTP_MOBILITY_PRIM_DELETED); |
| 4431 | sctp_timer_start(SCTP_TIMER_TYPE_PRIM_DELETED, |
| 4432 | stcb->sctp_ep, stcb, NULL); |
| 4433 | } |
| 4434 | out: |
| 4435 | /* Try to find a confirmed primary */ |
| 4436 | asoc->primary_destination = sctp_find_alternate_net(stcb, lnet, 0); |
| 4437 | } |
| 4438 | if (net == asoc->last_data_chunk_from) { |
| 4439 | /* Reset primary */ |
| 4440 | asoc->last_data_chunk_from = TAILQ_FIRST(&asoc->nets); |
| 4441 | } |
| 4442 | if (net == asoc->last_control_chunk_from) { |
| 4443 | /* Clear net */ |
| 4444 | asoc->last_control_chunk_from = NULL; |
| 4445 | } |
| 4446 | if (net == asoc->last_net_cmt_send_started) { |
| 4447 | /* Clear net */ |
| 4448 | asoc->last_net_cmt_send_started = NULL; |
| 4449 | } |
| 4450 | if (net == stcb->asoc.alternate) { |
| 4451 | sctp_free_remote_addr(stcb->asoc.alternate); |
| 4452 | stcb->asoc.alternate = NULL; |
| 4453 | } |
no test coverage detected