Index: sys/netipsec/key.c =================================================================== --- sys/netipsec/key.c +++ sys/netipsec/key.c @@ -1373,7 +1373,6 @@ static void key_unlinksav(struct secasvar *sav) { - struct secashead *sah; KEYDBG(KEY_STAMP, printf("%s: SA(%p)\n", __func__, sav)); @@ -1394,11 +1393,8 @@ /* Unlink from SPI hash */ LIST_REMOVE(sav, spihash); sav->state = SADB_SASTATE_DEAD; - sah = sav->sah; SAHTREE_WUNLOCK(); key_freesav(&sav); - /* Since we are unlinked, release reference to SAH */ - key_freesah(&sah); } /* %%% SPD management */ @@ -3130,6 +3126,8 @@ IPSEC_ASSERT(sav->refcnt == 0, ("reference count %u > 0", sav->refcnt)); + key_freesah(&sav->sah); + /* * SA must be unlinked from the chain and hashtbl. * If SA was cloned, we leave all fields untouched, @@ -4667,7 +4665,6 @@ while (sav != NULL) { nextsav = LIST_NEXT(sav, drainq); key_expire(sav, 1); - key_freesah(&sav->sah); /* release reference from SAV */ key_freesav(&sav); /* release extra reference */ key_freesav(&sav); /* release last reference */ sav = nextsav; @@ -4683,7 +4680,6 @@ sav = LIST_FIRST(&drainq); while (sav != NULL) { nextsav = LIST_NEXT(sav, drainq); - key_freesah(&sav->sah); /* release reference from SAV */ key_freesav(&sav); /* release extra reference */ key_freesav(&sav); /* release last reference */ sav = nextsav; @@ -5211,8 +5207,8 @@ __func__)); return (EINVAL); } - /* We hold reference to SA, thus SAH will be referenced too. */ sah = sav->sah; + SAH_ADDREF(sah); isnew = 0; } @@ -5311,8 +5307,7 @@ key_sendup_mbuf(so, n, KEY_SENDUP_ALL); return (0); fail: - if (isnew != 0) - key_freesah(&sah); + key_freesah(&sah); if (newsav != NULL) { if (newsav->natt != NULL) free(newsav->natt, M_IPSEC_MISC); @@ -6128,7 +6123,6 @@ printf("%s: SA(%p)\n", __func__, sav)); KEYDBG(KEY_DATA, kdebug_secasv(sav)); nextsav = TAILQ_NEXT(sav, chain); - key_freesah(&sav->sah); /* release reference from SAV */ key_freesav(&sav); /* release last reference */ sav = nextsav; } @@ -6197,7 +6191,6 @@ printf("%s: SA(%p)\n", __func__, sav)); KEYDBG(KEY_DATA, kdebug_secasv(sav)); nextsav = TAILQ_NEXT(sav, chain); - key_freesah(&sav->sah); /* release reference from SAV */ key_freesav(&sav); /* release last reference */ sav = nextsav; } @@ -7466,7 +7459,6 @@ nextsav = TAILQ_NEXT(sav, chain); TAILQ_REMOVE(&sah->savtree_larval, sav, chain); key_freesav(&sav); /* release last reference */ - key_freesah(&sah); /* release reference from SAV */ sav = nextsav; } sav = TAILQ_FIRST(&sah->savtree_alive); @@ -7474,7 +7466,6 @@ nextsav = TAILQ_NEXT(sav, chain); TAILQ_REMOVE(&sah->savtree_alive, sav, chain); key_freesav(&sav); /* release last reference */ - key_freesah(&sah); /* release reference from SAV */ sav = nextsav; } nextsah = TAILQ_NEXT(sah, chain);