* Delete all alive SAs for corresponding xform. * Larval SAs have not initialized tdb_xform, so it is safe to leave them * here when xform disappears. */
| 6116 | * here when xform disappears. |
| 6117 | */ |
| 6118 | void |
| 6119 | key_delete_xform(const struct xformsw *xsp) |
| 6120 | { |
| 6121 | struct secasvar_queue drainq; |
| 6122 | struct secashead *sah; |
| 6123 | struct secasvar *sav, *nextsav; |
| 6124 | |
| 6125 | TAILQ_INIT(&drainq); |
| 6126 | SAHTREE_WLOCK(); |
| 6127 | TAILQ_FOREACH(sah, &V_sahtree, chain) { |
| 6128 | sav = TAILQ_FIRST(&sah->savtree_alive); |
| 6129 | if (sav == NULL) |
| 6130 | continue; |
| 6131 | if (sav->tdb_xform != xsp) |
| 6132 | continue; |
| 6133 | /* |
| 6134 | * It is supposed that all SAs in the chain are related to |
| 6135 | * one xform. |
| 6136 | */ |
| 6137 | TAILQ_CONCAT(&drainq, &sah->savtree_alive, chain); |
| 6138 | } |
| 6139 | /* Unlink all queued SAs from SPI hash */ |
| 6140 | TAILQ_FOREACH(sav, &drainq, chain) { |
| 6141 | sav->state = SADB_SASTATE_DEAD; |
| 6142 | LIST_REMOVE(sav, spihash); |
| 6143 | } |
| 6144 | SAHTREE_WUNLOCK(); |
| 6145 | |
| 6146 | /* Now we can release reference for all SAs in drainq */ |
| 6147 | sav = TAILQ_FIRST(&drainq); |
| 6148 | while (sav != NULL) { |
| 6149 | KEYDBG(KEY_STAMP, |
| 6150 | printf("%s: SA(%p)\n", __func__, sav)); |
| 6151 | KEYDBG(KEY_DATA, kdebug_secasv(sav)); |
| 6152 | nextsav = TAILQ_NEXT(sav, chain); |
| 6153 | key_freesah(&sav->sah); /* release reference from SAV */ |
| 6154 | key_freesav(&sav); /* release last reference */ |
| 6155 | sav = nextsav; |
| 6156 | } |
| 6157 | } |
| 6158 | |
| 6159 | /* |
| 6160 | * SADB_GET processing |
no test coverage detected