-/* $OpenBSD: ipsec.c,v 1.152 2022/01/16 14:30:11 naddy Exp $ */
+/* $OpenBSD: ipsec.c,v 1.153 2023/08/07 04:01:29 dlg Exp $ */
/* $EOM: ipsec.c,v 1.143 2000/12/11 23:57:42 niklas Exp $ */
/*
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
+#include <limits.h>
#include <net/if.h>
#include <net/pfvar.h>
static int ipsec_sa_check_flow(struct sa *, void *);
static int ipsec_sa_check_flow_any(struct sa *, void *);
static int ipsec_sa_tag(struct exchange *, struct sa *, struct sa *);
+static int ipsec_sa_iface(struct exchange *, struct sa *, struct sa *);
static struct doi ipsec_doi = {
{0}, IPSEC_DOI_IPSEC,
isa->dport != isa2->dport)
return 0;
+ if ((sa->flags & SA_FLAG_IFACE) != (sa2->flags & SA_FLAG_IFACE))
+ return 0;
+
+ if (sa->flags & SA_FLAG_IFACE)
+ return sa->iface == sa2->iface;
+
/*
* If at least one of the IPsec SAs is incomplete, we're done.
*/
return (error);
}
+static int
+ipsec_sa_iface(struct exchange *exchange, struct sa *sa, struct sa *isakmp_sa)
+{
+ char *section, *value;
+ const char *errstr = NULL;
+
+ sa->tag = NULL;
+
+ if (exchange->name == NULL ||
+ (section = exchange->name) == NULL ||
+ (value = conf_get_str(section, "Interface")) == NULL)
+ return (0); /* ignore if not present */
+
+ sa->iface = strtonum(value, 0, UINT_MAX, &errstr);
+ if (errstr != NULL) {
+ log_error("[%s]:Interface %s", section, errstr);
+ return (-1);
+ }
+
+ sa->flags |= SA_FLAG_IFACE;
+
+ return (0);
+}
+
/*
* Do IPsec DOI specific finalizations task for the exchange where MSG was
* the final message.
if (ipsec_sa_tag(exchange, sa, isakmp_sa) == -1)
return;
+ if (ipsec_sa_iface(exchange, sa, isakmp_sa) == -1)
+ return;
+
for (proto = TAILQ_FIRST(&sa->protos),
last_proto = 0; proto;
proto = TAILQ_NEXT(proto, link)) {
* (a.k.a. flow) set up.
*/
if (!(sa->flags & SA_FLAG_ONDEMAND ||
+ sa->flags & SA_FLAG_IFACE ||
conf_get_str("General", "Acquire-Only") ||
acquire_only) &&
pf_key_v2_enable_sa(sa, isakmp_sa))
* We ignore any errors from the disabling of the flow.
*/
if (sa->flags & SA_FLAG_READY && !(sa->flags & SA_FLAG_ONDEMAND ||
- sa->flags & SA_FLAG_REPLACED || acquire_only ||
+ sa->flags & SA_FLAG_REPLACED || sa->flags & SA_FLAG_IFACE ||
+ acquire_only ||
conf_get_str("General", "Acquire-Only")))
pf_key_v2_disable_sa(sa, incoming);
-/* $OpenBSD: pf_key_v2.c,v 1.204 2022/01/31 23:51:15 sthen Exp $ */
+/* $OpenBSD: pf_key_v2.c,v 1.205 2023/08/07 04:01:30 dlg Exp $ */
/* $EOM: pf_key_v2.c,v 1.79 2000/12/12 00:33:19 niklas Exp $ */
/*
struct sadb_protocol flowtype, tprotocol;
struct sadb_x_udpencap udpencap;
char *addr_str, *s;
+ char iface_str[32];
msg.sadb_msg_type = incoming ? SADB_UPDATE : SADB_ADD;
switch (proto->proto) {
goto cleanup;
}
+ if (sa->flags & SA_FLAG_IFACE) {
+ struct sadb_x_iface *siface;
+
+ len = sizeof(*siface);
+ siface = calloc(1, len);
+ if (siface == NULL)
+ goto cleanup;
+
+ siface->sadb_x_iface_len = len / PF_KEY_V2_CHUNK;
+ siface->sadb_x_iface_exttype = SADB_X_EXT_IFACE;
+ siface->sadb_x_iface_unit = sa->iface;
+ siface->sadb_x_iface_direction = incoming ?
+ IPSP_DIRECTION_IN : IPSP_DIRECTION_OUT;
+
+ if (pf_key_v2_msg_add(update, (struct sadb_ext *)siface,
+ PF_KEY_V2_NODE_MALLOCED) == -1)
+ goto cleanup;
+
+ snprintf(iface_str, sizeof(iface_str), "iface %u", sa->iface);
+ }
+
/* XXX Here can sensitivity extensions be setup. */
if (sockaddr2text(dst, &addr_str, 0))
addr_str = 0;
LOG_DBG((LOG_SYSDEP, 10, "pf_key_v2_set_spi: "
- "satype %d dst %s SPI 0x%x%s%s", msg.sadb_msg_satype,
+ "satype %d dst %s SPI 0x%x%s%s%s", msg.sadb_msg_satype,
addr_str ? addr_str : "unknown",
ntohl(ssa.sadb_sa_spi), sa->tag ? " tag " : "",
- sa->tag ? sa->tag : ""));
+ sa->tag ? sa->tag : "", iface_str));
free(addr_str);
-/* $OpenBSD: sa.h,v 1.54 2018/01/15 09:54:48 mpi Exp $ */
+/* $OpenBSD: sa.h,v 1.55 2023/08/07 04:01:30 dlg Exp $ */
/* $EOM: sa.h,v 1.58 2000/10/10 12:39:01 provos Exp $ */
/*
/* The add a pf tag to packets matching the established SA. */
char *tag;
+
+ /* IPsec with Interface SAs, enabled with SA_FLAG_IFACE */
+ unsigned int iface;
};
/* This SA is alive. */
#define SA_FLAG_NAT_T_ENABLE 0x100
#define SA_FLAG_NAT_T_KEEPALIVE 0x200
+/* Policy is handled by routing/filtering on the specified iface */
+#define SA_FLAG_IFACE 0x400
+
extern void proto_free(struct proto * proto);
extern int sa_add_transform(struct sa *, struct payload *, int,
struct proto **);