* SADB_FLUSH processing * receive * * from the ikmpd, and free all entries in secastree. * and send, * * to the ikmpd. * NOTE: to do is only marking SADB_SASTATE_DEAD. * * m will always be freed. */
| 7445 | * m will always be freed. |
| 7446 | */ |
| 7447 | static int |
| 7448 | key_flush(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) |
| 7449 | { |
| 7450 | struct secashead_queue flushq; |
| 7451 | struct sadb_msg *newmsg; |
| 7452 | struct secashead *sah, *nextsah; |
| 7453 | struct secasvar *sav; |
| 7454 | uint8_t proto; |
| 7455 | int i; |
| 7456 | |
| 7457 | IPSEC_ASSERT(so != NULL, ("null socket")); |
| 7458 | IPSEC_ASSERT(mhp != NULL, ("null msghdr")); |
| 7459 | IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); |
| 7460 | |
| 7461 | /* map satype to proto */ |
| 7462 | if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { |
| 7463 | ipseclog((LOG_DEBUG, "%s: invalid satype is passed.\n", |
| 7464 | __func__)); |
| 7465 | return key_senderror(so, m, EINVAL); |
| 7466 | } |
| 7467 | KEYDBG(KEY_STAMP, |
| 7468 | printf("%s: proto %u\n", __func__, proto)); |
| 7469 | |
| 7470 | TAILQ_INIT(&flushq); |
| 7471 | if (proto == IPSEC_PROTO_ANY) { |
| 7472 | /* no SATYPE specified, i.e. flushing all SA. */ |
| 7473 | SAHTREE_WLOCK(); |
| 7474 | /* Move all SAHs into flushq */ |
| 7475 | TAILQ_CONCAT(&flushq, &V_sahtree, chain); |
| 7476 | /* Flush all buckets in SPI hash */ |
| 7477 | for (i = 0; i < V_savhash_mask + 1; i++) |
| 7478 | LIST_INIT(&V_savhashtbl[i]); |
| 7479 | /* Flush all buckets in SAHADDRHASH */ |
| 7480 | for (i = 0; i < V_sahaddrhash_mask + 1; i++) |
| 7481 | LIST_INIT(&V_sahaddrhashtbl[i]); |
| 7482 | /* Mark all SAHs as unlinked */ |
| 7483 | TAILQ_FOREACH(sah, &flushq, chain) { |
| 7484 | sah->state = SADB_SASTATE_DEAD; |
| 7485 | /* |
| 7486 | * Callout handler makes its job using |
| 7487 | * RLOCK and drain queues. In case, when this |
| 7488 | * function will be called just before it |
| 7489 | * acquires WLOCK, we need to mark SAs as |
| 7490 | * unlinked to prevent second unlink. |
| 7491 | */ |
| 7492 | TAILQ_FOREACH(sav, &sah->savtree_larval, chain) { |
| 7493 | sav->state = SADB_SASTATE_DEAD; |
| 7494 | } |
| 7495 | TAILQ_FOREACH(sav, &sah->savtree_alive, chain) { |
| 7496 | sav->state = SADB_SASTATE_DEAD; |
| 7497 | } |
| 7498 | } |
| 7499 | SAHTREE_WUNLOCK(); |
| 7500 | } else { |
| 7501 | SAHTREE_WLOCK(); |
| 7502 | sah = TAILQ_FIRST(&V_sahtree); |
| 7503 | while (sah != NULL) { |
| 7504 | IPSEC_ASSERT(sah->state != SADB_SASTATE_DEAD, |
nothing calls this directly
no test coverage detected