summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
Diffstat (limited to 'sbin')
-rw-r--r--sbin/iked/config.c4
-rw-r--r--sbin/iked/iked.h4
-rw-r--r--sbin/iked/ikev2.c63
-rw-r--r--sbin/iked/parse.y11
4 files changed, 77 insertions, 5 deletions
diff --git a/sbin/iked/config.c b/sbin/iked/config.c
index ecf03e64cd3..a77e5320381 100644
--- a/sbin/iked/config.c
+++ b/sbin/iked/config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.c,v 1.73 2020/11/25 22:17:13 tobhe Exp $ */
+/* $OpenBSD: config.c,v 1.74 2020/11/29 21:00:43 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -880,6 +880,8 @@ config_getstatic(struct iked *env, struct imsg *imsg)
log_debug("%s: %sfragmentation", __func__, env->sc_frag ? "" : "no ");
log_debug("%s: %smobike", __func__, env->sc_mobike ? "" : "no ");
log_debug("%s: nattport %u", __func__, env->sc_nattport);
+ log_debug("%s: %sstickyaddress", __func__,
+ env->sc_stickyaddress ? "" : "no ");
return (0);
}
diff --git a/sbin/iked/iked.h b/sbin/iked/iked.h
index 416fc507ab5..f50df6e64e0 100644
--- a/sbin/iked/iked.h
+++ b/sbin/iked/iked.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: iked.h,v 1.175 2020/11/26 22:24:06 tobhe Exp $ */
+/* $OpenBSD: iked.h,v 1.176 2020/11/29 21:00:43 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -716,6 +716,7 @@ struct iked_static {
uint8_t st_frag; /* fragmentation */
uint8_t st_mobike; /* MOBIKE */
in_port_t st_nattport;
+ int st_stickyaddress; /* addr per DSTID */
};
struct iked {
@@ -733,6 +734,7 @@ struct iked {
#define sc_frag sc_static.st_frag
#define sc_mobike sc_static.st_mobike
#define sc_nattport sc_static.st_nattport
+#define sc_stickyaddress sc_static.st_stickyaddress
struct iked_policies sc_policies;
struct iked_policy *sc_defaultcon;
diff --git a/sbin/iked/ikev2.c b/sbin/iked/ikev2.c
index 59f234d699d..e61a84eb44a 100644
--- a/sbin/iked/ikev2.c
+++ b/sbin/iked/ikev2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ikev2.c,v 1.289 2020/11/28 20:26:50 tobhe Exp $ */
+/* $OpenBSD: ikev2.c,v 1.290 2020/11/29 21:00:43 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -6602,6 +6602,7 @@ ikev2_cp_setaddr_pool(struct iked *env, struct iked_sa *sa,
struct sockaddr_in *in4 = NULL, *cfg4 = NULL;
struct sockaddr_in6 *in6 = NULL, *cfg6 = NULL;
struct iked_sa key;
+ struct iked_sa *osa;
char idstr[IKED_ID_SIZE];
struct iked_addr addr;
uint32_t mask, host, lower, upper, start, nhost;
@@ -6620,6 +6621,66 @@ ikev2_cp_setaddr_pool(struct iked *env, struct iked_sa *sa,
bzero(&addr, sizeof(addr));
addr.addr_af = family;
+ /* check if old IKESA for same DSTID already exists and transfer IPs */
+ if (env->sc_stickyaddress &&
+ (osa = sa_dstid_lookup(env, sa)) != NULL &&
+ ((family == AF_INET && osa->sa_addrpool) ||
+ (family == AF_INET6 && osa->sa_addrpool6))) {
+ /* we have to transfer both, even if we just need one */
+ if (osa->sa_addrpool) {
+ if (RB_REMOVE(iked_addrpool, &env->sc_addrpool, osa)
+ != osa) {
+ log_info("%s: addrpool error",
+ SPI_SA(osa, __func__));
+ return (-1);
+ }
+ }
+ if (osa->sa_addrpool6) {
+ if (RB_REMOVE(iked_addrpool6, &env->sc_addrpool6, osa)
+ != osa) {
+ log_info("%s: addrpool6 error",
+ SPI_SA(osa, __func__));
+ return (-1);
+ }
+ }
+ sa_dstid_remove(env, osa);
+ sa->sa_addrpool = osa->sa_addrpool;
+ osa->sa_addrpool = NULL;
+ sa->sa_addrpool6 = osa->sa_addrpool6;
+ osa->sa_addrpool6 = NULL;
+ if (osa->sa_state < IKEV2_STATE_CLOSING) {
+ if (osa->sa_state == IKEV2_STATE_ESTABLISHED)
+ ikev2_disable_timer(env, osa);
+ ikev2_ike_sa_setreason(osa,
+ "address re-use (identical dstid)");
+ ikev2_ikesa_delete(env, osa, 1);
+ timer_add(env, &osa->sa_timer,
+ 3 * IKED_RETRANSMIT_TIMEOUT);
+ }
+ if (sa->sa_addrpool) {
+ RB_INSERT(iked_addrpool, &env->sc_addrpool, sa);
+ log_info(
+ "%s: giving up assigned address %s to IKESA %s",
+ SPI_SA(osa, __func__),
+ print_host((struct sockaddr *)
+ &sa->sa_addrpool->addr, NULL, 0),
+ print_spi(sa->sa_hdr.sh_ispi, 8));
+ }
+ if (sa->sa_addrpool6) {
+ RB_INSERT(iked_addrpool6, &env->sc_addrpool6, sa);
+ log_info(
+ "%s: giving up assigned v6 address %s to IKESA %s",
+ SPI_SA(osa, __func__),
+ print_host((struct sockaddr *)
+ &sa->sa_addrpool6->addr, NULL, 0),
+ print_spi(sa->sa_hdr.sh_ispi, 8));
+ }
+ if (family == AF_INET && sa->sa_addrpool != NULL)
+ memcpy(&addr, sa->sa_addrpool, sizeof(addr));
+ else if (family == AF_INET6 && sa->sa_addrpool6 != NULL)
+ memcpy(&addr, sa->sa_addrpool6, sizeof(addr));
+ goto done;
+ }
switch (addr.addr_af) {
case AF_INET:
cfg4 = (struct sockaddr_in *)&ikecfg->cfg.address.addr;
diff --git a/sbin/iked/parse.y b/sbin/iked/parse.y
index 037894e85d7..e5d645d4c11 100644
--- a/sbin/iked/parse.y
+++ b/sbin/iked/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.117 2020/11/03 16:45:40 tobhe Exp $ */
+/* $OpenBSD: parse.y,v 1.118 2020/11/29 21:00:44 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -100,6 +100,7 @@ static int passive = 0;
static int decouple = 0;
static int mobike = 1;
static int enforcesingleikesa = 0;
+static int stickyaddress = 0;
static int fragmentation = 0;
static int dpd_interval = IKED_IKE_SA_ALIVE_TIMEOUT;
static char *ocsp_url = NULL;
@@ -454,6 +455,7 @@ typedef struct {
%token IPCOMP OCSP IKELIFETIME MOBIKE NOMOBIKE RDOMAIN
%token FRAGMENTATION NOFRAGMENTATION DPD_CHECK_INTERVAL
%token ENFORCESINGLEIKESA NOENFORCESINGLEIKESA
+%token STICKYADDRESS NOSTICKYADDRESS
%token TOLERATE MAXAGE DYNAMIC
%token CERTPARTIALCHAIN
%token REQUEST
@@ -524,6 +526,8 @@ set : SET ACTIVE { passive = 0; }
| SET NOMOBIKE { mobike = 0; }
| SET ENFORCESINGLEIKESA { enforcesingleikesa = 1; }
| SET NOENFORCESINGLEIKESA { enforcesingleikesa = 0; }
+ | SET STICKYADDRESS { stickyaddress = 1; }
+ | SET NOSTICKYADDRESS { stickyaddress = 0; }
| SET OCSP STRING {
if ((ocsp_url = strdup($3)) == NULL) {
yyerror("cannot set ocsp_url");
@@ -1364,6 +1368,7 @@ lookup(char *s)
{ "noesn", NOESN },
{ "nofragmentation", NOFRAGMENTATION },
{ "nomobike", NOMOBIKE },
+ { "nostickyaddress", NOSTICKYADDRESS },
{ "ocsp", OCSP },
{ "passive", PASSIVE },
{ "peer", PEER },
@@ -1378,6 +1383,7 @@ lookup(char *s)
{ "set", SET },
{ "skip", SKIP },
{ "srcid", SRCID },
+ { "stickyaddress", STICKYADDRESS },
{ "tag", TAG },
{ "tap", TAP },
{ "tcpmd5", TCPMD5 },
@@ -1765,7 +1771,7 @@ parse_config(const char *filename, struct iked *x_env)
free(ocsp_url);
mobike = 1;
- enforcesingleikesa = 0;
+ enforcesingleikesa = stickyaddress = 0;
cert_partial_chain = decouple = passive = 0;
ocsp_tolerate = 0;
ocsp_url = NULL;
@@ -1786,6 +1792,7 @@ parse_config(const char *filename, struct iked *x_env)
env->sc_decoupled = decouple ? 1 : 0;
env->sc_mobike = mobike;
env->sc_enforcesingleikesa = enforcesingleikesa;
+ env->sc_stickyaddress = stickyaddress;
env->sc_frag = fragmentation;
env->sc_alive_timeout = dpd_interval;
env->sc_ocsp_url = ocsp_url;