cleanup secasvar management; refcnt is key.c responsibility;

alloc/free is keydb.c responsibility.

Obtained from:	KAME
This commit is contained in:
Hajimu UMEMOTO 2003-11-02 10:49:47 +00:00
parent 02f4f60ad5
commit 9712142383
3 changed files with 66 additions and 99 deletions

View File

@ -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:
@ -2772,65 +2830,6 @@ key_newsav(m, mhp, sah, errp)
return newsav;
}
/*
* 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:

View File

@ -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);
}

View File

@ -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 *);