diff options
-rw-r--r-- | sys/netkey/key.c | 131 | ||||
-rw-r--r-- | sys/netkey/keydb.c | 31 | ||||
-rw-r--r-- | sys/netkey/keydb.h | 3 |
3 files changed, 66 insertions, 99 deletions
diff --git a/sys/netkey/key.c b/sys/netkey/key.c index e7b04aa..c91febe 100644 --- a/sys/netkey/key.c +++ b/sys/netkey/key.c @@ -123,7 +123,7 @@ __FBSDID("$FreeBSD$"); * referenced from SA header. * - SAs that are in DEAD state will have (total external reference) * in reference count field. they are ready to be freed. reference from - * SA header will be removed in key_delsav(), when the reference count + * SA header will be removed in keydb_delsecasvar(), when the reference count * field hits 0 (= no external reference other than from SA header. */ @@ -368,6 +368,7 @@ struct sadb_msghdr { static struct secasvar *key_allocsa_policy(struct secasindex *); static void key_freesp_so(struct secpolicy **); static struct secasvar *key_do_allocsa_policy(struct secashead *, u_int); +static void key_delsav(struct secasvar *); static void key_delsp(struct secpolicy *); static struct secpolicy *key_getsp(struct secpolicyindex *); static struct secpolicy *key_getspbyid(u_int32_t); @@ -395,7 +396,6 @@ static struct secashead *key_newsah(struct secasindex *); static void key_delsah(struct secashead *); static struct secasvar *key_newsav(struct mbuf *, const struct sadb_msghdr *, struct secashead *, int *); -static void key_delsav(struct secasvar *); static struct secashead *key_getsah(struct secasindex *); static struct secasvar *key_checkspidup(struct secasindex *, u_int32_t); static struct secasvar *key_getsavbyspi(struct secashead *, u_int32_t); @@ -1179,8 +1179,67 @@ key_freesav(sav) printf("DP freesav cause refcnt--:%d SA:%p SPI %u\n", sav->refcnt, sav, (u_int32_t)ntohl(sav->spi))); - if (sav->refcnt == 0) - key_delsav(sav); + if (sav->refcnt > 0) + return; + + key_delsav(sav); +} + +/* + * free() SA variable entry. + */ +static void +key_delsav(sav) + struct secasvar *sav; +{ + /* sanity check */ + if (sav == NULL) + panic("key_delsav: NULL pointer is passed."); + + if (sav->refcnt > 0) + panic("key_delsav: called with positive refcnt"); + + /* remove from SA header */ + if (__LIST_CHAINED(sav)) + LIST_REMOVE(sav, chain); + + if (sav->key_auth != NULL) { + bzero(_KEYBUF(sav->key_auth), _KEYLEN(sav->key_auth)); + KFREE(sav->key_auth); + sav->key_auth = NULL; + } + if (sav->key_enc != NULL) { + bzero(_KEYBUF(sav->key_enc), _KEYLEN(sav->key_enc)); + KFREE(sav->key_enc); + sav->key_enc = NULL; + } + if (sav->sched) { + bzero(sav->sched, sav->schedlen); + KFREE(sav->sched); + sav->sched = NULL; + } + if (sav->replay != NULL) { + keydb_delsecreplay(sav->replay); + sav->replay = NULL; + } + if (sav->lft_c != NULL) { + KFREE(sav->lft_c); + sav->lft_c = NULL; + } + if (sav->lft_h != NULL) { + KFREE(sav->lft_h); + sav->lft_h = NULL; + } + if (sav->lft_s != NULL) { + KFREE(sav->lft_s); + sav->lft_s = NULL; + } + if (sav->iv != NULL) { + KFREE(sav->iv); + sav->iv = NULL; + } + + keydb_delsecasvar(sav); return; } @@ -1202,7 +1261,7 @@ key_delsp(sp) sp->state = IPSEC_SPSTATE_DEAD; if (sp->refcnt > 0) - return; /* can't free */ + panic("key_delsp: called with positive refcnt"); s = splnet(); /*called from softclock()*/ /* remove from SP index */ @@ -2704,13 +2763,12 @@ key_newsav(m, mhp, sah, errp) if (m == NULL || mhp == NULL || mhp->msg == NULL || sah == NULL) panic("key_newsa: NULL pointer is passed."); - KMALLOC(newsav, struct secasvar *, sizeof(struct secasvar)); + newsav = keydb_newsecasvar(); if (newsav == NULL) { ipseclog((LOG_DEBUG, "key_newsa: No more memory.\n")); *errp = ENOBUFS; return NULL; } - bzero((caddr_t)newsav, sizeof(struct secasvar)); switch (mhp->msg->sadb_msg_type) { case SADB_GETSPI: @@ -2773,65 +2831,6 @@ key_newsav(m, mhp, sah, errp) } /* - * free() SA variable entry. - */ -static void -key_delsav(sav) - struct secasvar *sav; -{ - /* sanity check */ - if (sav == NULL) - panic("key_delsav: NULL pointer is passed."); - - if (sav->refcnt > 0) - return; /* can't free */ - - /* remove from SA header */ - if (__LIST_CHAINED(sav)) - LIST_REMOVE(sav, chain); - - if (sav->key_auth != NULL) { - bzero(_KEYBUF(sav->key_auth), _KEYLEN(sav->key_auth)); - KFREE(sav->key_auth); - sav->key_auth = NULL; - } - if (sav->key_enc != NULL) { - bzero(_KEYBUF(sav->key_enc), _KEYLEN(sav->key_enc)); - KFREE(sav->key_enc); - sav->key_enc = NULL; - } - if (sav->sched) { - bzero(sav->sched, sav->schedlen); - KFREE(sav->sched); - sav->sched = NULL; - } - if (sav->replay != NULL) { - keydb_delsecreplay(sav->replay); - sav->replay = NULL; - } - if (sav->lft_c != NULL) { - KFREE(sav->lft_c); - sav->lft_c = NULL; - } - if (sav->lft_h != NULL) { - KFREE(sav->lft_h); - sav->lft_h = NULL; - } - if (sav->lft_s != NULL) { - KFREE(sav->lft_s); - sav->lft_s = NULL; - } - if (sav->iv != NULL) { - KFREE(sav->iv); - sav->iv = NULL; - } - - KFREE(sav); - - return; -} - -/* * search SAD. * OUT: * NULL : not found diff --git a/sys/netkey/keydb.c b/sys/netkey/keydb.c index 1ca71f0..309b512 100644 --- a/sys/netkey/keydb.c +++ b/sys/netkey/keydb.c @@ -57,8 +57,6 @@ __FBSDID("$FreeBSD$"); MALLOC_DEFINE(M_SECA, "key mgmt", "security associations, key management"); -static void keydb_delsecasvar(struct secasvar *); - /* * secpolicy management */ @@ -120,43 +118,14 @@ keydb_newsecasvar() if (!p) return p; bzero(p, sizeof(*p)); - p->refcnt = 1; return p; } void -keydb_refsecasvar(p) - struct secasvar *p; -{ - int s; - - s = splnet(); - p->refcnt++; - splx(s); -} - -void -keydb_freesecasvar(p) - struct secasvar *p; -{ - int s; - - s = splnet(); - p->refcnt--; - /* negative refcnt will cause panic intentionally */ - if (p->refcnt <= 0) - keydb_delsecasvar(p); - splx(s); -} - -static void keydb_delsecasvar(p) struct secasvar *p; { - if (p->refcnt) - panic("keydb_delsecasvar called with refcnt != 0"); - free(p, M_SECA); } diff --git a/sys/netkey/keydb.h b/sys/netkey/keydb.h index 0690ec8..0fce183 100644 --- a/sys/netkey/keydb.h +++ b/sys/netkey/keydb.h @@ -150,8 +150,7 @@ extern struct secashead *keydb_newsecashead(void); extern void keydb_delsecashead(struct secashead *); /* secasvar */ extern struct secasvar *keydb_newsecasvar(void); -extern void keydb_refsecasvar(struct secasvar *); -extern void keydb_freesecasvar(struct secasvar *); +extern void keydb_delsecasvar(struct secasvar *); /* secreplay */ extern struct secreplay *keydb_newsecreplay(size_t); extern void keydb_delsecreplay(struct secreplay *); |