diff options
author | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1999-05-14 23:36:22 +0000 |
---|---|---|
committer | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1999-05-14 23:36:22 +0000 |
commit | 80d37d4a76e48037997eefe5ca18b7f795ecec23 (patch) | |
tree | 1a3bd00bd4ebe5da48daf5179f06be5b3d5f0005 /sys | |
parent | 7a72d8171dfa72f742eaa892e879c4eeb4f54334 (diff) |
A new scalable IPsec SA expiration model.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/pfkeyv2.c | 17 | ||||
-rw-r--r-- | sys/netinet/ip_ah.c | 25 | ||||
-rw-r--r-- | sys/netinet/ip_esp.c | 25 | ||||
-rw-r--r-- | sys/netinet/ip_ipsp.c | 229 | ||||
-rw-r--r-- | sys/netinet/ip_ipsp.h | 38 | ||||
-rw-r--r-- | sys/netinet/ip_output.c | 32 |
6 files changed, 132 insertions, 234 deletions
diff --git a/sys/net/pfkeyv2.c b/sys/net/pfkeyv2.c index bf0948766bd..767ad1936da 100644 --- a/sys/net/pfkeyv2.c +++ b/sys/net/pfkeyv2.c @@ -222,8 +222,6 @@ export_sa(void **p, struct tdb *tdb) void import_lifetime(struct tdb *tdb, struct sadb_lifetime *sadb_lifetime, int type) { - struct expiration *exp; - if (!sadb_lifetime) return; @@ -243,12 +241,6 @@ import_lifetime(struct tdb *tdb, struct sadb_lifetime *sadb_lifetime, int type) if ((tdb->tdb_exp_timeout = sadb_lifetime->sadb_lifetime_addtime) != 0) { tdb->tdb_flags |= TDBF_TIMER; tdb->tdb_exp_timeout += time.tv_sec; - exp = get_expiration(); - bcopy(&tdb->tdb_dst, &exp->exp_dst, SA_LEN(&tdb->tdb_dst.sa)); - exp->exp_spi = tdb->tdb_spi; - exp->exp_sproto = tdb->tdb_sproto; - exp->exp_timeout = tdb->tdb_exp_timeout; - put_expiration(exp); } else tdb->tdb_flags &= ~TDBF_TIMER; @@ -275,12 +267,6 @@ import_lifetime(struct tdb *tdb, struct sadb_lifetime *sadb_lifetime, int type) sadb_lifetime->sadb_lifetime_addtime) != 0) { tdb->tdb_flags |= TDBF_SOFT_TIMER; tdb->tdb_soft_timeout += time.tv_sec; - exp = get_expiration(); - bcopy(&tdb->tdb_dst, &exp->exp_dst, SA_LEN(&tdb->tdb_dst.sa)); - exp->exp_spi = tdb->tdb_spi; - exp->exp_sproto = tdb->tdb_sproto; - exp->exp_timeout = tdb->tdb_soft_timeout; - put_expiration(exp); } else tdb->tdb_flags &= ~TDBF_SOFT_TIMER; @@ -298,6 +284,9 @@ import_lifetime(struct tdb *tdb, struct sadb_lifetime *sadb_lifetime, int type) tdb->tdb_established = sadb_lifetime->sadb_lifetime_addtime; tdb->tdb_first_use = sadb_lifetime->sadb_lifetime_usetime; } + + /* Setup/update our position in the expiration queue. */ + tdb_expiration(tdb, 0); } void diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c index 5ae21da75fe..b2b2e347729 100644 --- a/sys/netinet/ip_ah.c +++ b/sys/netinet/ip_ah.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ah.c,v 1.21 1999/04/11 19:41:36 niklas Exp $ */ +/* $OpenBSD: ip_ah.c,v 1.22 1999/05/14 23:36:16 niklas Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), @@ -101,7 +101,6 @@ ah_input(m, va_alist) union sockaddr_union sunion; struct ifqueue *ifq = NULL; struct ah_old *ahp, ahn; - struct expiration *exp; struct ip *ipo, ipn; struct tdb *tdbp; int s; @@ -180,27 +179,7 @@ ah_input(m, va_alist) if (tdbp->tdb_first_use == 0) { tdbp->tdb_first_use = time.tv_sec; - - if (tdbp->tdb_flags & TDBF_FIRSTUSE) - { - exp = get_expiration(); - bcopy(&tdbp->tdb_dst, &exp->exp_dst, SA_LEN(&tdbp->tdb_dst.sa)); - exp->exp_spi = tdbp->tdb_spi; - exp->exp_sproto = tdbp->tdb_sproto; - exp->exp_timeout = tdbp->tdb_first_use + tdbp->tdb_exp_first_use; - put_expiration(exp); - } - - if ((tdbp->tdb_flags & TDBF_SOFT_FIRSTUSE) && - (tdbp->tdb_soft_first_use <= tdbp->tdb_exp_first_use)) - { - exp = get_expiration(); - bcopy(&tdbp->tdb_dst, &exp->exp_dst, SA_LEN(&tdbp->tdb_dst.sa)); - exp->exp_spi = tdbp->tdb_spi; - exp->exp_sproto = tdbp->tdb_sproto; - exp->exp_timeout = tdbp->tdb_first_use + tdbp->tdb_soft_first_use; - put_expiration(exp); - } + tdb_expiration(tdbp, 0); } ipn = *ipo; diff --git a/sys/netinet/ip_esp.c b/sys/netinet/ip_esp.c index a09c76481e4..609cd7b883a 100644 --- a/sys/netinet/ip_esp.c +++ b/sys/netinet/ip_esp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_esp.c,v 1.21 1999/04/11 19:41:37 niklas Exp $ */ +/* $OpenBSD: ip_esp.c,v 1.22 1999/05/14 23:36:17 niklas Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), @@ -100,7 +100,6 @@ esp_input(m, va_alist) int iphlen; union sockaddr_union sunion; struct ifqueue *ifq = NULL; - struct expiration *exp; struct ip *ipo, ipn; struct tdb *tdbp; u_int32_t spi; @@ -179,27 +178,7 @@ esp_input(m, va_alist) if (tdbp->tdb_first_use == 0) { tdbp->tdb_first_use = time.tv_sec; - - if (tdbp->tdb_flags & TDBF_FIRSTUSE) - { - exp = get_expiration(); - bcopy(&tdbp->tdb_dst, &exp->exp_dst, SA_LEN(&tdbp->tdb_dst.sa)); - exp->exp_spi = tdbp->tdb_spi; - exp->exp_sproto = tdbp->tdb_sproto; - exp->exp_timeout = tdbp->tdb_first_use + tdbp->tdb_exp_first_use; - put_expiration(exp); - } - - if ((tdbp->tdb_flags & TDBF_SOFT_FIRSTUSE) && - (tdbp->tdb_soft_first_use <= tdbp->tdb_exp_first_use)) - { - exp = get_expiration(); - bcopy(&tdbp->tdb_dst, &exp->exp_dst, SA_LEN(&tdbp->tdb_dst.sa)); - exp->exp_spi = tdbp->tdb_spi; - exp->exp_sproto = tdbp->tdb_sproto; - exp->exp_timeout = tdbp->tdb_first_use + tdbp->tdb_soft_first_use; - put_expiration(exp); - } + tdb_expiration(tdbp, 0); } ipn = *ipo; diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c index 48bc289fc26..0dca0bc9f39 100644 --- a/sys/netinet/ip_ipsp.c +++ b/sys/netinet/ip_ipsp.c @@ -1,9 +1,10 @@ -/* $OpenBSD: ip_ipsp.c,v 1.40 1999/04/12 03:17:09 deraadt Exp $ */ +/* $OpenBSD: ip_ipsp.c,v 1.41 1999/05/14 23:36:18 niklas Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), - * Angelos D. Keromytis (kermit@csd.uch.gr) and - * Niels Provos (provos@physnet.uni-hamburg.de). + * Angelos D. Keromytis (kermit@csd.uch.gr), + * Niels Provos (provos@physnet.uni-hamburg.de) and + * Niklas Hallqvist (niklas@appli.se). * * This code was written by John Ioannidis for BSD/OS in Athens, Greece, * in November 1995. @@ -14,11 +15,12 @@ * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis * and Niels Provos. * - * Additional features in 1999 by Angelos D. Keromytis. + * Additional features in 1999 by Angelos D. Keromytis and Niklas Hallqvist. * - * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis, + * Copyright (c) 1995, 1996, 1997, 1998, 1999 by John Ioannidis, * Angelos D. Keromytis and Niels Provos. - * + * Copyright (c) 1999 Niklas Hallqvist. + * * Permission to use, copy, and modify this software without fee * is hereby granted, provided that this entire notice is included in * all copies of any software which is or includes a copy or @@ -90,6 +92,10 @@ extern int encdebug; int ipsec_in_use = 0; u_int32_t kernfs_epoch = 0; +struct expclusterlist_head expclusterlist = + TAILQ_HEAD_INITIALIZER(expclusterlist); +struct explist_head explist = LIST_HEAD_INITIALIZER(explist); + u_int8_t hmac_ipad_buffer[64] = { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, @@ -420,73 +426,15 @@ get_flow(void) return flow; } -struct expiration * -get_expiration(void) -{ - struct expiration *exp; - - MALLOC(exp, struct expiration *, sizeof(struct expiration), M_TDB, - M_WAITOK); - - bzero(exp, sizeof(struct expiration)); - - return exp; -} - void -cleanup_expirations(union sockaddr_union *dst, u_int32_t spi, u_int8_t sproto) -{ - struct expiration *exp, *nexp; - - for (exp = explist; exp; exp = (exp ? exp->exp_next : explist)) - if (!bcmp(&exp->exp_dst, dst, SA_LEN(&dst->sa)) && - (exp->exp_spi == spi) && (exp->exp_sproto == sproto)) - { - /* Link previous to next */ - if (exp->exp_prev == (struct expiration *) NULL) - explist = exp->exp_next; - else - exp->exp_prev->exp_next = exp->exp_next; - - /* Link next (if it exists) to previous */ - if (exp->exp_next != (struct expiration *) NULL) - exp->exp_next->exp_prev = exp->exp_prev; - - nexp = exp; - exp = exp->exp_prev; - FREE(nexp, M_TDB); - } -} - -void handle_expirations(void *arg) { - struct expiration *exp; struct tdb *tdb; - if (explist == (struct expiration *) NULL) - return; - - while (1) + for (tdb = LIST_FIRST(&explist); + tdb && tdb->tdb_timeout <= time.tv_sec; + tdb = LIST_FIRST(&explist)) { - exp = explist; - - if (exp == (struct expiration *) NULL) - return; - else - if (exp->exp_timeout > time.tv_sec) - break; - - /* Advance pointer */ - explist = explist->exp_next; - if (explist) - explist->exp_prev = NULL; - - tdb = gettdb(exp->exp_spi, &exp->exp_dst, exp->exp_sproto); - free(exp, M_TDB); - if (tdb == (struct tdb *) NULL) - continue; /* TDB is gone, ignore this */ - /* Hard expirations first */ if ((tdb->tdb_flags & TDBF_TIMER) && (tdb->tdb_exp_timeout <= time.tv_sec)) @@ -510,6 +458,7 @@ handle_expirations(void *arg) { pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT); tdb->tdb_flags &= ~TDBF_SOFT_TIMER; + tdb_expiration(tdb, 1); } else if ((tdb->tdb_flags & TDBF_SOFT_FIRSTUSE) && @@ -518,79 +467,101 @@ handle_expirations(void *arg) { pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT); tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE; + tdb_expiration(tdb, 1); } } - if (explist) + /* If any tdb is left on the expiration queue, set the timer. */ + if (tdb) timeout(handle_expirations, (void *) NULL, - hz * (explist->exp_timeout - time.tv_sec)); + hz * (tdb->tdb_timeout - time.tv_sec)); } +/* + * Ensure the tdb is in the right place in the expiration list. + */ void -put_expiration(struct expiration *exp) +tdb_expiration(struct tdb *tdb, int early) { - struct expiration *expt; - int reschedflag = 0; - - if (exp == (struct expiration *) NULL) + u_int64_t next_timeout = 0; + struct tdb *t; + + /* Find the earliest expiration. */ + if ((tdb->tdb_flags & TDBF_FIRSTUSE) && tdb->tdb_first_use != 0 && + (next_timeout == 0 || + next_timeout > tdb->tdb_first_use + tdb->tdb_exp_first_use)) + next_timeout = tdb->tdb_first_use + tdb->tdb_exp_first_use; + if ((tdb->tdb_flags & TDBF_SOFT_FIRSTUSE) && tdb->tdb_first_use != 0 && + (next_timeout == 0 || + next_timeout > tdb->tdb_first_use + tdb->tdb_soft_first_use)) + next_timeout = tdb->tdb_first_use + tdb->tdb_soft_first_use; + if ((tdb->tdb_flags & TDBF_TIMER) && + (next_timeout == 0 || next_timeout > tdb->tdb_exp_timeout)) + next_timeout = tdb->tdb_exp_timeout; + if ((tdb->tdb_flags & TDBF_SOFT_TIMER) && + (next_timeout == 0 || next_timeout > tdb->tdb_soft_timeout)) + next_timeout = tdb->tdb_soft_timeout; + + /* No change? */ + if (next_timeout == tdb->tdb_timeout) + return; + + /* Our old position, if any, is not relevant anymore. */ + if (tdb->tdb_timeout != 0) { - DPRINTF(("put_expiration(): NULL argument\n")); - return; + if (tdb->tdb_expnext.tqe_prev) + { + if (LIST_NEXT(tdb, tdb_explink) && + tdb->tdb_timeout == LIST_NEXT(tdb, tdb_explink)->tdb_timeout) + TAILQ_INSERT_BEFORE(tdb, LIST_NEXT(tdb, tdb_explink), + tdb_expnext); + TAILQ_REMOVE(&expclusterlist, tdb, tdb_expnext); + tdb->tdb_expnext.tqe_prev = NULL; + } + LIST_REMOVE(tdb, tdb_explink); } - - if (explist == (struct expiration *) NULL) + + if (next_timeout == 0) + return; + + /* + * Search fron-to-back if we believe we will end up early, otherwise + * back-to-front. + */ + tdb->tdb_timeout = next_timeout; + for (t = (early ? TAILQ_FIRST(&expclusterlist) : + TAILQ_LAST(&expclusterlist, expclusterlist_head)); + t && (early ? (t->tdb_timeout <= next_timeout) : + (t->tdb_timeout > next_timeout)); + t = (early ? TAILQ_NEXT(t, tdb_expnext) : + TAILQ_PREV(t, expclusterlist_head, tdb_expnext))) + ; + if (early ? t == TAILQ_FIRST(&expclusterlist) : !t) { - explist = exp; - reschedflag = 1; + /* + * We are to become the first expiration, remove old timer, if any. + */ + if (TAILQ_FIRST(&expclusterlist)) + untimeout(handle_expirations, (void *) NULL); + TAILQ_INSERT_HEAD(&expclusterlist, tdb, tdb_expnext); + LIST_INSERT_HEAD(&explist, tdb, tdb_explink); } else - if (explist->exp_timeout > exp->exp_timeout) - { - exp->exp_next = explist; - explist->exp_prev = exp; - explist = exp; - reschedflag = 2; - } - else - { - for (expt = explist; expt->exp_next; expt = expt->exp_next) - if (expt->exp_next->exp_timeout > exp->exp_timeout) - { - expt->exp_next->exp_prev = exp; - exp->exp_next = expt->exp_next; - expt->exp_next = exp; - exp->exp_prev = expt; - break; - } - - if (expt->exp_next == (struct expiration *) NULL) - { - expt->exp_next = exp; - exp->exp_prev = expt; - } - } - - switch (reschedflag) { - case 1: - timeout(handle_expirations, (void *) NULL, - hz * (explist->exp_timeout - time.tv_sec)); - break; - - case 2: - untimeout(handle_expirations, (void *) NULL); - timeout(handle_expirations, (void *) NULL, - hz * (explist->exp_timeout - time.tv_sec)); - break; - - default: - break; + if (early) + t = (t ? TAILQ_PREV(t, expclusterlist_head, tdb_expnext) : + TAILQ_LAST(&expclusterlist, expclusterlist_head)); + if (t->tdb_timeout < next_timeout) + TAILQ_INSERT_AFTER(&expclusterlist, t, tdb, tdb_expnext); + LIST_INSERT_AFTER(t, tdb, tdb_explink); } + timeout(handle_expirations, (void *) NULL, + hz * (next_timeout - time.tv_sec)); } struct flow * find_flow(union sockaddr_union *src, union sockaddr_union *srcmask, - union sockaddr_union * dst, union sockaddr_union *dstmask, + union sockaddr_union *dst, union sockaddr_union *dstmask, u_int8_t proto, struct tdb *tdb) { struct flow *flow; @@ -745,9 +716,19 @@ tdb_delete(struct tdb *tdbp, int delchain) if (tdbp->tdb_bind_out) TAILQ_REMOVE(&tdbp->tdb_bind_out->tdb_bind_in, tdbp, tdb_bind_in_next); - /* removal of a larval SA should not remove the mature SA's expirations */ - if ((tdbp->tdb_flags & TDBF_INVALID) == 0) - cleanup_expirations(&tdbp->tdb_dst, tdbp->tdb_spi, tdbp->tdb_sproto); + if (tdbp->tdb_timeout != 0) + { + if (tdbp->tdb_expnext.tqe_prev) + { + if (LIST_NEXT(tdbp, tdb_explink) && + tdbp->tdb_timeout == LIST_NEXT(tdbp, tdb_explink)->tdb_timeout) + TAILQ_INSERT_BEFORE(tdbp, LIST_NEXT(tdbp, tdb_explink), + tdb_expnext); + TAILQ_REMOVE(&expclusterlist, tdbp, tdb_expnext); + tdbp->tdb_expnext.tqe_prev = NULL; + } + LIST_REMOVE(tdbp, tdb_explink); + } if (tdbp->tdb_srcid) FREE(tdbp->tdb_srcid, M_XDATA); diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h index d30f3e3fd24..931f32a0ba3 100644 --- a/sys/netinet/ip_ipsp.h +++ b/sys/netinet/ip_ipsp.h @@ -1,9 +1,10 @@ -/* $OpenBSD: ip_ipsp.h,v 1.30 1999/05/11 22:57:17 niklas Exp $ */ +/* $OpenBSD: ip_ipsp.h,v 1.31 1999/05/14 23:36:21 niklas Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), - * Angelos D. Keromytis (kermit@csd.uch.gr) and - * Niels Provos (provos@physnet.uni-hamburg.de). + * Angelos D. Keromytis (kermit@csd.uch.gr), + * Niels Provos (provos@physnet.uni-hamburg.de) and + * Niklas Hallqvist (niklas@appli.se). * * This code was written by John Ioannidis for BSD/OS in Athens, Greece, * in November 1995. @@ -14,11 +15,12 @@ * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis * and Niels Provos. * - * Additional features in 1999 by Angelos D. Keromytis. + * Additional features in 1999 by Angelos D. Keromytis and Niklas Hallqvist. * - * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis, + * Copyright (c) 1995, 1996, 1997, 1998, 1999 by John Ioannidis, * Angelos D. Keromytis and Niels Provos. - * + * Copyright (c) 1999 Niklas Hallqvist. + * * Permission to use, copy, and modify this software without fee * is hereby granted, provided that this entire notice is included in * all copies of any software which is or includes a copy or @@ -180,16 +182,6 @@ struct route_enc { struct sockaddr_encap re_dst; }; -struct expiration -{ - u_int32_t exp_timeout; - union sockaddr_union exp_dst; - u_int32_t exp_spi; - u_int8_t exp_sproto; - struct expiration *exp_next; - struct expiration *exp_prev; -}; - struct flow { struct flow *flow_next; /* Next in flow chain */ @@ -228,6 +220,9 @@ struct tdb /* tunnel descriptor block */ #define TDBF_TUNNELING 0x01000 /* Force IP-IP encapsulation */ u_int32_t tdb_flags; /* Flags related to this TDB */ + TAILQ_ENTRY(tdb) tdb_expnext; /* Expiration cluster list link */ + LIST_ENTRY(tdb) tdb_explink; /* Expiration ordered list link */ + u_int32_t tdb_exp_allocations; /* Expire after so many flows */ u_int32_t tdb_soft_allocations; /* Expiration warning */ u_int32_t tdb_cur_allocations; /* Total number of allocations */ @@ -239,11 +234,13 @@ struct tdb /* tunnel descriptor block */ u_int64_t tdb_exp_timeout; /* When does the SPI expire */ u_int64_t tdb_soft_timeout; /* Send a soft-expire warning */ u_int64_t tdb_established; /* When was the SPI established */ + u_int64_t tdb_timeout; /* Next absolute expiration time. */ u_int64_t tdb_first_use; /* When was it first used */ u_int64_t tdb_soft_first_use; /* Soft warning */ u_int64_t tdb_exp_first_use; /* Expire if tdb_first_use + * tdb_exp_first_use <= curtime */ + u_int32_t tdb_spi; /* SPI */ u_int16_t tdb_amxkeylen; /* AH-old only */ u_int16_t tdb_ivlen; /* IV length */ @@ -385,7 +382,8 @@ extern u_int8_t hmac_ipad_buffer[64]; extern u_int8_t hmac_opad_buffer[64]; struct tdb *tdbh[TDB_HASHMOD]; -struct expiration *explist; +extern TAILQ_HEAD(expclusterlist_head, tdb) expclusterlist; +extern LIST_HEAD(explist_head, tdb) explist; extern struct xformsw xformsw[], *xformswNXFORMSW; /* Check if a given tdb has encryption, authentication and/or tunneling */ @@ -418,12 +416,8 @@ extern struct tdb *gettdb(u_int32_t, union sockaddr_union *, u_int8_t); extern void puttdb(struct tdb *); extern int tdb_delete(struct tdb *, int); extern int tdb_init (struct tdb *, u_int16_t, struct ipsecinit *); - -/* Expiration management routines */ -extern struct expiration *get_expiration(void); -extern void put_expiration(struct expiration *); +extern void tdb_expiration(struct tdb *, int); extern void handle_expirations(void *); -extern void cleanup_expirations(union sockaddr_union *, u_int32_t, u_int8_t); /* Flow management routines */ extern struct flow *get_flow(void); diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 2f74c801df4..5d76c833c39 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.45 1999/04/11 19:41:39 niklas Exp $ */ +/* $OpenBSD: ip_output.c,v 1.46 1999/05/14 23:36:20 niklas Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -125,7 +125,6 @@ ip_output(m0, va_alist) struct mbuf *mp; struct udphdr *udp; struct tcphdr *tcp; - struct expiration *exp; struct inpcb *inp; #endif @@ -389,33 +388,10 @@ ip_output(m0, va_alist) /* Register first use, setup expiration timer */ if (tdb->tdb_first_use == 0) { - tdb->tdb_first_use = time.tv_sec; - - if (tdb->tdb_flags & TDBF_FIRSTUSE) { - exp = get_expiration(); - bcopy(&tdb->tdb_dst, &exp->exp_dst, - SA_LEN(&tdb->tdb_dst.sa)); - exp->exp_spi = tdb->tdb_spi; - exp->exp_sproto = tdb->tdb_sproto; - exp->exp_timeout = tdb->tdb_first_use + - tdb->tdb_exp_first_use; - put_expiration(exp); - } - - if ((tdb->tdb_flags & TDBF_SOFT_FIRSTUSE) && - (tdb->tdb_soft_first_use <= - tdb->tdb_exp_first_use)) { - exp = get_expiration(); - bcopy(&tdb->tdb_dst, &exp->exp_dst, - SA_LEN(&tdb->tdb_dst.sa)); - exp->exp_spi = tdb->tdb_spi; - exp->exp_sproto = tdb->tdb_sproto; - exp->exp_timeout = tdb->tdb_first_use + - tdb->tdb_soft_first_use; - put_expiration(exp); - } + tdb->tdb_first_use = time.tv_sec; + tdb_expiration(tdb, 0); } - + /* Check for tunneling */ if (((tdb->tdb_dst.sin.sin_addr.s_addr != INADDR_ANY && |