summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2017-03-13 15:06:51 +0000
committerpatrick <patrick@openbsd.org>2017-03-13 15:06:51 +0000
commit1a394ec9e9a36f4f4fcaf884df38387d7809ff99 (patch)
tree30a8f07b693b361042c1f8d6ef21e148f1de7e09
parentWhen freeing a Child SA make sure it's peer no longer points to it (diff)
downloadwireguard-openbsd-1a394ec9e9a36f4f4fcaf884df38387d7809ff99.tar.xz
wireguard-openbsd-1a394ec9e9a36f4f4fcaf884df38387d7809ff99.zip
When setting up IPcomp flows for the networks 'A' and 'B' between
gateways 'a' and 'b', we replace the ESP flow "A->B ESP" with an IPCOMP flow "A->B IPCOMP" and add a matching (transport mode) ESP flow between the gateways "a->b ESP". The later is now marked with flow_ipcomp so it is not translated into "a->b IPCOMP" on rekeying. When SAs get deleted we do an extra loop to figure out if matching IPcomp SAs can now be removed, too. This allows faster expiry of unused IPcomp SAs. Disable bytes lifetime for IP compression. ok markus@ reyk@
-rw-r--r--sbin/iked/iked.h3
-rw-r--r--sbin/iked/ikev2.c26
-rw-r--r--sbin/iked/pfkey.c8
3 files changed, 29 insertions, 8 deletions
diff --git a/sbin/iked/iked.h b/sbin/iked/iked.h
index 9f945b60899..89625e612a2 100644
--- a/sbin/iked/iked.h
+++ b/sbin/iked/iked.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: iked.h,v 1.104 2017/03/13 14:57:55 reyk Exp $ */
+/* $OpenBSD: iked.h,v 1.105 2017/03/13 15:06:51 patrick Exp $ */
/*
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
@@ -157,6 +157,7 @@ struct iked_flow {
RB_ENTRY(iked_flow) flow_node;
TAILQ_ENTRY(iked_flow) flow_entry;
+ int flow_ipcomp;
};
RB_HEAD(iked_flows, iked_flow);
TAILQ_HEAD(iked_saflows, iked_flow);
diff --git a/sbin/iked/ikev2.c b/sbin/iked/ikev2.c
index 0c1cfd235db..cdfbd5c41e4 100644
--- a/sbin/iked/ikev2.c
+++ b/sbin/iked/ikev2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ikev2.c,v 1.137 2017/03/13 14:57:55 reyk Exp $ */
+/* $OpenBSD: ikev2.c,v 1.138 2017/03/13 15:06:51 patrick Exp $ */
/*
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
@@ -4683,7 +4683,7 @@ ikev2_ipcomp_enable(struct iked *env, struct iked_sa *sa)
/* redirect flows to IPCOMP */
/* XXX expensive? should be merged into ikev2_childsa_negotiate() */
TAILQ_FOREACH_SAFE(flow, &sa->sa_flows, flow_entry, nflow) {
- if (flow->flow_loaded ||
+ if (flow->flow_loaded || flow->flow_ipcomp ||
flow->flow_saproto != IKEV2_SAPROTO_ESP)
continue;
TAILQ_FOREACH(oflow, &sa->sa_flows, flow_entry)
@@ -4706,6 +4706,7 @@ ikev2_ipcomp_enable(struct iked *env, struct iked_sa *sa)
}
/* setup ESP flows for gateways */
+ flowa->flow_ipcomp = 1;
flowa->flow_dir = IPSP_DIRECTION_OUT;
flowa->flow_saproto = IKEV2_SAPROTO_ESP;
flowa->flow_local = &sa->sa_local;
@@ -4802,7 +4803,7 @@ ikev2_childsa_delete(struct iked *env, struct iked_sa *sa, uint8_t saproto,
{
struct iked_childsa *csa, *nextcsa = NULL;
uint64_t peerspi = 0;
- int found = 0;
+ int found = 0, ipcomp = 0;
for (csa = TAILQ_FIRST(&sa->sa_childsas); csa != NULL; csa = nextcsa) {
nextcsa = TAILQ_NEXT(csa, csa_entry);
@@ -4829,10 +4830,23 @@ ikev2_childsa_delete(struct iked *env, struct iked_sa *sa, uint8_t saproto,
if (spi && csa->csa_spi.spi == spi)
peerspi = csa->csa_peerspi;
+ if (csa->csa_parent && csa->csa_parent->csa_children == 1)
+ ipcomp = 1;
TAILQ_REMOVE(&sa->sa_childsas, csa, csa_entry);
childsa_free(csa);
}
+ /* lookup and delete matching IPcomp SAs */
+ if (ipcomp) {
+ for (csa = TAILQ_FIRST(&sa->sa_childsas); csa != NULL;
+ csa = nextcsa) {
+ nextcsa = TAILQ_NEXT(csa, csa_entry);
+ if (csa->csa_saproto == IKEV2_SAPROTO_IPCOMP &&
+ csa->csa_children == 0)
+ ikev2_ipcomp_csa_free(env, csa);
+ }
+ }
+
if (spiptr)
*spiptr = peerspi;
@@ -5004,8 +5018,12 @@ ikev2_drop_sa(struct iked *env, struct iked_spi *drop)
return (0);
sa = csa->csa_ikesa;
- if (sa && (sa->sa_stateflags & IKED_REQ_CHILDSA))
+ if (csa->csa_saproto != IKEV2_SAPROTO_IPCOMP &&
+ sa && (sa->sa_stateflags & IKED_REQ_CHILDSA)) {
+ /* XXXX might loop, should we add a counter? */
+ log_debug("%s: parent SA busy", __func__);
return (-1); /* busy, retry later */
+ }
RB_REMOVE(iked_activesas, &env->sc_activesas, csa);
csa->csa_loaded = 0;
diff --git a/sbin/iked/pfkey.c b/sbin/iked/pfkey.c
index 73c481ec1b8..3ded6f1eec9 100644
--- a/sbin/iked/pfkey.c
+++ b/sbin/iked/pfkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkey.c,v 1.53 2017/02/28 16:46:27 bluhm Exp $ */
+/* $OpenBSD: pfkey.c,v 1.54 2017/03/13 15:06:51 patrick Exp $ */
/*
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
@@ -518,9 +518,11 @@ pfkey_sa(int sd, uint8_t satype, uint8_t action, struct iked_childsa *sa)
sa_ltime_hard.sadb_lifetime_bytes = lt->lt_bytes;
sa_ltime_hard.sadb_lifetime_addtime = lt->lt_seconds;
- /* double the lifetime for IP compression */
- if (satype == SADB_X_SATYPE_IPCOMP)
+ /* double the lifetime for IP compression; disable byte lifetime */
+ if (satype == SADB_X_SATYPE_IPCOMP) {
sa_ltime_hard.sadb_lifetime_addtime *= 2;
+ sa_ltime_hard.sadb_lifetime_bytes = 0;
+ }
sa_ltime_soft.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
sa_ltime_soft.sadb_lifetime_len = sizeof(sa_ltime_soft) / 8;