* Delete the address from the endpoint local address list. There is nothing * to be done if we are bound to all addresses */
| 5382 | * to be done if we are bound to all addresses |
| 5383 | */ |
| 5384 | void |
| 5385 | sctp_del_local_addr_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa) |
| 5386 | { |
| 5387 | struct sctp_laddr *laddr; |
| 5388 | int fnd; |
| 5389 | |
| 5390 | fnd = 0; |
| 5391 | if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { |
| 5392 | /* You are already bound to all. You have it already */ |
| 5393 | return; |
| 5394 | } |
| 5395 | LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { |
| 5396 | if (laddr->ifa == ifa) { |
| 5397 | fnd = 1; |
| 5398 | break; |
| 5399 | } |
| 5400 | } |
| 5401 | if (fnd && (inp->laddr_count < 2)) { |
| 5402 | /* can't delete unless there are at LEAST 2 addresses */ |
| 5403 | return; |
| 5404 | } |
| 5405 | if (fnd) { |
| 5406 | /* |
| 5407 | * clean up any use of this address go through our |
| 5408 | * associations and clear any last_used_address that match |
| 5409 | * this one for each assoc, see if a new primary_destination |
| 5410 | * is needed |
| 5411 | */ |
| 5412 | struct sctp_tcb *stcb; |
| 5413 | |
| 5414 | /* clean up "next_addr_touse" */ |
| 5415 | if (inp->next_addr_touse == laddr) |
| 5416 | /* delete this address */ |
| 5417 | inp->next_addr_touse = NULL; |
| 5418 | |
| 5419 | /* clean up "last_used_address" */ |
| 5420 | LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { |
| 5421 | struct sctp_nets *net; |
| 5422 | |
| 5423 | SCTP_TCB_LOCK(stcb); |
| 5424 | if (stcb->asoc.last_used_address == laddr) |
| 5425 | /* delete this address */ |
| 5426 | stcb->asoc.last_used_address = NULL; |
| 5427 | /* |
| 5428 | * Now spin through all the nets and purge any ref |
| 5429 | * to laddr |
| 5430 | */ |
| 5431 | TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { |
| 5432 | if (net->ro._s_addr == laddr->ifa) { |
| 5433 | /* Yep, purge src address selected */ |
| 5434 | RO_NHFREE(&net->ro); |
| 5435 | sctp_free_ifa(net->ro._s_addr); |
| 5436 | net->ro._s_addr = NULL; |
| 5437 | net->src_addr_selected = 0; |
| 5438 | } |
| 5439 | } |
| 5440 | SCTP_TCB_UNLOCK(stcb); |
| 5441 | } /* for each tcb */ |
no test coverage detected