summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAngelos D. Keromytis <angelos@cvs.openbsd.org>2001-06-26 03:52:43 +0000
committerAngelos D. Keromytis <angelos@cvs.openbsd.org>2001-06-26 03:52:43 +0000
commit61c02c4209050b64dec4b2427ec81f8596fb505e (patch)
treed15d89acf65e5e15b948f86575a5744bb7fe7a6f
parent01e8077361902845f37735cc3b7b170810f100d6 (diff)
KNF
-rw-r--r--sys/netinet/ip_ipsp.c1902
-rw-r--r--sys/netinet/ip_ipsp.h3
-rw-r--r--sys/netinet/ip_spd.c1392
3 files changed, 1623 insertions, 1674 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;
}
-
diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h
index 9e05c303244..82e7ba9008d 100644
--- a/sys/netinet/ip_ipsp.h
+++ b/sys/netinet/ip_ipsp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.h,v 1.109 2001/06/25 23:18:08 beck Exp $ */
+/* $OpenBSD: ip_ipsp.h,v 1.110 2001/06/26 03:52:42 angelos Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
@@ -613,5 +613,6 @@ extern struct m_tag *ipsp_parse_headers(struct mbuf *, int, u_int8_t);
extern int ipsp_ref_match(struct ipsec_ref *, struct ipsec_ref *);
extern ssize_t ipsec_hdrsz(struct tdb *);
extern void ipsec_adjust_mtu(struct mbuf *, u_int32_t);
+extern int ipsp_print_tdb(struct tdb *, char *);
#endif /* _KERNEL */
#endif /* _NETINET_IPSP_H_ */
diff --git a/sys/netinet/ip_spd.c b/sys/netinet/ip_spd.c
index d85134ae4da..c02709425f2 100644
--- a/sys/netinet/ip_spd.c
+++ b/sys/netinet/ip_spd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_spd.c,v 1.25 2001/06/25 05:11:59 angelos Exp $ */
+/* $OpenBSD: ip_spd.c,v 1.26 2001/06/26 03:52:42 angelos Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
*
@@ -49,9 +49,9 @@
#include <net/pfkeyv2.h>
#ifdef ENCDEBUG
-#define DPRINTF(x) if (encdebug) printf x
+#define DPRINTF(x) if (encdebug) printf x
#else
-#define DPRINTF(x)
+#define DPRINTF(x)
#endif
/*
@@ -71,491 +71,481 @@
*/
struct tdb *
ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction,
- struct tdb *tdbp, struct inpcb *inp)
+ struct tdb *tdbp, struct inpcb *inp)
{
- struct route_enc re0, *re = &re0;
- union sockaddr_union sdst, ssrc;
- struct sockaddr_encap *ddst;
- struct ipsec_policy *ipo;
- int signore = 0, dignore = 0;
-
- /*
- * If there are no flows in place, there's no point
- * continuing with the SPD lookup.
- */
- if (!ipsec_in_use && inp == NULL)
- {
- *error = 0;
- return NULL;
- }
-
- /* If an input packet is destined to a BYPASS socket, just accept it */
- if ((inp != NULL) && (direction == IPSP_DIRECTION_IN) &&
- (inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_BYPASS) &&
- (inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_BYPASS) &&
- (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_BYPASS))
- {
- *error = 0;
- return NULL;
- }
+ struct route_enc re0, *re = &re0;
+ union sockaddr_union sdst, ssrc;
+ struct sockaddr_encap *ddst;
+ struct ipsec_policy *ipo;
+ int signore = 0, dignore = 0;
+
+ /*
+ * If there are no flows in place, there's no point
+ * continuing with the SPD lookup.
+ */
+ if (!ipsec_in_use && inp == NULL) {
+ *error = 0;
+ return NULL;
+ }
+
+ /* If an input packet is destined to a BYPASS socket, just accept it. */
+ if ((inp != NULL) && (direction == IPSP_DIRECTION_IN) &&
+ (inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_BYPASS) &&
+ (inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_BYPASS) &&
+ (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_BYPASS)) {
+ *error = 0;
+ return NULL;
+ }
- bzero((caddr_t) re, sizeof(struct route_enc));
- bzero((caddr_t) &sdst, sizeof(union sockaddr_union));
- bzero((caddr_t) &ssrc, sizeof(union sockaddr_union));
- ddst = (struct sockaddr_encap *) &re->re_dst;
- ddst->sen_family = PF_KEY;
- ddst->sen_len = SENT_LEN;
+ bzero((caddr_t) re, sizeof(struct route_enc));
+ bzero((caddr_t) &sdst, sizeof(union sockaddr_union));
+ bzero((caddr_t) &ssrc, sizeof(union sockaddr_union));
+ ddst = (struct sockaddr_encap *) &re->re_dst;
+ ddst->sen_family = PF_KEY;
+ ddst->sen_len = SENT_LEN;
- switch (af)
- {
+ switch (af) {
#ifdef INET
case AF_INET:
- ddst->sen_direction = direction;
- ddst->sen_type = SENT_IP4;
-
- m_copydata(m, offsetof(struct ip, ip_src),
- sizeof(struct in_addr), (caddr_t) &(ddst->sen_ip_src));
- m_copydata(m, offsetof(struct ip, ip_dst),
- sizeof(struct in_addr), (caddr_t) &(ddst->sen_ip_dst));
- m_copydata(m, offsetof(struct ip, ip_p), sizeof(u_int8_t),
- (caddr_t) &(ddst->sen_proto));
-
- sdst.sin.sin_family = ssrc.sin.sin_family = AF_INET;
- sdst.sin.sin_len = ssrc.sin.sin_len = sizeof(struct sockaddr_in);
- ssrc.sin.sin_addr = ddst->sen_ip_src;
- sdst.sin.sin_addr = ddst->sen_ip_dst;
-
- /* If TCP/UDP, extract the port numbers to use in the lookup */
- switch (ddst->sen_proto)
- {
+ ddst->sen_direction = direction;
+ ddst->sen_type = SENT_IP4;
+
+ m_copydata(m, offsetof(struct ip, ip_src),
+ sizeof(struct in_addr), (caddr_t) &(ddst->sen_ip_src));
+ m_copydata(m, offsetof(struct ip, ip_dst),
+ sizeof(struct in_addr), (caddr_t) &(ddst->sen_ip_dst));
+ m_copydata(m, offsetof(struct ip, ip_p), sizeof(u_int8_t),
+ (caddr_t) &(ddst->sen_proto));
+
+ sdst.sin.sin_family = ssrc.sin.sin_family = AF_INET;
+ sdst.sin.sin_len = ssrc.sin.sin_len =
+ sizeof(struct sockaddr_in);
+ ssrc.sin.sin_addr = ddst->sen_ip_src;
+ sdst.sin.sin_addr = ddst->sen_ip_dst;
+
+ /* If TCP/UDP, extract the port numbers to use in the lookup */
+ switch (ddst->sen_proto) {
case IPPROTO_UDP:
case IPPROTO_TCP:
- /* Make sure there's enough data in the packet */
- if (m->m_pkthdr.len < hlen + 2 * sizeof(u_int16_t))
- {
- *error = EINVAL;
- return NULL;
- }
-
- /*
- * Luckily, the offset of the src/dst ports in both the UDP
- * and TCP headers is the same (first two 16-bit values
- * in the respective headers), so we can just copy them.
- */
- m_copydata(m, hlen, sizeof(u_int16_t),
- (caddr_t) &(ddst->sen_sport));
- m_copydata(m, hlen + sizeof(u_int16_t), sizeof(u_int16_t),
- (caddr_t) &(ddst->sen_dport));
- break;
+ /* Make sure there's enough data in the packet */
+ if (m->m_pkthdr.len < hlen + 2 * sizeof(u_int16_t)) {
+ *error = EINVAL;
+ return NULL;
+ }
+
+ /*
+ * Luckily, the offset of the src/dst ports in
+ * both the UDP and TCP headers is the same (first
+ * two 16-bit values in the respective headers),
+ * so we can just copy them.
+ */
+ m_copydata(m, hlen, sizeof(u_int16_t),
+ (caddr_t) &(ddst->sen_sport));
+ m_copydata(m, hlen + sizeof(u_int16_t), sizeof(u_int16_t),
+ (caddr_t) &(ddst->sen_dport));
+ break;
default:
- ddst->sen_sport = 0;
- ddst->sen_dport = 0;
- }
+ ddst->sen_sport = 0;
+ ddst->sen_dport = 0;
+ }
- break;
+ break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
- ddst->sen_type = SENT_IP6;
- ddst->sen_ip6_direction = direction;
-
- m_copydata(m, offsetof(struct ip6_hdr, ip6_src),
- sizeof(struct in6_addr),
- (caddr_t) &(ddst->sen_ip6_src));
- m_copydata(m, offsetof(struct ip6_hdr, ip6_dst),
- sizeof(struct in6_addr),
- (caddr_t) &(ddst->sen_ip6_dst));
- m_copydata(m, offsetof(struct ip6_hdr, ip6_nxt), sizeof(u_int8_t),
- (caddr_t) &(ddst->sen_ip6_proto));
-
- sdst.sin6.sin6_family = ssrc.sin6.sin6_family = AF_INET6;
- sdst.sin6.sin6_len = ssrc.sin6.sin6_family =
- sizeof(struct sockaddr_in6);
- ssrc.sin6.sin6_addr = ddst->sen_ip6_src;
- sdst.sin6.sin6_addr = ddst->sen_ip6_dst;
-
- /* If TCP/UDP, extract the port numbers to use in the lookup */
- switch (ddst->sen_ip6_proto)
- {
+ ddst->sen_type = SENT_IP6;
+ ddst->sen_ip6_direction = direction;
+
+ m_copydata(m, offsetof(struct ip6_hdr, ip6_src),
+ sizeof(struct in6_addr),
+ (caddr_t) &(ddst->sen_ip6_src));
+ m_copydata(m, offsetof(struct ip6_hdr, ip6_dst),
+ sizeof(struct in6_addr),
+ (caddr_t) &(ddst->sen_ip6_dst));
+ m_copydata(m, offsetof(struct ip6_hdr, ip6_nxt),
+ sizeof(u_int8_t),
+ (caddr_t) &(ddst->sen_ip6_proto));
+
+ sdst.sin6.sin6_family = ssrc.sin6.sin6_family = AF_INET6;
+ sdst.sin6.sin6_len = ssrc.sin6.sin6_family =
+ sizeof(struct sockaddr_in6);
+ ssrc.sin6.sin6_addr = ddst->sen_ip6_src;
+ sdst.sin6.sin6_addr = ddst->sen_ip6_dst;
+
+ /* If TCP/UDP, extract the port numbers to use in the lookup */
+ switch (ddst->sen_ip6_proto) {
case IPPROTO_UDP:
case IPPROTO_TCP:
- /* Make sure there's enough data in the packet */
- if (m->m_pkthdr.len < hlen + 2 * sizeof(u_int16_t))
- {
- *error = EINVAL;
- return NULL;
- }
-
- /*
- * Luckily, the offset of the src/dst ports in both the UDP
- * and TCP headers is the same (first two 16-bit values
- * in the respective headers), so we can just copy them.
- */
- m_copydata(m, hlen, sizeof(u_int16_t),
- (caddr_t) &(ddst->sen_ip6_sport));
- m_copydata(m, hlen + sizeof(u_int16_t), sizeof(u_int16_t),
- (caddr_t) &(ddst->sen_ip6_dport));
- break;
+ /* Make sure there's enough data in the packet */
+ if (m->m_pkthdr.len < hlen + 2 * sizeof(u_int16_t)) {
+ *error = EINVAL;
+ return NULL;
+ }
+
+ /*
+ * Luckily, the offset of the src/dst ports in
+ * both the UDP and TCP headers is the same
+ * (first two 16-bit values in the respective
+ * headers), so we can just copy them.
+ */
+ m_copydata(m, hlen, sizeof(u_int16_t),
+ (caddr_t) &(ddst->sen_ip6_sport));
+ m_copydata(m, hlen + sizeof(u_int16_t), sizeof(u_int16_t),
+ (caddr_t) &(ddst->sen_ip6_dport));
+ break;
default:
- ddst->sen_ip6_sport = 0;
- ddst->sen_ip6_dport = 0;
- }
+ ddst->sen_ip6_sport = 0;
+ ddst->sen_ip6_dport = 0;
+ }
- break;
+ break;
#endif /* INET6 */
default:
- *error = EAFNOSUPPORT;
- return NULL;
- }
-
- /* Actual SPD lookup */
- rtalloc((struct route *) re);
- if (re->re_rt == NULL)
- {
- *error = 0;
- return NULL; /* Nothing found -- means no IPsec needed */
- }
-
- /* Sanity check */
- if ((re->re_rt->rt_gateway == NULL) ||
- (((struct sockaddr_encap *) re->re_rt->rt_gateway)->sen_type !=
- SENT_IPSP))
- {
- RTFREE(re->re_rt);
- *error = EHOSTUNREACH;
- return NULL;
- }
+ *error = EAFNOSUPPORT;
+ return NULL;
+ }
- ipo = ((struct sockaddr_encap *) (re->re_rt->rt_gateway))->sen_ipsp;
- RTFREE(re->re_rt);
- if (ipo == NULL)
- {
- *error = EHOSTUNREACH;
- return NULL;
- }
+ /* Actual SPD lookup */
+ rtalloc((struct route *) re);
+ if (re->re_rt == NULL) {
+ /*
+ * Return whatever the socket requirements are, there are no
+ * system-wide policies.
+ */
+ *error = 0;
+ return ipsp_spd_inp(m, af, hlen, error, direction,
+ tdbp, inp, NULL);
+ }
+
+ /* Sanity check */
+ if ((re->re_rt->rt_gateway == NULL) ||
+ (((struct sockaddr_encap *) re->re_rt->rt_gateway)->sen_type !=
+ SENT_IPSP)) {
+ RTFREE(re->re_rt);
+ *error = EHOSTUNREACH;
+ return NULL;
+ }
+
+ ipo = ((struct sockaddr_encap *) (re->re_rt->rt_gateway))->sen_ipsp;
+ RTFREE(re->re_rt);
+ if (ipo == NULL) {
+ *error = EHOSTUNREACH;
+ return NULL;
+ }
- switch (ipo->ipo_type)
- {
+ switch (ipo->ipo_type) {
case IPSP_PERMIT:
- *error = 0;
- return NULL;
+ *error = 0;
+ return ipsp_spd_inp(m, af, hlen, error, direction, tdbp,
+ inp, ipo);
case IPSP_DENY:
- *error = EHOSTUNREACH;
- return NULL;
+ *error = EHOSTUNREACH;
+ return NULL;
case IPSP_IPSEC_USE:
case IPSP_IPSEC_ACQUIRE:
case IPSP_IPSEC_REQUIRE:
case IPSP_IPSEC_DONTACQ:
- /* Nothing more needed here */
- break;
+ /* Nothing more needed here */
+ break;
default:
- *error = EINVAL;
- return NULL;
- }
+ *error = EINVAL;
+ return NULL;
+ }
- /* Check for non-specific destination in the policy. */
- switch (ipo->ipo_dst.sa.sa_family)
- {
+ /* Check for non-specific destination in the policy. */
+ switch (ipo->ipo_dst.sa.sa_family) {
#ifdef INET
case AF_INET:
- if ((ipo->ipo_dst.sin.sin_addr.s_addr == INADDR_ANY) ||
- (ipo->ipo_dst.sin.sin_addr.s_addr == INADDR_BROADCAST))
- dignore = 1;
- break;
+ if ((ipo->ipo_dst.sin.sin_addr.s_addr == INADDR_ANY) ||
+ (ipo->ipo_dst.sin.sin_addr.s_addr == INADDR_BROADCAST))
+ dignore = 1;
+ break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
- if ((IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_dst.sin6.sin6_addr)) ||
- (bcmp(&ipo->ipo_dst.sin6.sin6_addr, &in6mask128,
- sizeof(in6mask128))))
- dignore = 1;
- break;
+ if ((IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_dst.sin6.sin6_addr)) ||
+ (bcmp(&ipo->ipo_dst.sin6.sin6_addr, &in6mask128,
+ sizeof(in6mask128))))
+ dignore = 1;
+ break;
#endif /* INET6 */
- }
+ }
- /* Likewise for source. */
- switch (ipo->ipo_src.sa.sa_family)
- {
+ /* Likewise for source. */
+ switch (ipo->ipo_src.sa.sa_family) {
#ifdef INET
case AF_INET:
- if (ipo->ipo_src.sin.sin_addr.s_addr == INADDR_ANY)
- signore = 1;
- break;
+ if (ipo->ipo_src.sin.sin_addr.s_addr == INADDR_ANY)
+ signore = 1;
+ break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
- if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_src.sin6.sin6_addr))
- signore = 1;
- break;
+ if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_src.sin6.sin6_addr))
+ signore = 1;
+ break;
#endif /* INET6 */
- }
-
- /* Do we have a cached entry ? If so, check if it's still valid. */
- if ((ipo->ipo_tdb) && (ipo->ipo_tdb->tdb_flags & TDBF_INVALID))
- {
- TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, ipo_tdb_next);
- ipo->ipo_tdb = NULL;
- }
-
- /* Outgoing packet SPD lookup */
- if (direction == IPSP_DIRECTION_OUT)
- {
- /*
- * If the packet is destined for the policy-specified gateway/endhost,
- * and the socket has the BYPASS option set, skip IPsec processing.
- */
- if ((inp != NULL) &&
- (inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_BYPASS) &&
- (inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_BYPASS) &&
- (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_BYPASS))
- {
- /* Direct match */
- if (!bcmp(&sdst, &ipo->ipo_dst, sdst.sa.sa_len) || dignore)
- {
- *error = 0;
- return NULL;
- }
}
- /* Check that the cached TDB (if present), is appropriate */
- if (ipo->ipo_tdb)
- {
- if ((ipo->ipo_last_searched <= ipsec_last_added) ||
- (ipo->ipo_sproto != ipo->ipo_tdb->tdb_sproto) ||
- bcmp(dignore ? &sdst : &ipo->ipo_dst, &ipo->ipo_tdb->tdb_dst,
- ipo->ipo_tdb->tdb_dst.sa.sa_len))
- goto nomatchout;
-
- /* Match source ID */
- if (ipo->ipo_srcid)
- {
- if (ipo->ipo_tdb->tdb_srcid == NULL ||
- !ipsp_ref_match(ipo->ipo_srcid, ipo->ipo_tdb->tdb_srcid))
- goto nomatchout;
- }
-
- /* Match destination ID */
- if (ipo->ipo_dstid)
- {
- if (ipo->ipo_tdb->tdb_dstid == NULL ||
- !ipsp_ref_match(ipo->ipo_dstid, ipo->ipo_tdb->tdb_dstid))
- goto nomatchout;
- }
-
- /* Match local credentials used */
- if (ipo->ipo_local_cred)
- {
- if (ipo->ipo_tdb->tdb_local_cred == NULL ||
- !ipsp_ref_match(ipo->ipo_local_cred,
- ipo->ipo_tdb->tdb_local_cred))
- goto nomatchout;
- }
-
- return ipo->ipo_tdb; /* Cached entry is good, we're done */
-
- nomatchout:
- /* Cached TDB was not good */
- TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, ipo_tdb_next);
- ipo->ipo_tdb = NULL;
- ipo->ipo_last_searched = 0;
+ /* Do we have a cached entry ? If so, check if it's still valid. */
+ if ((ipo->ipo_tdb) && (ipo->ipo_tdb->tdb_flags & TDBF_INVALID)) {
+ TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo,
+ ipo_tdb_next);
+ ipo->ipo_tdb = NULL;
}
- /*
- * If no SA has been added since the last time we did a
- * lookup, there's no point searching for one. However, if the
- * destination gateway is left unspecified (or is all-1's),
- * always lookup since this is a generic-match rule
- * (otherwise, we can have situations where SAs to some
- * destinations exist but are not used, possibly leading to an
- * explosion in the number of acquired SAs).
- */
- if (ipo->ipo_last_searched <= ipsec_last_added)
- {
- ipo->ipo_last_searched = time.tv_sec; /* "touch" the entry */
-
- /* Find an appropriate SA from among the existing SAs */
- ipo->ipo_tdb = gettdbbyaddr(dignore ? &sdst : &ipo->ipo_dst,
- ipo, m, af);
- if (ipo->ipo_tdb)
- {
- TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head, ipo,
- ipo_tdb_next);
- *error = 0;
- return ipo->ipo_tdb;
- }
- }
+ /* Outgoing packet SPD lookup. */
+ if (direction == IPSP_DIRECTION_OUT) {
+ /*
+ * If the packet is destined for the policy-specified
+ * gateway/endhost, and the socket has the BYPASS
+ * option set, skip IPsec processing.
+ */
+ if ((inp != NULL) &&
+ (inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_BYPASS) &&
+ (inp->inp_seclevel[SL_ESP_NETWORK] ==
+ IPSEC_LEVEL_BYPASS) &&
+ (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_BYPASS)) {
+ /* Direct match */
+ if (!bcmp(&sdst, &ipo->ipo_dst, sdst.sa.sa_len) ||
+ dignore) {
+ *error = 0;
+ return ipsp_spd_inp(m, af, hlen, error,
+ direction, tdbp, inp, ipo);
+ }
+ }
- /* So, we don't have an SA -- just a policy */
- switch (ipo->ipo_type)
- {
- case IPSP_IPSEC_REQUIRE:
- /* Acquire SA through key management */
- if (ipsp_acquire_sa(ipo, dignore ? &sdst : &ipo->ipo_dst,
- signore ? NULL : &ipo->ipo_src,
- ddst, m) != 0)
- {
- *error = EACCES;
- return NULL;
- }
-
- /* Fall through */
- case IPSP_IPSEC_DONTACQ:
- *error = -EINVAL; /* Silently drop packet */
- return NULL;
+ /* Check that the cached TDB (if present), is appropriate. */
+ if (ipo->ipo_tdb) {
+ if ((ipo->ipo_last_searched <= ipsec_last_added) ||
+ (ipo->ipo_sproto != ipo->ipo_tdb->tdb_sproto) ||
+ bcmp(dignore ? &sdst : &ipo->ipo_dst,
+ &ipo->ipo_tdb->tdb_dst,
+ ipo->ipo_tdb->tdb_dst.sa.sa_len))
+ goto nomatchout;
+
+ /* Match source ID. */
+ if (ipo->ipo_srcid) {
+ if (ipo->ipo_tdb->tdb_srcid == NULL ||
+ !ipsp_ref_match(ipo->ipo_srcid,
+ ipo->ipo_tdb->tdb_srcid))
+ goto nomatchout;
+ }
+
+ /* Match destination ID. */
+ if (ipo->ipo_dstid) {
+ if (ipo->ipo_tdb->tdb_dstid == NULL ||
+ !ipsp_ref_match(ipo->ipo_dstid,
+ ipo->ipo_tdb->tdb_dstid))
+ goto nomatchout;
+ }
+
+ /* Match local credentials used */
+ if (ipo->ipo_local_cred) {
+ if (ipo->ipo_tdb->tdb_local_cred == NULL ||
+ !ipsp_ref_match(ipo->ipo_local_cred,
+ ipo->ipo_tdb->tdb_local_cred))
+ goto nomatchout;
+ }
+
+ /* Cached entry is good */
+ return ipsp_spd_inp(m, af, hlen, error, direction,
+ tdbp, inp, ipo);
- case IPSP_IPSEC_ACQUIRE:
- /* Acquire SA through key management */
- if (ipsp_acquire_sa(ipo, dignore ? &sdst : &ipo->ipo_dst,
- signore ? NULL : &ipo->ipo_src,
- ddst, NULL) != 0)
- {
- *error = EACCES;
- return NULL;
- }
-
- /* Fall through */
- case IPSP_IPSEC_USE:
- *error = 0; /* Let packet through */
- return NULL;
- }
- }
- else /* IPSP_DIRECTION_IN */
- {
- if (tdbp != NULL)
- {
- if (ipo->ipo_tdb == tdbp)
- {
- *error = 0; /* Accept packet */
- return NULL;
- }
-
- if (bcmp(dignore ? &ssrc : &ipo->ipo_dst, &tdbp->tdb_src,
- tdbp->tdb_src.sa.sa_len) ||
- (ipo->ipo_sproto != tdbp->tdb_sproto))
- goto nomatchin;
-
- /* Match source ID */
- if (ipo->ipo_srcid)
- {
- if (tdbp->tdb_dstid == NULL ||
- !ipsp_ref_match(ipo->ipo_srcid, tdbp->tdb_dstid))
- goto nomatchin;
- }
-
- /* Match destination ID */
- if (ipo->ipo_dstid)
- {
- if (tdbp->tdb_srcid == NULL ||
- !ipsp_ref_match(ipo->ipo_dstid, tdbp->tdb_srcid))
- goto nomatchin;
- }
-
- /* Add it to the cache */
- if (ipo->ipo_tdb)
- TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, ipo_tdb_next);
- ipo->ipo_tdb = tdbp;
- TAILQ_INSERT_TAIL(&tdbp->tdb_policy_head, ipo, ipo_tdb_next);
- *error = 0;
- return NULL;
+ nomatchout:
+ /* Cached TDB was not good */
+ TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo,
+ ipo_tdb_next);
+ ipo->ipo_tdb = NULL;
+ ipo->ipo_last_searched = 0;
+ }
- nomatchin: /* Nothing needed here, falling through */
- }
+ /*
+ * If no SA has been added since the last time we did a
+ * lookup, there's no point searching for one. However, if the
+ * destination gateway is left unspecified (or is all-1's),
+ * always lookup since this is a generic-match rule
+ * (otherwise, we can have situations where SAs to some
+ * destinations exist but are not used, possibly leading to an
+ * explosion in the number of acquired SAs).
+ */
+ if (ipo->ipo_last_searched <= ipsec_last_added) {
+ /* "Touch" the entry. */
+ ipo->ipo_last_searched = time.tv_sec;
+
+ /* Find an appropriate SA from the existing ones. */
+ ipo->ipo_tdb =
+ gettdbbyaddr(dignore ? &sdst : &ipo->ipo_dst,
+ ipo, m, af);
+ if (ipo->ipo_tdb) {
+ TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head,
+ ipo, ipo_tdb_next);
+ *error = 0;
+ return ipsp_spd_inp(m, af, hlen, error,
+ direction, tdbp, inp, ipo);
+ }
+ }
- /* Check whether cached entry applies */
- if (ipo->ipo_tdb)
- {
- /*
- * We only need to check that the correct security protocol and
- * security gateway are set; credentials/IDs will be the same,
- * since the cached entry is linked on this policy.
- */
- if (ipo->ipo_sproto == ipo->ipo_tdb->tdb_sproto &&
- !bcmp(&ipo->ipo_tdb->tdb_src, dignore ? &ssrc : &ipo->ipo_dst,
- ipo->ipo_tdb->tdb_src.sa.sa_len))
- goto skipinputsearch;
-
- /* Not applicable, unlink */
- TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, ipo_tdb_next);
- ipo->ipo_tdb = NULL;
- }
+ /* So, we don't have an SA -- just a policy. */
+ switch (ipo->ipo_type) {
+ case IPSP_IPSEC_REQUIRE:
+ /* Acquire SA through key management. */
+ if (ipsp_acquire_sa(ipo, dignore ? &sdst : &ipo->ipo_dst,
+ signore ? NULL : &ipo->ipo_src, ddst, m) != 0) {
+ *error = EACCES;
+ return NULL;
+ }
+
+ /* Fall through */
+ case IPSP_IPSEC_DONTACQ:
+ *error = -EINVAL; /* Silently drop packet. */
+ return NULL;
- /* Find whether there exists an appropriate SA */
- if (ipo->ipo_last_searched <= ipsec_last_added)
- {
- ipo->ipo_last_searched = time.tv_sec; /* "touch" */
+ case IPSP_IPSEC_ACQUIRE:
+ /* Acquire SA through key management. */
+ if (ipsp_acquire_sa(ipo, dignore ? &sdst : &ipo->ipo_dst,
+ signore ? NULL : &ipo->ipo_src, ddst, NULL) != 0) {
+ *error = EACCES;
+ return NULL;
+ }
+
+ /* Fall through */
+ case IPSP_IPSEC_USE:
+ *error = 0;
+ return ipsp_spd_inp(m, af, hlen, error, direction,
+ tdbp, inp, ipo);
+ }
+ } else { /* IPSP_DIRECTION_IN */
+ if (tdbp != NULL) {
+ /* Direct match in the cache. */
+ if (ipo->ipo_tdb == tdbp) {
+ *error = 0;
+ return ipsp_spd_inp(m, af, hlen, error,
+ direction, tdbp, inp, ipo);
+ }
+
+ if (bcmp(dignore ? &ssrc : &ipo->ipo_dst,
+ &tdbp->tdb_src, tdbp->tdb_src.sa.sa_len) ||
+ (ipo->ipo_sproto != tdbp->tdb_sproto))
+ goto nomatchin;
+
+ /* Match source ID. */
+ if (ipo->ipo_srcid) {
+ if (tdbp->tdb_dstid == NULL ||
+ !ipsp_ref_match(ipo->ipo_srcid,
+ tdbp->tdb_dstid))
+ goto nomatchin;
+ }
+
+ /* Match destination ID. */
+ if (ipo->ipo_dstid) {
+ if (tdbp->tdb_srcid == NULL ||
+ !ipsp_ref_match(ipo->ipo_dstid,
+ tdbp->tdb_srcid))
+ goto nomatchin;
+ }
+
+ /* Add it to the cache. */
+ if (ipo->ipo_tdb)
+ TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head,
+ ipo, ipo_tdb_next);
+ ipo->ipo_tdb = tdbp;
+ TAILQ_INSERT_TAIL(&tdbp->tdb_policy_head, ipo,
+ ipo_tdb_next);
+ *error = 0;
+ return ipsp_spd_inp(m, af, hlen, error, direction,
+ tdbp, inp, ipo);
- ipo->ipo_tdb = gettdbbysrc(dignore ? &ssrc : &ipo->ipo_dst,
- ipo, m, af);
- if (ipo->ipo_tdb)
- TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head, ipo,
- ipo_tdb_next);
- }
- skipinputsearch:
+ nomatchin: /* Nothing needed here, falling through */
+ }
- switch (ipo->ipo_type)
- {
- case IPSP_IPSEC_REQUIRE:
- /* If an appropriate SA exists, don't acquire another */
- if (ipo->ipo_tdb)
- {
- *error = -EINVAL;
- return NULL;
+ /* Check whether cached entry applies. */
+ if (ipo->ipo_tdb) {
+ /*
+ * We only need to check that the correct
+ * security protocol and security gateway are
+ * set; credentials/IDs will be the same,
+ * since the cached entry is linked on this
+ * policy.
+ */
+ if (ipo->ipo_sproto == ipo->ipo_tdb->tdb_sproto &&
+ !bcmp(&ipo->ipo_tdb->tdb_src, dignore ? &ssrc : &ipo->ipo_dst,
+ ipo->ipo_tdb->tdb_src.sa.sa_len))
+ goto skipinputsearch;
+
+ /* Not applicable, unlink. */
+ TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo,
+ ipo_tdb_next);
+ ipo->ipo_tdb = NULL;
}
- /* Acquire SA through key management */
- if ((*error = ipsp_acquire_sa(ipo,
- dignore ? &ssrc : &ipo->ipo_dst,
- signore ? NULL : &ipo->ipo_src,
- ddst, m)) != 0)
- return NULL;
-
- /* Fall through */
- case IPSP_IPSEC_DONTACQ:
- /* Drop packet */
- *error = -EINVAL;
- return NULL;
+ /* Find whether there exists an appropriate SA. */
+ if (ipo->ipo_last_searched <= ipsec_last_added) {
+ ipo->ipo_last_searched = time.tv_sec; /* "touch" */
- case IPSP_IPSEC_ACQUIRE:
- /* If an appropriate SA exists, don't acquire another */
- if (ipo->ipo_tdb)
- {
- *error = 0;
- return NULL;
+ ipo->ipo_tdb =
+ gettdbbysrc(dignore ? &ssrc : &ipo->ipo_dst,
+ ipo, m, af);
+ if (ipo->ipo_tdb)
+ TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head,
+ ipo, ipo_tdb_next);
}
+ skipinputsearch:
- /* Acquire SA through key management */
- if ((*error = ipsp_acquire_sa(ipo,
- dignore ? &ssrc : &ipo->ipo_dst,
- signore ? NULL : &ipo->ipo_src,
- ddst, NULL)) != 0)
- return NULL;
+ switch (ipo->ipo_type) {
+ case IPSP_IPSEC_REQUIRE:
+ /* If appropriate SA exists, don't acquire another. */
+ if (ipo->ipo_tdb) {
+ *error = -EINVAL;
+ return NULL;
+ }
+
+ /* Acquire SA through key management. */
+ if ((*error = ipsp_acquire_sa(ipo,
+ dignore ? &ssrc : &ipo->ipo_dst,
+ signore ? NULL : &ipo->ipo_src, ddst, m)) != 0)
+ return NULL;
+
+ /* Fall through */
+ case IPSP_IPSEC_DONTACQ:
+ /* Drop packet. */
+ *error = -EINVAL;
+ return NULL;
- /* Fall through */
- case IPSP_IPSEC_USE:
- /*
- * It doesn't matter what protection it had (if any),
- * just accept it -- equivalent to PERMIT for input.
- * This means we can't say that we want in incoming
- * packet to be unprotected -- at least not directly;
- * we can always have a DENY policy for ESP/AH packets.
- */
- *error = 0;
- return NULL;
+ case IPSP_IPSEC_ACQUIRE:
+ /* If appropriate SA exists, don't acquire another. */
+ if (ipo->ipo_tdb) {
+ *error = 0;
+ return ipsp_spd_inp(m, af, hlen, error,
+ direction, tdbp, inp, ipo);
+ }
+
+ /* Acquire SA through key management. */
+ if ((*error = ipsp_acquire_sa(ipo,
+ dignore ? &ssrc : &ipo->ipo_dst,
+ signore ? NULL : &ipo->ipo_src, ddst, NULL)) != 0)
+ return NULL;
+
+ /* Fall through */
+ case IPSP_IPSEC_USE:
+ *error = 0;
+ return ipsp_spd_inp(m, af, hlen, error, direction,
+ tdbp, inp, ipo);
+ }
}
- }
- /* Shouldn't ever get this far */
- *error = EINVAL;
- return NULL;
+ /* Shouldn't ever get this far. */
+ *error = EINVAL;
+ return NULL;
}
/*
@@ -564,34 +554,34 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction,
int
ipsec_delete_policy(struct ipsec_policy *ipo)
{
- int err = 0;
+ int err = 0;
- /* Delete */
- if (!(ipo->ipo_flags & IPSP_POLICY_SOCKET))
- err = rtrequest(RTM_DELETE, (struct sockaddr *) &ipo->ipo_addr,
- (struct sockaddr *) 0,
- (struct sockaddr *) &ipo->ipo_mask,
- 0, (struct rtentry **) 0);
+ /* Delete */
+ if (!(ipo->ipo_flags & IPSP_POLICY_SOCKET))
+ err = rtrequest(RTM_DELETE, (struct sockaddr *) &ipo->ipo_addr,
+ (struct sockaddr *) 0,
+ (struct sockaddr *) &ipo->ipo_mask,
+ 0, (struct rtentry **) 0);
- if (ipo->ipo_tdb)
- TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, ipo_tdb_next);
+ if (ipo->ipo_tdb)
+ TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, ipo_tdb_next);
- TAILQ_REMOVE(&ipsec_policy_head, ipo, ipo_list);
+ TAILQ_REMOVE(&ipsec_policy_head, ipo, ipo_list);
- if (ipo->ipo_srcid)
- ipsp_reffree(ipo->ipo_srcid);
- if (ipo->ipo_dstid)
- ipsp_reffree(ipo->ipo_dstid);
- if (ipo->ipo_local_cred)
- ipsp_reffree(ipo->ipo_local_cred);
- if (ipo->ipo_local_auth)
- ipsp_reffree(ipo->ipo_local_cred);
+ if (ipo->ipo_srcid)
+ ipsp_reffree(ipo->ipo_srcid);
+ if (ipo->ipo_dstid)
+ ipsp_reffree(ipo->ipo_dstid);
+ if (ipo->ipo_local_cred)
+ ipsp_reffree(ipo->ipo_local_cred);
+ if (ipo->ipo_local_auth)
+ ipsp_reffree(ipo->ipo_local_cred);
- FREE(ipo, M_IPSEC_POLICY);
+ FREE(ipo, M_IPSEC_POLICY);
- ipsec_in_use--;
+ ipsec_in_use--;
- return err;
+ return err;
}
/*
@@ -601,43 +591,42 @@ struct ipsec_policy *
ipsec_add_policy(struct sockaddr_encap *dst, struct sockaddr_encap *mask,
union sockaddr_union *sdst, int type, int sproto)
{
- struct sockaddr_encap encapgw;
- struct ipsec_policy *ipon;
-
- MALLOC(ipon, struct ipsec_policy *, sizeof(struct ipsec_policy),
- M_IPSEC_POLICY, M_NOWAIT);
- if (ipon == NULL)
- return NULL;
-
- bzero(ipon, sizeof(struct ipsec_policy));
- bzero((caddr_t) &encapgw, sizeof(struct sockaddr_encap));
-
- encapgw.sen_len = SENT_LEN;
- encapgw.sen_family = PF_KEY;
- encapgw.sen_type = SENT_IPSP;
- encapgw.sen_ipsp = ipon;
-
- if (rtrequest(RTM_ADD, (struct sockaddr *) dst,
- (struct sockaddr *) &encapgw, (struct sockaddr *) mask,
- RTF_UP | RTF_GATEWAY | RTF_STATIC,
- (struct rtentry **) 0) != 0)
- {
- DPRINTF(("ipsec_add_policy: failed to add policy\n"));
- FREE(ipon, M_IPSEC_POLICY);
- return NULL;
- }
+ struct sockaddr_encap encapgw;
+ struct ipsec_policy *ipon;
+
+ MALLOC(ipon, struct ipsec_policy *, sizeof(struct ipsec_policy),
+ M_IPSEC_POLICY, M_NOWAIT);
+ if (ipon == NULL)
+ return NULL;
- ipsec_in_use++;
+ bzero(ipon, sizeof(struct ipsec_policy));
+ bzero((caddr_t) &encapgw, sizeof(struct sockaddr_encap));
+
+ encapgw.sen_len = SENT_LEN;
+ encapgw.sen_family = PF_KEY;
+ encapgw.sen_type = SENT_IPSP;
+ encapgw.sen_ipsp = ipon;
+
+ if (rtrequest(RTM_ADD, (struct sockaddr *) dst,
+ (struct sockaddr *) &encapgw, (struct sockaddr *) mask,
+ RTF_UP | RTF_GATEWAY | RTF_STATIC,
+ (struct rtentry **) 0) != 0) {
+ DPRINTF(("ipsec_add_policy: failed to add policy\n"));
+ FREE(ipon, M_IPSEC_POLICY);
+ return NULL;
+ }
- bcopy(dst, &ipon->ipo_addr, sizeof(struct sockaddr_encap));
- bcopy(mask, &ipon->ipo_mask, sizeof(struct sockaddr_encap));
- bcopy(sdst, &ipon->ipo_dst, sizeof(union sockaddr_union));
- ipon->ipo_sproto = sproto;
- ipon->ipo_type = type;
+ ipsec_in_use++;
- TAILQ_INSERT_HEAD(&ipsec_policy_head, ipon, ipo_list);
+ bcopy(dst, &ipon->ipo_addr, sizeof(struct sockaddr_encap));
+ bcopy(mask, &ipon->ipo_mask, sizeof(struct sockaddr_encap));
+ bcopy(sdst, &ipon->ipo_dst, sizeof(union sockaddr_union));
+ ipon->ipo_sproto = sproto;
+ ipon->ipo_type = type;
- return ipon;
+ TAILQ_INSERT_HEAD(&ipsec_policy_head, ipon, ipo_list);
+
+ return ipon;
}
/*
@@ -646,13 +635,13 @@ ipsec_add_policy(struct sockaddr_encap *dst, struct sockaddr_encap *mask,
void
ipsp_delete_acquire(void *v)
{
- struct ipsec_acquire *ipa = v;
+ struct ipsec_acquire *ipa = v;
- timeout_del(&ipa->ipa_timeout);
- TAILQ_REMOVE(&ipsec_acquire_head, ipa, ipa_next);
- if (ipa->ipa_packet)
- m_freem(ipa->ipa_packet);
- FREE(ipa, M_IPSEC_POLICY);
+ timeout_del(&ipa->ipa_timeout);
+ TAILQ_REMOVE(&ipsec_acquire_head, ipa, ipa_next);
+ if (ipa->ipa_packet)
+ m_freem(ipa->ipa_packet);
+ FREE(ipa, M_IPSEC_POLICY);
}
/*
@@ -661,92 +650,94 @@ ipsp_delete_acquire(void *v)
void
ipsp_clear_acquire(struct tdb *tdb)
{
- struct ipsec_acquire *ipa;
- struct ifqueue *ifq;
- int s;
-
- while ((ipa = ipsp_pending_acquire(&tdb->tdb_dst)) != NULL)
- {
-
- /* Retransmit */
- if (ipa->ipa_packet)
- {
- switch (ipa->ipa_info.sen_type)
- {
+ struct ipsec_acquire *ipa;
+ struct ifqueue *ifq;
+ int s;
+
+ while ((ipa = ipsp_pending_acquire(&tdb->tdb_dst)) != NULL) {
+ /* Retransmit */
+ if (ipa->ipa_packet) {
+ switch (ipa->ipa_info.sen_type) {
#ifdef INET
- case SENT_IP4:
- {
- struct ip *ip;
-
- switch (ipa->ipa_info.sen_direction)
- {
- case IPSP_DIRECTION_OUT:
- ip = mtod(ipa->ipa_packet, struct ip *);
- if (ipa->ipa_packet->m_len < sizeof(struct ip))
- break;
-
- /* Same as in ip_output() -- massage the header */
- ip->ip_len = htons((u_short) ip->ip_len);
- ip->ip_off = htons((u_short) ip->ip_off);
- ipa->ipa_packet->m_flags &= ~(M_MCAST | M_BCAST);
-
- ipsp_process_packet(ipa->ipa_packet, tdb,
- AF_INET, 0);
- ipa->ipa_packet = NULL;
- break;
-
- case IPSP_DIRECTION_IN:
- ifq = &ipintrq;
- s = splimp();
- if (IF_QFULL(ifq))
- {
- IF_DROP(ifq);
- splx(s);
- break;
- }
- IF_ENQUEUE(ifq, ipa->ipa_packet);
- ipa->ipa_packet = NULL;
- schednetisr(NETISR_IP);
- splx(s);
- break;
- }
- }
- break;
+ case SENT_IP4:
+ {
+ struct ip *ip;
+
+ switch (ipa->ipa_info.sen_direction) {
+ case IPSP_DIRECTION_OUT:
+ ip = mtod(ipa->ipa_packet,
+ struct ip *);
+
+ if (ipa->ipa_packet->m_len <
+ sizeof(struct ip))
+ break;
+
+ /* Same as in ip_output() --
+ * massage the header.
+ */
+
+ ip->ip_len =
+ htons((u_short) ip->ip_len);
+ ip->ip_off =
+ htons((u_short) ip->ip_off);
+ ipa->ipa_packet->m_flags &=
+ ~(M_MCAST | M_BCAST);
+
+ ipsp_process_packet(ipa->ipa_packet,
+ tdb, AF_INET, 0);
+ ipa->ipa_packet = NULL;
+ break;
+
+ case IPSP_DIRECTION_IN:
+ ifq = &ipintrq;
+ s = splimp();
+ if (IF_QFULL(ifq)) {
+ IF_DROP(ifq);
+ splx(s);
+ break;
+ }
+ IF_ENQUEUE(ifq, ipa->ipa_packet);
+ ipa->ipa_packet = NULL;
+ schednetisr(NETISR_IP);
+ splx(s);
+ break;
+ }
+ }
+ break;
#endif /* INET */
#ifdef INET6
- case SENT_IP6:
- switch (ipa->ipa_info.sen_ip6_direction)
- {
- case IPSP_DIRECTION_OUT:
- ipa->ipa_packet->m_flags &= ~(M_BCAST | M_MCAST);
- ipsp_process_packet(ipa->ipa_packet, tdb,
- AF_INET6, 0);
- ipa->ipa_packet = NULL;
- break;
-
- case IPSP_DIRECTION_IN:
- ifq = &ip6intrq;
- s = splimp();
- if (IF_QFULL(ifq))
- {
- IF_DROP(ifq);
- splx(s);
+ case SENT_IP6:
+ switch (ipa->ipa_info.sen_ip6_direction) {
+ case IPSP_DIRECTION_OUT:
+ ipa->ipa_packet->m_flags &=
+ ~(M_BCAST | M_MCAST);
+ ipsp_process_packet(ipa->ipa_packet,
+ tdb, AF_INET6, 0);
+ ipa->ipa_packet = NULL;
+ break;
+
+ case IPSP_DIRECTION_IN:
+ ifq = &ip6intrq;
+ s = splimp();
+ if (IF_QFULL(ifq)) {
+ IF_DROP(ifq);
+ splx(s);
+ break;
+ }
+ IF_ENQUEUE(ifq, ipa->ipa_packet);
+ ipa->ipa_packet = NULL;
+ schednetisr(NETISR_IPV6);
+ splx(s);
+ break;
+ }
break;
- }
- IF_ENQUEUE(ifq, ipa->ipa_packet);
- ipa->ipa_packet = NULL;
- schednetisr(NETISR_IPV6);
- splx(s);
- break;
- }
- break;
#endif /* INET6 */
- }
- }
+ }
+ }
- ipsp_delete_acquire(ipa);
- }
+ ipsp_delete_acquire(ipa);
+ }
}
/*
@@ -756,17 +747,15 @@ ipsp_clear_acquire(struct tdb *tdb)
struct ipsec_acquire *
ipsp_pending_acquire(union sockaddr_union *gw)
{
- struct ipsec_acquire *ipa;
+ struct ipsec_acquire *ipa;
- for (ipa = TAILQ_FIRST(&ipsec_acquire_head);
- ipa;
- ipa = TAILQ_NEXT(ipa, ipa_next))
- {
- if (!bcmp(gw, &ipa->ipa_addr, gw->sa.sa_len))
- return ipa;
- }
+ for (ipa = TAILQ_FIRST(&ipsec_acquire_head); ipa;
+ ipa = TAILQ_NEXT(ipa, ipa_next)) {
+ if (!bcmp(gw, &ipa->ipa_addr, gw->sa.sa_len))
+ return ipa;
+ }
- return NULL;
+ return NULL;
}
/*
@@ -778,149 +767,139 @@ ipsp_acquire_sa(struct ipsec_policy *ipo, union sockaddr_union *gw,
union sockaddr_union *laddr, struct sockaddr_encap *ddst,
struct mbuf *m)
{
- struct ipsec_acquire *ipa;
+ struct ipsec_acquire *ipa;
#ifdef INET6
- int i;
+ int i;
#endif
- /* Check whether request has been made already. */
- if ((ipa = ipsp_pending_acquire(gw)) != NULL)
- {
- if (ipa->ipa_packet && m)
- {
- m_freem(ipa->ipa_packet);
- ipa->ipa_packet = m_copym2(m, 0, M_COPYALL, M_DONTWAIT);
- }
+ /* Check whether request has been made already. */
+ if ((ipa = ipsp_pending_acquire(gw)) != NULL) {
+ if (ipa->ipa_packet && m) {
+ m_freem(ipa->ipa_packet);
+ ipa->ipa_packet = m_copym2(m, 0, M_COPYALL,
+ M_DONTWAIT);
+ }
- return 0;
- }
+ return 0;
+ }
- /* Add request in cache and proceed */
- MALLOC(ipa, struct ipsec_acquire *, sizeof(struct ipsec_acquire),
- M_IPSEC_POLICY, M_DONTWAIT);
- if (ipa == NULL)
- return ENOMEM;
+ /* Add request in cache and proceed */
+ MALLOC(ipa, struct ipsec_acquire *, sizeof(struct ipsec_acquire),
+ M_IPSEC_POLICY, M_DONTWAIT);
+ if (ipa == NULL)
+ return ENOMEM;
- bzero(ipa, sizeof(struct ipsec_acquire));
- bcopy(gw, &ipa->ipa_addr, sizeof(union sockaddr_union));
- timeout_set(&ipa->ipa_timeout, ipsp_delete_acquire, ipa);
+ bzero(ipa, sizeof(struct ipsec_acquire));
+ bcopy(gw, &ipa->ipa_addr, sizeof(union sockaddr_union));
+ timeout_set(&ipa->ipa_timeout, ipsp_delete_acquire, ipa);
- ipa->ipa_info.sen_len = ipa->ipa_mask.sen_len = SENT_LEN;
- ipa->ipa_info.sen_family = ipa->ipa_mask.sen_family = PF_KEY;
+ ipa->ipa_info.sen_len = ipa->ipa_mask.sen_len = SENT_LEN;
+ ipa->ipa_info.sen_family = ipa->ipa_mask.sen_family = PF_KEY;
- /* Just copy the right information */
- switch (ipo->ipo_addr.sen_type)
- {
+ /* Just copy the right information */
+ switch (ipo->ipo_addr.sen_type) {
#ifdef INET
case SENT_IP4:
- ipa->ipa_info.sen_type = ipa->ipa_mask.sen_type = SENT_IP4;
- ipa->ipa_info.sen_direction = ipo->ipo_addr.sen_direction;
- ipa->ipa_mask.sen_direction = ipo->ipo_mask.sen_direction;
-
- if (ipo->ipo_mask.sen_ip_src.s_addr == INADDR_ANY ||
- ipo->ipo_addr.sen_ip_src.s_addr == INADDR_ANY ||
- ipsp_is_unspecified(ipo->ipo_dst))
- {
- ipa->ipa_info.sen_ip_src = ddst->sen_ip_src;
- ipa->ipa_mask.sen_ip_src.s_addr = INADDR_BROADCAST;
- }
- else
- {
- ipa->ipa_info.sen_ip_src = ipo->ipo_addr.sen_ip_src;
- ipa->ipa_mask.sen_ip_src = ipo->ipo_mask.sen_ip_src;
- }
-
- if (ipo->ipo_mask.sen_ip_dst.s_addr == INADDR_ANY ||
- ipo->ipo_addr.sen_ip_dst.s_addr == INADDR_ANY ||
- ipsp_is_unspecified(ipo->ipo_dst))
- {
- ipa->ipa_info.sen_ip_dst = ddst->sen_ip_dst;
- ipa->ipa_mask.sen_ip_dst.s_addr = INADDR_BROADCAST;
- }
- else
- {
- ipa->ipa_info.sen_ip_dst = ipo->ipo_addr.sen_ip_dst;
- ipa->ipa_mask.sen_ip_dst = ipo->ipo_mask.sen_ip_dst;
- }
-
- ipa->ipa_info.sen_proto = ipo->ipo_addr.sen_proto;
- ipa->ipa_mask.sen_proto = ipo->ipo_mask.sen_proto;
-
- if (ipo->ipo_addr.sen_proto)
- {
- ipa->ipa_info.sen_sport = ipo->ipo_addr.sen_sport;
- ipa->ipa_mask.sen_sport = ipo->ipo_mask.sen_sport;
-
- ipa->ipa_info.sen_dport = ipo->ipo_addr.sen_dport;
- ipa->ipa_mask.sen_dport = ipo->ipo_mask.sen_dport;
- }
- break;
+ ipa->ipa_info.sen_type = ipa->ipa_mask.sen_type = SENT_IP4;
+ ipa->ipa_info.sen_direction = ipo->ipo_addr.sen_direction;
+ ipa->ipa_mask.sen_direction = ipo->ipo_mask.sen_direction;
+
+ if (ipo->ipo_mask.sen_ip_src.s_addr == INADDR_ANY ||
+ ipo->ipo_addr.sen_ip_src.s_addr == INADDR_ANY ||
+ ipsp_is_unspecified(ipo->ipo_dst)) {
+ ipa->ipa_info.sen_ip_src = ddst->sen_ip_src;
+ ipa->ipa_mask.sen_ip_src.s_addr = INADDR_BROADCAST;
+ } else {
+ ipa->ipa_info.sen_ip_src = ipo->ipo_addr.sen_ip_src;
+ ipa->ipa_mask.sen_ip_src = ipo->ipo_mask.sen_ip_src;
+ }
+
+ if (ipo->ipo_mask.sen_ip_dst.s_addr == INADDR_ANY ||
+ ipo->ipo_addr.sen_ip_dst.s_addr == INADDR_ANY ||
+ ipsp_is_unspecified(ipo->ipo_dst)) {
+ ipa->ipa_info.sen_ip_dst = ddst->sen_ip_dst;
+ ipa->ipa_mask.sen_ip_dst.s_addr = INADDR_BROADCAST;
+ } else {
+ ipa->ipa_info.sen_ip_dst = ipo->ipo_addr.sen_ip_dst;
+ ipa->ipa_mask.sen_ip_dst = ipo->ipo_mask.sen_ip_dst;
+ }
+
+ ipa->ipa_info.sen_proto = ipo->ipo_addr.sen_proto;
+ ipa->ipa_mask.sen_proto = ipo->ipo_mask.sen_proto;
+
+ if (ipo->ipo_addr.sen_proto) {
+ ipa->ipa_info.sen_sport = ipo->ipo_addr.sen_sport;
+ ipa->ipa_mask.sen_sport = ipo->ipo_mask.sen_sport;
+
+ ipa->ipa_info.sen_dport = ipo->ipo_addr.sen_dport;
+ ipa->ipa_mask.sen_dport = ipo->ipo_mask.sen_dport;
+ }
+ break;
#endif /* INET */
#ifdef INET6
case SENT_IP6:
- ipa->ipa_info.sen_type = ipa->ipa_mask.sen_type = SENT_IP6;
- ipa->ipa_info.sen_ip6_direction = ipo->ipo_addr.sen_ip6_direction;
- ipa->ipa_mask.sen_ip6_direction = ipo->ipo_mask.sen_ip6_direction;
-
- if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_mask.sen_ip6_src) ||
- IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_addr.sen_ip6_src) ||
- ipsp_is_unspecified(ipo->ipo_dst))
- {
- ipa->ipa_info.sen_ip6_src = ddst->sen_ip6_src;
- for (i = 0; i < 16; i++)
- ipa->ipa_mask.sen_ip6_src.s6_addr8[i] = 0xff;
- }
- else
- {
- ipa->ipa_info.sen_ip6_src = ipo->ipo_addr.sen_ip6_src;
- ipa->ipa_mask.sen_ip6_src = ipo->ipo_mask.sen_ip6_src;
- }
-
- if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_mask.sen_ip6_dst) ||
- IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_addr.sen_ip6_dst) ||
- ipsp_is_unspecified(ipo->ipo_dst))
- {
- ipa->ipa_info.sen_ip6_dst = ddst->sen_ip6_dst;
- for (i = 0; i < 16; i++)
- ipa->ipa_mask.sen_ip6_dst.s6_addr8[i] = 0xff;
- }
- else
- {
- ipa->ipa_info.sen_ip6_dst = ipo->ipo_addr.sen_ip6_dst;
- ipa->ipa_mask.sen_ip6_dst = ipo->ipo_mask.sen_ip6_dst;
- }
-
- ipa->ipa_info.sen_ip6_proto = ipo->ipo_addr.sen_ip6_proto;
- ipa->ipa_mask.sen_ip6_proto = ipo->ipo_mask.sen_ip6_proto;
-
- if (ipo->ipo_mask.sen_ip6_proto)
- {
- ipa->ipa_info.sen_ip6_sport = ipo->ipo_addr.sen_ip6_sport;
- ipa->ipa_mask.sen_ip6_sport = ipo->ipo_mask.sen_ip6_sport;
- ipa->ipa_info.sen_ip6_dport = ipo->ipo_addr.sen_ip6_dport;
- ipa->ipa_mask.sen_ip6_dport = ipo->ipo_mask.sen_ip6_dport;
- }
- break;
+ ipa->ipa_info.sen_type = ipa->ipa_mask.sen_type = SENT_IP6;
+ ipa->ipa_info.sen_ip6_direction =
+ ipo->ipo_addr.sen_ip6_direction;
+ ipa->ipa_mask.sen_ip6_direction =
+ ipo->ipo_mask.sen_ip6_direction;
+
+ if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_mask.sen_ip6_src) ||
+ IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_addr.sen_ip6_src) ||
+ ipsp_is_unspecified(ipo->ipo_dst)) {
+ ipa->ipa_info.sen_ip6_src = ddst->sen_ip6_src;
+ for (i = 0; i < 16; i++)
+ ipa->ipa_mask.sen_ip6_src.s6_addr8[i] = 0xff;
+ } else {
+ ipa->ipa_info.sen_ip6_src = ipo->ipo_addr.sen_ip6_src;
+ ipa->ipa_mask.sen_ip6_src = ipo->ipo_mask.sen_ip6_src;
+ }
+
+ if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_mask.sen_ip6_dst) ||
+ IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_addr.sen_ip6_dst) ||
+ ipsp_is_unspecified(ipo->ipo_dst)) {
+ ipa->ipa_info.sen_ip6_dst = ddst->sen_ip6_dst;
+ for (i = 0; i < 16; i++)
+ ipa->ipa_mask.sen_ip6_dst.s6_addr8[i] = 0xff;
+ } else {
+ ipa->ipa_info.sen_ip6_dst = ipo->ipo_addr.sen_ip6_dst;
+ ipa->ipa_mask.sen_ip6_dst = ipo->ipo_mask.sen_ip6_dst;
+ }
+
+ ipa->ipa_info.sen_ip6_proto = ipo->ipo_addr.sen_ip6_proto;
+ ipa->ipa_mask.sen_ip6_proto = ipo->ipo_mask.sen_ip6_proto;
+
+ if (ipo->ipo_mask.sen_ip6_proto) {
+ ipa->ipa_info.sen_ip6_sport =
+ ipo->ipo_addr.sen_ip6_sport;
+ ipa->ipa_mask.sen_ip6_sport =
+ ipo->ipo_mask.sen_ip6_sport;
+ ipa->ipa_info.sen_ip6_dport =
+ ipo->ipo_addr.sen_ip6_dport;
+ ipa->ipa_mask.sen_ip6_dport =
+ ipo->ipo_mask.sen_ip6_dport;
+ }
+ break;
#endif /* INET6 */
default:
- FREE(ipa, M_IPSEC_POLICY);
- return 0;
- }
-
- /*
- * Store the packet for eventual retransmission -- failure is not
- * catastrophic.
- */
- if (m)
- ipa->ipa_packet = m_copym2(m, 0, M_COPYALL, M_DONTWAIT);
-
- timeout_add(&ipa->ipa_timeout, ipsec_expire_acquire * hz);
- TAILQ_INSERT_TAIL(&ipsec_acquire_head, ipa, ipa_next);
-
- /* PF_KEYv2 notification message */
- return pfkeyv2_acquire(ipo, gw, laddr, &ipa->ipa_seq, ddst);
+ FREE(ipa, M_IPSEC_POLICY);
+ return 0;
+ }
+
+ /*
+ * Store the packet for eventual retransmission -- failure is not
+ * catastrophic.
+ */
+ if (m)
+ ipa->ipa_packet = m_copym2(m, 0, M_COPYALL, M_DONTWAIT);
+
+ timeout_add(&ipa->ipa_timeout, ipsec_expire_acquire * hz);
+ TAILQ_INSERT_TAIL(&ipsec_acquire_head, ipa, ipa_next);
+
+ /* PF_KEYv2 notification message */
+ return pfkeyv2_acquire(ipo, gw, laddr, &ipa->ipa_seq, ddst);
}
/*
@@ -930,13 +909,26 @@ ipsp_acquire_sa(struct ipsec_policy *ipo, union sockaddr_union *gw,
struct ipsec_acquire *
ipsec_get_acquire(u_int32_t seq)
{
- struct ipsec_acquire *ipa;
+ struct ipsec_acquire *ipa;
- for (ipa = TAILQ_FIRST(&ipsec_acquire_head);
- ipa;
- ipa = TAILQ_NEXT(ipa, ipa_next))
- if (ipa->ipa_seq == seq)
- return ipa;
+ for (ipa = TAILQ_FIRST(&ipsec_acquire_head); ipa;
+ ipa = TAILQ_NEXT(ipa, ipa_next))
+ if (ipa->ipa_seq == seq)
+ return ipa;
- return NULL;
+ return NULL;
+}
+
+/*
+ * Deal with PCB security requirements.
+ */
+struct tdb *
+ipsp_spd_inp(struct mbuf *m, int af, int hlen, int *error, int direction,
+ struct tdb *tdbp, struct inpcb *inp, struct ipsec_policy *ipo)
+{
+ /* XXX */
+ if (ipo)
+ return ipo->ipo_tdb;
+ else
+ return NULL;
}