* delete all SAs for src/dst. Called from key_delete(). */
| 6053 | * delete all SAs for src/dst. Called from key_delete(). |
| 6054 | */ |
| 6055 | static int |
| 6056 | key_delete_all(struct socket *so, struct mbuf *m, |
| 6057 | const struct sadb_msghdr *mhp, struct secasindex *saidx) |
| 6058 | { |
| 6059 | struct secasvar_queue drainq; |
| 6060 | struct secashead *sah; |
| 6061 | struct secasvar *sav, *nextsav; |
| 6062 | |
| 6063 | TAILQ_INIT(&drainq); |
| 6064 | SAHTREE_WLOCK(); |
| 6065 | LIST_FOREACH(sah, SAHADDRHASH_HASH(saidx), addrhash) { |
| 6066 | if (key_cmpsaidx(&sah->saidx, saidx, CMP_HEAD) == 0) |
| 6067 | continue; |
| 6068 | /* Move all ALIVE SAs into drainq */ |
| 6069 | TAILQ_CONCAT(&drainq, &sah->savtree_alive, chain); |
| 6070 | } |
| 6071 | /* Unlink all queued SAs from SPI hash */ |
| 6072 | TAILQ_FOREACH(sav, &drainq, chain) { |
| 6073 | sav->state = SADB_SASTATE_DEAD; |
| 6074 | LIST_REMOVE(sav, spihash); |
| 6075 | } |
| 6076 | SAHTREE_WUNLOCK(); |
| 6077 | /* Now we can release reference for all SAs in drainq */ |
| 6078 | sav = TAILQ_FIRST(&drainq); |
| 6079 | while (sav != NULL) { |
| 6080 | KEYDBG(KEY_STAMP, |
| 6081 | printf("%s: SA(%p)\n", __func__, sav)); |
| 6082 | KEYDBG(KEY_DATA, kdebug_secasv(sav)); |
| 6083 | nextsav = TAILQ_NEXT(sav, chain); |
| 6084 | key_freesah(&sav->sah); /* release reference from SAV */ |
| 6085 | key_freesav(&sav); /* release last reference */ |
| 6086 | sav = nextsav; |
| 6087 | } |
| 6088 | |
| 6089 | { |
| 6090 | struct mbuf *n; |
| 6091 | struct sadb_msg *newmsg; |
| 6092 | |
| 6093 | /* create new sadb_msg to reply. */ |
| 6094 | n = key_gather_mbuf(m, mhp, 1, 3, SADB_EXT_RESERVED, |
| 6095 | SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST); |
| 6096 | if (!n) |
| 6097 | return key_senderror(so, m, ENOBUFS); |
| 6098 | |
| 6099 | if (n->m_len < sizeof(struct sadb_msg)) { |
| 6100 | n = m_pullup(n, sizeof(struct sadb_msg)); |
| 6101 | if (n == NULL) |
| 6102 | return key_senderror(so, m, ENOBUFS); |
| 6103 | } |
| 6104 | newmsg = mtod(n, struct sadb_msg *); |
| 6105 | newmsg->sadb_msg_errno = 0; |
| 6106 | newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len); |
| 6107 | |
| 6108 | m_freem(m); |
| 6109 | return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); |
| 6110 | } |
| 6111 | } |
| 6112 |
no test coverage detected