summaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2001-03-15 06:31:01 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2001-03-15 06:31:01 +0000
commitedfec851c3cec5de63ae0e8f1a63810281ef55a5 (patch)
treeb662e8669f1c7b18ba2b25720785511bb59dc5f4 /sys/netinet
parentbb69ff7943a7dbbda58b37e949e9334d21194c8a (diff)
convert SA expirations to the new timeouts.
simplifies expirations handling a lot. tdb_exp_timeout and tdb_soft_timeout are made consistant throughout the code to be a relative time offsets, just like first_use timeouts. tested on singlehost isakmpd setup. lots of dangling spaces and tabs removed. angelos@ ok
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_ah.c32
-rw-r--r--sys/netinet/ip_esp.c34
-rw-r--r--sys/netinet/ip_ipsp.c357
-rw-r--r--sys/netinet/ip_ipsp.h33
-rw-r--r--sys/netinet/ipsec_input.c29
-rw-r--r--sys/netinet/ipsec_output.c9
6 files changed, 161 insertions, 333 deletions
diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c
index d9d7da6b3ee..7845272b22c 100644
--- a/sys/netinet/ip_ah.c
+++ b/sys/netinet/ip_ah.c
@@ -1,8 +1,8 @@
-/* $OpenBSD: ip_ah.c,v 1.46 2001/02/20 06:48:06 itojun Exp $ */
+/* $OpenBSD: ip_ah.c,v 1.47 2001/03/15 06:30:58 mickey Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
- * Angelos D. Keromytis (kermit@csd.uch.gr) and
+ * Angelos D. Keromytis (kermit@csd.uch.gr) and
* Niels Provos (provos@physnet.uni-hamburg.de).
*
* The original version of this code was written by John Ioannidis
@@ -23,7 +23,7 @@
* 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
- * modification of this software.
+ * modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
@@ -263,7 +263,7 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
m_freem(m);
return EINVAL;
}
-
+
switch (ptr[off])
{
case IPOPT_EOL:
@@ -372,7 +372,7 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
/* Done with IPv6 header */
m_copyback(m, 0, sizeof(struct ip6_hdr), (caddr_t) &ip6);
-
+
/* Let's deal with the remaining headers (if any) */
if (skip - sizeof(struct ip6_hdr) > 0)
{
@@ -574,7 +574,7 @@ ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
(tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes))
{
pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
- tdb_delete(tdb, TDBEXP_TIMEOUT);
+ tdb_delete(tdb);
m_freem(m);
return ENXIO;
}
@@ -676,7 +676,7 @@ ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
*/
int
ah_input_cb(void *op)
-{
+{
int roff, rplen, error, skip, protoff;
unsigned char calc[AH_ALEN_MAX];
struct mbuf *m1, *m0, *m;
@@ -778,7 +778,7 @@ ah_input_cb(void *op)
}
/* Remove the AH header from the mbuf */
- if (roff == 0)
+ if (roff == 0)
{
/* The AH header was conveniently at the beginning of the mbuf */
m_adj(m1, rplen + ahx->authsize);
@@ -816,7 +816,7 @@ ah_input_cb(void *op)
}
else
{
- /*
+ /*
* The AH header lies in the "middle" of the mbuf...do an
* overlapping copy of the remainder of the mbuf over the ESP
* header.
@@ -954,7 +954,7 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
(tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes))
{
pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
- tdb_delete(tdb, TDBEXP_TIMEOUT);
+ tdb_delete(tdb);
m_freem(m);
return EINVAL;
}
@@ -968,24 +968,24 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
}
/*
- * Loop through mbuf chain; if we find an M_EXT mbuf with
+ * Loop through mbuf chain; if we find an M_EXT mbuf with
* more than one reference, replace the rest of the chain.
*/
mi = m;
- while (mi != NULL &&
- (!(mi->m_flags & M_EXT) ||
+ while (mi != NULL &&
+ (!(mi->m_flags & M_EXT) ||
(mi->m_ext.ext_ref == NULL &&
mclrefcnt[mtocl(mi->m_ext.ext_buf)] <= 1)))
{
mo = mi;
mi = mi->m_next;
}
-
+
if (mi != NULL)
{
/* Replace the rest of the mbuf chain. */
struct mbuf *n = m_copym2(mi, 0, M_COPYALL, M_DONTWAIT);
-
+
if (n == NULL)
{
ahstat.ahs_hdrops++;
@@ -1017,7 +1017,7 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
* at the beginning of the returned mbuf.
*/
ah = mtod(mi, struct ah *);
-
+
/* Initialize the AH header */
m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &ah->ah_nh);
ah->ah_hl = (rplen + ahx->authsize - AH_FLENGTH) / sizeof(u_int32_t);
diff --git a/sys/netinet/ip_esp.c b/sys/netinet/ip_esp.c
index 8b232b8d7b9..df0c90f4255 100644
--- a/sys/netinet/ip_esp.c
+++ b/sys/netinet/ip_esp.c
@@ -1,8 +1,8 @@
-/* $OpenBSD: ip_esp.c,v 1.51 2000/11/17 04:15:42 angelos Exp $ */
+/* $OpenBSD: ip_esp.c,v 1.52 2001/03/15 06:30:59 mickey Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
- * Angelos D. Keromytis (kermit@csd.uch.gr) and
+ * Angelos D. Keromytis (kermit@csd.uch.gr) and
* Niels Provos (provos@physnet.uni-hamburg.de).
*
* The original version of this code was written by John Ioannidis
@@ -18,11 +18,11 @@
*
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
* Angelos D. Keromytis and Niels Provos.
- *
+ *
* 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
- * modification of this software.
+ * modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
@@ -148,7 +148,7 @@ esp_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii)
DPRINTF(("esp_init(): keylength %d too small (min length is %d) for algorithm %s\n", ii->ii_enckeylen, txform->minkey, txform->name));
return EINVAL;
}
-
+
if (ii->ii_enckeylen > txform->maxkey)
{
DPRINTF(("esp_init(): keylength %d too large (max length is %d) for algorithm %s\n", ii->ii_enckeylen, txform->maxkey, txform->name));
@@ -191,13 +191,13 @@ esp_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii)
DPRINTF(("esp_init(): keylength %d doesn't match algorithm %s keysize (%d)\n", ii->ii_authkeylen, thash->name, thash->keysize));
return EINVAL;
}
-
+
tdbp->tdb_authalgxform = thash;
DPRINTF(("esp_init(): initialized TDB with hash algorithm %s\n",
thash->name));
}
-
+
tdbp->tdb_xform = xsp;
tdbp->tdb_bitmap = 0;
tdbp->tdb_rpl = AH_HMAC_INITIAL_RPL;
@@ -359,7 +359,7 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
(tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes))
{
pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
- tdb_delete(tdb, TDBEXP_TIMEOUT);
+ tdb_delete(tdb);
m_freem(m);
return ENXIO;
}
@@ -585,7 +585,7 @@ esp_input_cb(void *op)
}
/* Remove the ESP header and IV from the mbuf. */
- if (roff == 0)
+ if (roff == 0)
{
/* The ESP header was conveniently at the beginning of the mbuf */
m_adj(m1, hlen);
@@ -623,7 +623,7 @@ esp_input_cb(void *op)
}
else
{
- /*
+ /*
* The ESP header lies in the "middle" of the mbuf...do an
* overlapping copy of the remainder of the mbuf over the ESP
* header.
@@ -811,7 +811,7 @@ esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
(tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes))
{
pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
- tdb_delete(tdb, TDBEXP_TIMEOUT);
+ tdb_delete(tdb);
m_freem(m);
return EINVAL;
}
@@ -825,24 +825,24 @@ esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
}
/*
- * Loop through mbuf chain; if we find an M_EXT mbuf with
+ * Loop through mbuf chain; if we find an M_EXT mbuf with
* more than one reference, replace the rest of the chain.
*/
mi = m;
- while (mi != NULL &&
- (!(mi->m_flags & M_EXT) ||
+ while (mi != NULL &&
+ (!(mi->m_flags & M_EXT) ||
(mi->m_ext.ext_ref == NULL &&
mclrefcnt[mtocl(mi->m_ext.ext_buf)] <= 1)))
{
mo = mi;
mi = mi->m_next;
}
-
+
if (mi != NULL)
{
/* Replace the rest of the mbuf chain. */
struct mbuf *n = m_copym2(mi, 0, M_COPYALL, M_DONTWAIT);
-
+
if (n == NULL)
{
espstat.esps_hdrops++;
@@ -1132,7 +1132,7 @@ m_pad(struct mbuf *m, int n)
register struct mbuf *m0, *m1;
register int len, pad;
caddr_t retval;
-
+
if (n <= 0) /* no stupid arguments */
{
DPRINTF(("m_pad(): pad length invalid (%d)\n", n));
diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c
index a8239aff0b3..135f36048bd 100644
--- a/sys/netinet/ip_ipsp.c
+++ b/sys/netinet/ip_ipsp.c
@@ -1,8 +1,8 @@
-/* $OpenBSD: ip_ipsp.c,v 1.108 2001/03/13 01:23:18 angelos Exp $ */
+/* $OpenBSD: ip_ipsp.c,v 1.109 2001/03/15 06:30:59 mickey Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
- * Angelos D. Keromytis (kermit@csd.uch.gr),
+ * Angelos D. Keromytis (kermit@csd.uch.gr),
* Niels Provos (provos@physnet.uni-hamburg.de) and
* Niklas Hallqvist (niklas@appli.se).
*
@@ -24,7 +24,7 @@
* 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
- * modification of this software.
+ * modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
@@ -94,6 +94,10 @@ void tdb_hashstats(void);
int ipsp_kern __P((int, char **, int));
u_int8_t get_sa_require __P((struct inpcb *));
void tdb_rehash __P((void));
+void tdb_timeout __P((void *v));
+void tdb_firstuse __P((void *v));
+void tdb_soft_timeout __P((void *v));
+void tdb_soft_firstuse __P((void *v));
extern int ipsec_auth_default_level;
extern int ipsec_esp_trans_default_level;
@@ -104,9 +108,6 @@ int ipsec_in_use = 0;
u_int64_t ipsec_last_added = 0;
u_int32_t kernfs_epoch = 0;
-struct expclusterlist_head expclusterlist =
- TAILQ_HEAD_INITIALIZER(expclusterlist);
-struct explist_head explist = TAILQ_HEAD_INITIALIZER(explist);
struct ipsec_policy_head ipsec_policy_head =
TAILQ_HEAD_INITIALIZER(ipsec_policy_head);
struct ipsec_acquire_head ipsec_acquire_head =
@@ -119,7 +120,7 @@ struct ipsec_acquire_head ipsec_acquire_head =
struct xformsw xformsw[] = {
{ XF_IP4, 0, "IPv4 Simple Encapsulation",
ipe4_attach, ipe4_init, ipe4_zeroize,
- (int (*)(struct mbuf *, struct tdb *, int, int))ipe4_input,
+ (int (*)(struct mbuf *, struct tdb *, int, int))ipe4_input,
ipip_output, },
{ XF_AH, XFT_AUTH, "IPsec AH",
ah_attach, ah_init, ah_zeroize,
@@ -137,7 +138,7 @@ struct xformsw xformsw[] = {
struct xformsw *xformswNXFORMSW = &xformsw[sizeof(xformsw)/sizeof(xformsw[0])];
-unsigned char ipseczeroes[IPSEC_ZEROES_SIZE]; /* zeroes! */
+unsigned char ipseczeroes[IPSEC_ZEROES_SIZE]; /* zeroes! */
#define TDB_HASHSIZE_INIT 32
static struct tdb **tdbh = NULL;
@@ -222,7 +223,7 @@ reserve_spi(u_int32_t sspi, u_int32_t tspi, union sockaddr_union *src,
get_random_bytes((void *) &spi, sizeof(spi));
spi = sspi + (spi % (tspi - sspi));
}
-
+
/* Don't allocate reserved SPIs. */
if (spi >= SPI_RESERVED_MIN && spi <= SPI_RESERVED_MAX)
continue;
@@ -239,7 +240,7 @@ reserve_spi(u_int32_t sspi, u_int32_t tspi, union sockaddr_union *src,
MALLOC(tdbp, struct tdb *, sizeof(struct tdb), M_TDB, M_WAITOK);
bzero((caddr_t) tdbp, sizeof(struct tdb));
-
+
tdbp->tdb_spi = spi;
bcopy(&dst->sa, &tdbp->tdb_dst.sa, SA_LEN(&dst->sa));
bcopy(&src->sa, &tdbp->tdb_src.sa, SA_LEN(&src->sa));
@@ -250,12 +251,18 @@ reserve_spi(u_int32_t sspi, u_int32_t tspi, union sockaddr_union *src,
tdbp->tdb_epoch = kernfs_epoch - 1;
puttdb(tdbp);
+ /* Initialize timeouts */
+ timeout_set(&tdbp->tdb_timer_tmo, tdb_timeout, tdbp);
+ timeout_set(&tdbp->tdb_first_tmo, tdb_firstuse, tdbp);
+ timeout_set(&tdbp->tdb_stimer_tmo, tdb_soft_timeout, tdbp);
+ timeout_set(&tdbp->tdb_sfirst_tmo, tdb_soft_firstuse, tdbp);
+
/* Setup a "silent" expiration (since TDBF_INVALID's set) */
if (ipsec_keep_invalid > 0)
{
tdbp->tdb_flags |= TDBF_TIMER;
- tdbp->tdb_exp_timeout = time.tv_sec + ipsec_keep_invalid;
- tdb_expiration(tdbp, TDBEXP_EARLY | TDBEXP_TIMEOUT);
+ tdbp->tdb_exp_timeout = ipsec_keep_invalid;
+ timeout_add(&tdbp->tdb_timer_tmo, hz * ipsec_keep_invalid);
}
return spi;
@@ -266,7 +273,7 @@ reserve_spi(u_int32_t sspi, u_int32_t tspi, union sockaddr_union *src,
}
/*
- * An IPSP SAID is really the concatenation of the SPI found in the
+ * An IPSP SAID is really the concatenation of the SPI found in the
* packet, the destination address of the packet and the IPsec protocol.
* When we receive an IPSP packet, we need to look up its tunnel descriptor
* block, based on the SPI in the packet and the destination address (which
@@ -286,7 +293,7 @@ gettdb(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto)
hashval = tdb_hash(spi, dst, proto);
for (tdbp = tdbh[hashval]; tdbp != NULL; tdbp = tdbp->tdb_hnext)
- if ((tdbp->tdb_spi == spi) &&
+ if ((tdbp->tdb_spi == spi) &&
!bcmp(&tdbp->tdb_dst, dst, SA_LEN(&dst->sa)) &&
(tdbp->tdb_sproto == proto))
break;
@@ -438,246 +445,58 @@ tdb_walk(int (*walker)(struct tdb *, void *, int), void *arg)
* Called at splsoftclock().
*/
void
-handle_expirations(void *arg)
+tdb_timeout(void *v)
{
- struct tdb *tdb;
-
- for (tdb = TAILQ_FIRST(&explist);
- tdb && tdb->tdb_timeout <= time.tv_sec;
- tdb = TAILQ_FIRST(&explist))
- {
- /* Hard expirations first */
- if ((tdb->tdb_flags & TDBF_TIMER) &&
- (tdb->tdb_exp_timeout <= time.tv_sec))
- {
- /* If it's an "invalid" TDB do a silent expiration. */
- if (!(tdb->tdb_flags & TDBF_INVALID))
- pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
- tdb_delete(tdb, 0);
- continue;
- }
- else
- if ((tdb->tdb_flags & TDBF_FIRSTUSE) &&
- (tdb->tdb_first_use + tdb->tdb_exp_first_use <= time.tv_sec))
- {
- /* If the TDB hasn't been used, don't renew it */
- if (tdb->tdb_first_use != 0)
- pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
- tdb_delete(tdb, 0);
- continue;
- }
+ struct tdb *tdb = v;
- /* Soft expirations */
- if ((tdb->tdb_flags & TDBF_SOFT_TIMER) &&
- (tdb->tdb_soft_timeout <= time.tv_sec))
- {
- pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
- tdb->tdb_flags &= ~TDBF_SOFT_TIMER;
- tdb_expiration(tdb, TDBEXP_EARLY);
- }
- else
- if ((tdb->tdb_flags & TDBF_SOFT_FIRSTUSE) &&
- (tdb->tdb_first_use + tdb->tdb_soft_first_use <=
- time.tv_sec))
- {
- /* If the TDB hasn't been used, don't renew it */
- if (tdb->tdb_first_use != 0)
- pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
- tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE;
- tdb_expiration(tdb, TDBEXP_EARLY);
- }
- }
+ if (!(tdb->tdb_flags & TDBF_TIMER))
+ return;
- /* If any tdb is left on the expiration queue, set the timer. */
- if (tdb)
- timeout(handle_expirations, (void *) NULL,
- hz * (tdb->tdb_timeout - time.tv_sec));
+ /* If it's an "invalid" TDB do a silent expiration. */
+ if (!(tdb->tdb_flags & TDBF_INVALID))
+ pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
+ tdb_delete(tdb);
}
-/*
- * Ensure the tdb is in the right place in the expiration list.
- */
void
-tdb_expiration(struct tdb *tdb, int flags)
+tdb_firstuse(void *v)
{
- struct tdb *t, *former_expirer, *next_expirer;
- int will_be_first, sole_reason, early;
- u_int64_t next_timeout = 0;
- int s = spltdb();
-
- /* 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)
- {
- splx(s);
- return;
- }
+ struct tdb *tdb = v;
- /*
- * Find out some useful facts: Will our tdb be first to expire?
- * Was our tdb the sole reason for the old timeout?
- */
- former_expirer = TAILQ_FIRST(&expclusterlist);
- next_expirer = TAILQ_NEXT(tdb, tdb_explink);
- will_be_first = (next_timeout != 0 &&
- (former_expirer == NULL ||
- next_timeout < former_expirer->tdb_timeout));
- sole_reason = (tdb == former_expirer &&
- (next_expirer == NULL ||
- tdb->tdb_timeout != next_expirer->tdb_timeout));
+ if (!(tdb->tdb_flags & TDBF_SOFT_FIRSTUSE))
+ return;
- /*
- * We need to untimeout if either:
- * - there is an expiration pending and the new timeout is earlier than
- * what already exists or
- * - the existing first expiration is due to our old timeout value solely
- */
- if ((former_expirer != NULL && will_be_first) || sole_reason)
- untimeout(handle_expirations, (void *) NULL);
-
- /*
- * We need to timeout if we've been asked to and if either
- * - our tdb has a timeout and no former expiration exist or
- * - the new timeout is earlier than what already exists or
- * - the existing first expiration is due to our old timeout value solely
- * and another expiration is in the pipe.
- */
- if ((flags & TDBEXP_TIMEOUT) &&
- (will_be_first || (sole_reason && next_expirer != NULL)))
- timeout(handle_expirations, (void *) NULL,
- hz * ((will_be_first ? next_timeout :
- next_expirer->tdb_timeout) - time.tv_sec));
-
- /* Our old position, if any, is not relevant anymore. */
- if (tdb->tdb_timeout != 0)
- {
- if (tdb->tdb_expnext.tqe_prev != NULL)
- {
- if (next_expirer && tdb->tdb_timeout == next_expirer->tdb_timeout)
- TAILQ_INSERT_BEFORE(tdb, next_expirer, tdb_expnext);
- TAILQ_REMOVE(&expclusterlist, tdb, tdb_expnext);
- tdb->tdb_expnext.tqe_prev = NULL;
- }
-
- TAILQ_REMOVE(&explist, tdb, tdb_explink);
- }
+ /* If the TDB hasn't been used, don't renew it */
+ if (tdb->tdb_first_use != 0)
+ pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
+ tdb_delete(tdb);
+}
- tdb->tdb_timeout = next_timeout;
+void
+tdb_soft_timeout(void *v)
+{
+ struct tdb *tdb = v;
- if (next_timeout == 0)
- {
- splx(s);
- return;
- }
+ if (!(tdb->tdb_flags & TDBF_SOFT_TIMER))
+ return;
- /*
- * Search front-to-back if we believe we will end up early, otherwise
- * back-to-front.
- */
- early = will_be_first || (flags & TDBEXP_EARLY);
- for (t = (early ? TAILQ_FIRST(&expclusterlist) :
- TAILQ_LAST(&expclusterlist, expclusterlist_head));
- t != NULL && (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 (t == (early ? TAILQ_FIRST(&expclusterlist) : NULL))
- {
- /* We are to become the first expiration. */
- TAILQ_INSERT_HEAD(&expclusterlist, tdb, tdb_expnext);
- TAILQ_INSERT_HEAD(&explist, tdb, tdb_explink);
- }
- else
- {
- if (early)
- t = (t ? TAILQ_PREV(t, expclusterlist_head, tdb_expnext) :
- TAILQ_LAST(&expclusterlist, expclusterlist_head));
- if (TAILQ_NEXT(t, tdb_expnext))
- TAILQ_INSERT_BEFORE(TAILQ_NEXT(t, tdb_expnext), tdb, tdb_explink);
- else
- TAILQ_INSERT_TAIL(&explist, tdb, tdb_explink);
- if (t->tdb_timeout < next_timeout)
- TAILQ_INSERT_AFTER(&expclusterlist, t, tdb, tdb_expnext);
- }
+ /* Soft expirations */
+ pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
+ tdb->tdb_flags &= ~TDBF_SOFT_TIMER;
+}
-#ifdef DIAGNOSTIC
- /*
- * Check various invariants.
- */
- if (tdb->tdb_expnext.tqe_prev != NULL)
- {
- t = TAILQ_FIRST(&expclusterlist);
- if (t != tdb && t->tdb_timeout >= tdb->tdb_timeout)
- panic("tdb_expiration: "
- "expclusterlist first link out of order (%p, %p)",
- tdb, t);
- t = TAILQ_PREV(tdb, expclusterlist_head, tdb_expnext);
- if (t != NULL && t->tdb_timeout >= tdb->tdb_timeout)
- panic("tdb_expiration: "
- "expclusterlist prev link out of order (%p, %p)",
- tdb, t);
- else if (t == NULL && tdb != TAILQ_FIRST(&expclusterlist))
- panic("tdb_expiration: "
- "expclusterlist first link out of order (%p, %p)",
- tdb, TAILQ_FIRST(&expclusterlist));
- t = TAILQ_NEXT(tdb, tdb_expnext);
- if (t != NULL && t->tdb_timeout <= tdb->tdb_timeout)
- panic("tdb_expiration: "
- "expclusterlist next link out of order (%p, %p)",
- tdb, t);
- else if (t == NULL &&
- tdb != TAILQ_LAST(&expclusterlist, expclusterlist_head))
- panic("tdb_expiration: "
- "expclusterlist last link out of order (%p, %p)",
- tdb, TAILQ_LAST(&expclusterlist, expclusterlist_head));
- t = TAILQ_LAST(&expclusterlist, expclusterlist_head);
- if (t != tdb && t->tdb_timeout <= tdb->tdb_timeout)
- panic("tdb_expiration: "
- "expclusterlist last link out of order (%p, %p)",
- tdb, t);
- }
+void
+tdb_soft_firstuse(void *v)
+{
+ struct tdb *tdb = v;
- t = TAILQ_FIRST(&explist);
- if (t != NULL && t->tdb_timeout > tdb->tdb_timeout)
- panic("tdb_expiration: explist first link out of order (%p, %p)", tdb,
- t);
-
- t = TAILQ_PREV(tdb, explist_head, tdb_explink);
- if (t != NULL && t->tdb_timeout > tdb->tdb_timeout)
- panic("tdb_expiration: explist prev link out of order (%p, %p)", tdb, t);
- else if (t == NULL && tdb != TAILQ_FIRST(&explist))
- panic("tdb_expiration: explist first link out of order (%p, %p)", tdb,
- TAILQ_FIRST(&explist));
-
- t = TAILQ_NEXT(tdb, tdb_explink);
- if (t != NULL && t->tdb_timeout < tdb->tdb_timeout)
- panic("tdb_expiration: explist next link out of order (%p, %p)", tdb, t);
- else if (t == NULL && tdb != TAILQ_LAST(&explist, explist_head))
- panic("tdb_expiration: explist last link out of order (%p, %p)", tdb,
- TAILQ_LAST(&explist, explist_head));
-
- t = TAILQ_LAST(&explist, explist_head);
- if (t != tdb && t->tdb_timeout < tdb->tdb_timeout)
- panic("tdb_expiration: explist last link out of order (%p, %p)", tdb, t);
-#endif
+ if (!(tdb->tdb_flags & TDBF_SOFT_FIRSTUSE))
+ return;
- splx(s);
+ /* If the TDB hasn't been used, don't renew it */
+ if (tdb->tdb_first_use != 0)
+ pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
+ tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE;
}
/*
@@ -767,7 +586,7 @@ puttdb(struct tdb *tdbp)
}
hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst, tdbp->tdb_sproto);
-
+
/*
* Rehash if this tdb would cause a bucket to have more than two items
* and if the number of tdbs exceed 10% of the bucket count. This
@@ -804,7 +623,7 @@ puttdb(struct tdb *tdbp)
* Caller is responsible to set at least spltdb().
*/
void
-tdb_delete(struct tdb *tdbp, int expflags)
+tdb_delete(struct tdb *tdbp)
{
struct ipsec_policy *ipo;
struct tdb *tdbpp;
@@ -891,13 +710,13 @@ tdb_delete(struct tdb *tdbp, int expflags)
ipo->ipo_last_searched = 0; /* Force a re-search */
}
- /* Remove us from the expiration lists. */
- if (tdbp->tdb_timeout != 0)
- {
- tdbp->tdb_flags &= ~(TDBF_FIRSTUSE | TDBF_SOFT_FIRSTUSE | TDBF_TIMER |
- TDBF_SOFT_TIMER);
- tdb_expiration(tdbp, expflags);
- }
+ /* Remove expiration timeouts. */
+ tdbp->tdb_flags &= ~(TDBF_FIRSTUSE | TDBF_SOFT_FIRSTUSE | TDBF_TIMER |
+ TDBF_SOFT_TIMER);
+ timeout_del(&tdbp->tdb_timer_tmo);
+ timeout_del(&tdbp->tdb_first_tmo);
+ timeout_del(&tdbp->tdb_stimer_tmo);
+ timeout_del(&tdbp->tdb_sfirst_tmo);
if (tdbp->tdb_srcid)
{
@@ -942,6 +761,12 @@ tdb_init(struct tdb *tdbp, u_int16_t alg, struct ipsecinit *ii)
tdbp->tdb_established = time.tv_sec;
tdbp->tdb_epoch = kernfs_epoch - 1;
+ /* Initialize timeouts */
+ timeout_set(&tdbp->tdb_timer_tmo, tdb_timeout, tdbp);
+ timeout_set(&tdbp->tdb_first_tmo, tdb_firstuse, tdbp);
+ timeout_set(&tdbp->tdb_stimer_tmo, tdb_soft_timeout, tdbp);
+ timeout_set(&tdbp->tdb_sfirst_tmo, tdb_soft_firstuse, tdbp);
+
/* Init Incoming SA-Binding Queues */
TAILQ_INIT(&tdbp->tdb_inp);
@@ -958,7 +783,7 @@ tdb_init(struct tdb *tdbp, u_int16_t alg, struct ipsecinit *ii)
return err;
}
- DPRINTF(("tdb_init(): no alg %d for spi %08x, addr %s, proto %d\n",
+ DPRINTF(("tdb_init(): no alg %d for spi %08x, addr %s, proto %d\n",
alg, ntohl(tdbp->tdb_spi), ipsp_address(tdbp->tdb_dst),
tdbp->tdb_sproto));
@@ -988,7 +813,7 @@ ipsp_kern(int off, char **bufp, int len)
ipsec_in_use);
return l;
}
-
+
if (tdbh == NULL)
return 0;
@@ -1107,7 +932,7 @@ ipsp_kern(int off, char **bufp, int len)
l += sprintf(buffer + l, "\tCrypto ID: %qu\n", tdb->tdb_cryptoid);
if (tdb->tdb_xform)
- l += sprintf(buffer + l, "\txform = <%s>\n",
+ l += sprintf(buffer + l, "\txform = <%s>\n",
tdb->tdb_xform->xf_name);
if (tdb->tdb_encalgxform)
@@ -1140,24 +965,26 @@ ipsp_kern(int off, char **bufp, int len)
l += sprintf(buffer + l, "\t%qu bytes processed by this SA\n",
tdb->tdb_cur_bytes);
-
+
l += sprintf(buffer + l, "\tExpirations:\n");
if (tdb->tdb_flags & TDBF_TIMER)
l += sprintf(buffer + l,
"\t\tHard expiration(1) in %qu seconds\n",
- tdb->tdb_exp_timeout - time.tv_sec);
-
+ tdb->tdb_established + tdb->tdb_exp_timeout -
+ time.tv_sec);
+
if (tdb->tdb_flags & TDBF_SOFT_TIMER)
l += sprintf(buffer + l,
"\t\tSoft expiration(1) in %qu seconds\n",
- tdb->tdb_soft_timeout - time.tv_sec);
-
+ tdb->tdb_established + tdb->tdb_soft_timeout -
+ time.tv_sec);
+
if (tdb->tdb_flags & TDBF_BYTES)
l += sprintf(buffer + l,
"\t\tHard expiration after %qu bytes\n",
tdb->tdb_exp_bytes);
-
+
if (tdb->tdb_flags & TDBF_SOFT_BYTES)
l += sprintf(buffer + l,
"\t\tSoft expiration after %qu bytes\n",
@@ -1167,7 +994,7 @@ ipsp_kern(int off, char **bufp, int len)
l += sprintf(buffer + l,
"\t\tHard expiration after %u flows\n",
tdb->tdb_exp_allocations);
-
+
if (tdb->tdb_flags & TDBF_SOFT_ALLOCATIONS)
l += sprintf(buffer + l,
"\t\tSoft expiration after %u flows\n",
@@ -1224,10 +1051,10 @@ u_int8_t
get_sa_require(struct inpcb *inp)
{
u_int8_t sareq = 0;
-
+
if (inp != NULL)
{
- sareq |= inp->inp_seclevel[SL_AUTH] >= IPSEC_LEVEL_USE ?
+ sareq |= inp->inp_seclevel[SL_AUTH] >= IPSEC_LEVEL_USE ?
NOTIFY_SATYPE_AUTH : 0;
sareq |= inp->inp_seclevel[SL_ESP_TRANS] >= IPSEC_LEVEL_USE ?
NOTIFY_SATYPE_CONF : 0;
@@ -1236,14 +1063,14 @@ get_sa_require(struct inpcb *inp)
}
else
{
- sareq |= ipsec_auth_default_level >= IPSEC_LEVEL_USE ?
+ sareq |= ipsec_auth_default_level >= IPSEC_LEVEL_USE ?
NOTIFY_SATYPE_AUTH : 0;
- sareq |= ipsec_esp_trans_default_level >= IPSEC_LEVEL_USE ?
+ sareq |= ipsec_esp_trans_default_level >= IPSEC_LEVEL_USE ?
NOTIFY_SATYPE_CONF : 0;
- sareq |= ipsec_esp_network_default_level >= IPSEC_LEVEL_USE ?
+ sareq |= ipsec_esp_network_default_level >= IPSEC_LEVEL_USE ?
NOTIFY_SATYPE_TUNNEL : 0;
}
-
+
return (sareq);
}
@@ -1274,7 +1101,7 @@ inet_ntoa4(struct in_addr ina)
static char buf[4][4 * sizeof "123" + 4];
unsigned char *ucp = (unsigned char *) &ina;
static int i = 3;
-
+
i = (i + 1) % 4;
sprintf(buf[i], "%d.%d.%d.%d", ucp[0] & 0xff, ucp[1] & 0xff,
ucp[2] & 0xff, ucp[3] & 0xff);
diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h
index e37f5a8828c..7f834d72728 100644
--- a/sys/netinet/ip_ipsp.h
+++ b/sys/netinet/ip_ipsp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.h,v 1.79 2001/03/04 20:34:00 angelos Exp $ */
+/* $OpenBSD: ip_ipsp.h,v 1.80 2001/03/15 06:31:00 mickey Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@@ -24,7 +24,7 @@
* 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
- * modification of this software.
+ * modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
@@ -46,6 +46,7 @@
#include <sys/types.h>
#include <sys/queue.h>
+#include <sys/timeout.h>
#include <netinet/in.h>
union sockaddr_union
@@ -144,7 +145,7 @@ struct sockaddr_encap
* system is concerned. By using only one bit in the type field
* for each type, we sort-of make sure that different types of
* encapsulation addresses won't be matched against the wrong type.
- *
+ *
*/
#define SENT_IP4 0x0001 /* data is two struct in_addr */
@@ -212,7 +213,7 @@ struct ipsec_policy
#define NOTIFY_SOFT_EXPIRE 0 /* Soft expiration of SA */
#define NOTIFY_HARD_EXPIRE 1 /* Hard expiration of SA */
#define NOTIFY_REQUEST_SA 2 /* Establish an SA */
-
+
#define NOTIFY_SATYPE_CONF 1 /* SA should do encryption */
#define NOTIFY_SATYPE_AUTH 2 /* SA should do authentication */
#define NOTIFY_SATYPE_TUNNEL 4 /* SA should use tunneling */
@@ -266,11 +267,13 @@ struct tdb /* tunnel descriptor block */
u_int32_t tdb_flags; /* Flags related to this TDB */
- TAILQ_ENTRY(tdb) tdb_expnext; /* Expiration cluster list link */
- TAILQ_ENTRY(tdb) tdb_explink; /* Expiration ordered list link */
+ struct timeout tdb_timer_tmo;
+ struct timeout tdb_first_tmo;
+ struct timeout tdb_stimer_tmo;
+ struct timeout tdb_sfirst_tmo;
u_int32_t tdb_exp_allocations; /* Expire after so many flows */
- u_int32_t tdb_soft_allocations; /* Expiration warning */
+ u_int32_t tdb_soft_allocations; /* Expiration warning */
u_int32_t tdb_cur_allocations; /* Total number of allocations */
u_int64_t tdb_exp_bytes; /* Expire after so many bytes passed */
@@ -280,7 +283,6 @@ 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 */
@@ -350,7 +352,7 @@ struct ipsecinit
u_int8_t ii_encalg;
u_int8_t ii_authalg;
};
-
+
struct xformsw
{
u_short xf_type; /* Unique ID of xform */
@@ -383,7 +385,7 @@ htonq(u_int64_t q)
register u_int32_t u, l;
u = q >> 32;
l = (u_int32_t) q;
-
+
return htonl(u) | ((u_int64_t)htonl(l) << 32);
}
@@ -396,7 +398,7 @@ htonq(u_int64_t q)
#else
#error "Please fix <machine/endian.h>"
-#endif
+#endif
#ifdef _KERNEL
@@ -437,8 +439,6 @@ extern struct auth_hash auth_hash_hmac_md5_96;
extern struct auth_hash auth_hash_hmac_sha1_96;
extern struct auth_hash auth_hash_hmac_ripemd_160_96;
-extern TAILQ_HEAD(expclusterlist_head, tdb) expclusterlist;
-extern TAILQ_HEAD(explist_head, tdb) explist;
extern TAILQ_HEAD(ipsec_policy_head, ipsec_policy) ipsec_policy_head;
extern TAILQ_HEAD(ipsec_acquire_head, ipsec_acquire) ipsec_acquire_head;
@@ -478,14 +478,9 @@ extern struct tdb *gettdbbyaddr(union sockaddr_union *, u_int8_t,
extern struct tdb *gettdbbysrc(union sockaddr_union *, u_int8_t,
struct mbuf *, int);
extern void puttdb(struct tdb *);
-extern void tdb_delete(struct tdb *, int);
+extern void tdb_delete(struct tdb *);
extern int tdb_init(struct tdb *, u_int16_t, struct ipsecinit *);
-extern void tdb_expiration(struct tdb *, int);
-/* Flag values for the last argument of tdb_expiration(). */
-#define TDBEXP_EARLY 1 /* The tdb is likely to end up early. */
-#define TDBEXP_TIMEOUT 2 /* Maintain expiration timeout. */
extern int tdb_walk(int (*)(struct tdb *, void *, int), void *);
-extern void handle_expirations(void *);
/* XF_IP4 */
extern int ipe4_attach(void);
diff --git a/sys/netinet/ipsec_input.c b/sys/netinet/ipsec_input.c
index de37437259d..65dd05c11ff 100644
--- a/sys/netinet/ipsec_input.c
+++ b/sys/netinet/ipsec_input.c
@@ -1,11 +1,11 @@
-/* $OpenBSD: ipsec_input.c,v 1.32 2000/09/19 03:20:59 angelos Exp $ */
+/* $OpenBSD: ipsec_input.c,v 1.33 2001/03/15 06:31:00 mickey Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
- * Angelos D. Keromytis (kermit@csd.uch.gr) and
+ * Angelos D. Keromytis (kermit@csd.uch.gr) and
* Niels Provos (provos@physnet.uni-hamburg.de).
*
- * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
+ * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
* in November 1995.
*
* Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
@@ -18,11 +18,11 @@
*
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
* Angelos D. Keromytis and Niels Provos.
- *
+ *
* 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
- * modification of this software.
+ * modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
@@ -193,7 +193,7 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
IPSEC_ISTAT(espstat.esps_notdb, ahstat.ahs_notdb);
return ENOENT;
}
-
+
if (tdbp->tdb_flags & TDBF_INVALID)
{
splx(s);
@@ -228,7 +228,10 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
if (tdbp->tdb_first_use == 0)
{
tdbp->tdb_first_use = time.tv_sec;
- tdb_expiration(tdbp, TDBEXP_TIMEOUT);
+ if (tdbp->tdb_flags & TDBF_FIRSTUSE)
+ timeout_add(&tdbp->tdb_first_tmo, hz * tdbp->tdb_exp_first_use);
+ if (tdbp->tdb_flags & TDBF_SOFT_FIRSTUSE)
+ timeout_add(&tdbp->tdb_sfirst_tmo, hz * tdbp->tdb_soft_first_use);
}
/*
@@ -348,7 +351,7 @@ ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff)
}
#endif /* INET6 */
- /*
+ /*
* Check that the source address is an expected one, if we know what
* it's supposed to be. This avoids source address spoofing.
*/
@@ -432,7 +435,7 @@ ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff)
}
}
- /*
+ /*
* Check that the source address is an expected one, if we know what
* it's supposed to be. This avoids source address spoofing.
*/
@@ -490,7 +493,7 @@ ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff)
bpfif = (struct ifnet *) tdbp->tdb_interface;
else
bpfif = &encif[0].sc_if;
- if (bpfif->if_bpf)
+ if (bpfif->if_bpf)
{
/*
* We need to prepend the address family as
@@ -509,7 +512,7 @@ ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff)
m1.m_next = m;
m1.m_len = ENC_HDRLEN;
m1.m_data = (char *) &hdr;
-
+
bpf_mtap(bpfif->if_bpf, &m1);
}
#endif
@@ -621,7 +624,7 @@ ah4_input_cb(struct mbuf *m, ...)
struct ifqueue *ifq = &ipintrq;
/*
- * Interface pointer is already in first mbuf; chop off the
+ * Interface pointer is already in first mbuf; chop off the
* `outer' header and reschedule.
*/
@@ -664,7 +667,7 @@ esp4_input_cb(struct mbuf *m, ...)
struct ifqueue *ifq = &ipintrq;
/*
- * Interface pointer is already in first mbuf; chop off the
+ * Interface pointer is already in first mbuf; chop off the
* `outer' header and reschedule.
*/
if (IF_QFULL(ifq))
diff --git a/sys/netinet/ipsec_output.c b/sys/netinet/ipsec_output.c
index 3bc9239757c..724a7b7ded5 100644
--- a/sys/netinet/ipsec_output.c
+++ b/sys/netinet/ipsec_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsec_output.c,v 1.2 2000/09/19 08:38:59 angelos Exp $ */
+/* $OpenBSD: ipsec_output.c,v 1.3 2001/03/15 06:31:00 mickey Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
@@ -8,7 +8,7 @@
* 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
- * modification of this software.
+ * modification of this software.
* You may use this code under the GNU public license if you so wish. Please
* contribute changes back to the authors under this freer than GPL license
* so that we may further the use of strong encryption without limitations to
@@ -127,7 +127,10 @@ ipsp_process_packet(struct mbuf *m, struct tdb *tdb, int af, int tunalready)
if (tdb->tdb_first_use == 0)
{
tdb->tdb_first_use = time.tv_sec;
- tdb_expiration(tdb, TDBEXP_TIMEOUT);
+ if (tdb->tdb_flags & TDBF_FIRSTUSE)
+ timeout_add(&tdb->tdb_first_tmo, hz * tdb->tdb_exp_first_use);
+ if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE)
+ timeout_add(&tdb->tdb_sfirst_tmo, hz * tdb->tdb_soft_first_use);
}
/*