-/* $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>
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" : "");
+ }
}
}
-/* $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>
#include <netinet/in.h>
#include <netinet/ip_ipsp.h>
+#include <net/if.h>
#include <net/pfkeyv2.h>
#include <err.h>
#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
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;
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;
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;
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));
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) \
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;