summaryrefslogtreecommitdiff
path: root/sys/netinet/ip_ipsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/ip_ipsp.c')
-rw-r--r--sys/netinet/ip_ipsp.c1902
1 files changed, 929 insertions, 973 deletions
diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c
index 90d98d84e1e..b74e6526a5d 100644
--- a/sys/netinet/ip_ipsp.c
+++ b/sys/netinet/ip_ipsp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.c,v 1.135 2001/06/25 05:11:58 angelos Exp $ */
+/* $OpenBSD: ip_ipsp.c,v 1.136 2001/06/26 03:52:40 angelos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
@@ -71,13 +71,13 @@ void tdb_hashstats(void);
#endif
#ifdef ENCDEBUG
-#define DPRINTF(x) if (encdebug) printf x
+#define DPRINTF(x) if (encdebug) printf x
#else
-#define DPRINTF(x)
+#define DPRINTF(x)
#endif
#ifdef __GNUC__
-#define INLINE static __inline
+#define INLINE static __inline
#endif
int ipsp_kern __P((int, char **, int));
@@ -107,21 +107,21 @@ 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,
- ipip_output, },
- { XF_AH, XFT_AUTH, "IPsec AH",
- ah_attach, ah_init, ah_zeroize,
- ah_input, ah_output, },
- { XF_ESP, XFT_CONF|XFT_AUTH, "IPsec ESP",
- esp_attach, esp_init, esp_zeroize,
- esp_input, esp_output, },
+ { XF_IP4, 0, "IPv4 Simple Encapsulation",
+ ipe4_attach, ipe4_init, ipe4_zeroize,
+ (int (*)(struct mbuf *, struct tdb *, int, int))ipe4_input,
+ ipip_output, },
+ { XF_AH, XFT_AUTH, "IPsec AH",
+ ah_attach, ah_init, ah_zeroize,
+ ah_input, ah_output, },
+ { XF_ESP, XFT_CONF|XFT_AUTH, "IPsec ESP",
+ esp_attach, esp_init, esp_zeroize,
+ esp_input, esp_output, },
#ifdef TCP_SIGNATURE
- { XF_TCPSIGNATURE, XFT_AUTH, "TCP MD5 Signature Option, RFC 2385",
- tcp_signature_tdb_attach, tcp_signature_tdb_init,
- tcp_signature_tdb_zeroize, tcp_signature_tdb_input,
- tcp_signature_tdb_output, }
+ { XF_TCPSIGNATURE, XFT_AUTH, "TCP MD5 Signature Option, RFC 2385",
+ tcp_signature_tdb_attach, tcp_signature_tdb_init,
+ tcp_signature_tdb_zeroize, tcp_signature_tdb_input,
+ tcp_signature_tdb_output, }
#endif /* TCP_SIGNATURE */
};
@@ -129,7 +129,8 @@ struct xformsw *xformswNXFORMSW = &xformsw[sizeof(xformsw)/sizeof(xformsw[0])];
unsigned char ipseczeroes[IPSEC_ZEROES_SIZE]; /* zeroes! */
-#define TDB_HASHSIZE_INIT 32
+#define TDB_HASHSIZE_INIT 32
+
static struct tdb **tdbh = NULL;
static struct tdb **tdbaddr = NULL;
static struct tdb **tdbsrc = NULL;
@@ -143,36 +144,34 @@ static int tdb_count;
INLINE int
tdb_hash(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto)
{
- static u_int32_t mult1 = 0, mult2 = 0;
- u_int8_t *ptr = (u_int8_t *) dst;
- int i, shift;
- u_int64_t hash;
- int val32 = 0;
-
- while (mult1 == 0)
- mult1 = arc4random();
- while (mult2 == 0)
- mult2 = arc4random();
-
- hash = (spi ^ proto) * mult1;
- for (i = 0; i < SA_LEN(&dst->sa); i++)
- {
- val32 = (val32 << 8) | ptr[i];
- if (i % 4 == 3)
- {
- hash ^= val32 * mult2;
- val32 = 0;
+ static u_int32_t mult1 = 0, mult2 = 0;
+ u_int8_t *ptr = (u_int8_t *) dst;
+ int i, shift;
+ u_int64_t hash;
+ int val32 = 0;
+
+ while (mult1 == 0)
+ mult1 = arc4random();
+ while (mult2 == 0)
+ mult2 = arc4random();
+
+ hash = (spi ^ proto) * mult1;
+ for (i = 0; i < SA_LEN(&dst->sa); i++) {
+ val32 = (val32 << 8) | ptr[i];
+ if (i % 4 == 3) {
+ hash ^= val32 * mult2;
+ val32 = 0;
+ }
}
- }
- if (i % 4 != 0)
- hash ^= val32 * mult2;
+ if (i % 4 != 0)
+ hash ^= val32 * mult2;
- shift = ffs(tdb_hashmask + 1);
- while ((hash & ~tdb_hashmask) != 0)
- hash = (hash >> shift) ^ (hash & tdb_hashmask);
+ shift = ffs(tdb_hashmask + 1);
+ while ((hash & ~tdb_hashmask) != 0)
+ hash = (hash >> shift) ^ (hash & tdb_hashmask);
- return hash;
+ return hash;
}
/*
@@ -181,72 +180,69 @@ tdb_hash(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto)
*/
u_int32_t
reserve_spi(u_int32_t sspi, u_int32_t tspi, union sockaddr_union *src,
- union sockaddr_union *dst, u_int8_t sproto, int *errval)
+ union sockaddr_union *dst, u_int8_t sproto, int *errval)
{
- struct tdb *tdbp;
- u_int32_t spi;
- int nums, s;
-
- /* Don't accept ranges only encompassing reserved SPIs. */
- if (tspi < sspi || tspi <= SPI_RESERVED_MAX)
- {
- (*errval) = EINVAL;
- return 0;
- }
-
- /* Limit the range to not include reserved areas. */
- if (sspi <= SPI_RESERVED_MAX)
- sspi = SPI_RESERVED_MAX + 1;
-
- if (sspi == tspi) /* Asking for a specific SPI */
- nums = 1;
- else
- nums = 100; /* Arbitrarily chosen */
-
- while (nums--)
- {
- if (sspi == tspi) /* Specific SPI asked */
- spi = tspi;
- else /* Range specified */
- spi = sspi + (arc4random() % (tspi - sspi));
-
- /* Don't allocate reserved SPIs. */
- if (spi >= SPI_RESERVED_MIN && spi <= SPI_RESERVED_MAX)
- continue;
- else
- spi = htonl(spi);
-
- /* Check whether we're using this SPI already */
- s = spltdb();
- tdbp = gettdb(spi, dst, sproto);
- splx(s);
+ struct tdb *tdbp;
+ u_int32_t spi;
+ int nums, s;
- if (tdbp != (struct tdb *) NULL)
- continue;
-
- tdbp = tdb_alloc();
-
- 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));
- tdbp->tdb_sproto = sproto;
- tdbp->tdb_flags |= TDBF_INVALID; /* Mark SA as invalid for now */
- tdbp->tdb_satype = SADB_SATYPE_UNSPEC;
- puttdb(tdbp);
-
- /* Setup a "silent" expiration (since TDBF_INVALID's set) */
- if (ipsec_keep_invalid > 0)
- {
- tdbp->tdb_flags |= TDBF_TIMER;
- tdbp->tdb_exp_timeout = ipsec_keep_invalid;
- timeout_add(&tdbp->tdb_timer_tmo, hz * ipsec_keep_invalid);
+ /* Don't accept ranges only encompassing reserved SPIs. */
+ if (tspi < sspi || tspi <= SPI_RESERVED_MAX) {
+ (*errval) = EINVAL;
+ return 0;
}
- return spi;
- }
+ /* Limit the range to not include reserved areas. */
+ if (sspi <= SPI_RESERVED_MAX)
+ sspi = SPI_RESERVED_MAX + 1;
+
+ if (sspi == tspi) /* Asking for a specific SPI */
+ nums = 1;
+ else
+ nums = 100; /* Arbitrarily chosen */
+
+ while (nums--) {
+ if (sspi == tspi) /* Specific SPI asked */
+ spi = tspi;
+ else /* Range specified */
+ spi = sspi + (arc4random() % (tspi - sspi));
+
+ /* Don't allocate reserved SPIs. */
+ if (spi >= SPI_RESERVED_MIN && spi <= SPI_RESERVED_MAX)
+ continue;
+ else
+ spi = htonl(spi);
+
+ /* Check whether we're using this SPI already */
+ s = spltdb();
+ tdbp = gettdb(spi, dst, sproto);
+ splx(s);
+
+ if (tdbp != (struct tdb *) NULL)
+ continue;
+
+ tdbp = tdb_alloc();
+
+ 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));
+ tdbp->tdb_sproto = sproto;
+ tdbp->tdb_flags |= TDBF_INVALID; /* Mark SA invalid for now */
+ tdbp->tdb_satype = SADB_SATYPE_UNSPEC;
+ puttdb(tdbp);
+
+ /* Setup a "silent" expiration (since TDBF_INVALID's set) */
+ if (ipsec_keep_invalid > 0) {
+ tdbp->tdb_flags |= TDBF_TIMER;
+ tdbp->tdb_exp_timeout = ipsec_keep_invalid;
+ timeout_add(&tdbp->tdb_timer_tmo, hz * ipsec_keep_invalid);
+ }
+
+ return spi;
+ }
- (*errval) = EEXIST;
- return 0;
+ (*errval) = EEXIST;
+ return 0;
}
/*
@@ -261,21 +257,21 @@ reserve_spi(u_int32_t sspi, u_int32_t tspi, union sockaddr_union *src,
struct tdb *
gettdb(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto)
{
- u_int32_t hashval;
- struct tdb *tdbp;
+ u_int32_t hashval;
+ struct tdb *tdbp;
- if (tdbh == NULL)
- return (struct tdb *) NULL;
+ if (tdbh == NULL)
+ return (struct tdb *) NULL;
- hashval = tdb_hash(spi, dst, proto);
+ hashval = tdb_hash(spi, dst, proto);
- for (tdbp = tdbh[hashval]; tdbp != NULL; tdbp = tdbp->tdb_hnext)
- if ((tdbp->tdb_spi == spi) &&
- !bcmp(&tdbp->tdb_dst, dst, SA_LEN(&dst->sa)) &&
- (tdbp->tdb_sproto == proto))
- break;
+ for (tdbp = tdbh[hashval]; tdbp != NULL; tdbp = tdbp->tdb_hnext)
+ if ((tdbp->tdb_spi == spi) &&
+ !bcmp(&tdbp->tdb_dst, dst, SA_LEN(&dst->sa)) &&
+ (tdbp->tdb_sproto == proto))
+ break;
- return tdbp;
+ return tdbp;
}
/*
@@ -284,77 +280,64 @@ gettdb(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto)
*/
struct tdb *
gettdbbyaddr(union sockaddr_union *dst, struct ipsec_policy *ipo,
- struct mbuf *m, int af)
+ struct mbuf *m, int af)
{
- u_int32_t hashval;
- struct tdb *tdbp;
-
- if (tdbaddr == NULL)
- return (struct tdb *) NULL;
-
- hashval = tdb_hash(0, dst, ipo->ipo_sproto);
-
- for (tdbp = tdbaddr[hashval]; tdbp != NULL; tdbp = tdbp->tdb_anext)
- if ((tdbp->tdb_sproto == ipo->ipo_sproto) &&
- ((tdbp->tdb_flags & TDBF_INVALID) == 0) &&
- (!bcmp(&tdbp->tdb_dst, dst, SA_LEN(&dst->sa))))
- {
- /*
- * If the IDs are not set, this was probably a manually-keyed
- * SA, so it can be used for any type of traffic.
- */
- if (tdbp->tdb_srcid != NULL)
- {
- if (ipo->ipo_srcid != NULL)
- {
- if (!ipsp_ref_match(ipo->ipo_srcid, tdbp->tdb_srcid))
- continue;
- }
-
- /* Otherwise, this is fine */
- }
- else
- if (ipo->ipo_srcid != NULL)
- continue;
-
- if (tdbp->tdb_dstid != NULL)
- {
- if (ipo->ipo_dstid != NULL)
- {
- if (!ipsp_ref_match(ipo->ipo_dstid, tdbp->tdb_dstid))
- continue;
- }
-
- /* Otherwise, this is fine */
- }
- else
- if (ipo->ipo_dstid != NULL)
- continue;
-
- /* Check for credential matches */
- if (tdbp->tdb_local_cred != NULL)
- {
- if (ipo->ipo_local_cred != NULL)
- {
- if (!ipsp_ref_match(ipo->ipo_local_cred,
- tdbp->tdb_local_cred))
- continue;
- }
- }
- else
- if (ipo->ipo_local_cred != NULL)
- continue; /* If no credential was used in the TDB, try
- * to establish a new SA with the given
- * credential, since some type of access control
- * may be done on the other side based on that
- * credential.
- */
+ u_int32_t hashval;
+ struct tdb *tdbp;
+
+ if (tdbaddr == NULL)
+ return (struct tdb *) NULL;
+
+ hashval = tdb_hash(0, dst, ipo->ipo_sproto);
- /* XXX Check for filter matches */
- break;
- }
+ for (tdbp = tdbaddr[hashval]; tdbp != NULL; tdbp = tdbp->tdb_anext)
+ if ((tdbp->tdb_sproto == ipo->ipo_sproto) &&
+ ((tdbp->tdb_flags & TDBF_INVALID) == 0) &&
+ (!bcmp(&tdbp->tdb_dst, dst, SA_LEN(&dst->sa)))) {
+ /*
+ * If the IDs are not set, this was probably a manually-keyed
+ * SA, so it can be used for any type of traffic.
+ */
+ if (tdbp->tdb_srcid != NULL) {
+ if (ipo->ipo_srcid != NULL &&
+ !ipsp_ref_match(ipo->ipo_srcid,
+ tdbp->tdb_srcid))
+ continue;
+ /* Otherwise, this is fine */
+ } else if (ipo->ipo_srcid != NULL)
+ continue;
+
+ if (tdbp->tdb_dstid != NULL) {
+ if (ipo->ipo_dstid != NULL &&
+ !ipsp_ref_match(ipo->ipo_dstid,
+ tdbp->tdb_dstid))
+ continue;
+ /* Otherwise, this is fine */
+ } else if (ipo->ipo_dstid != NULL)
+ continue;
+
+ /* Check for credential matches */
+ if (tdbp->tdb_local_cred != NULL) {
+ if (ipo->ipo_local_cred != NULL &&
+ !ipsp_ref_match(ipo->ipo_local_cred,
+ tdbp->tdb_local_cred))
+ continue;
+ } else if (ipo->ipo_local_cred != NULL)
+ continue; /* If no credential was used
+ * in the TDB, try to
+ * establish a new SA with
+ * the given credential,
+ * since some type of access
+ * control may be done on
+ * the other side based on
+ * that credential.
+ */
+
+ /* XXX Check for filter matches */
+ break;
+ }
- return tdbp;
+ return tdbp;
}
/*
@@ -363,86 +346,75 @@ gettdbbyaddr(union sockaddr_union *dst, struct ipsec_policy *ipo,
*/
struct tdb *
gettdbbysrc(union sockaddr_union *src, struct ipsec_policy *ipo,
- struct mbuf *m, int af)
+ struct mbuf *m, int af)
{
- u_int32_t hashval;
- struct tdb *tdbp;
-
- if (tdbsrc == NULL)
- return (struct tdb *) NULL;
-
- hashval = tdb_hash(0, src, ipo->ipo_sproto);
-
- for (tdbp = tdbsrc[hashval]; tdbp != NULL; tdbp = tdbp->tdb_snext)
- if ((tdbp->tdb_sproto == ipo->ipo_sproto) &&
- ((tdbp->tdb_flags & TDBF_INVALID) == 0) &&
- (!bcmp(&tdbp->tdb_src, src, SA_LEN(&src->sa))))
- {
- /*
- * If the IDs are not set, this was probably a manually-keyed
- * SA, so it can be used for any type of traffic.
- */
- if (tdbp->tdb_srcid != NULL)
- {
- if (ipo->ipo_dstid != NULL)
- {
- if (!ipsp_ref_match(ipo->ipo_dstid, tdbp->tdb_srcid))
- continue;
- }
-
- /* Otherwise, this is fine */
- }
- else
- if (ipo->ipo_dstid != NULL)
- continue;
-
- if (tdbp->tdb_dstid != NULL)
- {
- if (ipo->ipo_srcid != NULL)
- {
- if (!ipsp_ref_match(ipo->ipo_srcid, tdbp->tdb_dstid))
- continue;
- }
-
- /* Otherwise, this is fine */
- }
- else
- if (ipo->ipo_srcid != NULL)
- continue;
-
- /* XXX Check for filter matches */
- break;
- }
-
- return tdbp;
+ u_int32_t hashval;
+ struct tdb *tdbp;
+
+ if (tdbsrc == NULL)
+ return (struct tdb *) NULL;
+
+ hashval = tdb_hash(0, src, ipo->ipo_sproto);
+
+ for (tdbp = tdbsrc[hashval]; tdbp != NULL; tdbp = tdbp->tdb_snext)
+ if ((tdbp->tdb_sproto == ipo->ipo_sproto) &&
+ ((tdbp->tdb_flags & TDBF_INVALID) == 0) &&
+ (!bcmp(&tdbp->tdb_src, src, SA_LEN(&src->sa)))) {
+ /*
+ * If the IDs are not set, this was probably a manually-keyed
+ * SA, so it can be used for any type of traffic.
+ */
+ if (tdbp->tdb_srcid != NULL) {
+ if (ipo->ipo_dstid != NULL &&
+ !ipsp_ref_match(ipo->ipo_dstid,
+ tdbp->tdb_srcid))
+ continue;
+ /* Otherwise, this is fine */
+ } else if (ipo->ipo_dstid != NULL)
+ continue;
+
+ if (tdbp->tdb_dstid != NULL) {
+ if (ipo->ipo_srcid != NULL &&
+ !ipsp_ref_match(ipo->ipo_srcid,
+ tdbp->tdb_dstid))
+ continue;
+ /* Otherwise, this is fine */
+ } else if (ipo->ipo_srcid != NULL)
+ continue;
+
+ /* XXX Check for filter matches */
+ break;
+ }
+
+ return tdbp;
}
#if DDB
void
tdb_hashstats(void)
{
- int i, cnt, buckets[16];
- struct tdb *tdbp;
-
- if (tdbh == NULL)
- {
- db_printf("no tdb hash table\n");
- return;
- }
-
- bzero (buckets, sizeof(buckets));
- for (i = 0; i <= tdb_hashmask; i++)
- {
- cnt = 0;
- for (tdbp = tdbh[i]; cnt < 16 && tdbp != NULL; tdbp = tdbp->tdb_hnext)
- cnt++;
- buckets[cnt]++;
- }
-
- db_printf("tdb cnt\t\tbucket cnt\n");
- for (i = 0; i < 16; i++)
- if (buckets[i] > 0)
- db_printf("%d%c\t\t%d\n", i, i == 15 ? "+" : "", buckets[i]);
+ int i, cnt, buckets[16];
+ struct tdb *tdbp;
+
+ if (tdbh == NULL) {
+ db_printf("no tdb hash table\n");
+ return;
+ }
+
+ bzero (buckets, sizeof(buckets));
+ for (i = 0; i <= tdb_hashmask; i++) {
+ cnt = 0;
+ for (tdbp = tdbh[i]; cnt < 16 && tdbp != NULL;
+ tdbp = tdbp->tdb_hnext)
+ cnt++;
+ buckets[cnt]++;
+ }
+
+ db_printf("tdb cnt\t\tbucket cnt\n");
+ for (i = 0; i < 16; i++)
+ if (buckets[i] > 0)
+ db_printf("%d%c\t\t%d\n", i, i == 15 ? "+" : "",
+ buckets[i]);
}
#endif /* DDB */
@@ -452,23 +424,22 @@ tdb_hashstats(void)
int
tdb_walk(int (*walker)(struct tdb *, void *, int), void *arg)
{
- int i, rval = 0;
- struct tdb *tdbp, *next;
-
- if (tdbh == NULL)
- return ENOENT;
-
- for (i = 0; i <= tdb_hashmask; i++)
- for (tdbp = tdbh[i]; rval == 0 && tdbp != NULL; tdbp = next)
- {
- next = tdbp->tdb_hnext;
- if (i == tdb_hashmask && next == NULL)
- rval = walker(tdbp, (void *)arg, 1);
- else
- rval = walker(tdbp, (void *)arg, 0);
- }
-
- return rval;
+ int i, rval = 0;
+ struct tdb *tdbp, *next;
+
+ if (tdbh == NULL)
+ return ENOENT;
+
+ for (i = 0; i <= tdb_hashmask; i++)
+ for (tdbp = tdbh[i]; rval == 0 && tdbp != NULL; tdbp = next) {
+ next = tdbp->tdb_hnext;
+ if (i == tdb_hashmask && next == NULL)
+ rval = walker(tdbp, (void *)arg, 1);
+ else
+ rval = walker(tdbp, (void *)arg, 0);
+ }
+
+ return rval;
}
/*
@@ -535,59 +506,55 @@ tdb_soft_firstuse(void *v)
void
tdb_rehash(void)
{
- struct tdb **new_tdbh, **new_tdbaddr, **new_srcaddr, *tdbp, *tdbnp;
- u_int i, old_hashmask = tdb_hashmask;
- u_int32_t hashval;
-
- tdb_hashmask = (tdb_hashmask << 1) | 1;
-
- MALLOC(new_tdbh, struct tdb **, sizeof(struct tdb *) * (tdb_hashmask + 1),
- M_TDB, M_WAITOK);
- MALLOC(new_tdbaddr, struct tdb **,
- sizeof(struct tdb *) * (tdb_hashmask + 1), M_TDB, M_WAITOK);
- MALLOC(new_srcaddr, struct tdb **,
- sizeof(struct tdb *) * (tdb_hashmask + 1), M_TDB, M_WAITOK);
-
- bzero(new_tdbh, sizeof(struct tdb *) * (tdb_hashmask + 1));
- bzero(new_tdbaddr, sizeof(struct tdb *) * (tdb_hashmask + 1));
- bzero(new_srcaddr, sizeof(struct tdb *) * (tdb_hashmask + 1));
-
- for (i = 0; i <= old_hashmask; i++)
- {
- for (tdbp = tdbh[i]; tdbp != NULL; tdbp = tdbnp)
- {
- tdbnp = tdbp->tdb_hnext;
- hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst,
- tdbp->tdb_sproto);
- tdbp->tdb_hnext = new_tdbh[hashval];
- new_tdbh[hashval] = tdbp;
- }
+ struct tdb **new_tdbh, **new_tdbaddr, **new_srcaddr, *tdbp, *tdbnp;
+ u_int i, old_hashmask = tdb_hashmask;
+ u_int32_t hashval;
+
+ tdb_hashmask = (tdb_hashmask << 1) | 1;
+
+ MALLOC(new_tdbh, struct tdb **, sizeof(struct tdb *) * (tdb_hashmask + 1),
+ M_TDB, M_WAITOK);
+ MALLOC(new_tdbaddr, struct tdb **,
+ sizeof(struct tdb *) * (tdb_hashmask + 1), M_TDB, M_WAITOK);
+ MALLOC(new_srcaddr, struct tdb **,
+ sizeof(struct tdb *) * (tdb_hashmask + 1), M_TDB, M_WAITOK);
+
+ bzero(new_tdbh, sizeof(struct tdb *) * (tdb_hashmask + 1));
+ bzero(new_tdbaddr, sizeof(struct tdb *) * (tdb_hashmask + 1));
+ bzero(new_srcaddr, sizeof(struct tdb *) * (tdb_hashmask + 1));
+
+ for (i = 0; i <= old_hashmask; i++) {
+ for (tdbp = tdbh[i]; tdbp != NULL; tdbp = tdbnp) {
+ tdbnp = tdbp->tdb_hnext;
+ hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst,
+ tdbp->tdb_sproto);
+ tdbp->tdb_hnext = new_tdbh[hashval];
+ new_tdbh[hashval] = tdbp;
+ }
- for (tdbp = tdbaddr[i]; tdbp != NULL; tdbp = tdbnp)
- {
- tdbnp = tdbp->tdb_anext;
- hashval = tdb_hash(0, &tdbp->tdb_dst, tdbp->tdb_sproto);
- tdbp->tdb_anext = new_tdbaddr[hashval];
- new_tdbaddr[hashval] = tdbp;
- }
+ for (tdbp = tdbaddr[i]; tdbp != NULL; tdbp = tdbnp) {
+ tdbnp = tdbp->tdb_anext;
+ hashval = tdb_hash(0, &tdbp->tdb_dst, tdbp->tdb_sproto);
+ tdbp->tdb_anext = new_tdbaddr[hashval];
+ new_tdbaddr[hashval] = tdbp;
+ }
- for (tdbp = tdbsrc[i]; tdbp != NULL; tdbp = tdbnp)
- {
- tdbnp = tdbp->tdb_snext;
- hashval = tdb_hash(0, &tdbp->tdb_src, tdbp->tdb_sproto);
- tdbp->tdb_snext = new_srcaddr[hashval];
- new_srcaddr[hashval] = tdbp;
+ for (tdbp = tdbsrc[i]; tdbp != NULL; tdbp = tdbnp) {
+ tdbnp = tdbp->tdb_snext;
+ hashval = tdb_hash(0, &tdbp->tdb_src, tdbp->tdb_sproto);
+ tdbp->tdb_snext = new_srcaddr[hashval];
+ new_srcaddr[hashval] = tdbp;
+ }
}
- }
- FREE(tdbh, M_TDB);
- tdbh = new_tdbh;
+ FREE(tdbh, M_TDB);
+ tdbh = new_tdbh;
- FREE(tdbaddr, M_TDB);
- tdbaddr = new_tdbaddr;
+ FREE(tdbaddr, M_TDB);
+ tdbaddr = new_tdbaddr;
- FREE(tdbsrc, M_TDB);
- tdbsrc = new_srcaddr;
+ FREE(tdbsrc, M_TDB);
+ tdbsrc = new_srcaddr;
}
/*
@@ -596,57 +563,57 @@ tdb_rehash(void)
void
puttdb(struct tdb *tdbp)
{
- u_int32_t hashval;
- int s = spltdb();
-
- if (tdbh == NULL)
- {
- MALLOC(tdbh, struct tdb **, sizeof(struct tdb *) * (tdb_hashmask + 1),
- M_TDB, M_WAITOK);
- MALLOC(tdbaddr, struct tdb **,
- sizeof(struct tdb *) * (tdb_hashmask + 1),
- M_TDB, M_WAITOK);
- MALLOC(tdbsrc, struct tdb **,
- sizeof(struct tdb *) * (tdb_hashmask + 1),
- M_TDB, M_WAITOK);
-
- bzero(tdbh, sizeof(struct tdb *) * (tdb_hashmask + 1));
- bzero(tdbaddr, sizeof(struct tdb *) * (tdb_hashmask + 1));
- bzero(tdbsrc, sizeof(struct tdb *) * (tdb_hashmask + 1));
- }
-
- 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
- * number is arbitratily chosen and is just a measure to not keep rehashing
- * when adding and removing tdbs which happens to always end up in the
- * same bucket, which is not uncommon when doing manual keying.
- */
- if (tdbh[hashval] != NULL && tdbh[hashval]->tdb_hnext != NULL &&
- tdb_count * 10 > tdb_hashmask + 1)
- {
- tdb_rehash();
+ u_int32_t hashval;
+ int s = spltdb();
+
+ if (tdbh == NULL) {
+ MALLOC(tdbh, struct tdb **,
+ sizeof(struct tdb *) * (tdb_hashmask + 1),
+ M_TDB, M_WAITOK);
+ MALLOC(tdbaddr, struct tdb **,
+ sizeof(struct tdb *) * (tdb_hashmask + 1),
+ M_TDB, M_WAITOK);
+ MALLOC(tdbsrc, struct tdb **,
+ sizeof(struct tdb *) * (tdb_hashmask + 1),
+ M_TDB, M_WAITOK);
+
+ bzero(tdbh, sizeof(struct tdb *) * (tdb_hashmask + 1));
+ bzero(tdbaddr, sizeof(struct tdb *) * (tdb_hashmask + 1));
+ bzero(tdbsrc, sizeof(struct tdb *) * (tdb_hashmask + 1));
+ }
+
hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst, tdbp->tdb_sproto);
- }
- tdbp->tdb_hnext = tdbh[hashval];
- tdbh[hashval] = tdbp;
+ /*
+ * 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
+ * number is arbitratily chosen and is just a measure to not keep rehashing
+ * when adding and removing tdbs which happens to always end up in the
+ * same bucket, which is not uncommon when doing manual keying.
+ */
+ if (tdbh[hashval] != NULL && tdbh[hashval]->tdb_hnext != NULL &&
+ tdb_count * 10 > tdb_hashmask + 1) {
+ tdb_rehash();
+ hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst,
+ tdbp->tdb_sproto);
+ }
+
+ tdbp->tdb_hnext = tdbh[hashval];
+ tdbh[hashval] = tdbp;
- hashval = tdb_hash(0, &tdbp->tdb_dst, tdbp->tdb_sproto);
- tdbp->tdb_anext = tdbaddr[hashval];
- tdbaddr[hashval] = tdbp;
+ hashval = tdb_hash(0, &tdbp->tdb_dst, tdbp->tdb_sproto);
+ tdbp->tdb_anext = tdbaddr[hashval];
+ tdbaddr[hashval] = tdbp;
- hashval = tdb_hash(0, &tdbp->tdb_src, tdbp->tdb_sproto);
- tdbp->tdb_snext = tdbsrc[hashval];
- tdbsrc[hashval] = tdbp;
+ hashval = tdb_hash(0, &tdbp->tdb_src, tdbp->tdb_sproto);
+ tdbp->tdb_snext = tdbsrc[hashval];
+ tdbsrc[hashval] = tdbp;
- tdb_count++;
+ tdb_count++;
- ipsec_last_added = time.tv_sec;
+ ipsec_last_added = time.tv_sec;
- splx(s);
+ splx(s);
}
/*
@@ -655,152 +622,143 @@ puttdb(struct tdb *tdbp)
void
tdb_delete(struct tdb *tdbp)
{
- struct ipsec_policy *ipo;
- struct tdb *tdbpp;
- struct inpcb *inp;
- u_int32_t hashval;
- int s;
-
- if (tdbh == NULL)
- return;
-
- hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst, tdbp->tdb_sproto);
-
- s = spltdb();
- if (tdbh[hashval] == tdbp)
- {
- tdbpp = tdbp;
- tdbh[hashval] = tdbp->tdb_hnext;
- }
- else
- for (tdbpp = tdbh[hashval]; tdbpp != NULL; tdbpp = tdbpp->tdb_hnext)
- if (tdbpp->tdb_hnext == tdbp)
- {
- tdbpp->tdb_hnext = tdbp->tdb_hnext;
- tdbpp = tdbp;
- break;
+ struct ipsec_policy *ipo;
+ struct tdb *tdbpp;
+ struct inpcb *inp;
+ u_int32_t hashval;
+ int s;
+
+ if (tdbh == NULL)
+ return;
+
+ hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst, tdbp->tdb_sproto);
+
+ s = spltdb();
+ if (tdbh[hashval] == tdbp) {
+ tdbpp = tdbp;
+ tdbh[hashval] = tdbp->tdb_hnext;
+ } else {
+ for (tdbpp = tdbh[hashval]; tdbpp != NULL;
+ tdbpp = tdbpp->tdb_hnext) {
+ if (tdbpp->tdb_hnext == tdbp) {
+ tdbpp->tdb_hnext = tdbp->tdb_hnext;
+ tdbpp = tdbp;
+ break;
+ }
+ }
}
- tdbp->tdb_hnext = NULL;
-
- hashval = tdb_hash(0, &tdbp->tdb_dst, tdbp->tdb_sproto);
-
- if (tdbaddr[hashval] == tdbp)
- {
- tdbpp = tdbp;
- tdbaddr[hashval] = tdbp->tdb_anext;
- }
- else
- for (tdbpp = tdbaddr[hashval]; tdbpp != NULL; tdbpp = tdbpp->tdb_anext)
- if (tdbpp->tdb_anext == tdbp)
- {
- tdbpp->tdb_anext = tdbp->tdb_anext;
- tdbpp = tdbp;
- break;
+ tdbp->tdb_hnext = NULL;
+
+ hashval = tdb_hash(0, &tdbp->tdb_dst, tdbp->tdb_sproto);
+
+ if (tdbaddr[hashval] == tdbp) {
+ tdbpp = tdbp;
+ tdbaddr[hashval] = tdbp->tdb_anext;
+ } else {
+ for (tdbpp = tdbaddr[hashval]; tdbpp != NULL;
+ tdbpp = tdbpp->tdb_anext) {
+ if (tdbpp->tdb_anext == tdbp) {
+ tdbpp->tdb_anext = tdbp->tdb_anext;
+ tdbpp = tdbp;
+ break;
+ }
+ }
}
- hashval = tdb_hash(0, &tdbp->tdb_src, tdbp->tdb_sproto);
-
- if (tdbsrc[hashval] == tdbp)
- {
- tdbpp = tdbp;
- tdbsrc[hashval] = tdbp->tdb_snext;
- }
- else
- for (tdbpp = tdbsrc[hashval]; tdbpp != NULL; tdbpp = tdbpp->tdb_snext)
- if (tdbpp->tdb_snext == tdbp)
- {
- tdbpp->tdb_snext = tdbp->tdb_snext;
- tdbpp = tdbp;
- break;
+ hashval = tdb_hash(0, &tdbp->tdb_src, tdbp->tdb_sproto);
+
+ if (tdbsrc[hashval] == tdbp) {
+ tdbpp = tdbp;
+ tdbsrc[hashval] = tdbp->tdb_snext;
}
+ else {
+ for (tdbpp = tdbsrc[hashval]; tdbpp != NULL;
+ tdbpp = tdbpp->tdb_snext) {
+ if (tdbpp->tdb_snext == tdbp) {
+ tdbpp->tdb_snext = tdbp->tdb_snext;
+ tdbpp = tdbp;
+ break;
+ }
+ }
+ }
+
+ tdbp->tdb_snext = NULL;
- tdbp->tdb_snext = NULL;
-
- if (tdbp->tdb_xform)
- {
- (*(tdbp->tdb_xform->xf_zeroize))(tdbp);
- tdbp->tdb_xform = NULL;
- }
-
- /* Cleanup inp references */
- for (inp = TAILQ_FIRST(&tdbp->tdb_inp_in); inp;
- inp = TAILQ_FIRST(&tdbp->tdb_inp_in))
- {
- TAILQ_REMOVE(&tdbp->tdb_inp_in, inp, inp_tdb_in_next);
- inp->inp_tdb_in = NULL;
- }
-
- for (inp = TAILQ_FIRST(&tdbp->tdb_inp_out); inp;
- inp = TAILQ_FIRST(&tdbp->tdb_inp_out))
- {
- TAILQ_REMOVE(&tdbp->tdb_inp_out, inp, inp_tdb_out_next);
- inp->inp_tdb_out = NULL;
- }
-
- /* Cleanup SPD references */
- for (ipo = TAILQ_FIRST(&tdbp->tdb_policy_head); ipo;
- ipo = TAILQ_FIRST(&tdbp->tdb_policy_head))
- {
- TAILQ_REMOVE(&tdbp->tdb_policy_head, ipo, ipo_tdb_next);
- ipo->ipo_tdb = NULL;
- ipo->ipo_last_searched = 0; /* Force a re-search */
- }
-
- /* 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_local_auth)
- {
- ipsp_reffree(tdbp->tdb_local_auth);
- tdbp->tdb_local_auth = NULL;
- }
-
- if (tdbp->tdb_remote_auth)
- {
- ipsp_reffree(tdbp->tdb_remote_auth);
- tdbp->tdb_remote_auth = NULL;
- }
-
- if (tdbp->tdb_srcid)
- {
- ipsp_reffree(tdbp->tdb_srcid);
- tdbp->tdb_srcid = NULL;
- }
-
- if (tdbp->tdb_dstid)
- {
- ipsp_reffree(tdbp->tdb_dstid);
- tdbp->tdb_dstid = NULL;
- }
-
- if (tdbp->tdb_local_cred)
- {
- ipsp_reffree(tdbp->tdb_local_cred);
- tdbp->tdb_local_cred = NULL;
- }
-
- if (tdbp->tdb_remote_cred)
- {
- ipsp_reffree(tdbp->tdb_remote_cred);
- tdbp->tdb_local_cred = NULL;
- }
-
- if ((tdbp->tdb_onext) && (tdbp->tdb_onext->tdb_inext == tdbp))
- tdbp->tdb_onext->tdb_inext = NULL;
-
- if ((tdbp->tdb_inext) && (tdbp->tdb_inext->tdb_onext == tdbp))
- tdbp->tdb_inext->tdb_onext = NULL;
-
- FREE(tdbp, M_TDB);
- tdb_count--;
-
- splx(s);
+ if (tdbp->tdb_xform) {
+ (*(tdbp->tdb_xform->xf_zeroize))(tdbp);
+ tdbp->tdb_xform = NULL;
+ }
+
+ /* Cleanup inp references */
+ for (inp = TAILQ_FIRST(&tdbp->tdb_inp_in); inp;
+ inp = TAILQ_FIRST(&tdbp->tdb_inp_in)) {
+ TAILQ_REMOVE(&tdbp->tdb_inp_in, inp, inp_tdb_in_next);
+ inp->inp_tdb_in = NULL;
+ }
+
+ for (inp = TAILQ_FIRST(&tdbp->tdb_inp_out); inp;
+ inp = TAILQ_FIRST(&tdbp->tdb_inp_out)) {
+ TAILQ_REMOVE(&tdbp->tdb_inp_out, inp, inp_tdb_out_next);
+ inp->inp_tdb_out = NULL;
+ }
+
+ /* Cleanup SPD references */
+ for (ipo = TAILQ_FIRST(&tdbp->tdb_policy_head); ipo;
+ ipo = TAILQ_FIRST(&tdbp->tdb_policy_head)) {
+ TAILQ_REMOVE(&tdbp->tdb_policy_head, ipo, ipo_tdb_next);
+ ipo->ipo_tdb = NULL;
+ ipo->ipo_last_searched = 0; /* Force a re-search */
+ }
+
+ /* 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_local_auth) {
+ ipsp_reffree(tdbp->tdb_local_auth);
+ tdbp->tdb_local_auth = NULL;
+ }
+
+ if (tdbp->tdb_remote_auth) {
+ ipsp_reffree(tdbp->tdb_remote_auth);
+ tdbp->tdb_remote_auth = NULL;
+ }
+
+ if (tdbp->tdb_srcid) {
+ ipsp_reffree(tdbp->tdb_srcid);
+ tdbp->tdb_srcid = NULL;
+ }
+
+ if (tdbp->tdb_dstid) {
+ ipsp_reffree(tdbp->tdb_dstid);
+ tdbp->tdb_dstid = NULL;
+ }
+
+ if (tdbp->tdb_local_cred) {
+ ipsp_reffree(tdbp->tdb_local_cred);
+ tdbp->tdb_local_cred = NULL;
+ }
+
+ if (tdbp->tdb_remote_cred) {
+ ipsp_reffree(tdbp->tdb_remote_cred);
+ tdbp->tdb_local_cred = NULL;
+ }
+
+ if ((tdbp->tdb_onext) && (tdbp->tdb_onext->tdb_inext == tdbp))
+ tdbp->tdb_onext->tdb_inext = NULL;
+
+ if ((tdbp->tdb_inext) && (tdbp->tdb_inext->tdb_onext == tdbp))
+ tdbp->tdb_inext->tdb_onext = NULL;
+
+ FREE(tdbp, M_TDB);
+ tdb_count--;
+
+ splx(s);
}
/*
@@ -839,252 +797,253 @@ tdb_alloc(void)
int
tdb_init(struct tdb *tdbp, u_int16_t alg, struct ipsecinit *ii)
{
- struct xformsw *xsp;
- int err;
+ struct xformsw *xsp;
+ int err;
- for (xsp = xformsw; xsp < xformswNXFORMSW; xsp++)
- if (xsp->xf_type == alg)
- {
- err = (*(xsp->xf_init))(tdbp, xsp, ii);
+ for (xsp = xformsw; xsp < xformswNXFORMSW; xsp++) {
+ if (xsp->xf_type == alg) {
+ err = (*(xsp->xf_init))(tdbp, xsp, ii);
- /* Clear possible pending acquires */
- if (!err)
- ipsp_clear_acquire(tdbp);
+ /* Clear possible pending acquires */
+ if (!err)
+ ipsp_clear_acquire(tdbp);
- return err;
- }
+ return err;
+ }
+ }
- 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));
+ 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));
- return EINVAL;
+ return EINVAL;
}
#ifdef KERNFS
/*
- * Used by kernfs.
+ * Print TDB information on a buffer.
*/
int
-ipsp_kern(int off, char **bufp, int len)
+ipsp_print_tdb(struct tdb *tdb, char *buffer)
{
- static char buffer[IPSEC_KERNFS_BUFSIZE];
- struct tdb *tdb;
- int l, i, s, k;
-
- struct ctlname ipspflags[] = { \
- { "unique", TDBF_UNIQUE }, \
- { "invalid", TDBF_INVALID }, \
- { "halfiv", TDBF_HALFIV }, \
- { "pfs", TDBF_PFS }, \
- { "tunneling", TDBF_TUNNELING }, \
- { "noreplay", TDBF_NOREPLAY }, \
- { "random padding", TDBF_RANDOMPADDING }, \
- { "skipcrypto", TDBF_SKIPCRYPTO }, \
- { "usedtunnel", TDBF_USEDTUNNEL }, \
- };
-
- if (bufp == NULL)
- return 0;
-
- bzero(buffer, IPSEC_KERNFS_BUFSIZE);
- *bufp = buffer;
-
- if (off == 0)
- {
- kernfs_epoch++;
- l = sprintf(buffer, "Hashmask: %d, policy entries: %d\n", tdb_hashmask,
- ipsec_in_use);
- return l;
- }
-
- if (tdbh == NULL)
- return 0;
-
- for (i = 0; i <= tdb_hashmask; i++)
- {
- s = spltdb();
- for (tdb = tdbh[i]; tdb; tdb = tdb->tdb_hnext)
- if (tdb->tdb_epoch != kernfs_epoch)
- {
- tdb->tdb_epoch = kernfs_epoch;
-
- l = sprintf(buffer,
- "SPI = %08x, Destination = %s, Sproto = %u\n",
- ntohl(tdb->tdb_spi),
- ipsp_address(tdb->tdb_dst), tdb->tdb_sproto);
-
- l += sprintf(buffer + l, "\tEstablished %d seconds ago\n",
- time.tv_sec - tdb->tdb_established);
-
- l += sprintf(buffer + l, "\tSource = %s",
- ipsp_address(tdb->tdb_src));
-
- if (tdb->tdb_proxy.sa.sa_family)
+ int l, i, k;
+
+ struct ctlname ipspflags[] = { \
+ { "unique", TDBF_UNIQUE }, \
+ { "invalid", TDBF_INVALID }, \
+ { "halfiv", TDBF_HALFIV }, \
+ { "pfs", TDBF_PFS }, \
+ { "tunneling", TDBF_TUNNELING }, \
+ { "noreplay", TDBF_NOREPLAY }, \
+ { "random padding", TDBF_RANDOMPADDING }, \
+ { "skipcrypto", TDBF_SKIPCRYPTO }, \
+ { "usedtunnel", TDBF_USEDTUNNEL }, \
+ };
+
+ l = sprintf(buffer, "SPI = %08x, Destination = %s, Sproto = %u\n",
+ ntohl(tdb->tdb_spi), ipsp_address(tdb->tdb_dst), tdb->tdb_sproto);
+
+ l += sprintf(buffer + l, "\tEstablished %d seconds ago\n",
+ time.tv_sec - tdb->tdb_established);
+
+ l += sprintf(buffer + l, "\tSource = %s", ipsp_address(tdb->tdb_src));
+
+ if (tdb->tdb_proxy.sa.sa_family)
l += sprintf(buffer + l, ", Proxy = %s\n",
- ipsp_address(tdb->tdb_proxy));
- else
+ ipsp_address(tdb->tdb_proxy));
+ else
l += sprintf(buffer + l, "\n");
- if (tdb->tdb_mtu && tdb->tdb_mtutimeout > time.tv_sec)
- l += sprintf(buffer + l,
- "\tMTU: %d, expires in %qu seconds\n",
- tdb->tdb_mtu, tdb->tdb_mtutimeout - time.tv_sec);
+ if (tdb->tdb_mtu && tdb->tdb_mtutimeout > time.tv_sec)
+ l += sprintf(buffer + l, "\tMTU: %d, expires in %qu seconds\n",
+ tdb->tdb_mtu, tdb->tdb_mtutimeout - time.tv_sec);
- if (tdb->tdb_local_cred)
- l += sprintf(buffer + l, "\tLocal credential type %d\n", ((struct ipsec_ref *) tdb->tdb_local_cred)->ref_type);
+ if (tdb->tdb_local_cred)
+ l += sprintf(buffer + l, "\tLocal credential type %d\n",
+ ((struct ipsec_ref *) tdb->tdb_local_cred)->ref_type);
- if (tdb->tdb_remote_cred)
- l += sprintf(buffer + l, "\tRemote credential type %d\n", ((struct ipsec_ref *) tdb->tdb_remote_cred)->ref_type);
+ if (tdb->tdb_remote_cred)
+ l += sprintf(buffer + l, "\tRemote credential type %d\n",
+ ((struct ipsec_ref *) tdb->tdb_remote_cred)->ref_type);
- if (tdb->tdb_local_auth)
- l += sprintf(buffer + l, "\tLocal auth type %d\n", ((struct ipsec_ref *) tdb->tdb_local_auth)->ref_type);
+ if (tdb->tdb_local_auth)
+ l += sprintf(buffer + l, "\tLocal auth type %d\n",
+ ((struct ipsec_ref *) tdb->tdb_local_auth)->ref_type);
- if (tdb->tdb_remote_auth)
- l += sprintf(buffer + l, "\tRemote auth type %d\n", ((struct ipsec_ref *) tdb->tdb_remote_auth)->ref_type);
+ if (tdb->tdb_remote_auth)
+ l += sprintf(buffer + l, "\tRemote auth type %d\n",
+ ((struct ipsec_ref *) tdb->tdb_remote_auth)->ref_type);
- l += sprintf(buffer + l, "\tFlags (%08x) = <", tdb->tdb_flags);
+ l += sprintf(buffer + l, "\tFlags (%08x) = <", tdb->tdb_flags);
- if ((tdb->tdb_flags & ~(TDBF_TIMER | TDBF_BYTES |
- TDBF_ALLOCATIONS | TDBF_FIRSTUSE |
- TDBF_SOFT_TIMER | TDBF_SOFT_BYTES |
- TDBF_SOFT_FIRSTUSE |
- TDBF_SOFT_ALLOCATIONS)) == 0)
+ if ((tdb->tdb_flags & ~(TDBF_TIMER | TDBF_BYTES | TDBF_ALLOCATIONS |
+ TDBF_FIRSTUSE | TDBF_SOFT_TIMER | TDBF_SOFT_BYTES |
+ TDBF_SOFT_FIRSTUSE | TDBF_SOFT_ALLOCATIONS)) == 0)
l += sprintf(buffer + l, "none>\n");
- else
- {
- /* We can reuse variable 'i' here, since we're not looping */
+ else {
for (k = 0, i = 0;
- k < sizeof(ipspflags) / sizeof(struct ctlname); k++)
- if (tdb->tdb_flags & ipspflags[k].ctl_type)
- {
- l += sprintf(buffer + l, "%s,", ipspflags[k].ctl_name);
- i = 1;
- }
+ k < sizeof(ipspflags) / sizeof(struct ctlname); k++) {
+ if (tdb->tdb_flags & ipspflags[k].ctl_type) {
+ l += sprintf(buffer + l, "%s,",
+ ipspflags[k].ctl_name);
+ i = 1;
+ }
+ }
- if (i) /* If we added flags, remove trailing comma */
- l--;
- l += sprintf(buffer + l, ">\n");
- }
+ /* If we added flags, remove trailing comma. */
+ if (i)
+ l--;
+ l += sprintf(buffer + l, ">\n");
+ }
- l += sprintf(buffer + l, "\tCrypto ID: %qu\n", tdb->tdb_cryptoid);
+ l += sprintf(buffer + l, "\tCrypto ID: %qu\n", tdb->tdb_cryptoid);
- if (tdb->tdb_xform)
+ if (tdb->tdb_xform)
l += sprintf(buffer + l, "\txform = <%s>\n",
- tdb->tdb_xform->xf_name);
+ tdb->tdb_xform->xf_name);
- if (tdb->tdb_encalgxform)
+ if (tdb->tdb_encalgxform)
l += sprintf(buffer + l, "\t\tEncryption = <%s>\n",
- tdb->tdb_encalgxform->name);
+ tdb->tdb_encalgxform->name);
- if (tdb->tdb_authalgxform)
+ if (tdb->tdb_authalgxform)
l += sprintf(buffer + l, "\t\tAuthentication = <%s>\n",
- tdb->tdb_authalgxform->name);
-
- if (tdb->tdb_onext)
- l += sprintf(buffer + l,
- "\tNext SA: SPI = %08x, "
- "Destination = %s, Sproto = %u\n",
- ntohl(tdb->tdb_onext->tdb_spi),
- ipsp_address(tdb->tdb_onext->tdb_dst),
- tdb->tdb_onext->tdb_sproto);
+ tdb->tdb_authalgxform->name);
- if (tdb->tdb_inext)
+ if (tdb->tdb_onext)
l += sprintf(buffer + l,
- "\tPrevious SA: SPI = %08x, "
- "Destination = %s, Sproto = %u\n",
- ntohl(tdb->tdb_inext->tdb_spi),
- ipsp_address(tdb->tdb_inext->tdb_dst),
- tdb->tdb_inext->tdb_sproto);
-
- l += sprintf(buffer + l, "\t%qu bytes processed by this SA\n",
- tdb->tdb_cur_bytes);
-
- if (tdb->tdb_last_used)
+ "\tNext SA: SPI = %08x, Destination = %s, Sproto = %u\n",
+ ntohl(tdb->tdb_onext->tdb_spi),
+ ipsp_address(tdb->tdb_onext->tdb_dst),
+ tdb->tdb_onext->tdb_sproto);
+
+ if (tdb->tdb_inext)
+ l += sprintf(buffer + l, "\tPrevious SA: SPI = %08x, "
+ "Destination = %s, Sproto = %u\n",
+ ntohl(tdb->tdb_inext->tdb_spi),
+ ipsp_address(tdb->tdb_inext->tdb_dst),
+ tdb->tdb_inext->tdb_sproto);
+
+ l += sprintf(buffer + l, "\t%qu bytes processed by this SA\n",
+ tdb->tdb_cur_bytes);
+
+ if (tdb->tdb_last_used)
l += sprintf(buffer + l, "\tLast used %qu seconds ago\n",
- time.tv_sec - tdb->tdb_last_used);
+ time.tv_sec - tdb->tdb_last_used);
- if (tdb->tdb_last_marked)
- l += sprintf(buffer + l,
- "\tLast marked/unmarked %qu seconds ago\n",
- time.tv_sec - tdb->tdb_last_marked);
+ if (tdb->tdb_last_marked)
+ l += sprintf(buffer + l,
+ "\tLast marked/unmarked %qu seconds ago\n",
+ time.tv_sec - tdb->tdb_last_marked);
- l += sprintf(buffer + l, "\tExpirations:\n");
+ l += sprintf(buffer + l, "\tExpirations:\n");
- if (tdb->tdb_flags & TDBF_TIMER)
+ if (tdb->tdb_flags & TDBF_TIMER)
l += sprintf(buffer + l,
- "\t\tHard expiration(1) in %qu seconds\n",
- tdb->tdb_established + tdb->tdb_exp_timeout -
- time.tv_sec);
+ "\t\tHard expiration(1) in %qu seconds\n",
+ tdb->tdb_established + tdb->tdb_exp_timeout - time.tv_sec);
- if (tdb->tdb_flags & TDBF_SOFT_TIMER)
+ if (tdb->tdb_flags & TDBF_SOFT_TIMER)
l += sprintf(buffer + l,
- "\t\tSoft expiration(1) in %qu seconds\n",
- tdb->tdb_established + tdb->tdb_soft_timeout -
- time.tv_sec);
+ "\t\tSoft expiration(1) in %qu seconds\n",
+ tdb->tdb_established + tdb->tdb_soft_timeout -
+ time.tv_sec);
- if (tdb->tdb_flags & TDBF_BYTES)
+ if (tdb->tdb_flags & TDBF_BYTES)
l += sprintf(buffer + l,
- "\t\tHard expiration after %qu bytes\n",
- tdb->tdb_exp_bytes);
+ "\t\tHard expiration after %qu bytes\n",
+ tdb->tdb_exp_bytes);
- if (tdb->tdb_flags & TDBF_SOFT_BYTES)
+ if (tdb->tdb_flags & TDBF_SOFT_BYTES)
l += sprintf(buffer + l,
- "\t\tSoft expiration after %qu bytes\n",
- tdb->tdb_soft_bytes);
+ "\t\tSoft expiration after %qu bytes\n",
+ tdb->tdb_soft_bytes);
- if (tdb->tdb_flags & TDBF_ALLOCATIONS)
+ if (tdb->tdb_flags & TDBF_ALLOCATIONS)
l += sprintf(buffer + l,
- "\t\tHard expiration after %u flows\n",
- tdb->tdb_exp_allocations);
+ "\t\tHard expiration after %u flows\n",
+ tdb->tdb_exp_allocations);
- if (tdb->tdb_flags & TDBF_SOFT_ALLOCATIONS)
+ if (tdb->tdb_flags & TDBF_SOFT_ALLOCATIONS)
l += sprintf(buffer + l,
- "\t\tSoft expiration after %u flows\n",
- tdb->tdb_soft_allocations);
-
- if (tdb->tdb_flags & TDBF_FIRSTUSE)
- {
- if (tdb->tdb_first_use)
- l += sprintf(buffer + l,
- "\t\tHard expiration(2) in %qu seconds\n",
- (tdb->tdb_first_use +
- tdb->tdb_exp_first_use) - time.tv_sec);
- else
- l += sprintf(buffer + l,
- "\t\tHard expiration in %qu seconds "
- "after first use\n",
- tdb->tdb_exp_first_use);
- }
-
- if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE)
- {
- if (tdb->tdb_first_use)
- l += sprintf(buffer + l,
- "\t\tSoft expiration(2) in %qu seconds\n",
- (tdb->tdb_first_use +
- tdb->tdb_soft_first_use) - time.tv_sec);
- else
- l += sprintf(buffer + l,
- "\t\tSoft expiration in %qu seconds "
- "after first use\n",
- tdb->tdb_soft_first_use);
- }
-
- if (!(tdb->tdb_flags &
- (TDBF_TIMER | TDBF_SOFT_TIMER | TDBF_BYTES |
- TDBF_SOFT_ALLOCATIONS | TDBF_ALLOCATIONS |
- TDBF_SOFT_BYTES | TDBF_FIRSTUSE | TDBF_SOFT_FIRSTUSE)))
+ "\t\tSoft expiration after %u flows\n",
+ tdb->tdb_soft_allocations);
+
+ if (tdb->tdb_flags & TDBF_FIRSTUSE) {
+ if (tdb->tdb_first_use)
+ l += sprintf(buffer + l,
+ "\t\tHard expiration(2) in %qu seconds\n",
+ (tdb->tdb_first_use + tdb->tdb_exp_first_use) -
+ time.tv_sec);
+ else
+ l += sprintf(buffer + l,
+ "\t\tHard expiration in %qu seconds "
+ "after first use\n",
+ tdb->tdb_exp_first_use);
+ }
+
+ if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE) {
+ if (tdb->tdb_first_use)
+ l += sprintf(buffer + l,
+ "\t\tSoft expiration(2) in %qu seconds\n",
+ (tdb->tdb_first_use + tdb->tdb_soft_first_use) -
+ time.tv_sec);
+ else
+ l += sprintf(buffer + l,
+ "\t\tSoft expiration in %qu seconds "
+ "after first use\n", tdb->tdb_soft_first_use);
+ }
+
+ if (!(tdb->tdb_flags &
+ (TDBF_TIMER | TDBF_SOFT_TIMER | TDBF_BYTES |
+ TDBF_SOFT_ALLOCATIONS | TDBF_ALLOCATIONS |
+ TDBF_SOFT_BYTES | TDBF_FIRSTUSE | TDBF_SOFT_FIRSTUSE)))
l += sprintf(buffer + l, "\t\t(none)\n");
- l += sprintf(buffer + l, "\n");
+ l += sprintf(buffer + l, "\n");
- splx(s);
- return l;
- }
- splx(s);
- }
- return 0;
+ return l;
+}
+
+/*
+ * Used by kernfs.
+ */
+int
+ipsp_kern(int off, char **bufp, int len)
+{
+ static char buffer[IPSEC_KERNFS_BUFSIZE];
+ struct tdb *tdb;
+ int i, s, l;
+
+ if (bufp == NULL)
+ return 0;
+
+ bzero(buffer, IPSEC_KERNFS_BUFSIZE);
+ *bufp = buffer;
+
+ if (off == 0) {
+ kernfs_epoch++;
+ l = sprintf(buffer, "Hashmask: %d, policy entries: %d\n",
+ tdb_hashmask, ipsec_in_use);
+ return l;
+ }
+
+ if (tdbh == NULL)
+ return 0;
+
+ for (i = 0; i <= tdb_hashmask; i++) {
+ s = spltdb();
+ for (tdb = tdbh[i]; tdb; tdb = tdb->tdb_hnext) {
+ if (tdb->tdb_epoch != kernfs_epoch) {
+ tdb->tdb_epoch = kernfs_epoch;
+ l = ipsp_print_tdb(tdb, buffer);
+ splx(s);
+ return l;
+ }
+ }
+ splx(s);
+ }
+ return 0;
}
#endif /* KERNFS */
@@ -1094,28 +1053,25 @@ ipsp_kern(int off, char **bufp, int len)
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 ?
- NOTIFY_SATYPE_AUTH : 0;
- sareq |= inp->inp_seclevel[SL_ESP_TRANS] >= IPSEC_LEVEL_USE ?
- NOTIFY_SATYPE_CONF : 0;
- sareq |= inp->inp_seclevel[SL_ESP_NETWORK] >= IPSEC_LEVEL_USE ?
- NOTIFY_SATYPE_TUNNEL : 0;
- }
- else
- {
- sareq |= ipsec_auth_default_level >= IPSEC_LEVEL_USE ?
- NOTIFY_SATYPE_AUTH : 0;
- sareq |= ipsec_esp_trans_default_level >= IPSEC_LEVEL_USE ?
- NOTIFY_SATYPE_CONF : 0;
- sareq |= ipsec_esp_network_default_level >= IPSEC_LEVEL_USE ?
- NOTIFY_SATYPE_TUNNEL : 0;
- }
-
- return (sareq);
+ u_int8_t sareq = 0;
+
+ if (inp != NULL) {
+ 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;
+ sareq |= inp->inp_seclevel[SL_ESP_NETWORK] >= IPSEC_LEVEL_USE ?
+ NOTIFY_SATYPE_TUNNEL : 0;
+ } else {
+ sareq |= ipsec_auth_default_level >= IPSEC_LEVEL_USE ?
+ NOTIFY_SATYPE_AUTH : 0;
+ sareq |= ipsec_esp_trans_default_level >= IPSEC_LEVEL_USE ?
+ NOTIFY_SATYPE_CONF : 0;
+ sareq |= ipsec_esp_network_default_level >= IPSEC_LEVEL_USE ?
+ NOTIFY_SATYPE_TUNNEL : 0;
+ }
+
+ return (sareq);
}
/*
@@ -1124,96 +1080,90 @@ get_sa_require(struct inpcb *inp)
void
tdb_add_inp(struct tdb *tdb, struct inpcb *inp, int inout)
{
- if (inout)
- {
- if (inp->inp_tdb_in)
- {
- if (inp->inp_tdb_in == tdb)
- return;
-
- TAILQ_REMOVE(&inp->inp_tdb_in->tdb_inp_in, inp, inp_tdb_in_next);
- }
-
- inp->inp_tdb_in = tdb;
- TAILQ_INSERT_TAIL(&tdb->tdb_inp_in, inp, inp_tdb_in_next);
- }
- else
- {
- if (inp->inp_tdb_out)
- {
- if (inp->inp_tdb_out == tdb)
- return;
-
- TAILQ_REMOVE(&inp->inp_tdb_out->tdb_inp_out, inp,
- inp_tdb_out_next);
- }
-
- inp->inp_tdb_out = tdb;
- TAILQ_INSERT_TAIL(&tdb->tdb_inp_out, inp, inp_tdb_out_next);
- }
+ if (inout) {
+ if (inp->inp_tdb_in) {
+ if (inp->inp_tdb_in == tdb)
+ return;
+
+ TAILQ_REMOVE(&inp->inp_tdb_in->tdb_inp_in, inp,
+ inp_tdb_in_next);
+ }
+
+ inp->inp_tdb_in = tdb;
+ TAILQ_INSERT_TAIL(&tdb->tdb_inp_in, inp, inp_tdb_in_next);
+ } else {
+ if (inp->inp_tdb_out) {
+ if (inp->inp_tdb_out == tdb)
+ return;
+
+ TAILQ_REMOVE(&inp->inp_tdb_out->tdb_inp_out, inp,
+ inp_tdb_out_next);
+ }
+
+ inp->inp_tdb_out = tdb;
+ TAILQ_INSERT_TAIL(&tdb->tdb_inp_out, inp, inp_tdb_out_next);
+ }
}
/* Return a printable string for the IPv4 address. */
char *
inet_ntoa4(struct in_addr ina)
{
- static char buf[4][4 * sizeof "123" + 4];
- unsigned char *ucp = (unsigned char *) &ina;
- static int i = 3;
+ 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,
+ i = (i + 1) % 4;
+ sprintf(buf[i], "%d.%d.%d.%d", ucp[0] & 0xff, ucp[1] & 0xff,
ucp[2] & 0xff, ucp[3] & 0xff);
- return (buf[i]);
+ return (buf[i]);
}
/* Return a printable string for the address. */
char *
ipsp_address(union sockaddr_union sa)
{
- switch (sa.sa.sa_family)
- {
+ switch (sa.sa.sa_family) {
#if INET
case AF_INET:
- return inet_ntoa4(sa.sin.sin_addr);
+ return inet_ntoa4(sa.sin.sin_addr);
#endif /* INET */
#if INET6
case AF_INET6:
- return ip6_sprintf(&sa.sin6.sin6_addr);
+ return ip6_sprintf(&sa.sin6.sin6_addr);
#endif /* INET6 */
default:
- return "(unknown address family)";
- }
+ return "(unknown address family)";
+ }
}
/* Check whether an IP{4,6} address is unspecified. */
int
ipsp_is_unspecified(union sockaddr_union addr)
{
- switch (addr.sa.sa_family)
- {
+ switch (addr.sa.sa_family) {
#ifdef INET
case AF_INET:
- if (addr.sin.sin_addr.s_addr == INADDR_ANY)
- return 1;
- else
- return 0;
+ if (addr.sin.sin_addr.s_addr == INADDR_ANY)
+ return 1;
+ else
+ return 0;
#endif /* INET */
#ifdef INET6
case AF_INET6:
- if (IN6_IS_ADDR_UNSPECIFIED(&addr.sin6.sin6_addr))
- return 1;
- else
- return 0;
+ if (IN6_IS_ADDR_UNSPECIFIED(&addr.sin6.sin6_addr))
+ return 1;
+ else
+ return 0;
#endif /* INET6 */
case 0: /* No family set */
default:
- return 1;
- }
+ return 1;
+ }
}
/* Free reference-counted structure. */
@@ -1221,43 +1171,43 @@ void
ipsp_reffree(struct ipsec_ref *ipr)
{
#ifdef DIAGNOSTIC
- if (ipr->ref_count <= 0)
- printf("ipsp_reffree: illegal reference count %d for object %p (len = %d, malloctype = %d)\n", ipr->ref_count, ipr, ipr->ref_len, ipr->ref_malloctype);
+ if (ipr->ref_count <= 0)
+ printf("ipsp_reffree: illegal reference count %d for "
+ "object %p (len = %d, malloctype = %d)\n",
+ ipr->ref_count, ipr, ipr->ref_len, ipr->ref_malloctype);
#endif
- if (--ipr->ref_count <= 0)
- FREE(ipr, ipr->ref_malloctype);
+ if (--ipr->ref_count <= 0)
+ FREE(ipr, ipr->ref_malloctype);
}
/* Mark a TDB as TDBF_SKIPCRYPTO. */
void
ipsp_skipcrypto_mark(struct tdb_ident *tdbi)
{
- struct tdb *tdb;
- int s = spltdb();
+ struct tdb *tdb;
+ int s = spltdb();
- tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
- if (tdb != NULL)
- {
- tdb->tdb_flags |= TDBF_SKIPCRYPTO;
- tdb->tdb_last_marked = time.tv_sec;
- }
- splx(s);
+ tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
+ if (tdb != NULL) {
+ tdb->tdb_flags |= TDBF_SKIPCRYPTO;
+ tdb->tdb_last_marked = time.tv_sec;
+ }
+ splx(s);
}
/* Unmark a TDB as TDBF_SKIPCRYPTO. */
void
ipsp_skipcrypto_unmark(struct tdb_ident *tdbi)
{
- struct tdb *tdb;
- int s = spltdb();
+ struct tdb *tdb;
+ int s = spltdb();
- tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
- if (tdb != NULL)
- {
- tdb->tdb_flags &= ~TDBF_SKIPCRYPTO;
- tdb->tdb_last_marked = time.tv_sec;
- }
- splx(s);
+ tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
+ if (tdb != NULL) {
+ tdb->tdb_flags &= ~TDBF_SKIPCRYPTO;
+ tdb->tdb_last_marked = time.tv_sec;
+ }
+ splx(s);
}
/*
@@ -1268,236 +1218,242 @@ ipsp_skipcrypto_unmark(struct tdb_ident *tdbi)
struct m_tag *
ipsp_parse_headers(struct mbuf *m, int off, u_int8_t proto)
{
- int ipv4sa = 0, s, esphlen = 0, trail = 0, i;
- SLIST_HEAD(packet_tags, m_tag) tags;
- unsigned char lasteight[8];
- struct tdb_ident *tdbi;
- struct m_tag *mtag;
- struct tdb *tdb;
+ int ipv4sa = 0, s, esphlen = 0, trail = 0, i;
+ SLIST_HEAD(packet_tags, m_tag) tags;
+ unsigned char lasteight[8];
+ struct tdb_ident *tdbi;
+ struct m_tag *mtag;
+ struct tdb *tdb;
#ifdef INET
- struct ip iph;
+ struct ip iph;
#endif /* INET */
#ifdef INET6
- struct in6_addr ip6_dst;
+ struct in6_addr ip6_dst;
#endif /* INET6 */
- /* We have to start with a known network protocol */
- if (proto != IPPROTO_IPV4 && proto != IPPROTO_IPV6)
- return NULL;
+ /* We have to start with a known network protocol */
+ if (proto != IPPROTO_IPV4 && proto != IPPROTO_IPV6)
+ return NULL;
- SLIST_INIT(&tags);
+ SLIST_INIT(&tags);
- while (1)
- {
- switch (proto)
- {
+ while (1) {
+ switch (proto) {
#ifdef INET
- case IPPROTO_IPV4: /* Also IPPROTO_IPIP */
- {
- /* Save the IP header (we need both the address and ip_hl) */
- m_copydata(m, off, sizeof(struct ip), (caddr_t) &iph);
- ipv4sa = 1;
- proto = iph.ip_p;
- off += iph.ip_hl << 2;
- break;
- }
+ case IPPROTO_IPV4: /* Also IPPROTO_IPIP */
+ {
+ /*
+ * Save the IP header (we need both the
+ * address and ip_hl).
+ */
+ m_copydata(m, off, sizeof(struct ip), (caddr_t) &iph);
+ ipv4sa = 1;
+ proto = iph.ip_p;
+ off += iph.ip_hl << 2;
+ break;
+ }
#endif /* INET */
#ifdef INET6
- case IPPROTO_IPV6:
- {
- int nxtp, l;
-
- /* Copy the IPv6 address */
- m_copydata(m, off + offsetof(struct ip6_hdr, ip6_dst),
- sizeof(struct ip6_hdr), (caddr_t) &ip6_dst);
- ipv4sa = 0;
-
- /*
- * Go down the chain of headers until we encounter a
- * non-option.
- */
- for (l = ip6_nexthdr(m, off, proto, &nxtp); l != -1;
- l = ip6_nexthdr(m, off, proto, &nxtp))
+ case IPPROTO_IPV6:
{
- off += l;
- proto = nxtp;
-
- /* Construct a tag */
- if (nxtp == IPPROTO_AH)
- {
- mtag = m_tag_get(PACKET_TAG_IPSEC_IN_CRYPTO_DONE,
- sizeof(struct tdb_ident), M_NOWAIT);
- if (mtag == NULL)
- return tags.slh_first;
+ int nxtp, l;
- tdbi = (struct tdb_ident *) (mtag + 1);
- bzero(tdbi, sizeof(struct tdb_ident));
- m_copydata(m, off + sizeof(u_int32_t),
- sizeof(u_int32_t), (caddr_t) &tdbi->spi);
- tdbi->proto = IPPROTO_AH;
- tdbi->dst.sin6.sin6_family = AF_INET6;
- tdbi->dst.sin6.sin6_len = sizeof(struct sockaddr_in6);
- tdbi->dst.sin6.sin6_addr = ip6_dst;
- SLIST_INSERT_HEAD(&tags, mtag, m_tag_link);
- }
- else
- if (nxtp == IPPROTO_IPV6)
+ /* Copy the IPv6 address. */
m_copydata(m, off + offsetof(struct ip6_hdr, ip6_dst),
- sizeof(struct ip6_hdr), (caddr_t) &ip6_dst);
+ sizeof(struct ip6_hdr), (caddr_t) &ip6_dst);
+ ipv4sa = 0;
+
+ /*
+ * Go down the chain of headers until we encounter a
+ * non-option.
+ */
+ for (l = ip6_nexthdr(m, off, proto, &nxtp); l != -1;
+ l = ip6_nexthdr(m, off, proto, &nxtp)) {
+ off += l;
+ proto = nxtp;
+
+ /* Construct a tag */
+ if (nxtp == IPPROTO_AH) {
+ mtag = m_tag_get(PACKET_TAG_IPSEC_IN_CRYPTO_DONE,
+ sizeof(struct tdb_ident),
+ M_NOWAIT);
+
+ if (mtag == NULL)
+ return tags.slh_first;
+
+ tdbi = (struct tdb_ident *) (mtag + 1);
+ bzero(tdbi, sizeof(struct tdb_ident));
+
+ m_copydata(m, off + sizeof(u_int32_t),
+ sizeof(u_int32_t),
+ (caddr_t) &tdbi->spi);
+
+ tdbi->proto = IPPROTO_AH;
+ tdbi->dst.sin6.sin6_family = AF_INET6;
+ tdbi->dst.sin6.sin6_len =
+ sizeof(struct sockaddr_in6);
+ tdbi->dst.sin6.sin6_addr = ip6_dst;
+ SLIST_INSERT_HEAD(&tags,
+ mtag, m_tag_link);
+ }
+ else
+ if (nxtp == IPPROTO_IPV6)
+ m_copydata(m, off +
+ offsetof(struct ip6_hdr,
+ ip6_dst),
+ sizeof(struct ip6_hdr),
+ (caddr_t) &ip6_dst);
+ }
+ break;
}
- break;
- }
#endif /* INET6 */
- case IPPROTO_ESP:
+ case IPPROTO_ESP:
/* Verify that this has been decrypted */
{
- union sockaddr_union su;
- u_int32_t spi;
+ union sockaddr_union su;
+ u_int32_t spi;
- m_copydata(m, off, sizeof(u_int32_t), (caddr_t) &spi);
- bzero(&su, sizeof(union sockaddr_union));
+ m_copydata(m, off, sizeof(u_int32_t), (caddr_t) &spi);
+ bzero(&su, sizeof(union sockaddr_union));
- s = spltdb();
+ s = spltdb();
#ifdef INET
- if (ipv4sa)
- {
- su.sin.sin_family = AF_INET;
- su.sin.sin_len = sizeof(struct sockaddr_in);
- su.sin.sin_addr = iph.ip_dst;
- }
+ if (ipv4sa) {
+ su.sin.sin_family = AF_INET;
+ su.sin.sin_len = sizeof(struct sockaddr_in);
+ su.sin.sin_addr = iph.ip_dst;
+ }
#endif /* INET */
#ifdef INET6
- if (!ipv4sa)
- {
- su.sin6.sin6_family = AF_INET6;
- su.sin6.sin6_len = sizeof(struct sockaddr_in6);
- su.sin6.sin6_addr = ip6_dst;
- }
+ if (!ipv4sa) {
+ su.sin6.sin6_family = AF_INET6;
+ su.sin6.sin6_len = sizeof(struct sockaddr_in6);
+ su.sin6.sin6_addr = ip6_dst;
+ }
#endif /* INET6 */
- tdb = gettdb(spi, &su, IPPROTO_ESP);
- if (tdb == NULL)
- {
- splx(s);
- return tags.slh_first;
- }
-
- /* How large is the ESP header ? We use this later */
- if (tdb->tdb_flags & TDBF_NOREPLAY)
- esphlen = sizeof(u_int32_t) + tdb->tdb_ivlen;
- else
- esphlen = 2 * sizeof(u_int32_t) + tdb->tdb_ivlen;
-
- /*
- * Verify decryption. If the SA is using random padding
- * (as the "old" ESP SAs were bound to do, there's nothing
- * we can do to see if the payload has been decrypted.
- */
- if (tdb->tdb_flags & TDBF_RANDOMPADDING)
- {
- splx(s);
- return tags.slh_first;
- }
-
- /* Update the length of trailing ESP authenticators */
- if (tdb->tdb_authalgxform)
- trail += AH_HMAC_HASHLEN;
-
- splx(s);
+ tdb = gettdb(spi, &su, IPPROTO_ESP);
+ if (tdb == NULL) {
+ splx(s);
+ return tags.slh_first;
+ }
+
+ /* How large is the ESP header ? We use this later. */
+ if (tdb->tdb_flags & TDBF_NOREPLAY)
+ esphlen = sizeof(u_int32_t) + tdb->tdb_ivlen;
+ else
+ esphlen = 2 * sizeof(u_int32_t) +
+ tdb->tdb_ivlen;
+
+ /*
+ * Verify decryption. If the SA is using
+ * random padding (as the "old" ESP SAs were
+ * bound to do, there's nothing we can do to
+ * see if the payload has been decrypted.
+ */
+ if (tdb->tdb_flags & TDBF_RANDOMPADDING) {
+ splx(s);
+ return tags.slh_first;
+ }
- /* Copy the last 10 bytes */
- m_copydata(m, m->m_pkthdr.len - trail - 8, 8, lasteight);
+ /* Update the length of trailing ESP authenticators. */
+ if (tdb->tdb_authalgxform)
+ trail += AH_HMAC_HASHLEN;
- /* Verify the self-describing padding values */
- if (lasteight[6] != 0)
- {
- if (lasteight[6] != lasteight[5])
- return tags.slh_first;
+ splx(s);
- for (i = 4; lasteight[i + 1] != 1 && i >= 0; i--)
- if (lasteight[i + 1] != lasteight[i] + 1)
- return tags.slh_first;
- }
+ /* Copy the last 10 bytes. */
+ m_copydata(m, m->m_pkthdr.len - trail - 8, 8,
+ lasteight);
+
+ /* Verify the self-describing padding values */
+ if (lasteight[6] != 0) {
+ if (lasteight[6] != lasteight[5])
+ return tags.slh_first;
+
+ for (i = 4; lasteight[i + 1] != 1 && i >= 0;
+ i--)
+ if (lasteight[i + 1] !=
+ lasteight[i] + 1)
+ return tags.slh_first;
+ }
}
/* Fall through */
- case IPPROTO_AH:
- mtag = m_tag_get(PACKET_TAG_IPSEC_IN_CRYPTO_DONE,
- sizeof(struct tdb_ident), M_NOWAIT);
- if (mtag == NULL)
- return tags.slh_first;
+ case IPPROTO_AH:
+ mtag = m_tag_get(PACKET_TAG_IPSEC_IN_CRYPTO_DONE,
+ sizeof(struct tdb_ident), M_NOWAIT);
+ if (mtag == NULL)
+ return tags.slh_first;
- tdbi = (struct tdb_ident *) (mtag + 1);
- bzero(tdbi, sizeof(struct tdb_ident));
+ tdbi = (struct tdb_ident *) (mtag + 1);
+ bzero(tdbi, sizeof(struct tdb_ident));
- /* Get SPI off the relevant header */
- if (proto == IPPROTO_AH)
- m_copydata(m, off + sizeof(u_int32_t), sizeof(u_int32_t),
- (caddr_t) &tdbi->spi);
- else /* IPPROTO_ESP */
- m_copydata(m, off, sizeof(u_int32_t), (caddr_t) &tdbi->spi);
+ /* Get SPI off the relevant header */
+ if (proto == IPPROTO_AH)
+ m_copydata(m, off + sizeof(u_int32_t),
+ sizeof(u_int32_t), (caddr_t) &tdbi->spi);
+ else /* IPPROTO_ESP */
+ m_copydata(m, off, sizeof(u_int32_t),
+ (caddr_t) &tdbi->spi);
- tdbi->proto = proto; /* We can get here for AH or ESP */
+ tdbi->proto = proto; /* AH or ESP */
#ifdef INET
- /* Last network header was IPv4 */
- if (ipv4sa)
- {
- tdbi->dst.sin.sin_family = AF_INET;
- tdbi->dst.sin.sin_len = sizeof(struct sockaddr_in);
- tdbi->dst.sin.sin_addr = iph.ip_dst;
- }
+ /* Last network header was IPv4. */
+ if (ipv4sa) {
+ tdbi->dst.sin.sin_family = AF_INET;
+ tdbi->dst.sin.sin_len =
+ sizeof(struct sockaddr_in);
+ tdbi->dst.sin.sin_addr = iph.ip_dst;
+ }
#endif /* INET */
#ifdef INET6
- /* Last network header was IPv6 */
- if (!ipv4sa)
- {
- tdbi->dst.sin6.sin6_family = AF_INET6;
- tdbi->dst.sin6.sin6_len = sizeof(struct sockaddr_in6);
- tdbi->dst.sin6.sin6_addr = ip6_dst;
- }
+ /* Last network header was IPv6 */
+ if (!ipv4sa) {
+ tdbi->dst.sin6.sin6_family = AF_INET6;
+ tdbi->dst.sin6.sin6_len =
+ sizeof(struct sockaddr_in6);
+ tdbi->dst.sin6.sin6_addr = ip6_dst;
+ }
#endif /* INET6 */
- SLIST_INSERT_HEAD(&tags, mtag, m_tag_link);
-
- /* Update next protocol/header and header offset */
- if (proto == IPPROTO_AH)
- {
- u_int8_t foo[2];
+ SLIST_INSERT_HEAD(&tags, mtag, m_tag_link);
- m_copydata(m, off, 2 * sizeof(u_int8_t), foo);
- proto = foo[0];
- off += (foo[1] + 2) << 2;
- }
- else /* IPPROTO_ESP */
- {
- /* Initialized in IPPROTO_ESP case */
- off += esphlen;
- proto = lasteight[7];
+ /* Update next protocol/header and header offset. */
+ if (proto == IPPROTO_AH) {
+ u_int8_t foo[2];
+
+ m_copydata(m, off, 2 * sizeof(u_int8_t), foo);
+ proto = foo[0];
+ off += (foo[1] + 2) << 2;
+ } else {/* IPPROTO_ESP */
+ /* Initialized in IPPROTO_ESP case */
+ off += esphlen;
+ proto = lasteight[7];
+ }
+ break;
+
+ default:
+ return tags.slh_first; /* done */
}
- break;
-
- default:
- return tags.slh_first; /* done */
}
- }
}
/* Return true if the two structures match. */
int
ipsp_ref_match(struct ipsec_ref *ref1, struct ipsec_ref *ref2)
{
- if (ref1->ref_type != ref2->ref_type ||
- ref1->ref_len != ref2->ref_len ||
- bcmp(ref1 + 1, ref2 + 1, ref1->ref_len))
- return 0;
+ if (ref1->ref_type != ref2->ref_type ||
+ ref1->ref_len != ref2->ref_len ||
+ bcmp(ref1 + 1, ref2 + 1, ref1->ref_len))
+ return 0;
- return 1;
+ return 1;
}
-