* SADB_SPDFLUSH processing * receive * * from the user, and free all entries in secpctree. * and send, * * to the user. * NOTE: what to do is only marking SADB_SASTATE_DEAD. * * m will always be freed. */
| 2482 | * m will always be freed. |
| 2483 | */ |
| 2484 | static int |
| 2485 | key_spdflush(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) |
| 2486 | { |
| 2487 | struct secpolicy_queue drainq; |
| 2488 | struct sadb_msg *newmsg; |
| 2489 | struct secpolicy *sp, *nextsp; |
| 2490 | u_int dir; |
| 2491 | |
| 2492 | IPSEC_ASSERT(so != NULL, ("null socket")); |
| 2493 | IPSEC_ASSERT(m != NULL, ("null mbuf")); |
| 2494 | IPSEC_ASSERT(mhp != NULL, ("null msghdr")); |
| 2495 | IPSEC_ASSERT(mhp->msg != NULL, ("null msg")); |
| 2496 | |
| 2497 | if (m->m_len != PFKEY_ALIGN8(sizeof(struct sadb_msg))) |
| 2498 | return key_senderror(so, m, EINVAL); |
| 2499 | |
| 2500 | TAILQ_INIT(&drainq); |
| 2501 | SPTREE_WLOCK(); |
| 2502 | for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { |
| 2503 | TAILQ_CONCAT(&drainq, &V_sptree[dir], chain); |
| 2504 | } |
| 2505 | /* |
| 2506 | * We need to set state to DEAD for each policy to be sure, |
| 2507 | * that another thread won't try to unlink it. |
| 2508 | * Also remove SP from sphash. |
| 2509 | */ |
| 2510 | TAILQ_FOREACH(sp, &drainq, chain) { |
| 2511 | sp->state = IPSEC_SPSTATE_DEAD; |
| 2512 | LIST_REMOVE(sp, idhash); |
| 2513 | } |
| 2514 | V_sp_genid++; |
| 2515 | V_spd_size = 0; |
| 2516 | SPTREE_WUNLOCK(); |
| 2517 | if (SPDCACHE_ENABLED()) |
| 2518 | spdcache_clear(); |
| 2519 | sp = TAILQ_FIRST(&drainq); |
| 2520 | while (sp != NULL) { |
| 2521 | nextsp = TAILQ_NEXT(sp, chain); |
| 2522 | key_freesp(&sp); |
| 2523 | sp = nextsp; |
| 2524 | } |
| 2525 | |
| 2526 | if (sizeof(struct sadb_msg) > m->m_len + M_TRAILINGSPACE(m)) { |
| 2527 | ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); |
| 2528 | return key_senderror(so, m, ENOBUFS); |
| 2529 | } |
| 2530 | |
| 2531 | if (m->m_next) |
| 2532 | m_freem(m->m_next); |
| 2533 | m->m_next = NULL; |
| 2534 | m->m_pkthdr.len = m->m_len = PFKEY_ALIGN8(sizeof(struct sadb_msg)); |
| 2535 | newmsg = mtod(m, struct sadb_msg *); |
| 2536 | newmsg->sadb_msg_errno = 0; |
| 2537 | newmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len); |
| 2538 | |
| 2539 | return key_sendup_mbuf(so, m, KEY_SENDUP_ALL); |
| 2540 | } |
| 2541 |
nothing calls this directly
no test coverage detected