summaryrefslogtreecommitdiff
path: root/sbin/iked
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/iked')
-rw-r--r--sbin/iked/iked.h3
-rw-r--r--sbin/iked/ikev2.c106
-rw-r--r--sbin/iked/parse.y6
-rw-r--r--sbin/iked/pfkey.c35
4 files changed, 94 insertions, 56 deletions
diff --git a/sbin/iked/iked.h b/sbin/iked/iked.h
index 2c7fbe14af3..bdfac0ee74e 100644
--- a/sbin/iked/iked.h
+++ b/sbin/iked/iked.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: iked.h,v 1.223 2023/07/28 11:23:03 claudio Exp $ */
+/* $OpenBSD: iked.h,v 1.224 2023/08/11 11:24:55 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -260,6 +260,7 @@ struct iked_policy {
#define IKED_POLICY_SKIP 0x10
#define IKED_POLICY_IPCOMP 0x20
#define IKED_POLICY_TRANSPORT 0x40
+#define IKED_POLICY_ROUTING 0x80
int pol_refcnt;
diff --git a/sbin/iked/ikev2.c b/sbin/iked/ikev2.c
index bf6bf0fb0d4..e243432a742 100644
--- a/sbin/iked/ikev2.c
+++ b/sbin/iked/ikev2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ikev2.c,v 1.377 2023/08/04 19:06:25 claudio Exp $ */
+/* $OpenBSD: ikev2.c,v 1.378 2023/08/11 11:24:55 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -6532,63 +6532,65 @@ ikev2_childsa_enable(struct iked *env, struct iked_sa *sa)
peer_changed = (memcmp(&sa->sa_peer_loaded, &sa->sa_peer,
sizeof(sa->sa_peer_loaded)) != 0);
- TAILQ_FOREACH(flow, &sa->sa_flows, flow_entry) {
- /* re-load the flow if the peer for the flow has changed */
- reload = 0;
- if (flow->flow_loaded) {
- if (!peer_changed) {
- log_debug("%s: flow already loaded %p",
- __func__, flow);
- continue;
+ if (!(sa->sa_policy->pol_flags & IKED_POLICY_ROUTING)) {
+ TAILQ_FOREACH(flow, &sa->sa_flows, flow_entry) {
+ /* re-load the flow if the peer for the flow has changed */
+ reload = 0;
+ if (flow->flow_loaded) {
+ if (!peer_changed) {
+ log_debug("%s: flow already loaded %p",
+ __func__, flow);
+ continue;
+ }
+ RB_REMOVE(iked_flows, &env->sc_activeflows, flow);
+ (void)pfkey_flow_delete(env, flow);
+ flow->flow_loaded = 0; /* we did RB_REMOVE */
+ reload = 1;
}
- RB_REMOVE(iked_flows, &env->sc_activeflows, flow);
- (void)pfkey_flow_delete(env, flow);
- flow->flow_loaded = 0; /* we did RB_REMOVE */
- reload = 1;
- }
- if (pfkey_flow_add(env, flow) != 0) {
- log_debug("%s: failed to load flow", __func__);
- goto done;
- }
+ if (pfkey_flow_add(env, flow) != 0) {
+ log_debug("%s: failed to load flow", __func__);
+ goto done;
+ }
- if ((oflow = RB_FIND(iked_flows, &env->sc_activeflows, flow))
- != NULL) {
- log_debug("%s: replaced old flow %p with %p",
- __func__, oflow, flow);
- oflow->flow_loaded = 0;
- RB_REMOVE(iked_flows, &env->sc_activeflows, oflow);
- }
+ if ((oflow = RB_FIND(iked_flows, &env->sc_activeflows, flow))
+ != NULL) {
+ log_debug("%s: replaced old flow %p with %p",
+ __func__, oflow, flow);
+ oflow->flow_loaded = 0;
+ RB_REMOVE(iked_flows, &env->sc_activeflows, oflow);
+ }
- RB_INSERT(iked_flows, &env->sc_activeflows, flow);
+ RB_INSERT(iked_flows, &env->sc_activeflows, flow);
- log_debug("%s: %sloaded flow %p", __func__,
- reload ? "re" : "", flow);
+ log_debug("%s: %sloaded flow %p", __func__,
+ reload ? "re" : "", flow);
- /* append flow to log buffer */
- if (flow->flow_dir == IPSP_DIRECTION_OUT &&
- flow->flow_prenat.addr_af != 0)
- snprintf(prenat_mask, sizeof(prenat_mask), "%d",
- flow->flow_prenat.addr_mask);
- else
- prenat_mask[0] = '\0';
- if (flow->flow_dir == IPSP_DIRECTION_OUT) {
- if (ftello(flowf) > 0)
- fputs(", ", flowf);
- fprintf(flowf, "%s-%s/%d%s%s%s%s%s=%s/%d(%u)%s",
- print_map(flow->flow_saproto, ikev2_saproto_map),
- print_addr(&flow->flow_src.addr),
- flow->flow_src.addr_mask,
- flow->flow_prenat.addr_af != 0 ? "[": "",
- flow->flow_prenat.addr_af != 0 ?
- print_addr(&flow->flow_prenat.addr) : "",
- flow->flow_prenat.addr_af != 0 ? "/" : "",
- flow->flow_prenat.addr_af != 0 ? prenat_mask : "",
- flow->flow_prenat.addr_af != 0 ? "]": "",
- print_addr(&flow->flow_dst.addr),
- flow->flow_dst.addr_mask,
- flow->flow_ipproto,
- reload ? "-R" : "");
+ /* append flow to log buffer */
+ if (flow->flow_dir == IPSP_DIRECTION_OUT &&
+ flow->flow_prenat.addr_af != 0)
+ snprintf(prenat_mask, sizeof(prenat_mask), "%d",
+ flow->flow_prenat.addr_mask);
+ else
+ prenat_mask[0] = '\0';
+ if (flow->flow_dir == IPSP_DIRECTION_OUT) {
+ if (ftello(flowf) > 0)
+ fputs(", ", flowf);
+ fprintf(flowf, "%s-%s/%d%s%s%s%s%s=%s/%d(%u)%s",
+ print_map(flow->flow_saproto, ikev2_saproto_map),
+ print_addr(&flow->flow_src.addr),
+ flow->flow_src.addr_mask,
+ flow->flow_prenat.addr_af != 0 ? "[": "",
+ flow->flow_prenat.addr_af != 0 ?
+ print_addr(&flow->flow_prenat.addr) : "",
+ flow->flow_prenat.addr_af != 0 ? "/" : "",
+ flow->flow_prenat.addr_af != 0 ? prenat_mask : "",
+ flow->flow_prenat.addr_af != 0 ? "]": "",
+ print_addr(&flow->flow_dst.addr),
+ flow->flow_dst.addr_mask,
+ flow->flow_ipproto,
+ reload ? "-R" : "");
+ }
}
}
diff --git a/sbin/iked/parse.y b/sbin/iked/parse.y
index 075981db320..5fadcd200e6 100644
--- a/sbin/iked/parse.y
+++ b/sbin/iked/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.143 2023/06/14 14:09:29 claudio Exp $ */
+/* $OpenBSD: parse.y,v 1.144 2023/08/11 11:24:55 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -2519,6 +2519,10 @@ create_ike(char *name, int af, struct ipsec_addr_wrap *ipproto,
}
if (iface != NULL) {
+ /* sec(4) */
+ if (strncmp("sec", iface, strlen("sec")) == 0)
+ pol.pol_flags |= IKED_POLICY_ROUTING;
+
pol.pol_iface = if_nametoindex(iface);
if (pol.pol_iface == 0) {
yyerror("invalid iface");
diff --git a/sbin/iked/pfkey.c b/sbin/iked/pfkey.c
index eaebe53a990..80a931d5132 100644
--- a/sbin/iked/pfkey.c
+++ b/sbin/iked/pfkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkey.c,v 1.82 2023/06/13 12:34:12 tb Exp $ */
+/* $OpenBSD: pfkey.c,v 1.83 2023/08/11 11:24:55 tobhe Exp $ */
/*
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
@@ -25,6 +25,7 @@
#include <netinet/in.h>
#include <netinet/ip_ipsp.h>
+#include <net/if.h>
#include <net/pfkeyv2.h>
#include <err.h>
@@ -40,7 +41,7 @@
#include "ikev2.h"
#define ROUNDUP(x) (((x) + (PFKEYV2_CHUNK - 1)) & ~(PFKEYV2_CHUNK - 1))
-#define IOV_CNT 27
+#define IOV_CNT 28
#define PFKEYV2_CHUNK sizeof(uint64_t)
#define PFKEY_REPLY_TIMEOUT 1000
@@ -453,6 +454,7 @@ pfkey_flow(struct iked *env, uint8_t satype, uint8_t action, struct iked_flow *f
int
pfkey_sa(struct iked *env, uint8_t satype, uint8_t action, struct iked_childsa *sa)
{
+ char iface[IF_NAMESIZE];
struct sadb_msg smsg;
struct sadb_sa sadb;
struct sadb_address sa_src, sa_dst, sa_pxy;
@@ -460,6 +462,7 @@ pfkey_sa(struct iked *env, uint8_t satype, uint8_t action, struct iked_childsa *
struct sadb_lifetime sa_ltime_hard, sa_ltime_soft;
struct sadb_x_udpencap udpencap;
struct sadb_x_tag sa_tag;
+ struct sadb_x_iface sa_iface;
char *tag = NULL;
struct sadb_x_tap sa_tap;
struct sadb_x_rdomain sa_rdomain;
@@ -469,6 +472,8 @@ pfkey_sa(struct iked *env, uint8_t satype, uint8_t action, struct iked_childsa *
struct iked_policy *pol;
struct iked_addr *dst;
struct iovec iov[IOV_CNT];
+ const char *errstr = NULL;
+ uint32_t ifminor;
uint32_t jitter;
int iov_cnt;
int ret, dotap = 0;
@@ -549,6 +554,7 @@ pfkey_sa(struct iked *env, uint8_t satype, uint8_t action, struct iked_childsa *
bzero(&udpencap, sizeof udpencap);
bzero(&sa_ltime_hard, sizeof(sa_ltime_hard));
bzero(&sa_ltime_soft, sizeof(sa_ltime_soft));
+ bzero(&sa_iface, sizeof(sa_iface));
if (pol->pol_rdomain >= 0) {
bzero(&sa_rdomain, sizeof(sa_rdomain));
@@ -688,6 +694,24 @@ pfkey_sa(struct iked *env, uint8_t satype, uint8_t action, struct iked_childsa *
sa_tap.sadb_x_tap_unit = pol->pol_tap;
}
+ if (pol->pol_flags & IKED_POLICY_ROUTING) {
+ sa_iface.sadb_x_iface_exttype = SADB_X_EXT_IFACE;
+ sa_iface.sadb_x_iface_len = sizeof(sa_iface) / 8;
+ if (if_indextoname(pol->pol_iface, iface) == NULL) {
+ log_warnx("%s: unsupported interface %s",
+ __func__, iface);
+ return (-1);
+ }
+ ifminor = strtonum(iface + strlen("sec"), 0, UINT_MAX, &errstr);
+ if (errstr != NULL) {
+ log_warnx("%s: unsupported interface %s",
+ __func__, iface);
+ return (-1);
+ }
+ sa_iface.sadb_x_iface_unit = ifminor;
+ sa_iface.sadb_x_iface_direction = sa->csa_dir;
+ }
+
send:
#define PAD(len) \
@@ -816,6 +840,13 @@ pfkey_sa(struct iked *env, uint8_t satype, uint8_t action, struct iked_childsa *
PAD(strlen(tag) + 1);
}
+ if (sa_iface.sadb_x_iface_len) {
+ iov[iov_cnt].iov_base = &sa_iface;
+ iov[iov_cnt].iov_len = sa_iface.sadb_x_iface_len * 8;
+ smsg.sadb_msg_len += sa_iface.sadb_x_iface_len;
+ iov_cnt++;
+ }
+
if (dotap != 0) {
/* enc(4) device tap unit */
iov[iov_cnt].iov_base = &sa_tap;